mirror of
https://github.com/fsolla/teqo.git
synced 2026-11-12 22:13:05 +00:00
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.
57 lines
3 KiB
YAML
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 }}"
|