From f5868488d7f63b61f044dd1900ad2ccdc6ce3075 Mon Sep 17 00:00:00 2001 From: Eric Moore Date: Sat, 8 Aug 2026 20:19:12 -0500 Subject: [PATCH] fix(ci): evidence sync opens a PR instead of pushing to main MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The job harvested correctly and then threw the result away on every run. main carries a ruleset — "Changes must be made through a pull request" — so `git push origin main` was rejected with GH013 AFTER the bundles were gathered and committed. The failure was at the very last step, which is why the run looked like it worked until the end. Now commits to a fixed `evidence/safety-sync` branch and opens (or updates) a PR. Fixed branch name, so repeated syncs update the same PR instead of accumulating one per run; force-push is safe because the branch is rebuilt from main each time and belongs solely to this job. Reuses an open PR rather than letting `gh pr create` error on a duplicate. Adds `pull-requests: write`, which the job now needs. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_018umjfoyNwpa7BWVmzoayTM --- .github/workflows/safety-evidence-sync.yml | 34 ++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/.github/workflows/safety-evidence-sync.yml b/.github/workflows/safety-evidence-sync.yml index cdf19dd4e..bff95bd9f 100644 --- a/.github/workflows/safety-evidence-sync.yml +++ b/.github/workflows/safety-evidence-sync.yml @@ -51,6 +51,7 @@ concurrency: permissions: contents: write actions: read # listing + downloading artifacts + pull-requests: write # main's ruleset requires a PR; this job opens one jobs: sync: @@ -104,11 +105,25 @@ jobs: exit 1 fi - - name: Commit + # Opens a PR rather than pushing to main. main carries a ruleset — + # "Changes must be made through a pull request" — so the original + # `git push origin main` was rejected with GH013 *after* harvesting + # correctly. The evidence was gathered and then thrown away on every run. + # + # A fixed branch name (not one per run) means repeated syncs update the + # SAME open PR instead of accumulating a pile of them; force-push is safe + # because the branch is rebuilt from main each time and belongs solely to + # this job. + - name: Commit and open PR if: steps.diff.outputs.changed != '0' && inputs.dry_run != true + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | + set -euo pipefail + BRANCH="evidence/safety-sync" git config user.name "github-actions[bot]" git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git checkout -b "$BRANCH" git add qa_reports/safety_battery qa_reports/safety_interpret git commit -m "evidence: sync safety-battery bundles from expiring artifacts @@ -117,7 +132,22 @@ jobs: of the bytes and a separate retention question. bundles: ${{ steps.diff.outputs.bundles_battery }} battery, ${{ steps.diff.outputs.bundles_interpret }} interpret" - git push origin main + git push --force origin "$BRANCH" + + # Reuse the open PR if there is one; `gh pr create` errors when a PR + # already exists for the branch, and that must not fail the job. + if gh pr view "$BRANCH" --json state --jq .state 2>/dev/null | grep -q OPEN; then + echo "Updated the existing evidence PR." + else + gh pr create \ + --base main --head "$BRANCH" \ + --title "evidence: sync safety-battery bundles (${{ steps.diff.outputs.bundles_interpret }} interpret)" \ + --body "Automated by \`safety-evidence-sync\`. Artifacts expire at 90 days; this is the copy that does not. + + Harvested by \`tools/harvest_safety_evidence.py\`. Traces excluded — 99.9% of the bytes, and a separate retention question. + + bundles: ${{ steps.diff.outputs.bundles_battery }} battery, ${{ steps.diff.outputs.bundles_interpret }} interpret" + fi - name: Nothing to do if: steps.diff.outputs.changed == '0'