Skip to content

fix(registry-verification): use Windows-valid synthetic URL for createRequire shim #2758

fix(registry-verification): use Windows-valid synthetic URL for createRequire shim

fix(registry-verification): use Windows-valid synthetic URL for createRequire shim #2758

Workflow file for this run

name: Visual Regression — Apply
# Commits accepted visual baselines when a maintainer comments
# `/accept-baselines` on a PR. The command is the human gate: only users with
# write access (author association OWNER/MEMBER/COLLABORATOR) can trigger it.
#
# It downloads the inert candidate-baseline artifact produced by the measure
# job for the PR's current head and commits those PNGs to the PR branch. It
# never checks out or executes PR-authored code.
#
# Like all issue_comment workflows, this runs from the default branch, so it
# only takes effect once merged to main.
on:
issue_comment:
types: [created]
permissions:
actions: read # find + download the measure artifact
contents: read # app token handles the write/push
pull-requests: write # comment back with the result
issues: write # react to the triggering comment (issues-scoped API)
jobs:
apply:
name: Apply
# Only on PR comments, from a non-bot with write access. Exact match (as in
# format-command.yml) so quoted or suffixed text can't trigger a write.
if: >-
github.event.issue.pull_request != null
&& github.event.sender.type != 'Bot'
&& github.event.comment.body == '/accept-baselines'
&& contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association)
concurrency:
group: visual-apply-${{ github.event.issue.number }}
cancel-in-progress: false
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Acknowledge
continue-on-error: true # a missing 👀 must not block the apply
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
await github.rest.reactions.createForIssueComment({
owner: context.repo.owner, repo: context.repo.repo,
comment_id: context.payload.comment.id, content: 'eyes',
});
- name: Resolve PR and measure run
id: resolve
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const { owner, repo } = context.repo;
const number = context.issue.number;
const { data: pr } = await github.rest.pulls.get({
owner, repo, pull_number: number,
});
// Find the measure run (with the candidate artifact) for this head.
// The run "fails" red on drift, so match on completion, not
// conclusion. listWorkflowRuns returns newest first.
const sha7 = pr.head.sha.slice(0, 7);
const runs = await github.rest.actions.listWorkflowRuns({
owner, repo, workflow_id: 'visual.yml', head_sha: pr.head.sha, per_page: 20,
});
const all = runs.data.workflow_runs ?? [];
const run = all.find((r) => r.status === 'completed');
if (!run) {
await github.rest.issues.createComment({
owner, repo, issue_number: number,
body: all.length > 0
? `The \`Visual Regression\` run for the current head (\`${sha7}\`) is still in progress. Wait for it to finish, then comment \`/accept-baselines\` again.`
: `No \`Visual Regression\` run found for the current head (\`${sha7}\`). Push a commit to trigger it (or wait for the measure job), then comment \`/accept-baselines\` again.`,
});
core.setOutput('eligible', 'false');
return;
}
core.setOutput('eligible', 'true');
core.setOutput('number', String(number));
core.setOutput('head_sha', pr.head.sha);
core.setOutput('ref', pr.head.ref);
core.setOutput('full_name', pr.head.repo.full_name);
core.setOutput('is_fork', String(
pr.head.repo.fork || pr.head.repo.full_name !== `${owner}/${repo}`,
));
core.setOutput('run_id', String(run.id));
- name: Download candidate baselines
id: download
if: steps.resolve.outputs.eligible == 'true'
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
RUN_ID: ${{ steps.resolve.outputs.run_id }}
PR_NUMBER: ${{ steps.resolve.outputs.number }}
with:
script: |
const fs = require('node:fs');
const path = require('node:path');
const runId = Number(process.env.RUN_ID);
const number = Number(process.env.PR_NUMBER);
const { data } = await github.rest.actions.listWorkflowRunArtifacts({
owner: context.repo.owner, repo: context.repo.repo, run_id: runId,
});
const artifact = data.artifacts.find((a) => a.name === 'visual-regression');
if (!artifact) {
await github.rest.issues.createComment({
owner: context.repo.owner, repo: context.repo.repo, issue_number: number,
body: "Couldn't find the candidate-baseline artifact for the completed measure run (it may have expired after 7 days, or the run failed before uploading). Push a commit to regenerate it, then comment `/accept-baselines` again.",
});
core.setOutput('found', 'false');
return;
}
const dl = await github.rest.actions.downloadArtifact({
owner: context.repo.owner, repo: context.repo.repo,
artifact_id: artifact.id, archive_format: 'zip',
});
const outDir = path.join(process.env.RUNNER_TEMP, 'va');
fs.mkdirSync(outDir, { recursive: true });
fs.writeFileSync(path.join(outDir, 'artifact.zip'), Buffer.from(dl.data));
core.setOutput('found', 'true');
- name: Unpack and validate
id: validate
if: steps.download.outputs.found == 'true'
env:
HEAD_SHA: ${{ steps.resolve.outputs.head_sha }}
run: |
cd "$RUNNER_TEMP/va"
unzip -o artifact.zip
drift=$(cat has-drift 2>/dev/null || echo false)
measured=$(cat head-sha 2>/dev/null || echo "")
if [ "$drift" != "true" ]; then
echo "reason=no_drift" >> "$GITHUB_OUTPUT"
echo "ok=false" >> "$GITHUB_OUTPUT"
elif [ "$measured" != "$HEAD_SHA" ]; then
echo "reason=head_mismatch" >> "$GITHUB_OUTPUT"
echo "ok=false" >> "$GITHUB_OUTPUT"
elif [ -z "$(ls -A candidates 2>/dev/null)" ]; then
echo "reason=no_candidates" >> "$GITHUB_OUTPUT"
echo "ok=false" >> "$GITHUB_OUTPUT"
else
echo "ok=true" >> "$GITHUB_OUTPUT"
fi
- name: Report nothing to apply
if: steps.validate.outputs.ok == 'false'
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
PR_NUMBER: ${{ steps.resolve.outputs.number }}
REASON: ${{ steps.validate.outputs.reason }}
with:
script: |
const messages = {
no_drift: 'There is no visual drift on the current head, so there are no baselines to accept.',
head_mismatch: 'The measured baselines are for an older commit. Wait for the `Visual Regression` run on the current head to finish, then comment `/accept-baselines` again.',
no_candidates: 'The measure run produced no candidate baselines (likely an infrastructure failure, not a UI change). Check the `Visual Regression` logs.',
};
await github.rest.issues.createComment({
owner: context.repo.owner, repo: context.repo.repo,
issue_number: Number(process.env.PR_NUMBER),
body: messages[process.env.REASON] || 'Nothing to apply.',
});
- name: Generate app token
id: app-token
if: steps.validate.outputs.ok == 'true'
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
with:
client-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
permission-contents: write
- name: Checkout (same-repo)
if: steps.validate.outputs.ok == 'true' && steps.resolve.outputs.is_fork == 'false'
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
ref: ${{ steps.resolve.outputs.head_sha }}
token: ${{ steps.app-token.outputs.token }}
persist-credentials: true
- name: Checkout (fork)
if: steps.validate.outputs.ok == 'true' && steps.resolve.outputs.is_fork == 'true'
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
repository: ${{ steps.resolve.outputs.full_name }}
ref: ${{ steps.resolve.outputs.head_sha }}
persist-credentials: false
# Reviewed opt-in: no code from the fork tree is executed. The steps
# below only copy inert PNGs from the trusted measure artifact and run
# git add/commit/push -- no scripts, hooks, or tooling from the tree.
allow-unsafe-pr-checkout: true
- name: Stage baselines
id: stage
if: steps.validate.outputs.ok == 'true'
run: |
set -e
dest="e2e/tests/visual-regression.spec.ts-snapshots"
mkdir -p "$dest"
cp -r "$RUNNER_TEMP/va/candidates/." "$dest/"
git add "$dest"
if git diff --staged --quiet; then
echo "changed=false" >> "$GITHUB_OUTPUT"
else
echo "changed=true" >> "$GITHUB_OUTPUT"
fi
- name: Commit and push (same-repo)
if: steps.stage.outputs.changed == 'true' && steps.resolve.outputs.is_fork == 'false'
env:
HEAD_REF: ${{ steps.resolve.outputs.ref }}
ACCEPTER: ${{ github.event.comment.user.login }}
run: |
set -e
git config user.name "emdashbot[bot]"
git config user.email "emdashbot[bot]@users.noreply.github.com"
git commit -m "ci: accept visual baselines (requested by @$ACCEPTER)"
if ! git push origin "HEAD:$HEAD_REF"; then
echo "::error::Non-fast-forward push — the PR branch moved. Wait for the new measure run, then comment /accept-baselines again." >&2
exit 1
fi
- name: Commit and push (fork)
if: steps.stage.outputs.changed == 'true' && steps.resolve.outputs.is_fork == 'true'
env:
APP_TOKEN: ${{ steps.app-token.outputs.token }}
HEAD_REF: ${{ steps.resolve.outputs.ref }}
FULL_NAME: ${{ steps.resolve.outputs.full_name }}
ACCEPTER: ${{ github.event.comment.user.login }}
run: |
set -e
git config user.name "emdashbot[bot]"
git config user.email "emdashbot[bot]@users.noreply.github.com"
git commit -m "ci: accept visual baselines (requested by @$ACCEPTER)"
export GIT_ASKPASS="$RUNNER_TEMP/git-askpass.sh"
printf '#!/bin/sh\necho "%s"\n' "$APP_TOKEN" > "$GIT_ASKPASS"
chmod +x "$GIT_ASKPASS"
git remote add fork "https://x-access-token@github.com/$FULL_NAME.git"
if ! git push fork "HEAD:$HEAD_REF"; then
rm -f "$GIT_ASKPASS"
echo "::error::Failed to push to fork. The contributor likely has 'Allow edits by maintainers' disabled; they must regenerate baselines in the pinned Playwright Docker image and commit." >&2
exit 1
fi
rm -f "$GIT_ASKPASS"
- name: Report result
if: steps.validate.outputs.ok == 'true'
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
PR_NUMBER: ${{ steps.resolve.outputs.number }}
ACCEPTER: ${{ github.event.comment.user.login }}
CHANGED: ${{ steps.stage.outputs.changed }}
with:
script: |
const changed = process.env.CHANGED === 'true';
const body = changed
? `✅ Baselines accepted by @${process.env.ACCEPTER} and committed to this PR.`
: 'ℹ️ The committed baselines already match the candidates; nothing to commit.';
await github.rest.issues.createComment({
owner: context.repo.owner, repo: context.repo.repo,
issue_number: Number(process.env.PR_NUMBER), body,
});
- name: Report failure
if: failure()
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
with:
script: |
await github.rest.issues.createComment({
owner: context.repo.owner, repo: context.repo.repo,
issue_number: context.issue.number,
body: `❌ \`/accept-baselines\` failed. See the [run log](${process.env.RUN_URL}). If this is a fork PR, the contributor may have "Allow edits by maintainers" disabled.`,
});