Files
webstudio/.github/workflows/delete-github-deployments.yml
Oleg Isonen 50958a68b3 ci: Restore safe-to-deploy workflows (#6054)
## Summary

Restore CI, visual testing, and Vercel preview workflows for reviewed
fork pull requests after `actions/checkout` began refusing fork code in
`pull_request_target` jobs by default.

The affected workflows now also use Node 24-compatible action releases,
and the shared Builder E2E artifact is retained long enough for delayed
failed-job reruns.

Closes #6053

## Root cause

Applying `safe-to-deploy` still triggered the intended workflows, but
each job stopped at checkout with:

> Refusing to check out fork pull request code from a
`pull_request_target` workflow.

The label is the repository's explicit human-review gate for trusted
fork code, but the checkout steps did not pass the action's new explicit
opt-in.

A later failed-job rerun also could not download `builder-e2e-build`
because its one-day retention period had elapsed. The affected
JavaScript actions additionally targeted the deprecated Node 20 action
runtime.

## Implementation

- Opt into fork checkout only when the event is `pull_request_target`
and the applied label is exactly `safe-to-deploy`.
- Apply the opt-in to Main, Chromatic, Visual Regression Tests, and
Vercel staging checkout steps.
- Gate `check-size` with the same push, regular PR, or reviewed-fork
condition as the other Main workflow jobs.
- Gate `deployment-host` so synchronize events only remove the approval
label and do not check out fork code.
- Upgrade the affected Checkout, Setup Node, pnpm setup, Cache,
artifact, GitHub Script, and Chromatic actions to Node 24-compatible
majors.
- Retain `builder-e2e-build` for seven days so delayed failed-job reruns
can download it.
- Preserve existing push and normal `pull_request` paths.

## Security tradeoff

`pull_request_target` jobs have base-repository credentials and secrets.
This change deliberately permits fork checkout only after a maintainer
applies `safe-to-deploy`; no other label or synchronize event receives
the opt-in.

## Todo

- [x] Reproduce and inspect the checkout failure on fork PR #6041.
- [x] Add explicit checkout opt-in behind the trusted label.
- [x] Gate previously unconditional jobs before enabling fork checkout.
- [x] Upgrade affected JavaScript actions to Node 24-compatible
releases.
- [x] Keep Builder E2E prerequisites available for delayed reruns.
- [x] Review documentation impact; no product documentation is affected.
- [x] Verify fixture inputs and outputs are unaffected.
- [ ] Verify the labeled fork path after this workflow version reaches
`main`.

## Verification

- `git diff --check`
- Parsed all changed workflow and composite-action YAML files with
Ruby's YAML parser.
- Verified each upgraded action manifest declares the Node 24 runtime.
- Verified `actions/checkout@v5` retains the `allow-unsafe-pr-checkout`
input.
- Audited every `actions/checkout` step in the affected
`pull_request_target` workflows for the exact label guard.
- PR checks passed for Main, Chromatic, Vercel staging, submodules, and
PR title validation; Lost Pixel remains excluded from this fix.

The live labeled-fork execution cannot be proven from this PR itself
because `pull_request_target` loads workflow definitions from the base
branch. It should be verified with a fork PR after this change reaches
`main`.
2026-08-10 16:15:19 +02:00

53 lines
1.4 KiB
YAML

# https://github.com/orgs/community/discussions/36919
name: Delete github deployments
on:
workflow_call:
inputs:
ref:
type: string
required: true
permissions:
deployments: write
jobs:
delete_github_deployments:
runs-on: ubuntu-latest
if: ${{ always() }}
steps:
- name: Delete Previous deployments
uses: actions/github-script@v8
env:
REF: ${{ inputs.ref }}
with:
script: |
const { REF } = process.env;
console.log(REF);
const deployments = await github.rest.repos.listDeployments({
owner: context.repo.owner,
repo: context.repo.repo,
ref: REF,
per_page: 100
});
console.log(deployments);
await Promise.allSettled(
deployments.data.map(async (deployment) => {
await github.rest.repos.createDeploymentStatus({
owner: context.repo.owner,
repo: context.repo.repo,
deployment_id: deployment.id,
state: 'inactive'
});
return github.rest.repos.deleteDeployment({
owner: context.repo.owner,
repo: context.repo.repo,
deployment_id: deployment.id
});
})
);