Skip to content

fix(admin): stop saving an outdated rich text body over newer content #1131

fix(admin): stop saving an outdated rich text body over newer content

fix(admin): stop saving an outdated rich text body over newer content #1131

Workflow file for this run

name: CI Run

Check warning on line 1 in .github/workflows/ci-run.yml

View workflow run for this annotation

GitHub Actions / CI Run

Workflow execution policy warning (evaluate mode)

On December 2, 2026, GitHub will restrict `pull_request_target` on public repositories by default. To continue allowing the event trigger, configure an Actions policy. Learn more: https://gh.io/securely-using-pull_request_target#default-policy-for-pull_request_target
# Runs CI on a PR's latest commit when someone adds the `ci:run` label: approves
# workflow runs waiting for approval (first-time contributors) and re-runs
# failed jobs. Approving and re-running need write access; applying a label
# only needs triage, so this lets triagers start CI on fork PRs.
# Pure actions/github-script: no checkout, no secrets. Approved and re-run
# workflows keep the permissions of a fork PR's `pull_request` run, so they
# stay read-only and get no secrets.
on:
pull_request_target:
types: [labeled]
permissions:
contents: read
jobs:
run:
name: Approve and re-run CI
if: github.event.label.name == 'ci:run'
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
actions: write # approve runs and re-run the failed jobs
pull-requests: write # remove the ci:run label
concurrency:
group: ci-run-${{ github.event.pull_request.number }}
cancel-in-progress: false
steps:
- name: Approve and re-run workflows on the PR head
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const { owner, repo } = context.repo;
const pr = context.payload.pull_request;
// Remove the label before anything can fail, so it can be added
// again for the next attempt.
try {
await github.rest.issues.removeLabel({
owner,
repo,
issue_number: pr.number,
name: 'ci:run',
});
} catch (e) {
if (e.status !== 404) throw e;
}
// `pr.head.sha` is the commit at the time the label was added, so
// a commit pushed afterwards is never approved by this label.
// `pull_request` runs only: the `pull_request_target` workflows
// report on the PR rather than test it.
const allRuns = await github.paginate(github.rest.actions.listWorkflowRunsForRepo, {
owner,
repo,
event: 'pull_request',
head_sha: pr.head.sha,
per_page: 100,
});
// Reopening a PR can leave two runs of a workflow on the same commit;
// re-running the older one would override the newer checks.
const newest = new Map();
for (const run of allRuns) {
const seen = newest.get(run.workflow_id);
if (!seen || run.run_number > seen.run_number) newest.set(run.workflow_id, run);
}
const runs = [...newest.values()];
// Runs waiting for approval count as `completed`, with conclusion
// `action_required`.
const pending = runs.filter(
(run) => run.status === 'completed' && run.conclusion === 'action_required',
);
for (const run of pending) {
await github.rest.actions.approveWorkflowRun({ owner, repo, run_id: run.id });
core.info(`#${pr.number}: approved ${run.name} (${run.html_url})`);
}
const running = runs.filter((run) => run.status !== 'completed');
for (const run of running) {
core.warning(`${run.name} is still running; add ci:run again once it finishes.`);
}
const failed = runs.filter(
(run) =>
run.status === 'completed' &&
['failure', 'cancelled', 'timed_out'].includes(run.conclusion),
);
if (pending.length === 0 && failed.length === 0) {
core.info(`#${pr.number}: no failed or pending runs on ${pr.head.sha}`);
return;
}
for (const run of failed) {
// A run still waiting for approval when its PR is closed ends as
// `failure` without starting a job, and can't be re-run.
const { data: jobs } = await github.rest.actions.listJobsForWorkflowRun({
owner,
repo,
run_id: run.id,
per_page: 1,
});
if (jobs.total_count === 0) {
core.warning(`${run.name} never started a job, so ci:run leaves it alone.`);
continue;
}
await github.rest.actions.reRunWorkflowFailedJobs({ owner, repo, run_id: run.id });
core.info(`#${pr.number}: re-running the failed jobs of ${run.name} (${run.html_url})`);
}