diff --git a/.github/workflows/auditor-audit.yml b/.github/workflows/auditor-audit.yml index 65a275cb9..693c2ae7d 100644 --- a/.github/workflows/auditor-audit.yml +++ b/.github/workflows/auditor-audit.yml @@ -753,6 +753,7 @@ jobs: TOTAL: ${{ steps.triage.outputs.total }} STRATEGY: ${{ steps.triage.outputs.strategy }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PAT_TOKEN: ${{ secrets.PAT_TOKEN }} run: | SLUG="${TARGET_REPO//\//-}" mkdir -p "auditor/audits" @@ -828,16 +829,10 @@ jobs: exit 1 fi - # Re-enable git credentials for push - git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/$GITHUB_REPOSITORY.git" - git config user.name "nlpm-auditor[bot]" - git config user.email "nlpm-auditor[bot]@users.noreply.github.com" + # Commit via bot PR. git add auditor/audits/ auditor/reports/ auditor/registry/ auditor/logs/events.jsonl auditor/findings.jsonl auditor/disagreements.jsonl bash auditor/scripts/guard-protected-paths.sh || exit 1 - git diff --cached --quiet || { - git commit -m "audit: $TARGET_REPO ($SCORE/100, security:$SECURITY, $STRATEGY, $TOTAL artifacts)" - bash auditor/scripts/git-push-with-retry.sh 5 - } + bash auditor/scripts/commit-via-pr.sh "audit: $TARGET_REPO ($SCORE/100, security:$SECURITY, $STRATEGY, $TOTAL artifacts)" gh issue edit "$ISSUE_NUM" --add-label "audit-complete" --remove-label "audit-ready" 2>/dev/null || true @@ -979,11 +974,8 @@ jobs: # and the push retry logic still has to handle conflicts. git add auditor/disclosures-pending/ auditor/logs/events.jsonl bash auditor/scripts/guard-protected-paths.sh || exit 1 - git diff --cached --quiet || { - git commit -m "disclosure-pending: $TARGET_REPO (security:$SECURITY)" - bash auditor/scripts/git-push-with-retry.sh 5 \ - || echo "WARN: disclosure-pending push failed after 5 attempts; file is staged but not pushed" - } + bash auditor/scripts/commit-via-pr.sh "disclosure-pending: $TARGET_REPO (security:$SECURITY)" \ + || echo "WARN: disclosure-pending bot PR failed; file is staged locally but not pushed" fi fi diff --git a/.github/workflows/auditor-case-study.yml b/.github/workflows/auditor-case-study.yml index d8e59fb62..8a013a4a9 100644 --- a/.github/workflows/auditor-case-study.yml +++ b/.github/workflows/auditor-case-study.yml @@ -628,6 +628,7 @@ jobs: steps.worthiness.outputs.worthy == 'false' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PAT_TOKEN: ${{ secrets.PAT_TOKEN }} TARGET_REPO: ${{ steps.target.outputs.repo }} ISSUE_NUM: ${{ steps.target.outputs.issue }} REASON: ${{ steps.worthiness.outputs.reason }} @@ -666,22 +667,10 @@ jobs: log_event "case-study" "no_narrative" "$(jq -cn --arg repo "$TARGET_REPO" --arg reason "$REASON" '{repo: $repo, reason: $reason}')" || true - # Commit the registry + event. - git config user.name "nlpm-auditor[bot]" - git config user.email "nlpm-auditor[bot]@users.noreply.github.com" - git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" + # Commit the registry + event via bot PR. git add auditor/registry/repos.json auditor/logs/events.jsonl bash auditor/scripts/guard-protected-paths.sh || exit 1 - git diff --cached --quiet || { - git commit -m "case-study: $TARGET_REPO — no narrative ($REASON)" - for ATTEMPT in 1 2 3 4 5; do - if git push 2>/dev/null; then break; fi - git pull --no-rebase origin main --no-edit 2>/dev/null || true - bash auditor/scripts/resolve-merge-conflicts.sh || true - git diff --cached --quiet 2>/dev/null || git commit --no-edit 2>/dev/null || true - [ "$ATTEMPT" -eq 5 ] && { echo "WARN: push failed after 5 attempts"; break; } - done - } + bash auditor/scripts/commit-via-pr.sh "case-study: $TARGET_REPO — no narrative ($REASON)" - name: Compute write_article gate # Folds skipcheck + worthiness into a single output that every @@ -1317,6 +1306,7 @@ jobs: if: steps.gate.outputs.write_article == 'true' || steps.skipcheck.outputs.skip == 'true' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PAT_TOKEN: ${{ secrets.PAT_TOKEN }} TARGET_REPO: ${{ steps.target.outputs.repo }} ISSUE_NUM: ${{ steps.target.outputs.issue }} SKIP: ${{ steps.skipcheck.outputs.skip }} @@ -1343,28 +1333,13 @@ jobs: log_event "case-study" "published" "{\"repo\": \"$TARGET_REPO\", \"article_lines\": $LINES, \"has_cover\": $HAS_IMAGE}" - git config user.name "nlpm-auditor[bot]" - git config user.email "nlpm-auditor[bot]@users.noreply.github.com" - git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" - # Also stage re-audit artifacts written earlier in this run: - # .re-audit.md (scoring report), .re-audit.findings.jsonl - # (sidecar), .re-audit.diff.md (verification table). The diff - # script also appended finding_verified / finding_introduced - # events to logs/events.jsonl — already included above. + # Stage the case study + re-audit artifacts written earlier in + # this run (.re-audit.md, .re-audit.findings.jsonl, + # .re-audit.diff.md) and the appended finding_verified / + # finding_introduced events. git add case-studies/ auditor/logs/events.jsonl auditor/audits/ bash auditor/scripts/guard-protected-paths.sh || exit 1 - git diff --cached --quiet || { - git commit -m "case-study: $TARGET_REPO ($LINES lines)" - - for ATTEMPT in 1 2 3 4 5; do - if git push 2>/dev/null; then break; fi - echo "Push attempt $ATTEMPT failed, pulling..." - git pull --no-rebase origin main --no-edit 2>/dev/null || true - bash auditor/scripts/resolve-merge-conflicts.sh || true - git diff --cached --quiet 2>/dev/null || git commit --no-edit 2>/dev/null || true - [ "$ATTEMPT" -eq 5 ] && { echo "ERROR: push failed after 5 attempts"; exit 1; } - done - } + bash auditor/scripts/commit-via-pr.sh "case-study: $TARGET_REPO ($LINES lines)" # Update registry jq --arg name "$TARGET_REPO" --arg cs "case-studies/${DATE}-${SLUG}.md" \ @@ -1374,18 +1349,7 @@ jobs: git add auditor/registry/repos.json bash auditor/scripts/guard-protected-paths.sh || exit 1 - git diff --cached --quiet || { - git commit -m "chore: mark $TARGET_REPO complete" - - for ATTEMPT in 1 2 3 4 5; do - if git push 2>/dev/null; then break; fi - echo "Push attempt $ATTEMPT failed, pulling..." - git pull --no-rebase origin main --no-edit 2>/dev/null || true - bash auditor/scripts/resolve-merge-conflicts.sh || true - git diff --cached --quiet 2>/dev/null || git commit --no-edit 2>/dev/null || true - [ "$ATTEMPT" -eq 5 ] && { echo "ERROR: push failed after 5 attempts"; exit 1; } - done - } + bash auditor/scripts/commit-via-pr.sh "chore: mark $TARGET_REPO complete" # Comment and close issue SUMMARY="Case study published" diff --git a/.github/workflows/auditor-classify.yml b/.github/workflows/auditor-classify.yml index 3551161d2..0de5f8399 100644 --- a/.github/workflows/auditor-classify.yml +++ b/.github/workflows/auditor-classify.yml @@ -229,17 +229,12 @@ jobs: '{classifications: $c, invalid: $i}')" || true echo "Appended $APPENDED classifications ($INVALID invalid lines skipped)." - - name: Commit + - name: Commit via bot PR if: steps.scan.outputs.unseen != '0' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PAT_TOKEN: ${{ secrets.PAT_TOKEN }} run: | - git config user.name "nlpm-auditor[bot]" - git config user.email "nlpm-auditor[bot]@users.noreply.github.com" - git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" git add auditor/disagreements.jsonl auditor/logs/events.jsonl bash auditor/scripts/guard-protected-paths.sh || exit 1 - git diff --cached --quiet || { - git commit -m "classify: $(date +%Y-%m-%d) dissent classifications" - bash auditor/scripts/git-push-with-retry.sh 5 - } + bash auditor/scripts/commit-via-pr.sh "classify: $(date +%Y-%m-%d) dissent classifications" diff --git a/.github/workflows/auditor-contribute.yml b/.github/workflows/auditor-contribute.yml index cc37863f4..b8678fb61 100644 --- a/.github/workflows/auditor-contribute.yml +++ b/.github/workflows/auditor-contribute.yml @@ -76,6 +76,7 @@ jobs: TARGET_REPO: ${{ steps.target.outputs.repo }} ISSUE_NUM: ${{ steps.target.outputs.issue }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PAT_TOKEN: ${{ secrets.PAT_TOKEN }} run: | OWNER=$(echo "$TARGET_REPO" | cut -d/ -f1) # Owners that don't accept external PRs (policy, not code). @@ -100,20 +101,9 @@ jobs: auditor/registry/repos.json > /tmp/reg.json \ && bash auditor/scripts/atomic-registry-write.sh - git config user.name "nlpm-auditor[bot]" - git config user.email "nlpm-auditor[bot]@users.noreply.github.com" - git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" git add auditor/registry/repos.json bash auditor/scripts/guard-protected-paths.sh || exit 1 - git diff --cached --quiet || { - git commit -m "policy: $TARGET_REPO — no external PRs (gated in contribute step)" - # Was `git push 2>/dev/null || true` — silently swallowing - # push failures meant the policy gate state could miss - # main and the target would be re-attempted on the next - # contribute run. Use the retry helper so we either land - # the change or fail loudly. - bash auditor/scripts/git-push-with-retry.sh - } + bash auditor/scripts/commit-via-pr.sh "policy: $TARGET_REPO — no external PRs (gated in contribute step)" exit 0 fi done @@ -145,6 +135,7 @@ jobs: ISSUE_NUM: ${{ steps.target.outputs.issue }} CLA_SIGNED: ${{ vars.GOOGLE_CLA_SIGNED || 'false' }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PAT_TOKEN: ${{ secrets.PAT_TOKEN }} run: | OWNER=$(echo "$TARGET_REPO" | cut -d/ -f1) # Orgs whose maintainers require a signed Google CLA before review. @@ -194,15 +185,9 @@ jobs: auditor/registry/repos.json > /tmp/reg.json \ && bash auditor/scripts/atomic-registry-write.sh - git config user.name "nlpm-auditor[bot]" - git config user.email "nlpm-auditor[bot]@users.noreply.github.com" - git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" git add auditor/registry/repos.json bash auditor/scripts/guard-protected-paths.sh || exit 1 - git diff --cached --quiet || { - git commit -m "policy: $TARGET_REPO — CLA gate ($GATE_REASON)" - bash auditor/scripts/git-push-with-retry.sh - } + bash auditor/scripts/commit-via-pr.sh "policy: $TARGET_REPO — CLA gate ($GATE_REASON)" exit 0 fi fi @@ -223,6 +208,7 @@ jobs: id: pushback_gate env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PAT_TOKEN: ${{ secrets.PAT_TOKEN }} TARGET_REPO: ${{ steps.target.outputs.repo }} ISSUE_NUM: ${{ steps.target.outputs.issue }} run: | @@ -279,13 +265,8 @@ jobs: # the gated status to main, so the next contribute attempt # would re-process this target as if no gate decision had # been made. - git config user.name "nlpm-auditor[bot]" - git config user.email "nlpm-auditor[bot]@users.noreply.github.com" git add auditor/registry/repos.json - if ! git diff --cached --quiet; then - git commit -m "contribute: mark $TARGET_REPO pushback_gated" - bash auditor/scripts/git-push-with-retry.sh - fi + bash auditor/scripts/commit-via-pr.sh "contribute: mark $TARGET_REPO pushback_gated" # Persist the gate decision so subsequent steps skip cleanly. echo "gated=true" >> "$GITHUB_OUTPUT" @@ -454,6 +435,7 @@ jobs: steps.sidecar.outputs.skip_contribute == 'true' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PAT_TOKEN: ${{ secrets.PAT_TOKEN }} ISSUE_NUM: ${{ steps.target.outputs.issue }} TARGET_REPO: ${{ steps.target.outputs.repo }} run: | @@ -475,16 +457,11 @@ jobs: auditor/registry/repos.json > /tmp/reg.json \ && bash auditor/scripts/atomic-registry-write.sh - # Same fix as the pushback gate above: commit + push the - # status change, otherwise the runner's mutation never lands - # on main and the target gets re-processed. - git config user.name "nlpm-auditor[bot]" - git config user.email "nlpm-auditor[bot]@users.noreply.github.com" + # Same fix as the pushback gate above: commit the status change + # via a bot PR, otherwise the runner's mutation never lands on + # main and the target gets re-processed. git add auditor/registry/repos.json - if ! git diff --cached --quiet; then - git commit -m "contribute: $TARGET_REPO — no high-confidence findings" - bash auditor/scripts/git-push-with-retry.sh - fi + bash auditor/scripts/commit-via-pr.sh "contribute: $TARGET_REPO — no high-confidence findings" - name: Contribute with Claude Code if: | diff --git a/.github/workflows/auditor-daily-report.yml b/.github/workflows/auditor-daily-report.yml index 4024dee01..4f6bb042e 100644 --- a/.github/workflows/auditor-daily-report.yml +++ b/.github/workflows/auditor-daily-report.yml @@ -73,26 +73,13 @@ jobs: - name: Log and commit env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PAT_TOKEN: ${{ secrets.PAT_TOKEN }} run: | source auditor/scripts/log-event.sh TOTAL=$(jq '.repos | length' auditor/registry/repos.json) log_event "daily-report" "report_generated" "$(jq -cn --arg total "$TOTAL" '{total_repos: ($total | tonumber)}')" || true - git config user.name "nlpm-auditor[bot]" - git config user.email "nlpm-auditor[bot]@users.noreply.github.com" - git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" git add auditor/reports/ auditor/feedback/ auditor/logs/events.jsonl bash auditor/scripts/guard-protected-paths.sh || exit 1 - git diff --cached --quiet || { - git commit -m "report: daily $(date +%Y-%m-%d)" - - for ATTEMPT in 1 2 3 4 5; do - if git push 2>/dev/null; then break; fi - echo "Push attempt $ATTEMPT failed, pulling..." - git pull --no-rebase origin main --no-edit 2>/dev/null || true - bash auditor/scripts/resolve-merge-conflicts.sh || true - git diff --cached --quiet 2>/dev/null || git commit --no-edit 2>/dev/null || true - [ "$ATTEMPT" -eq 5 ] && { echo "ERROR: push failed after 5 attempts"; exit 1; } - done - } + bash auditor/scripts/commit-via-pr.sh "report: daily $(date +%Y-%m-%d)" diff --git a/.github/workflows/auditor-discover.yml b/.github/workflows/auditor-discover.yml index 7e60b7ee2..5d98ce097 100644 --- a/.github/workflows/auditor-discover.yml +++ b/.github/workflows/auditor-discover.yml @@ -302,6 +302,7 @@ jobs: if: inputs.dry_run != true && inputs.dry_run != 'true' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PAT_TOKEN: ${{ secrets.PAT_TOKEN }} run: | source auditor/scripts/log-event.sh @@ -312,15 +313,9 @@ jobs: log_event "discover" "search_complete" "{\"candidates\": $CANDIDATES, \"new\": $NEW, \"worthy\": $WORTHY, \"oversized\": $OVERSIZED}" - git config user.name "nlpm-auditor[bot]" - git config user.email "nlpm-auditor[bot]@users.noreply.github.com" - git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" git add auditor/registry/repos.json auditor/logs/events.jsonl bash auditor/scripts/guard-protected-paths.sh || exit 1 - git diff --cached --quiet || { - git commit -m "chore: discovery $(date +%Y-%m-%d) — $WORTHY new repos" - bash auditor/scripts/git-push-with-retry.sh - } + bash auditor/scripts/commit-via-pr.sh "chore: discovery $(date +%Y-%m-%d) — $WORTHY new repos" - name: Summary run: | diff --git a/.github/workflows/auditor-docs-diff.yml b/.github/workflows/auditor-docs-diff.yml index 41a59d3a1..c34459a83 100644 --- a/.github/workflows/auditor-docs-diff.yml +++ b/.github/workflows/auditor-docs-diff.yml @@ -140,21 +140,10 @@ jobs: fi done < /tmp/changed-urls.txt - - name: Commit hash store + - name: Commit hash store via bot PR env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PAT_TOKEN: ${{ secrets.PAT_TOKEN }} run: | - git config user.name "nlpm-auditor[bot]" - git config user.email "nlpm-auditor[bot]@users.noreply.github.com" - git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" git add auditor/docs-hashes.json - git diff --cached --quiet || { - git commit -m "docs-diff: $(date +%Y-%m-%d) — hash store update" - for ATTEMPT in 1 2 3 4 5; do - if git push 2>/dev/null; then break; fi - git pull --no-rebase origin main --no-edit 2>/dev/null || true - bash auditor/scripts/resolve-merge-conflicts.sh || true - git diff --cached --quiet 2>/dev/null || git commit --no-edit 2>/dev/null || true - [ "$ATTEMPT" -eq 5 ] && { echo "ERROR: push failed after 5 attempts"; exit 1; } - done - } + bash auditor/scripts/commit-via-pr.sh "docs-diff: $(date +%Y-%m-%d) — hash store update" diff --git a/.github/workflows/auditor-exemplar.yml b/.github/workflows/auditor-exemplar.yml index 384785d60..0f5b328ff 100644 --- a/.github/workflows/auditor-exemplar.yml +++ b/.github/workflows/auditor-exemplar.yml @@ -202,6 +202,7 @@ jobs: EXEMPLAR_PATH: ${{ steps.ctx.outputs.exemplar_path }} SCORE: ${{ steps.ctx.outputs.score }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PAT_TOKEN: ${{ secrets.PAT_TOKEN }} run: | source auditor/scripts/log-event.sh @@ -215,15 +216,9 @@ jobs: exit 1 fi - git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/$GITHUB_REPOSITORY.git" - git config user.name "nlpm-auditor[bot]" - git config user.email "nlpm-auditor[bot]@users.noreply.github.com" git add "$EXEMPLAR_PATH" auditor/exemplars/README.md auditor/registry/repos.json auditor/logs/events.jsonl bash auditor/scripts/guard-protected-paths.sh || exit 1 - git diff --cached --quiet || { - git commit -m "exemplar: $TARGET_REPO (score $SCORE/100)" - bash auditor/scripts/git-push-with-retry.sh 5 - } + bash auditor/scripts/commit-via-pr.sh "exemplar: $TARGET_REPO (score $SCORE/100)" log_event "exemplar" "exemplar_published" "$(jq -cn \ --arg repo "$TARGET_REPO" \ diff --git a/.github/workflows/auditor-render-dashboard.yml b/.github/workflows/auditor-render-dashboard.yml index f625857a5..b67f7e4dd 100644 --- a/.github/workflows/auditor-render-dashboard.yml +++ b/.github/workflows/auditor-render-dashboard.yml @@ -59,16 +59,11 @@ jobs: "$(jq -cn --argjson r "$REPO_COUNT" --argjson f "$FIND_COUNT" --argjson a "$ADV_COUNT" \ '{repos: $r, findings: $f, advisories: $a}')" || true - - name: Commit dashboard + - name: Commit dashboard via bot PR env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PAT_TOKEN: ${{ secrets.PAT_TOKEN }} run: | - git config user.name "nlpm-auditor[bot]" - git config user.email "nlpm-auditor[bot]@users.noreply.github.com" - git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" git add auditor/reports/ auditor/logs/events.jsonl 2>/dev/null || true bash auditor/scripts/guard-protected-paths.sh || exit 1 - git diff --cached --quiet || { - git commit -m "dashboard: $(date -u +%Y-%m-%d) render" - bash auditor/scripts/git-push-with-retry.sh - } + bash auditor/scripts/commit-via-pr.sh "dashboard: $(date -u +%Y-%m-%d) render" diff --git a/.github/workflows/auditor-repo-report.yml b/.github/workflows/auditor-repo-report.yml index 920f42d53..c3b33afac 100644 --- a/.github/workflows/auditor-repo-report.yml +++ b/.github/workflows/auditor-repo-report.yml @@ -66,17 +66,12 @@ jobs: "$(jq -cn --arg r "$INPUT_REPO" --argjson ok "$OK" --argjson fail "$FAIL" \ '{scope: $r, rendered: $ok, failed: $fail}')" || true - - name: Commit reports + - name: Commit reports via bot PR env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PAT_TOKEN: ${{ secrets.PAT_TOKEN }} INPUT_REPO: ${{ inputs.repo }} run: | - git config user.name "nlpm-auditor[bot]" - git config user.email "nlpm-auditor[bot]@users.noreply.github.com" - git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" git add auditor/reports/ auditor/logs/events.jsonl 2>/dev/null || true bash auditor/scripts/guard-protected-paths.sh || exit 1 - git diff --cached --quiet || { - git commit -m "repo-report: backfill ${INPUT_REPO} ($(date -u +%Y-%m-%d))" - bash auditor/scripts/git-push-with-retry.sh - } + bash auditor/scripts/commit-via-pr.sh "repo-report: backfill ${INPUT_REPO} ($(date -u +%Y-%m-%d))" diff --git a/.github/workflows/auditor-suppressions.yml b/.github/workflows/auditor-suppressions.yml index 8c6bf7c16..89e1f2000 100644 --- a/.github/workflows/auditor-suppressions.yml +++ b/.github/workflows/auditor-suppressions.yml @@ -54,16 +54,11 @@ jobs: source auditor/scripts/log-event.sh log_event "suppressions" "scan_complete" "$SUMMARY" || true - - name: Commit and push + - name: Commit via bot PR env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PAT_TOKEN: ${{ secrets.PAT_TOKEN }} run: | - git config user.name "nlpm-auditor[bot]" - git config user.email "nlpm-auditor[bot]@users.noreply.github.com" - git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" git add auditor/disagreements.jsonl auditor/logs/events.jsonl bash auditor/scripts/guard-protected-paths.sh || exit 1 - git diff --cached --quiet || { - git commit -m "suppressions: $(date +%Y-%m-%d) scan" - bash auditor/scripts/git-push-with-retry.sh - } + bash auditor/scripts/commit-via-pr.sh "suppressions: $(date +%Y-%m-%d) scan" diff --git a/.github/workflows/auditor-vocab-drift.yml b/.github/workflows/auditor-vocab-drift.yml index bfdc593b7..00f4fcaa6 100644 --- a/.github/workflows/auditor-vocab-drift.yml +++ b/.github/workflows/auditor-vocab-drift.yml @@ -279,17 +279,14 @@ jobs: # ================================================================ # COMMIT # ================================================================ - - name: Commit advisory artifacts + - name: Commit advisory artifacts via bot PR if: steps.count.outputs.skip == 'false' env: TARGET_REPO: ${{ steps.target.outputs.repo }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PAT_TOKEN: ${{ secrets.PAT_TOKEN }} run: | SLUG="${TARGET_REPO//\//-}" - git config user.name "nlpm-auditor[bot]" - git config user.email "nlpm-auditor[bot]@users.noreply.github.com" - git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" - git add \ "auditor/audits/${SLUG}.vocab-drift.md" \ "auditor/audits/${SLUG}.vocab-drift.jsonl" \ @@ -297,10 +294,7 @@ jobs: "auditor/vocab-advisories.jsonl" \ "auditor/logs/events.jsonl" 2>/dev/null || true bash auditor/scripts/guard-protected-paths.sh || exit 1 - git diff --cached --quiet || { - git commit -m "vocab-drift: ${TARGET_REPO} advisory ($(date +%Y-%m-%d))" - bash auditor/scripts/git-push-with-retry.sh - } + bash auditor/scripts/commit-via-pr.sh "vocab-drift: ${TARGET_REPO} advisory ($(date +%Y-%m-%d))" # ================================================================ # COMMENT on the tracking issue (if there is one) diff --git a/auditor/scripts/commit-via-pr.sh b/auditor/scripts/commit-via-pr.sh index 5bcebecc3..b60bfb682 100755 --- a/auditor/scripts/commit-via-pr.sh +++ b/auditor/scripts/commit-via-pr.sh @@ -69,11 +69,15 @@ git -c user.name="nlpm-auditor[bot]" \ -c user.email="nlpm-auditor[bot]@users.noreply.github.com" \ commit -m "$MSG" HEAD_AFTER=$(git rev-parse HEAD) +SHORT_SHA=$(git rev-parse --short=8 HEAD) -# --- create the bot branch pointing at the new commit --- +# --- create the bot branch pointing at the new commit. The short SHA +# in the branch name keeps multiple helper calls within ONE workflow +# run from colliding on the same branch (case-study and audit make +# several commits per run). --- SAFE_WF=$(echo "${GITHUB_WORKFLOW:-unknown-workflow}" | tr -c 'a-zA-Z0-9._-' '-') RUN_ID="${GITHUB_RUN_ID:-$(date +%s)}" -BRANCH="auditor/bot/${SAFE_WF}/${RUN_ID}" +BRANCH="auditor/bot/${SAFE_WF}/${RUN_ID}-${SHORT_SHA}" git branch -f "$BRANCH" "$HEAD_AFTER" # --- push the branch via the chosen token --- @@ -90,6 +94,13 @@ for attempt in 1 2 3; do sleep $((attempt * 3)) done +# --- ensure the auditor-bot label exists (idempotent; --force is a no-op +# when label already exists with this color/description) --- +GH_TOKEN="$TOKEN" gh label create auditor-bot \ + --color "ededed" \ + --description "Automated commit from an auditor workflow" \ + --force >/dev/null 2>&1 || true + # --- open PR + enable auto-merge --- RUN_URL="https://github.com/${GITHUB_REPOSITORY}/actions/runs/${RUN_ID}" BODY=$(printf 'Automated bot commit from `%s` ([run %s](%s)).\n\nMerged via the auditor PR-flow (see `auditor/scripts/commit-via-pr.sh`).' \