diff --git a/.github/workflows/sync-autoheal.yml b/.github/workflows/sync-autoheal.yml new file mode 100644 index 0000000..76b0a21 --- /dev/null +++ b/.github/workflows/sync-autoheal.yml @@ -0,0 +1,74 @@ +name: Sync spec auto-heal + +# The automated spec-sync PRs (branch `chore/sync-v2-spec-*`) update +# spec/openapi.yaml but not the generated comfy_low models, so the codegen-drift +# check in ci.yml fails until someone runs scripts/gen_models.sh by hand. This +# workflow does that automatically: on those branches it regenerates the models +# and, if they changed, commits and pushes them back onto the PR branch. +# +# The push uses SPEC_SYNC_TOKEN (a token with contents:write) rather than the +# default GITHUB_TOKEN: a GITHUB_TOKEN push does not re-trigger CI (GitHub's +# recursive-run guard), so the required checks would stay red on the new head +# commit. With SPEC_SYNC_TOKEN the follow-up CI run fires and goes green. When +# regeneration produces no changes the step pushes nothing, so this cannot loop. +# +# Only runs on the sync branches; an ordinary PR is never touched. + +on: + pull_request: + types: [opened, synchronize, reopened] + branches: [main] + +concurrency: + group: sync-autoheal-${{ github.head_ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + autoheal: + if: startsWith(github.head_ref, 'chore/sync-v2-spec-') + runs-on: ubuntu-latest + env: + SPEC_SYNC_TOKEN: ${{ secrets.SPEC_SYNC_TOKEN }} + steps: + - name: Require a push-capable token + if: env.SPEC_SYNC_TOKEN == '' + run: | + echo "::error::SPEC_SYNC_TOKEN is not set — cannot push the regenerated" \ + "models, so the codegen-drift check would stay red. Add a token with" \ + "contents:write on this repo as the SPEC_SYNC_TOKEN secret." >&2 + exit 1 + + - name: Check out the PR branch + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + token: ${{ env.SPEC_SYNC_TOKEN }} + ref: ${{ github.head_ref }} + + - name: Set up Python + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + with: + python-version: '3.12' + cache: 'pip' + cache-dependency-path: pyproject.toml + + - name: Install codegen dependencies + run: pip install -e .[codegen] + + - name: Regenerate the models from the vendored spec + run: bash scripts/gen_models.sh + + - name: Commit and push the regenerated models if they changed + run: | + set -euo pipefail + if [ -z "$(git status --porcelain)" ]; then + echo "Generated models already in sync — nothing to push." + exit 0 + fi + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git add -A + git commit -m "chore: regenerate models for synced v2 spec" + git push origin "HEAD:${GITHUB_HEAD_REF}"