feat(store): add agent x402 capacity purchases #1546
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| env: | |
| E2E_CLOUD_PRO_EMAIL: ${{ secrets.E2E_CLOUD_PRO_EMAIL }} | |
| E2E_CLOUD_PRO_PASSWORD: ${{ secrets.E2E_CLOUD_PRO_PASSWORD }} | |
| # Least-privilege default; jobs that need more (e.g. packages: write) opt in per-job. | |
| permissions: | |
| contents: read | |
| jobs: | |
| downloader: | |
| name: Downloader (Go) | |
| runs-on: ubuntu-latest | |
| if: github.repository == 'saltbo/zpan' | |
| defaults: | |
| run: | |
| working-directory: cmd | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: actions/setup-go@v6 | |
| with: | |
| go-version-file: cmd/go.mod | |
| cache-dependency-path: cmd/go.sum | |
| - name: Check formatting | |
| run: | | |
| files="$(gofmt -l .)" | |
| if [ -n "$files" ]; then | |
| echo "$files" | |
| exit 1 | |
| fi | |
| - name: Test with coverage threshold | |
| run: bash scripts/test-coverage.sh | |
| - name: Install live downloader engines | |
| run: sudo apt-get update && sudo apt-get install -y aria2 qbittorrent-nox | |
| working-directory: . | |
| - name: Verify live downloads | |
| run: LIVE_DOWNLOAD_VERIFY=1 go test ./pkg/downloaders -run 'TestLive(DownloadThreeSourceTypes|QBittorrentDownloadTorrentURL)' -count=1 -v | |
| check: | |
| name: Typecheck & Test | |
| runs-on: ubuntu-latest | |
| if: github.repository == 'saltbo/zpan' | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: pnpm/action-setup@v4 | |
| - uses: actions/setup-node@v6 | |
| with: | |
| node-version: 24 | |
| cache: pnpm | |
| - uses: actions/setup-go@v6 | |
| with: | |
| go-version-file: cmd/go.mod | |
| cache-dependency-path: cmd/go.sum | |
| - run: pnpm install --frozen-lockfile | |
| - run: pnpm lint | |
| - run: pnpm lint:arch | |
| - run: pnpm lint:http | |
| - run: pnpm lint:spec | |
| - run: pnpm typecheck | |
| - run: pnpm openapi:client:check | |
| - run: pnpm exec vitest run --project unit --coverage --coverage.reportsDirectory=coverage/unit | |
| - uses: codecov/codecov-action@v5 | |
| if: always() | |
| with: | |
| files: coverage/unit/coverage-final.json | |
| flags: unit | |
| disable_search: true | |
| fail_ci_if_error: false | |
| handle_no_reports_found: true | |
| - run: pnpm exec vitest run --project integration --coverage --coverage.reportsDirectory=coverage/integration | |
| - uses: codecov/codecov-action@v5 | |
| if: always() | |
| with: | |
| files: coverage/integration/coverage-final.json | |
| flags: integration | |
| disable_search: true | |
| fail_ci_if_error: false | |
| handle_no_reports_found: true | |
| - run: mkdir -p dist | |
| - run: pnpm test:cf | |
| docker-smoke: | |
| name: Docker image smoke test | |
| runs-on: ubuntu-latest | |
| if: github.repository == 'saltbo/zpan' | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: docker/setup-buildx-action@v4 | |
| - name: Build & start the stack | |
| run: docker compose -f docker-compose.yml up -d --build --wait --wait-timeout 300 | |
| - name: Assert server health from host | |
| run: curl --fail --retry 5 --retry-delay 3 --retry-connrefused http://localhost:8222/api/health | |
| - name: Dump logs on failure | |
| if: failure() | |
| run: docker compose -f docker-compose.yml logs --no-color | |
| - name: Tear down | |
| if: always() | |
| run: docker compose -f docker-compose.yml down -v | |
| docker-dev: | |
| name: Docker dev image | |
| runs-on: ubuntu-latest | |
| needs: [check, docker-smoke] | |
| # Publish the bleeding-edge `:dev` image only for green pushes to main on the | |
| # canonical repo — never on PRs or forks. `:latest` stays pinned to releases. | |
| if: github.repository == 'saltbo/zpan' && github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| permissions: | |
| contents: read | |
| packages: write | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: docker/login-action@v4 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - uses: docker/setup-buildx-action@v4 | |
| - name: Build & push server image | |
| uses: docker/build-push-action@v7 | |
| with: | |
| context: . | |
| push: true | |
| # Dev images are amd64-only to skip slow arm64 QEMU emulation | |
| # (native better-sqlite3/sharp). Releases stay multi-arch. | |
| platforms: linux/amd64 | |
| build-args: | | |
| APP_VERSION=dev | |
| APP_COMMIT=${{ github.sha }} | |
| tags: ghcr.io/${{ github.repository }}:dev | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| - name: Build & push CLI image | |
| uses: docker/build-push-action@v7 | |
| with: | |
| context: . | |
| target: cli | |
| push: true | |
| # Dev images are amd64-only (see server image above). Releases stay multi-arch. | |
| platforms: linux/amd64 | |
| build-args: | | |
| APP_VERSION=dev | |
| APP_COMMIT=${{ github.sha }} | |
| tags: ghcr.io/${{ github.repository }}:dev-cli | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| cf-deploy-dry-run: | |
| name: CF deploy dry-run | |
| runs-on: ubuntu-latest | |
| if: github.repository == 'saltbo/zpan' | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: pnpm/action-setup@v4 | |
| - uses: actions/setup-node@v6 | |
| with: | |
| node-version: 24 | |
| cache: pnpm | |
| - run: pnpm install --frozen-lockfile | |
| - name: Build | |
| env: | |
| ZPAN_APP_VERSION: ci-dry-run | |
| run: pnpm build | |
| # --dry-run compiles the Worker and validates wrangler.toml + the | |
| # vite-plugin deploy config (assets dir, queues, bindings) without | |
| # contacting Cloudflare, so it needs no secrets and runs on fork PRs. | |
| # Guards the deploy regressions a unit test can't: a dropped build step | |
| # (#417) or an unprovisioned binding added to wrangler.toml. | |
| - name: Validate Cloudflare deploy config | |
| run: pnpm exec wrangler deploy --dry-run | |
| e2e-node: | |
| name: E2E (Node) | |
| runs-on: ubuntu-latest | |
| needs: check | |
| env: | |
| BETTER_AUTH_SECRET: ci-test-secret-that-is-at-least-32-chars | |
| E2E_CLOUD_BUSINESS_EMAIL_NODE: ${{ secrets.E2E_CLOUD_BUSINESS_EMAIL_NODE }} | |
| E2E_CLOUD_BUSINESS_PASSWORD_NODE: ${{ secrets.E2E_CLOUD_BUSINESS_PASSWORD_NODE }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: pnpm/action-setup@v4 | |
| - uses: actions/setup-node@v6 | |
| with: | |
| node-version: 24 | |
| cache: pnpm | |
| - run: pnpm install --frozen-lockfile | |
| - name: Run E2E | |
| run: | | |
| E2E_APP_PORT=5185 \ | |
| E2E_BASE_URL=http://localhost:5185 \ | |
| E2E_LOCAL_BASE_URL=http://localhost:5185 \ | |
| E2E_S3_MOCK=1 \ | |
| E2E_STORAGE_ENDPOINT=http://127.0.0.1:9191 \ | |
| E2E_STORAGE_BUCKET=e2e-test \ | |
| E2E_STORAGE_REGION=auto \ | |
| E2E_STORAGE_ACCESS_KEY=e2e-access-key \ | |
| E2E_STORAGE_SECRET_KEY=e2e-secret-key \ | |
| BETTER_AUTH_URL=http://localhost:5185 \ | |
| TRUSTED_ORIGINS=http://localhost:5185 \ | |
| pnpm e2e --project=desktop --grep-invert "Cloud store|Cloud licensing|Archive jobs|Site announcements" | |
| - name: Install cloudflared | |
| if: env.E2E_CLOUD_BUSINESS_EMAIL_NODE != '' && env.E2E_CLOUD_BUSINESS_PASSWORD_NODE != '' | |
| run: | | |
| curl -L --fail --output cloudflared https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 | |
| chmod +x cloudflared | |
| - name: Run cloud E2E | |
| if: env.E2E_CLOUD_BUSINESS_EMAIL_NODE != '' && env.E2E_CLOUD_BUSINESS_PASSWORD_NODE != '' | |
| run: | | |
| ZPAN_CLOUD_URL=https://zpan-cloud-staging.saltbo.workers.dev \ | |
| VITE_ZPAN_CLOUD_URL=https://zpan-cloud-staging.saltbo.workers.dev \ | |
| CLOUDFLARED_BIN=./cloudflared \ | |
| pnpm e2e:cloud -- --runtime node | |
| - uses: actions/upload-artifact@v4 | |
| if: failure() | |
| with: | |
| name: playwright-report-node | |
| path: playwright-report/ | |
| retention-days: 7 | |
| e2e-cf: | |
| name: E2E (CF Workers) | |
| runs-on: ubuntu-latest | |
| needs: check | |
| env: | |
| BETTER_AUTH_SECRET: ci-test-secret-that-is-at-least-32-chars | |
| E2E_CLOUD_BUSINESS_EMAIL_CF: ${{ secrets.E2E_CLOUD_BUSINESS_EMAIL_CF }} | |
| E2E_CLOUD_BUSINESS_PASSWORD_CF: ${{ secrets.E2E_CLOUD_BUSINESS_PASSWORD_CF }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: pnpm/action-setup@v4 | |
| - uses: actions/setup-node@v6 | |
| with: | |
| node-version: 24 | |
| cache: pnpm | |
| - run: pnpm install --frozen-lockfile | |
| - name: Prepare local D1 | |
| run: pnpm exec wrangler d1 migrations apply DB --local | |
| - name: Prepare CF E2E env | |
| run: | | |
| cat > .dev.vars <<'EOF' | |
| BETTER_AUTH_SECRET=ci-test-secret-that-is-at-least-32-chars | |
| BETTER_AUTH_URL=http://localhost:5185 | |
| TRUSTED_ORIGINS=http://localhost:5185 | |
| ZPAN_CLOUD_URL=https://zpan-cloud-staging.saltbo.workers.dev | |
| VITE_ZPAN_CLOUD_URL=https://zpan-cloud-staging.saltbo.workers.dev | |
| E2E_STORAGE_ENDPOINT=http://127.0.0.1:9191 | |
| E2E_STORAGE_BUCKET=e2e-test | |
| E2E_STORAGE_REGION=auto | |
| E2E_STORAGE_ACCESS_KEY=e2e-access-key | |
| E2E_STORAGE_SECRET_KEY=e2e-secret-key | |
| EOF | |
| - name: Run E2E | |
| run: | | |
| E2E_RUNTIME=cf \ | |
| E2E_APP_PORT=5185 \ | |
| E2E_BASE_URL=http://localhost:5185 \ | |
| E2E_LOCAL_BASE_URL=http://localhost:5185 \ | |
| E2E_S3_MOCK=1 \ | |
| E2E_STORAGE_ENDPOINT=http://127.0.0.1:9191 \ | |
| E2E_STORAGE_BUCKET=e2e-test \ | |
| E2E_STORAGE_REGION=auto \ | |
| E2E_STORAGE_ACCESS_KEY=e2e-access-key \ | |
| E2E_STORAGE_SECRET_KEY=e2e-secret-key \ | |
| BETTER_AUTH_URL=http://localhost:5185 \ | |
| TRUSTED_ORIGINS=http://localhost:5185 \ | |
| pnpm e2e --project=desktop --grep-invert "Cloud store|Cloud licensing|Archive jobs|Site announcements" | |
| - name: Install cloudflared | |
| if: env.E2E_CLOUD_BUSINESS_EMAIL_CF != '' && env.E2E_CLOUD_BUSINESS_PASSWORD_CF != '' | |
| run: | | |
| curl -L --fail --output cloudflared https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 | |
| chmod +x cloudflared | |
| - name: Run cloud E2E | |
| if: env.E2E_CLOUD_BUSINESS_EMAIL_CF != '' && env.E2E_CLOUD_BUSINESS_PASSWORD_CF != '' | |
| run: | | |
| ZPAN_CLOUD_URL=https://zpan-cloud-staging.saltbo.workers.dev \ | |
| VITE_ZPAN_CLOUD_URL=https://zpan-cloud-staging.saltbo.workers.dev \ | |
| CLOUDFLARED_BIN=./cloudflared \ | |
| pnpm e2e:cloud:cf | |
| - uses: actions/upload-artifact@v4 | |
| if: failure() | |
| with: | |
| name: playwright-report-cf | |
| path: playwright-report/ | |
| retention-days: 7 |