Files
pnpm/.github/workflows/pacquet-integrated-benchmark-comment.yml
Zoltan Kochan d2b64b6689 ci(pacquet): fix all zizmor code-scanning findings (#11641)
* ci(pacquet): fix all zizmor code-scanning findings

Resolves the 90 alerts opened by zizmor against the imported pacquet-*
workflows and shared composite actions:

- unpinned-uses: pin every third-party action to a SHA + version comment
  (matching SHAs already used elsewhere in the repo where applicable;
  taiki-e/install-action collapsed onto v2.78.0 with explicit `tool:` input).
- artipacked: add `persist-credentials: false` to every actions/checkout.
- template-injection: pass `inputs.*` and `steps.*.outputs.*` through `env:`
  in binstall/rustup composite actions and pacquet-release-to-npm.yml.
- excessive-permissions: add top-level `permissions: contents: read` to
  pacquet-release-to-npm.yml; move issues/pull-requests writes from the
  workflow level to the benchmark-compare job in pacquet-micro-benchmark.yml.
- dangerous-triggers: keep workflow_run in pacquet-integrated-benchmark-
  comment.yml but suppress with a documented zizmor: ignore — the trigger
  is the recommended pattern for posting comments back to fork PRs.
- superfluous-actions: keep softprops/action-gh-release with a zizmor:
  ignore (matches release.yml).

Verified by running `zizmor .github` locally with no remaining findings.

* ci(pacquet): point SHA pins at the patch-version tag

Swatinem/rust-cache and montudor/action-zip were pinned to the SHA the
major-version alias (`v2`, `v1`) resolves to, but the version comments
claimed `v2.9.1` / `v1.0.0`. zizmor's online `ref-version-mismatch`
audit flagged the inconsistency. Repoint at the SHAs the patch-version
tags actually annotate so the pin and the comment agree.
2026-05-14 19:33:30 +02:00

134 lines
6.1 KiB
YAML

name: Pacquet Integrated-Benchmark Comment
# Stage 2 of the benchmark pipeline. `pacquet-integrated-benchmark.yml` runs
# the benchmark on `pull_request` (read-only token on fork PRs) and uploads
# the report as an artifact. This workflow runs on `workflow_run`, which
# fires in the base repository's privilege context, so it can post the
# comment back to the PR even when the PR is from a fork. See
# https://securitylab.github.com/research/github-actions-preventing-pwn-requests/
# for the security rationale.
on:
# zizmor: ignore[dangerous-triggers]
# `workflow_run` is intentional and required: this workflow runs in the
# base-repo privilege context so it can comment on fork PRs (the build
# workflow itself runs with a read-only token on fork PRs). The job-level
# `if` only proceeds on `success`, the PR number is resolved from the
# trusted `workflow_run` event payload (not from the fork-controlled
# artifact), and the artifact body is treated as untrusted markdown.
# See https://securitylab.github.com/research/github-actions-preventing-pwn-requests/.
workflow_run:
workflows: ["Pacquet Integrated-Benchmark"]
types: [completed]
permissions:
contents: read
actions: read
issues: write
pull-requests: write
jobs:
comment:
name: Post benchmark comment
runs-on: ubuntu-latest
# Only post when the upstream benchmark ran on a PR and succeeded.
# Same gating as the original in-workflow comment, which only ran
# on the success path of the previous steps.
if: |
github.event.workflow_run.event == 'pull_request' &&
github.event.workflow_run.conclusion == 'success'
steps:
- name: Resolve PR number from workflow_run trigger
# `workflow_run.pull_requests` is empty for fork PRs (the case
# this workflow exists to fix), so fall back to listing open
# PRs in this repo and filtering by `head.sha`. The base repo's
# `commits/{sha}/pulls` endpoint *only* finds PRs whose head
# commit exists on the base repo — for fork PRs the head lives
# on the fork, so the lookup returns `[]`. Listing PRs and
# filtering works for both cases.
#
# `head_sha` is sourced from the `workflow_run` event payload,
# which GitHub fills in for us — not from the artifact, since
# the artifact is fork-controlled and could otherwise redirect
# the comment to an arbitrary PR.
id: meta
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
REPO: ${{ github.repository }}
TRIGGER_PR: ${{ github.event.workflow_run.pull_requests[0].number }}
shell: bash
run: |
set -eu
if [[ -n "${TRIGGER_PR:-}" ]]; then
# Same-repo PR: GitHub already gave us the number on the
# trigger payload. Trusted source, no API call needed.
pr="$TRIGGER_PR"
else
# Fork PR: walk every open PR and match by head.sha. The
# 40-char SHA is a unique identifier; multiple PRs sharing
# one is essentially impossible, but the count check below
# still flags it loudly if it ever happens.
#
# `--paginate --jq '.[]'` emits each PR object on its own
# line so `jq -s` can slurp the whole stream into a single
# array; using `--paginate --jq '[...]'` would apply the
# filter per-page and produce one array per page (broken
# past 100 open PRs). `--arg sha` keeps the head SHA out
# of the jq program text — defensive against any future
# change to where HEAD_SHA is sourced from.
pr=$(
gh api "repos/$REPO/pulls?state=open&per_page=100" --paginate --jq '.[]' \
| jq -s --arg sha "$HEAD_SHA" \
'[.[] | select(.head.sha == $sha) | .number] | unique'
)
count=$(echo "$pr" | jq 'length')
if [[ "$count" == "0" ]]; then
echo "::error::no open PR matches head_sha=$HEAD_SHA in $REPO"
exit 1
fi
if [[ "$count" != "1" ]]; then
echo "::error::ambiguous head_sha=$HEAD_SHA matches $count PRs: $pr"
exit 1
fi
pr=$(echo "$pr" | jq '.[0]')
fi
# Final sanity check: the resolved value must be a positive integer.
if ! [[ "$pr" =~ ^[1-9][0-9]*$ ]]; then
echo "::error::resolved PR number is not a positive integer: '$pr'"
exit 1
fi
echo "pr=$pr" >> "$GITHUB_OUTPUT"
- name: Download benchmark report
# `run-id` + `github-token` lets v8 pull artifacts from a different
# workflow run, which is exactly the workflow_run pattern.
uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0
with:
name: integrated-benchmark-report-ubuntu-latest
path: benchmark-artifact
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Find existing comment
# Match on the literal substring the report header carries.
# Updating the heading text in `integrated-benchmark.yml` (the
# `Integrated-Benchmark Report (${{ runner.os }})` line) needs
# to keep this matcher in sync, otherwise duplicate comments
# accrue across runs. Today the matrix only runs on Linux, so
# there is one fixed string to track.
uses: peter-evans/find-comment@b30e6a3c0ed37e7c023ccd3f1db5c6c0b0c23aad # v4.0.0
id: fc
with:
issue-number: ${{ steps.meta.outputs.pr }}
comment-author: 'github-actions[bot]'
body-includes: 'Integrated-Benchmark Report (Linux)'
- name: Create or update comment
uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 # v5.0.0
with:
issue-number: ${{ steps.meta.outputs.pr }}
edit-mode: replace
comment-id: ${{ steps.fc.outputs.comment-id }}
body-file: benchmark-artifact/SUMMARY.md