Files
wehub-resource-sync 0d3cb498a3
Deploy local.promptfoo.app / Deploy to Cloudflare Pages (push) Waiting to run
Test and Publish Multi-arch Docker Image / test (push) Waiting to run
Test and Publish Multi-arch Docker Image / build-docker-and-push-digests (map[digest-suffix:linux-amd64 platform:linux/amd64 runner:ubuntu-latest]) (push) Blocked by required conditions
Test and Publish Multi-arch Docker Image / build-docker-and-push-digests (map[digest-suffix:linux-arm64 platform:linux/arm64 runner:ubuntu-24.04-arm]) (push) Blocked by required conditions
Test and Publish Multi-arch Docker Image / merge-docker-digests (push) Blocked by required conditions
Test and Publish Multi-arch Docker Image / Attest Multi-arch Image (push) Blocked by required conditions
Validate Renovate Config / Validate Renovate Configuration (push) Waiting to run
CI / Shell Format Check (push) Has been cancelled
CI / Check Ruby (3.4) (push) Has been cancelled
CI / CI Config (push) Has been cancelled
CI / Test on Node ${{ matrix.node }} and ${{ matrix.os }}${{ matrix.shard && format(' (shard {0}/3)', matrix.shard) || '' }} (push) Has been cancelled
CI / Build on Node ${{ matrix.node }} (push) Has been cancelled
CI / Style Check (push) Has been cancelled
CI / Generate Assets (push) Has been cancelled
CI / Check Python (3.14) (push) Has been cancelled
CI / Check Python (3.9) (push) Has been cancelled
CI / Build Docs (push) Has been cancelled
CI / Code Scan Action (push) Has been cancelled
CI / Site tests (push) Has been cancelled
CI / webui tests (push) Has been cancelled
CI / Run Integration Tests (push) Has been cancelled
CI / Run Smoke Tests (push) Has been cancelled
CI / Go Tests (push) Has been cancelled
CI / Share Test (push) Has been cancelled
CI / Redteam (Production API) (push) Has been cancelled
CI / Redteam (Staging API) (push) Has been cancelled
CI / GitHub Actions Lint (push) Has been cancelled
CI / Check Ruby (3.0) (push) Has been cancelled
release-please / release-please (push) Has been cancelled
release-please / build (push) Has been cancelled
release-please / publish-npm (push) Has been cancelled
release-please / publish-npm-backfill (push) Has been cancelled
release-please / docker (push) Has been cancelled
release-please / publish-code-scan-action (push) Has been cancelled
release-please / attest-code-scan-action (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:24:08 +08:00

150 lines
6.4 KiB
YAML

name: release-please-format
run-name: format CHANGELOG on release PR (${{ github.event.pull_request.head.ref }})
# Runs prettier on CHANGELOG files in release-please PRs. Lives in its own
# workflow (not inside release-please.yml) so it re-runs on every PR
# synchronize event — release-please force-pushes its PR branch when new
# commits land on main, which would wipe any formatting commit created
# inline in the release-please job.
on:
pull_request:
types: [opened, synchronize, reopened]
paths:
- '**/CHANGELOG.md'
permissions:
contents: read
jobs:
format:
# Branch prefix alone is not a trust boundary. Require: same-repo PR (forks
# cannot be legitimate release-please PRs), the exact release bot as
# author, and the release-please branch naming convention.
if: >-
github.event.pull_request.head.repo.full_name == github.repository &&
github.event.pull_request.user.login == 'promptfoobot[bot]' &&
startsWith(github.event.pull_request.head.ref, 'release-please--')
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: read
steps:
# Pin an explicit Node version so this step does not depend on a
# PR-controlled .nvmrc — the install below happens before checkout.
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version: 'lts/*'
# Isolated install before checkout so a PR-controlled .npmrc cannot
# redirect the registry or inject a package.
- name: Install prettier (outside PR checkout)
run: |
set -euo pipefail
install_dir="$RUNNER_TEMP/prettier-install"
mkdir -p "$install_dir"
cd "$install_dir"
npm install \
--no-save --no-audit --no-fund --ignore-scripts \
--registry=https://registry.npmjs.org/ \
prettier@3.8.1
echo "$install_dir/node_modules/.bin" >> "$GITHUB_PATH"
# persist-credentials: false keeps GITHUB_TOKEN out of .git/config so it
# can't be read via a PR-planted pre-push hook. The App token is not
# created until after the untrusted steps below.
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
with:
ref: ${{ github.event.pull_request.head.ref }}
fetch-depth: 0
persist-credentials: false
- name: Format and commit CHANGELOG files
id: format
env:
BASE_REF: ${{ github.event.pull_request.base.ref }}
run: |
set -euo pipefail
# Ensure base ref is available locally — actions/checkout with
# fetch-depth: 0 fetches history of the head ref, not other branches.
git fetch --no-tags --prune origin "${BASE_REF}"
# Capture diff output separately so a failing `git diff` does not get
# swallowed by `|| true` on the downstream grep pipeline.
changed_paths="$(git diff --name-only --diff-filter=ACMRT "origin/${BASE_REF}...HEAD")"
mapfile -t changelog_files < <(
printf '%s\n' "$changed_paths" | grep -E '(^|/)CHANGELOG\.md$' || true
)
if [[ "${#changelog_files[@]}" -eq 0 ]]; then
echo "No CHANGELOG files changed in release PR"
echo "has_changes=false" >> "$GITHUB_OUTPUT"
exit 0
fi
# --no-config and --no-editorconfig prevent prettier from loading a
# PR-controlled .prettierrc.js (which would execute arbitrary code) or
# .editorconfig that could change what gets written.
prettier --no-config --no-editorconfig --write "${changelog_files[@]}"
if git diff --quiet -- "${changelog_files[@]}"; then
echo "No formatting changes needed"
echo "has_changes=false" >> "$GITHUB_OUTPUT"
exit 0
fi
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add "${changelog_files[@]}"
# core.hooksPath=/dev/null prevents a PR-planted .git/hooks/pre-commit
# from tampering with the commit.
git -c core.hooksPath=/dev/null \
commit -m "chore: format CHANGELOG files with prettier"
echo "has_changes=true" >> "$GITHUB_OUTPUT"
# Refuse to push if the just-created commit touches anything other than
# CHANGELOG.md files. Runs before the App token is issued.
- name: Verify commit scope
if: steps.format.outputs.has_changes == 'true'
run: |
set -euo pipefail
mapfile -t touched < <(git diff-tree --no-commit-id --name-only -r HEAD)
# Match the selector used above (^|/)CHANGELOG\.md$ — basename only,
# so MY_CHANGELOG.md or CHANGELOG.md.bak are rejected.
for path in "${touched[@]}"; do
if [[ "$path" != "CHANGELOG.md" && "$path" != */CHANGELOG.md ]]; then
echo "::error::Refusing to push: commit touches non-CHANGELOG path: $path"
exit 1
fi
done
# Create the App token only after untrusted steps so prettier / npm
# install never had it in reach. Token inherits the App installation's
# granted permissions — do NOT add `permission-*` inputs here until the
# App installation is confirmed to grant every requested permission;
# see the matching note on release-please.yml.
- name: Create App token for push
if: steps.format.outputs.has_changes == 'true'
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3
id: app-token
with:
app-id: ${{ vars.PROMPTFOOBOT_APP_ID }}
private-key: ${{ secrets.PROMPTFOOBOT_APP_PRIVATE_KEY }}
- name: Push formatted CHANGELOG commit
if: steps.format.outputs.has_changes == 'true'
env:
HEAD_REF: ${{ github.event.pull_request.head.ref }}
GH_TOKEN: ${{ steps.app-token.outputs.token }}
run: |
set -euo pipefail
# GitHub's Git smart HTTP endpoint expects Basic auth. Build the
# header just-in-time so credentials are scoped to this invocation
# instead of being persisted in .git/config.
basic_auth="$(printf 'x-access-token:%s' "${GH_TOKEN}" | base64 | tr -d '\n')"
git -c core.hooksPath=/dev/null \
-c "http.https://github.com/.extraheader=AUTHORIZATION: basic ${basic_auth}" \
push origin "HEAD:${HEAD_REF}"