Repository navigation
chore: sync with upstream pingdotgg/t3code main #144
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
4fef307
7d87be3
ff1f6fd
26c3625
7de9535
5b55036
70bd962
d31269e
79e392c
f416175
3f3a1bf
cf731de
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,203 @@ | ||
| name: Clean up relay preview | ||
|
|
||
| # Tears down stage `pr-<n>` when `relay:preview` is removed or the PR closes, | ||
| # and retries teardown for closed labeled PRs on a schedule. A label stays on a | ||
| # PR only while its teardown is outstanding, so the scheduled retry lists | ||
| # exactly the failures. | ||
| # | ||
| # This runs under pull_request_target, so the workflow and the Alchemy program | ||
| # come from the default branch. No PR code runs here, which is why it needs no | ||
| # reviewer approval and why a PR cannot edit its own teardown to reach secrets. | ||
| on: | ||
| pull_request_target: | ||
| types: [unlabeled, closed] | ||
| schedule: | ||
| - cron: "17 7 * * *" | ||
| workflow_dispatch: | ||
|
|
||
| permissions: | ||
| contents: read | ||
| issues: read | ||
| pull-requests: read | ||
|
|
||
| jobs: | ||
| cleanup_pr: | ||
| name: Tear down relay preview | ||
| if: >- | ||
| github.ref == 'refs/heads/main' && | ||
| github.event_name == 'pull_request_target' && | ||
| ( | ||
| (github.event.action == 'unlabeled' && github.event.label.name == 'relay:preview') || | ||
| (github.event.action == 'closed' && contains(github.event.pull_request.labels.*.name, 'relay:preview')) | ||
| ) | ||
| # Job-level so that events which skip this job, such as a closed PR without | ||
| # the label, never take the group's pending slot. GitHub replaces a pending | ||
| # run in a group with a newer one, which would drop a queued teardown. | ||
| concurrency: | ||
| group: relay-preview-${{ github.event.pull_request.number }} | ||
| cancel-in-progress: false | ||
| permissions: | ||
| contents: read | ||
| issues: write | ||
| pull-requests: write | ||
| runs-on: blacksmith-8vcpu-ubuntu-2404 | ||
| timeout-minutes: 30 | ||
| environment: | ||
| name: relay-preview-cleanup | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| STAGE: pr-${{ github.event.pull_request.number }} | ||
| CLOUDFLARE_ACCOUNT_ID: ${{ vars.CLOUDFLARE_ACCOUNT_ID }} | ||
| PLANETSCALE_ORGANIZATION: ${{ vars.PLANETSCALE_ORGANIZATION }} | ||
| AXIOM_ORG_ID: ${{ vars.AXIOM_ORG_ID }} | ||
| RELAY_API_ZONE_NAME: ${{ vars.RELAY_API_ZONE_NAME }} | ||
| RELAY_TUNNEL_ZONE_NAME: ${{ vars.RELAY_TUNNEL_ZONE_NAME }} | ||
| CLERK_PUBLISHABLE_KEY: ${{ vars.CLERK_PUBLISHABLE_KEY }} | ||
| CLERK_JWT_AUDIENCE: ${{ vars.CLERK_JWT_AUDIENCE }} | ||
| APNS_ENABLED: "false" | ||
| ALCHEMY_TELEMETRY_DISABLED: "1" | ||
| steps: | ||
| - name: Checkout default branch | ||
| uses: actions/checkout@v6 | ||
| with: | ||
| ref: ${{ github.event.repository.default_branch }} | ||
| sparse-checkout: | | ||
| /* | ||
| !/.repos/ | ||
| sparse-checkout-cone-mode: false | ||
|
|
||
| - name: Setup Vite+ | ||
| uses: voidzero-dev/setup-vp@v1 | ||
| with: | ||
| node-version-file: package.json | ||
| cache: true | ||
| run-install: | | ||
| args: | ||
| - --filter=t3code-relay... | ||
| # Destroy also runs the preview tunnel sweep, which is part of the stack. | ||
| - name: Destroy preview stage | ||
| run: vp run --filter t3code-relay destroy --stage "$STAGE" --yes --no-input | ||
| env: | ||
| CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} | ||
| PLANETSCALE_API_TOKEN_ID: ${{ secrets.PLANETSCALE_API_TOKEN_ID }} | ||
| PLANETSCALE_API_TOKEN: ${{ secrets.PLANETSCALE_API_TOKEN }} | ||
| AXIOM_TOKEN: ${{ secrets.AXIOM_TOKEN }} | ||
| CLERK_SECRET_KEY: ${{ secrets.CLERK_SECRET_KEY }} | ||
|
|
||
| # Only reached after a successful destroy. A failed one keeps the label, | ||
| # so the scheduled retry picks the PR up again. | ||
| - name: Clear the teardown marker | ||
| if: github.event.action == 'closed' | ||
| run: gh pr edit "${{ github.event.pull_request.number }}" --repo "$GITHUB_REPOSITORY" --remove-label relay:preview | ||
|
|
||
| # An unlabeled event has already removed the label, so a failed teardown | ||
| # must put it back or no retry will ever see the stage. Labels added with | ||
| # GITHUB_TOKEN do not start new runs, so this does not redeploy. | ||
| - name: Restore the teardown marker after a failed destroy | ||
| if: failure() && github.event.action == 'unlabeled' | ||
| run: gh pr edit "${{ github.event.pull_request.number }}" --repo "$GITHUB_REPOSITORY" --add-label relay:preview | ||
|
|
||
| list_closed_previews: | ||
| name: List closed relay previews | ||
| if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request_target' | ||
| runs-on: blacksmith-8vcpu-ubuntu-2404 | ||
| timeout-minutes: 10 | ||
| outputs: | ||
| numbers: ${{ steps.list.outputs.numbers }} | ||
| steps: | ||
| # The issues endpoint is paginated by gh, so there is no listing cap. Pull | ||
| # requests appear there with a `pull_request` key. | ||
| - name: List closed PRs labeled relay:preview | ||
| id: list | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| run: | | ||
| numbers=$(gh api --paginate --method GET "repos/$GITHUB_REPOSITORY/issues" \ | ||
| -f labels=relay:preview -f state=closed -f per_page=100 \ | ||
| --jq '.[] | select(.pull_request) | .number') \ | ||
| || { echo "Could not list closed relay:preview PRs" >&2; exit 1; } | ||
| json=$(printf '%s\n' "$numbers" | jq -Rsc 'split("\n") | map(select(length > 0) | tonumber)') | ||
| echo "Closed relay:preview PRs: $json" | ||
| echo "numbers=$json" >> "$GITHUB_OUTPUT" | ||
| sweep_pr: | ||
| name: Retry teardown for PR ${{ matrix.number }} | ||
| needs: list_closed_previews | ||
| if: github.ref == 'refs/heads/main' && needs.list_closed_previews.outputs.numbers != '[]' | ||
| runs-on: blacksmith-8vcpu-ubuntu-2404 | ||
| timeout-minutes: 30 | ||
| strategy: | ||
| fail-fast: false | ||
| max-parallel: 4 | ||
| matrix: | ||
| number: ${{ fromJSON(needs.list_closed_previews.outputs.numbers) }} | ||
| # Same group as the deploy and teardown for this PR, so a reopened PR's | ||
| # deploy cannot run concurrently with a teardown of its previous stage. | ||
| concurrency: | ||
| group: relay-preview-${{ matrix.number }} | ||
| cancel-in-progress: false | ||
| permissions: | ||
| contents: read | ||
| issues: write | ||
| pull-requests: write | ||
| environment: | ||
| name: relay-preview-cleanup | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| STAGE: pr-${{ matrix.number }} | ||
| CLOUDFLARE_ACCOUNT_ID: ${{ vars.CLOUDFLARE_ACCOUNT_ID }} | ||
| PLANETSCALE_ORGANIZATION: ${{ vars.PLANETSCALE_ORGANIZATION }} | ||
| AXIOM_ORG_ID: ${{ vars.AXIOM_ORG_ID }} | ||
| RELAY_API_ZONE_NAME: ${{ vars.RELAY_API_ZONE_NAME }} | ||
| RELAY_TUNNEL_ZONE_NAME: ${{ vars.RELAY_TUNNEL_ZONE_NAME }} | ||
| CLERK_PUBLISHABLE_KEY: ${{ vars.CLERK_PUBLISHABLE_KEY }} | ||
| CLERK_JWT_AUDIENCE: ${{ vars.CLERK_JWT_AUDIENCE }} | ||
| APNS_ENABLED: "false" | ||
| ALCHEMY_TELEMETRY_DISABLED: "1" | ||
| steps: | ||
| # The lock above is taken before this runs, so the state read here is | ||
| # current. An open PR, including one reopened since the listing, is left | ||
| # alone. GitHub reports merged PRs as MERGED, so anything not OPEN counts. | ||
| - name: Confirm the PR is not open | ||
| id: eligible | ||
| run: | | ||
| state=$(gh pr view "${{ matrix.number }}" --repo "$GITHUB_REPOSITORY" \ | ||
| --json state --jq 'if .state == "OPEN" then "no" else "yes" end') \ | ||
| || { echo "Could not read PR ${{ matrix.number }}" >&2; exit 1; } | ||
| echo "eligible=$state" >> "$GITHUB_OUTPUT" | ||
| [ "$state" = yes ] || echo "PR ${{ matrix.number }} is open again; leaving $STAGE alone." | ||
| - name: Checkout default branch | ||
| if: steps.eligible.outputs.eligible == 'yes' | ||
| uses: actions/checkout@v6 | ||
| with: | ||
| ref: ${{ github.event.repository.default_branch }} | ||
| sparse-checkout: | | ||
| /* | ||
| !/.repos/ | ||
| sparse-checkout-cone-mode: false | ||
|
|
||
| - name: Setup Vite+ | ||
| if: steps.eligible.outputs.eligible == 'yes' | ||
| uses: voidzero-dev/setup-vp@v1 | ||
| with: | ||
| node-version-file: package.json | ||
| cache: true | ||
| run-install: | | ||
| args: | ||
| - --filter=t3code-relay... | ||
| - name: Destroy preview stage | ||
| if: steps.eligible.outputs.eligible == 'yes' | ||
| run: vp run --filter t3code-relay destroy --stage "$STAGE" --yes --no-input | ||
| env: | ||
| CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} | ||
| PLANETSCALE_API_TOKEN_ID: ${{ secrets.PLANETSCALE_API_TOKEN_ID }} | ||
| PLANETSCALE_API_TOKEN: ${{ secrets.PLANETSCALE_API_TOKEN }} | ||
| AXIOM_TOKEN: ${{ secrets.AXIOM_TOKEN }} | ||
| CLERK_SECRET_KEY: ${{ secrets.CLERK_SECRET_KEY }} | ||
|
|
||
| - name: Clear the teardown marker | ||
| if: steps.eligible.outputs.eligible == 'yes' | ||
| run: gh pr edit "${{ matrix.number }}" --repo "$GITHUB_REPOSITORY" --remove-label relay:preview |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| name: Deploy relay preview | ||
|
|
||
| # Labeling a same-repository PR `relay:preview` deploys Alchemy stage `pr-<n>`. | ||
| # This job runs the PR's own code with account credentials, so it waits for an | ||
| # approval in the `relay-preview` environment on every run. Teardown is in | ||
| # relay-preview-cleanup.yml and never runs PR code. | ||
| on: | ||
| pull_request: | ||
| types: [labeled, synchronize, reopened] | ||
|
|
||
| permissions: | ||
| contents: read | ||
| pull-requests: read | ||
|
|
||
| concurrency: | ||
| group: relay-preview-${{ github.event.pull_request.number }} | ||
| cancel-in-progress: false | ||
|
|
||
| jobs: | ||
| deploy_preview: | ||
| name: Deploy relay preview | ||
| if: >- | ||
| github.event.pull_request.head.repo.full_name == github.repository && | ||
| contains(github.event.pull_request.labels.*.name, 'relay:preview') | ||
| runs-on: blacksmith-8vcpu-ubuntu-2404 | ||
| timeout-minutes: 20 | ||
| environment: | ||
| name: relay-preview | ||
| env: | ||
| STAGE: pr-${{ github.event.pull_request.number }} | ||
| CLOUDFLARE_ACCOUNT_ID: ${{ vars.CLOUDFLARE_ACCOUNT_ID }} | ||
| PLANETSCALE_ORGANIZATION: ${{ vars.PLANETSCALE_ORGANIZATION }} | ||
| AXIOM_ORG_ID: ${{ vars.AXIOM_ORG_ID }} | ||
| RELAY_API_ZONE_NAME: ${{ vars.RELAY_API_ZONE_NAME }} | ||
| RELAY_TUNNEL_ZONE_NAME: ${{ vars.RELAY_TUNNEL_ZONE_NAME }} | ||
| CLERK_PUBLISHABLE_KEY: ${{ vars.CLERK_PUBLISHABLE_KEY }} | ||
| CLERK_JWT_AUDIENCE: ${{ vars.CLERK_JWT_AUDIENCE }} | ||
| # Previews take no alert notifier, no tunnel cleanup, and no custom | ||
| # domain, so they stay silent and reap nothing outside their own stage. | ||
| APNS_ENABLED: "false" | ||
| ALCHEMY_TELEMETRY_DISABLED: "1" | ||
| steps: | ||
| - name: Confirm the PR is still open and labeled | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| PR_NUMBER: ${{ github.event.pull_request.number }} | ||
| run: | | ||
| state=$(gh pr view "$PR_NUMBER" --repo "$GITHUB_REPOSITORY" --json state,labels \ | ||
| --jq 'if .state == "OPEN" and any(.labels[]; .name == "relay:preview") then "ok" else "stale" end') | ||
| if [ "$state" != "ok" ]; then | ||
| echo "PR #$PR_NUMBER is no longer open with relay:preview; not deploying." >&2 | ||
| exit 1 | ||
| fi | ||
| - name: Checkout | ||
| uses: actions/checkout@v6 | ||
| with: | ||
| ref: ${{ github.event.pull_request.head.sha }} | ||
| sparse-checkout: | | ||
| /* | ||
| !/.repos/ | ||
| sparse-checkout-cone-mode: false | ||
|
|
||
| - name: Setup Vite+ | ||
| uses: voidzero-dev/setup-vp@v1 | ||
| with: | ||
| node-version-file: package.json | ||
| cache: true | ||
| run-install: | | ||
| args: | ||
| - --filter=t3code-relay... | ||
| - name: Deploy preview stage | ||
| run: vp run --filter t3code-relay deploy --stage "$STAGE" --yes --no-input | ||
| env: | ||
| T3CODE_RELAY_CLIENT_CONFIG_ENV: ${{ runner.temp }}/relay-client-config.env | ||
| CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} | ||
| PLANETSCALE_API_TOKEN_ID: ${{ secrets.PLANETSCALE_API_TOKEN_ID }} | ||
| PLANETSCALE_API_TOKEN: ${{ secrets.PLANETSCALE_API_TOKEN }} | ||
| AXIOM_TOKEN: ${{ secrets.AXIOM_TOKEN }} | ||
| CLERK_SECRET_KEY: ${{ secrets.CLERK_SECRET_KEY }} | ||
|
Comment on lines
+77
to
+81
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | The This workflow runs on
Move the secrets this workflow uses into the Based on learnings: "flag reliance on Environment required reviewers as their sole safeguard: the actor can omit
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🩺 Stability & Availability |
Minor | ⚡ Quick win
Workflow-level
concurrencycan drop a queued teardown.Every
labeled,synchronizeandreopenedevent creates a run that claims therelay-preview-<n>group, even when the jobifis false.relay-preview-cleanup.ymluses a job-level group for this reason.Assume a deploy run is waiting for approval or still running, and a user removes the label. The cleanup job then queues in the same group. If the user pushes a new commit, a new deploy run queues in that group. GitHub replaces the pending cleanup job with it, so the teardown is canceled. The label is already gone, so the nightly retry never lists the PR. The
pr-<n>stage leaks until someone removes it by hand.Move the group to the job, so a skipped job does not take the pending slot.
Proposed fix
Then add the group to
deploy_preview, next toruns-on: