diff --git a/.github/workflows/auto-rebase-prs.yaml b/.github/workflows/auto-rebase-prs.yaml deleted file mode 100644 index 8a10a83ccc..0000000000 --- a/.github/workflows/auto-rebase-prs.yaml +++ /dev/null @@ -1,118 +0,0 @@ -name: "Auto-rebase open PRs" - -# Rebase open PRs against `dev` whenever it moves. Thin wrapper over -# peter-evans/rebase@v3. -# -# Forks: the app token is scoped to repos where the app is installed, so -# fork PR heads cannot be pushed. The action silently skips them (same -# behaviour as before; fork authors need "Allow edits by maintainers" -# enabled and the app installed on their fork, or rebase manually). -# Conflicts are also silently skipped. -# -# Token: GitHub App token (APP_ID + APP_PRIVATE_KEY). The app must have -# Contents R/W, Pull requests R/W, and Workflows R/W permissions so that -# rebased PRs containing `.github/workflows/` diffs can be pushed. - -on: - push: - branches: [dev] - workflow_dispatch: - inputs: - pr_number: - description: "Optional: rebase just this PR number (the action accepts head as `:`; we resolve via gh api). Leave empty to rebase all open PRs against dev." - required: false - default: "" - -permissions: - contents: write - pull-requests: write - -concurrency: - # Serialize so two back-to-back pushes to dev don't race and produce - # interleaved force-pushes on the same PR. - group: auto-rebase-prs - cancel-in-progress: false - -jobs: - rebase: - runs-on: ubuntu-latest - steps: - - name: Generate app token - uses: actions/create-github-app-token@v1 - id: app-token - with: - app-id: ${{ secrets.APP_ID }} - private-key: ${{ secrets.APP_PRIVATE_KEY }} - - - name: Checkout - uses: actions/checkout@v6 - with: - fetch-depth: 0 - token: ${{ steps.app-token.outputs.token }} - - - name: Resolve single-PR head spec (if pr_number given) - id: resolve_head - if: inputs.pr_number != '' - env: - GH_TOKEN: ${{ steps.app-token.outputs.token }} - PR_NUMBER: ${{ inputs.pr_number }} - run: | - set -euo pipefail - # Guard against rebasing a closed PR or one targeting - # a non-dev base (e.g. a hotfix staging branch). - PR_JSON=$(gh pr view "${PR_NUMBER}" --repo '${{ github.repository }}' \ - --json state,baseRefName,headRepositoryOwner,headRefName) - PR_STATE=$(echo "${PR_JSON}" | jq -r '.state') - PR_BASE=$(echo "${PR_JSON}" | jq -r '.baseRefName') - if [[ "${PR_STATE}" != "OPEN" ]]; then - echo "::warning::PR #${PR_NUMBER} is ${PR_STATE}, not OPEN — skipping." - echo "head=" >> "$GITHUB_OUTPUT" - exit 0 - fi - if [[ "${PR_BASE}" != "dev" ]]; then - echo "::warning::PR #${PR_NUMBER} targets '${PR_BASE}', not 'dev' — skipping to avoid rebasing the wrong base." - echo "head=" >> "$GITHUB_OUTPUT" - exit 0 - fi - HEAD_REF=$(echo "${PR_JSON}" | jq -r '"\(.headRepositoryOwner.login):\(.headRefName)"') - echo "head=${HEAD_REF}" >> "$GITHUB_OUTPUT" - - - name: Rebase open PRs against dev - id: rebase - # Single-PR dispatches without a valid head fall through to - # the all-PRs default; this guard keeps that from happening. - if: inputs.pr_number == '' || steps.resolve_head.outputs.head != '' - uses: peter-evans/rebase@v3 - with: - token: ${{ steps.app-token.outputs.token }} - base: dev - head: ${{ steps.resolve_head.outputs.head }} - exclude-drafts: true - exclude-labels: | - no-auto-rebase - - - name: Summarize - env: - REBASED: ${{ steps.rebase.outputs.rebased-count }} - run: | - { - echo "## Auto-rebase summary" - echo "" - echo "- PRs rebased: \`${REBASED:-0}\`" - echo "- Base: \`dev\`" - if [[ -n '${{ inputs.pr_number }}' ]]; then - echo "- Targeted single PR: #${{ inputs.pr_number }} (head \`${{ steps.resolve_head.outputs.head }}\`)" - fi - echo "" - echo "PRs not rebased fall into one of three buckets:" - echo "- Already up-to-date with \`dev\` (no-op)" - echo "- Draft or labeled \`no-auto-rebase\` (excluded)" - echo "- Conflict during rebase, OR fork without maintainer-edit access (action silently skips)" - echo "" - echo "PRs in the conflict bucket need a manual rebase by the author:" - echo '```bash' - echo "git fetch origin && git rebase origin/dev" - echo "# resolve conflicts, git rebase --continue" - echo "git push --force-with-lease" - echo '```' - } >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/release-semantic.yaml b/.github/workflows/release-semantic.yaml index d861db1c04..3fddf9c84b 100644 --- a/.github/workflows/release-semantic.yaml +++ b/.github/workflows/release-semantic.yaml @@ -7,7 +7,7 @@ name: "Release: Semantic Version" # release, then reconcile dev. Dev-source reconciles FF-only; hotfix- # staging source rebases dev onto the new main so the release tag # enters dev's ancestry — the only force-push this workflow performs. -# `auto-rebase-prs.yaml` then rebases open PRs targeting dev. +# Open PRs targeting dev will need a manual rebase by their authors. on: workflow_dispatch: @@ -249,6 +249,6 @@ jobs: echo "- Source: hotfix-staging \`${{ steps.validate.outputs.source }}\`" echo "- New main: \`$(git rev-parse --short=9 "${NEW_MAIN}")\`" echo "- Dev rebased linearly onto new main; identical-patch commits auto-dropped by \`git rebase\`." - echo "- Open PRs against dev are auto-rebased by the \`Auto-rebase open PRs\` workflow." + echo "- Open PRs against dev will need a manual rebase by their authors." } >> "$GITHUB_STEP_SUMMARY" echo "::notice::Reconciled dev onto main via rebase (linear history preserved)."