From 42d596c667208c66a31476b279ad22c161d1b585 Mon Sep 17 00:00:00 2001 From: MK Date: Sun, 25 Oct 2026 16:49:02 +0900 Subject: [PATCH] ci: use setup-vp and run checks on Linux --- .github/workflows/ci.yml | 20 +++++++++------- .github/workflows/remote-cache-deploy.yml | 24 ++++++++++++++----- .github/workflows/remote-cache-production.yml | 14 +++++++---- README.md | 4 ++-- docs/e2e-plan.md | 20 ++++++++-------- 5 files changed, 51 insertions(+), 31 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 73c94cb..a0c1583 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,17 +14,19 @@ concurrency: jobs: check: - name: Check (${{ matrix.os }}) - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - runs-on: ${{ matrix.os }} + name: Check (ubuntu-latest) + runs-on: ubuntu-latest timeout-minutes: 15 steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: persist-credentials: false - - uses: oxc-project/setup-node@f46a72f95efdc55273fcd042d61c84e723b2892c # v1.4.1 - - run: pnpm check - - run: pnpm smoke + - uses: voidzero-dev/setup-vp@cab1ab9eaff52d4857875f4f2c016e36af8f2c76 # v1.22.0 + with: + node-version-file: .node-version + cache: true + cache-save: ${{ github.ref_name == (github.event.repository.default_branch || 'main') }} + run-install: | + - args: ['--frozen-lockfile', '--ignore-scripts'] + - run: vp run check + - run: vp run smoke diff --git a/.github/workflows/remote-cache-deploy.yml b/.github/workflows/remote-cache-deploy.yml index ab09636..1034f80 100644 --- a/.github/workflows/remote-cache-deploy.yml +++ b/.github/workflows/remote-cache-deploy.yml @@ -32,9 +32,15 @@ jobs: with: ref: ${{ env.REMOTE_CACHE_SOURCE_SHA }} persist-credentials: false - - uses: oxc-project/setup-node@f46a72f95efdc55273fcd042d61c84e723b2892c # v1.4.1 - - run: pnpm check - - run: pnpm smoke + - uses: voidzero-dev/setup-vp@cab1ab9eaff52d4857875f4f2c016e36af8f2c76 # v1.22.0 + with: + node-version-file: .node-version + cache: true + cache-save: ${{ github.ref_name == (github.event.repository.default_branch || 'main') }} + run-install: | + - args: ['--frozen-lockfile', '--ignore-scripts'] + - run: vp run check + - run: vp run smoke - name: Explain staging deployment availability if: >- always() && github.event_name == 'pull_request' && @@ -78,15 +84,21 @@ jobs: with: ref: ${{ env.REMOTE_CACHE_SOURCE_SHA }} persist-credentials: false - - uses: oxc-project/setup-node@f46a72f95efdc55273fcd042d61c84e723b2892c # v1.4.1 + - uses: voidzero-dev/setup-vp@cab1ab9eaff52d4857875f4f2c016e36af8f2c76 # v1.22.0 + with: + node-version-file: .node-version + cache: true + cache-save: ${{ github.ref_name == (github.event.repository.default_branch || 'main') }} + run-install: | + - args: ['--frozen-lockfile', '--ignore-scripts'] - name: Create or update persistent staging resources id: deploy - run: pnpm ci:deploy staging + run: vp run ci:deploy staging env: CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} - name: Run smoke tests against the staging Worker, D1, and R2 - run: pnpm e2e + run: vp run e2e env: CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} diff --git a/.github/workflows/remote-cache-production.yml b/.github/workflows/remote-cache-production.yml index f60f555..49f7923 100644 --- a/.github/workflows/remote-cache-production.yml +++ b/.github/workflows/remote-cache-production.yml @@ -23,13 +23,19 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: persist-credentials: false - - uses: oxc-project/setup-node@f46a72f95efdc55273fcd042d61c84e723b2892c # v1.4.1 - - run: pnpm check - - run: pnpm smoke + - uses: voidzero-dev/setup-vp@cab1ab9eaff52d4857875f4f2c016e36af8f2c76 # v1.22.0 + with: + node-version-file: .node-version + cache: true + cache-save: ${{ github.ref_name == (github.event.repository.default_branch || 'main') }} + run-install: | + - args: ['--frozen-lockfile', '--ignore-scripts'] + - run: vp run check + - run: vp run smoke # The script accepts only manual runs of this repository's main branch. - name: Deploy the production Worker, D1, and R2 id: deploy - run: pnpm ci:deploy production + run: vp run ci:deploy production env: CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} diff --git a/README.md b/README.md index 901ba4c..95908ec 100644 --- a/README.md +++ b/README.md @@ -40,9 +40,9 @@ pnpm check pnpm smoke ``` -The repository created by the deployment button runs the same commands. `pnpm check` generates binding/runtime types, runs Vite+ formatting, lint, and type checks, and runs the existing TypeScript compiler check on all source, operator, benchmark, test, and Vite+ configuration files. `pnpm smoke` runs isolated workerd/D1/R2 tests with `vite-plus/test` and bundles a Wrangler deployment dry run. Tests generate a temporary RSA key and intercept only GitHub's fixed JWKS URL. They need no Cloudflare account, GitHub credentials, or client adapter. CI runs them on Linux, macOS, and Windows. +The repository created by the deployment button runs the same commands. `pnpm check` generates binding/runtime types, runs Vite+ formatting, lint, and type checks, and runs the existing TypeScript compiler check on all source, operator, benchmark, test, and Vite+ configuration files. `pnpm smoke` runs isolated workerd/D1/R2 tests with `vite-plus/test` and bundles a Wrangler deployment dry run. Tests generate a temporary RSA key and intercept only GitHub's fixed JWKS URL. They need no Cloudflare account, GitHub credentials, or client adapter. CI runs them on Linux. -Vite+ is pinned in `pnpm-workspace.yaml`; `vite.config.ts` configures formatting, linting, and tests. With the global CLI, use `vp install --frozen-lockfile`, `vp run check`, and `vp run smoke`. The `packageManager` field selects pnpm for Vite+ dependency commands. A global installation is optional: use `pnpm exec vp ` for the local CLI. +Vite+ is pinned in `pnpm-workspace.yaml`; `vite.config.ts` configures formatting, linting, and tests. CI uses `voidzero-dev/setup-vp` to install the pinned Vite+ version and the Node.js version from `.node-version`, then runs scripts with `vp run`. With the global CLI, use `vp install --frozen-lockfile`, `vp run check`, and `vp run smoke`. The `packageManager` field selects pnpm for Vite+ dependency commands. A global installation is optional: use `pnpm exec vp ` for the local CLI. `vp test run` runs the test suite once; `vp test` starts watch mode in an interactive terminal. `vp run ` runs a project script, so `vp run test` uses the one-shot test script and `vp run check` generates Worker types before checking. After generating types with `vp run types`, you can also run `vp check` directly. Use `vp run dev` for the Wrangler dev server and `vp run build` for the deployment dry run. The built-in `vp dev` and `vp build` run Vite and do not call these Wrangler scripts. This Worker keeps Wrangler's binding, scheduled-event, and deployment configuration. diff --git a/docs/e2e-plan.md b/docs/e2e-plan.md index f2aa664..7f1c9b6 100644 --- a/docs/e2e-plan.md +++ b/docs/e2e-plan.md @@ -8,7 +8,7 @@ The [self-hosting quick start](self-hosting.md#quick-start-deploy-to-cloudflare) Automated regression checks cover independently named resources, an empty D1 database, repository binding, optional Paid cleanup batches, retries from a clean checkout, preserved withdrawal and quotas, rejected repository reassignment, missing storage, and placeholder IDs. Post-deployment HTTP checks require the current deployment ID and `Cache-Control: no-store`. They check an anonymous upload (`401`), malformed fetch (`400`), and a valid cache miss (`404`). A disabled namespace must continue to return `404`. Polling allows for route/revision propagation and fails the build if checks never pass. These checks do not publish data or validate authorized uploads. -Linux, macOS, and Windows CI also install with the frozen lockfile, check types, run the tests, and bundle the Worker, as the repository created by the button does. +Linux CI also installs with the frozen lockfile, checks types, runs the tests, and bundles the Worker, as the repository created by the button does. Before releasing the button, complete this live acceptance exercise in a dedicated account or with dedicated test resources: @@ -26,7 +26,7 @@ Local tests cannot prove the Cloudflare setup form, resource provisioning, build `.github/workflows/remote-cache-deploy.yml` runs for every PR and push to `main`. It also supports manual runs from the default branch. -1. Check the exact source commit with `pnpm check` and `pnpm smoke`. +1. Check the exact source commit with `vp run check` and `vp run smoke`. 2. Create or update the shared staging Worker, D1 database, and R2 bucket. Apply D1 migrations. 3. Check that the R2 bucket has no public domain. Seed public test fixtures through the authenticated operator API. 4. Run smoke tests against the deployed HTTP endpoints. Every response must identify the expected commit and workflow attempt through `X-Remote-Cache-Deployment`. @@ -74,13 +74,13 @@ GitHub can suppress `pull_request` workflows when a PR has merge conflicts. Reso The production write policy requires a real GitHub token with `event_name=push`, the registered repository and owner IDs, its configured main branch, and the exact namespace audience. A `workflow_dispatch` token cannot pass this policy, and neither can a PR token unless its namespace opts in to [pull request uploads](../README.md#pull-request-uploads). Staging keeps that opt-in off, so PR runs keep checking that PR tokens are rejected. GitHub signs the event claim; the test runner cannot change it. -| Level | Trigger | What it proves | -| ---------------------------- | ------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | -| Local regression | Every normal CI run, on Linux/macOS/Windows | Protocol, storage state transitions, failures, and the e2e driver against workerd/D1/R2 emulators | -| PR staging smoke tests | Related changes in an internal PR | Deployment revision, migrations, private R2, real public HTTP reads, real rejected OIDC writes, policy changes, and expiry | -| Main staging smoke tests | Related push to `main` | All PR cases plus real authorized HTTP writes, multipart uploads, replacement, concurrency, and quota checks | -| Manual staging smoke tests | Default-branch workflow dispatch | The same public-read and rejected-write checks as PR runs | -| Release / incident exercises | Maintainer-controlled staging session | Maximum payloads, real Cron, long-running limits, provider outages, lifecycle delays, restore, rollback, and hostile workflow identities | +| Level | Trigger | What it proves | +| ---------------------------- | ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | +| Local regression | Every normal CI run, on Linux | Protocol, storage state transitions, failures, and the e2e driver against workerd/D1/R2 emulators | +| PR staging smoke tests | Related changes in an internal PR | Deployment revision, migrations, private R2, real public HTTP reads, real rejected OIDC writes, policy changes, and expiry | +| Main staging smoke tests | Related push to `main` | All PR cases plus real authorized HTTP writes, multipart uploads, replacement, concurrency, and quota checks | +| Manual staging smoke tests | Default-branch workflow dispatch | The same public-read and rejected-write checks as PR runs | +| Release / incident exercises | Maintainer-controlled staging session | Maximum payloads, real Cron, long-running limits, provider outages, lifecycle delays, restore, rollback, and hostile workflow identities | The runner obtains tokens directly from GitHub with `id-token: write`. It checks the token request host, rejects redirects, bounds responses, and caches each audience separately for three minutes. Tokens remain in memory. Reports and artifacts contain no GitHub or Cloudflare credentials. The Worker has no alternate issuer, test signing key, administrative HTTP endpoint, or weakened write policy. @@ -173,7 +173,7 @@ Staging policies belong to CI. Do not use these names for an operator-managed pr `.github/workflows/remote-cache-production.yml` deploys this repository's production cache. It runs only when a maintainer starts it from **Actions → Remote cache production → Run workflow** on `main`. Pushes and PRs never deploy production. Before starting it, check that the commit's main-branch staging run passed. -The workflow repeats `pnpm check` and `pnpm smoke`, then runs `pnpm ci:deploy production`. `scripts/ci/production.ts` names the Worker, D1 database, and R2 bucket. `.github/production-repositories.jsonc` maps each cache namespace to a public GitHub repository. The command refuses other repositories, branches, and events, so repositories created by Deploy to Cloudflare cannot run it. Staging and production share `scripts/ci/deploy.ts`. Setup creates or reuses the named resources, applies migrations, and binds each namespace; then the Worker deploys once. Every namespace endpoint must then serve the new deployment ID. The run summary and the `production` environment list the endpoints, for example `https://voidzero-remote-cache..workers.dev/projects/rolldown`. +The workflow repeats `vp run check` and `vp run smoke`, then runs `vp run ci:deploy production`. `scripts/ci/production.ts` names the Worker, D1 database, and R2 bucket. `.github/production-repositories.jsonc` maps each cache namespace to a public GitHub repository. The command refuses other repositories, branches, and events, so repositories created by Deploy to Cloudflare cannot run it. Staging and production share `scripts/ci/deploy.ts`. Setup creates or reuses the named resources, applies migrations, and binds each namespace; then the Worker deploys once. Every namespace endpoint must then serve the new deployment ID. The run summary and the `production` environment list the endpoints, for example `https://voidzero-remote-cache..workers.dev/projects/rolldown`. To bind another repository, add `"namespace": "owner/repository"` to `.github/production-repositories.jsonc`, merge the change, and run the workflow. Only public repositories can publish. The list decides which namespaces serve reads and accept uploads: each deployment enables every listed namespace and disables every other namespace, so a `pnpm operator policy` change lasts only until the next deployment. To withdraw a repository, remove its entry and run the workflow. For an immediate stop, also run `pnpm operator policy --namespace --enabled off`. Data in a disabled namespace expires with its retention; `pnpm operator purge` deletes it sooner. Deployments never change the cache-wide `pnpm operator deployment` switches or move a namespace to another repository. To roll back, re-run an earlier successful production run. A re-run deploys its original commit.