diff --git a/.github/workflows/bump-cursor-review-callers.yml b/.github/workflows/bump-cursor-review-callers.yml index 4f9d730..073932d 100644 --- a/.github/workflows/bump-cursor-review-callers.yml +++ b/.github/workflows/bump-cursor-review-callers.yml @@ -3,6 +3,21 @@ name: Bump cursor-review callers # When cursor-review.yml is updated on main, open a SHA-bump PR in every repo # that pins a caller against it. PRs are opened by Cloud Code Bot so they are # easy to filter and merge. +# +# The caller list is NOT hardcoded here. This repo is PUBLIC (workflow file and +# Actions run logs are both publicly viewable), and most callers are private, so +# their names must never appear in this file or its logs. The list lives in the +# repo-level Actions variable `CURSOR_REVIEW_CALLERS` (config, not a credential — +# a variable, not a secret, since secrets are write-only via the API) as a JSON +# array of {"repo","file","label"} objects. Every repo name is `::add-mask::`ed +# out of the (public) run logs before it is ever echoed. +# +# Update flow — adding/removing a caller needs NO public commit: +# gh variable set CURSOR_REVIEW_CALLERS --repo Comfy-Org/github-workflows \ +# --body "$(jq -c . callers.json)" +# Keep the canonical callers.json in a PRIVATE infra/ops repo so variable edits +# have a reviewed source of truth; the org audit log records each edit. (The +# specific home repo is intentionally not named here — this file is public.) on: workflow_dispatch: {} # allow on-demand runs (e.g. to re-bump callers) @@ -27,6 +42,10 @@ jobs: env: GH_TOKEN: ${{ steps.token.outputs.token }} NEW_SHA: ${{ github.sha }} + # JSON array of {"repo","file","label"} — see the header comment for the + # update flow. Kept in a variable (not the file) so private caller names + # never land in this public repo or its logs. + CALLERS_JSON: ${{ vars.CURSOR_REVIEW_CALLERS }} run: | # NOTE: deliberately no `set -e`. Each caller is bumped independently # in bump_one(); a failure there returns non-zero and is downgraded to @@ -36,20 +55,32 @@ jobs: SHORT="${NEW_SHA:0:7}" BRANCH="ci/bump-cursor-review-${SHORT}" - # repo|file|label — label is optional, leave empty if the repo has none - CALLERS=( - "Comfy-Org/cloud|.github/workflows/ci-cursor-review.yml|" - "Comfy-Org/comfy-cloud-mcp-server|.github/workflows/ci-cursor-review.yml|" - "Comfy-Org/comfy-local-mcp|.github/workflows/ci-cursor-review.yml|" - "Comfy-Org/Comfy-iOS|.github/workflows/ci-cursor-review.yml|" - "Comfy-Org/ComfySwiftSDK|.github/workflows/ci-cursor-review.yml|" - "Comfy-Org/comfy-inapp-agent|.github/workflows/ci-cursor-review.yml|" - "Comfy-Org/swarmhost|.github/workflows/cursor-review.yml|" - "Comfy-Org/comfy-infra|.github/workflows/ci-cursor-review.yml|" - "Comfy-Org/ComfyUI_frontend|.github/workflows/pr-cursor-review.yaml|" - "Comfy-Org/Comfy-Desktop|.github/workflows/ci-cursor-review.yml|ci" - "Comfy-Org/ComfyUI|.github/workflows/ci-cursor-review.yml|Core" - ) + # Load the caller list from the CURSOR_REVIEW_CALLERS variable. Hard-fail + # loudly on a missing/empty/invalid value — a silent no-op dispatcher + # (which would leave every caller un-bumped without anyone noticing) must + # not be possible. + if [[ -z "${CALLERS_JSON//[[:space:]]/}" ]]; then + echo "::error::CURSOR_REVIEW_CALLERS variable is missing or empty. Seed it with the caller list — see this workflow's header comment for the update flow." + exit 1 + fi + if ! jq -e 'type == "array" and length > 0 and all(.[]; (.repo | type == "string" and . != "") and (.file | type == "string" and . != ""))' <<<"$CALLERS_JSON" >/dev/null 2>&1; then + echo "::error::CURSOR_REVIEW_CALLERS is not a non-empty JSON array of {repo,file,label} objects (each needing a non-empty repo and file). Fix the variable — see the workflow header." + exit 1 + fi + + # Parse the JSON into repo|file|label tuples, and mask every repo name in + # the (publicly viewable) run logs BEFORE the loop that echoes it, so all + # per-repo output shows *** instead of a private repo name. + CALLERS=() + while IFS= read -r ENTRY; do + echo "::add-mask::${ENTRY%%|*}" + CALLERS+=("$ENTRY") + done < <(jq -r '.[] | "\(.repo)|\(.file)|\(.label // "")"' <<<"$CALLERS_JSON") + + if (( ${#CALLERS[@]} == 0 )); then + echo "::error::CURSOR_REVIEW_CALLERS parsed to zero callers — refusing to run a no-op dispatcher." + exit 1 + fi # Bump a single caller repo. Every external call is guarded, so a bad # repo returns non-zero here (caught by the loop) instead of killing