teqo/.forgejo/workflows/agent-pr-ready-automerge.yml
Francisco Solla 4f7de670f5
Some checks are pending
CI (PR) / scope (pull_request) Successful in 35s
CI (PR) / lint (pull_request) Successful in 45s
CI (PR) / docs-guards (pull_request) Successful in 8s
CI (PR) / plans-only-closes (pull_request) Successful in 7s
CI (PR) / format (pull_request) Successful in 54s
CI (PR) / typecheck (pull_request) Successful in 31s
CI (PR) / knip (pull_request) Successful in 32s
CI (PR) / cycles (pull_request) Successful in 32s
CI (PR) / unit (pull_request) Successful in 55s
CI (PR) / int (pull_request) Successful in 2m46s
CI (PR) / build (pull_request) Has been skipped
CI (PR) / e2e (1) (pull_request) Has been skipped
CI (PR) / e2e (2) (pull_request) Has been skipped
CI (PR) / checks (pull_request) Successful in 1s
CI / deploy homeserver (teqo-1313) (push) Blocked by required conditions
CI / static (push) Waiting to run
CI / int (push) Waiting to run
CI / build (push) Waiting to run
CI / e2e (1) (push) Waiting to run
CI / e2e (2) (push) Waiting to run
CI / checks (push) Blocked by required conditions
PR Ready + auto-merge / ready-automerge (pull_request) Successful in 21m31s
Main merge flips claimed issues to done + in-prod / issue-done (pull_request) Successful in 12s
Promote plan-issue Related on main merge / plan-issue-ready (pull_request) Has been skipped
Agent pool supervisor / tick (pull_request) Successful in 28s
fix(OPS61): merge do safety net com FORGEJO_API_TOKEN — 409 PushRejected do hook pre-receive
O merge POST faz um push para main; o hook pre-receive do Forgejo rejeita o
push quando o usuário do token não tem write no repo — o GITHUB_TOKEN nativo
age como o usuário sistema do Actions. Por isso nenhum auto-merge funcionou
(o CLI morria no 409; runs 'success' eram leituras de PR já mergeada
manualmente). O workflow do safety net agora injeta o mesmo PAT dos pós-merge.
2026-08-18 18:07:55 -03:00

57 lines
3 KiB
YAML

# Safety net: every same-repo PR to main must be Ready + auto-merge.
# Covers Cloud ManagePullRequest defaulting to draft, agents that forget to
# arm the merge, and human/worktree PRs (the OPS52 incident was a human PR
# whose merge failed silently). Draft PRs from non-`cursor/*` branches are
# never touched — the draft flag is the actor's veto (the CLI skips them).
# Fork PRs are excluded (the repo is public; a merged fork PR would deploy).
#
# Forgejo port (OPS50): Forgejo's API has no auto-merge scheduling, so the
# workflow runs scripts/forgejo-pr-automerge.mjs (plain Node): marks draft →
# ready, waits for the commit statuses (the branch-protection `checks` gate),
# then merges by rebase. Same semantics as `gh pr merge --auto --rebase`,
# implemented as poll + merge. GitHub's cancel-workflow-on-failure action was
# dropped (no GITHUB_RUN_ID plumbing on Forgejo).
#
# OPS61: the job injects FORGEJO_API_TOKEN. The merge POST performs a git push
# of the rebased branch to main; Forgejo's pre-receive hook rejects that push
# when the caller's user has no repo write — and the native GITHUB_TOKEN acts
# as the Actions system user (no write, and the same 403 that broke issue
# label flips). Every pre-OPS61 "auto-merge" that ended success had actually
# found the PR already merged manually; the CLI's own merge attempts died on
# 409 "User permission denied for writing".
name: PR Ready + auto-merge
on:
pull_request:
types: [opened, reopened, synchronize, ready_for_review, converted_to_draft]
branches: [main]
jobs:
ready-automerge:
# Same-repo only. This MUST stay in the `if:` (pre-checkout): for a fork
# PR, actions/checkout checks out the fork's head, so a same-repo guard
# inside the CLI would already be running the fork's own script — RCE with
# the Actions token. Fork PRs are excluded here because the repo is public
# and a merged fork PR would deploy attacker code to production. The draft
# policy lives in the CLI (skips non-`cursor/*` drafts) because there the
# PR state is re-read from the API, not from webhook payload fields.
if: >-
github.event.pull_request.state == 'open' &&
github.event.pull_request.head.repo.full_name == github.repository
runs-on: ubuntu-latest
# OPS61: the CLI now waits for the full CI (PR) cascade (the `checks`
# rollup posts only after every ci-pr job, incl. e2e shards) — 55 min keeps
# 10 min of slack over the CLI's 45 min timeout.
timeout-minutes: 55
env:
FORGEJO_API_TOKEN: ${{ secrets.FORGEJO_API_TOKEN }}
steps:
- uses: actions/checkout@v5
# Script is plain Node (stdlib) — no pnpm. Disable package-manager-cache:
# setup-node@v5 defaults to true and looks for pnpm before pnpm/action-setup.
- uses: actions/setup-node@v5
with:
node-version: 24
package-manager-cache: false
- name: Mark Ready and merge when checks pass
run: node scripts/forgejo-pr-automerge.mjs --pr "${{ github.event.pull_request.number }}"