Repository navigation
feat(app): vault front door, PRF browser gate, honest backup copy, passkey names #75
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: Deploy Vault SPA | |
| on: | |
| push: | |
| branches: | |
| - main | |
| paths: | |
| - "app/**" | |
| - ".github/workflows/deploy-app.yml" | |
| pull_request: | |
| paths: | |
| - "app/**" | |
| - ".github/workflows/deploy-app.yml" | |
| # One in-flight deploy per ref. New pushes cancel queued runs so we never | |
| # leak a stale build over a newer commit. | |
| concurrency: | |
| group: deploy-app-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| build-and-deploy: | |
| name: Build & Deploy | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| deployments: write | |
| pull-requests: write | |
| defaults: | |
| run: | |
| working-directory: app | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - uses: actions/setup-node@v5 | |
| with: | |
| node-version: 20 | |
| cache: npm | |
| cache-dependency-path: app/package-lock.json | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Typecheck + unit tests | |
| run: | | |
| npx tsc -b --noEmit | |
| npx vitest run | |
| - name: Build | |
| env: | |
| # Production main → real prod relay. Anything else (PR previews, | |
| # branch builds) → staging relay. Keep this in sync with the | |
| # CORS_ORIGINS env var on each Railway service. | |
| VITE_SERVER_URL: ${{ github.ref == 'refs/heads/main' && 'https://api.totalreclaw.xyz' || 'https://api-staging.totalreclaw.xyz' }} | |
| run: npm run build | |
| - name: Publish to Cloudflare Pages | |
| id: deploy | |
| uses: cloudflare/wrangler-action@v4 | |
| env: | |
| # wrangler-action did not always propagate the `apiToken` / | |
| # `accountId` inputs into wrangler's process env (observed on v3), | |
| # so set them explicitly here (where wrangler actually reads them) | |
| # as a belt-and-suspenders guard across action versions. | |
| CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| with: | |
| apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| workingDirectory: app | |
| # PR previews land on <hash>.totalreclaw-app.pages.dev, main lands | |
| # on the production alias (custom domain once attached). Slashes | |
| # in branch names break the CF Pages branch alias, so replace. | |
| command: pages deploy dist --project-name=totalreclaw-app --branch=${{ github.head_ref && format('pr-{0}', github.event.pull_request.number) || github.ref_name }} | |
| - name: Comment preview URL on PR | |
| if: github.event_name == 'pull_request' | |
| uses: actions/github-script@v8 | |
| with: | |
| script: | | |
| const url = `${{ steps.deploy.outputs.deployment-url }}`; | |
| if (!url) return; | |
| const { owner, repo } = context.repo; | |
| const issue_number = context.issue.number; | |
| const marker = "<!-- vault-spa-preview -->"; | |
| const body = `${marker}\n🔗 **Vault SPA preview**: ${url}\n\nBacked by staging relay (\`api-staging.totalreclaw.xyz\`).`; | |
| const { data: comments } = await github.rest.issues.listComments({ owner, repo, issue_number }); | |
| const existing = comments.find(c => c.body && c.body.includes(marker)); | |
| if (existing) { | |
| await github.rest.issues.updateComment({ owner, repo, comment_id: existing.id, body }); | |
| } else { | |
| await github.rest.issues.createComment({ owner, repo, issue_number, body }); | |
| } | |
| # Fire qa-autopilot on the internal repo against this preview URL. The | |
| # phrase + reporting stay private over there. Skipped if the dispatch | |
| # PAT isn't configured yet (gate-by-secret-presence in the next step). | |
| - name: Check internal-dispatch PAT | |
| id: dispatch_gate | |
| if: github.event_name == 'pull_request' && steps.deploy.outputs.deployment-url != '' | |
| env: | |
| PAT: ${{ secrets.INTERNAL_DISPATCH_PAT }} | |
| run: | | |
| if [ -n "$PAT" ]; then | |
| echo "ready=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "ready=false" >> "$GITHUB_OUTPUT" | |
| echo "::notice::INTERNAL_DISPATCH_PAT not set — skipping QA autopilot dispatch" | |
| fi | |
| - name: Trigger QA autopilot on totalreclaw-internal | |
| if: steps.dispatch_gate.outputs.ready == 'true' | |
| env: | |
| GH_TOKEN: ${{ secrets.INTERNAL_DISPATCH_PAT }} | |
| PREVIEW_URL: ${{ steps.deploy.outputs.deployment-url }} | |
| PR_NUMBER: ${{ github.event.pull_request.number }} | |
| run: | | |
| gh workflow run qa-autopilot.yml \ | |
| --repo graphprotocol/totalreclaw-internal \ | |
| --ref main \ | |
| --field target_url="$PREVIEW_URL" \ | |
| --field pr_number="$PR_NUMBER" |