diff --git a/.github/workflows/sync-feature-branch.yaml b/.github/workflows/sync-feature-branch.yaml deleted file mode 100644 index 51a8f286..00000000 --- a/.github/workflows/sync-feature-branch.yaml +++ /dev/null @@ -1,126 +0,0 @@ -name: Sync feature branch with main - -on: - push: - branches: [main] - workflow_dispatch: - inputs: - target_branch: - description: "Feature branch to sync with main" - required: true - default: "new-resolver-config" - -permissions: - contents: read - -jobs: - sync-branch: - runs-on: ubuntu-latest - if: ${{ github.repository_owner == 'python-wheel-build' }} - concurrency: - group: sync-${{ inputs.target_branch || 'new-resolver-config' }} - cancel-in-progress: false - permissions: - contents: write - issues: write - env: - TARGET_BRANCH: ${{ inputs.target_branch || 'new-resolver-config' }} - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - steps: - - name: Checkout target branch - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - ref: ${{ env.TARGET_BRANCH }} - fetch-depth: 0 - persist-credentials: false - - - name: Configure git - run: | - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - gh auth setup-git - - - name: Merge main into feature branch - id: merge - run: | - git fetch origin main - BEFORE=$(git rev-parse HEAD) - if git merge origin/main --no-edit; then - AFTER=$(git rev-parse HEAD) - if [ "$BEFORE" = "$AFTER" ]; then - echo "result=up-to-date" >> "$GITHUB_OUTPUT" - else - echo "result=merged" >> "$GITHUB_OUTPUT" - fi - else - CONFLICTS=$(git diff --name-only --diff-filter=U) - git merge --abort - echo "result=conflict" >> "$GITHUB_OUTPUT" - echo "conflicts<> "$GITHUB_OUTPUT" - echo "$CONFLICTS" >> "$GITHUB_OUTPUT" - echo "DELIM" >> "$GITHUB_OUTPUT" - fi - - - name: Push merged changes - if: steps.merge.outputs.result == 'merged' - run: git push origin "HEAD:${TARGET_BRANCH}" - - - name: Close resolved sync-conflict issues - if: steps.merge.outputs.result == 'merged' || steps.merge.outputs.result == 'up-to-date' - run: | - EXPECTED_TITLE="Sync conflict: ${TARGET_BRANCH} cannot merge main" - gh issue list --label "sync-conflict" --state open --json number,title \ - | jq -r --arg t "$EXPECTED_TITLE" '.[] | select(.title == $t) | .number' \ - | xargs -rI{} gh issue close {} --comment "Resolved by automated sync." - - - name: Report up-to-date - if: steps.merge.outputs.result == 'up-to-date' - run: echo "Branch ${TARGET_BRANCH} is already up to date with main." - - - name: Open issue on conflict - if: steps.merge.outputs.result == 'conflict' - run: | - EXPECTED_TITLE="Sync conflict: ${TARGET_BRANCH} cannot merge main" - - EXISTING=$(gh issue list \ - --label "sync-conflict" \ - --state open \ - --json title \ - | jq --arg expected "$EXPECTED_TITLE" \ - '[.[] | select(.title == $expected)] | length') - - if [ "$EXISTING" -gt 0 ]; then - echo "An open sync-conflict issue for ${TARGET_BRANCH} already exists, skipping." - exit 0 - fi - - gh label create "sync-conflict" \ - --description "Automated sync with main hit merge conflicts" \ - --color "D93F0B" \ - --force - - gh issue create \ - --title "$EXPECTED_TITLE" \ - --label "sync-conflict" \ - --body "$(cat <2026-10-13T18:55:47Z + - head!=new-resolver-config + actions: + backport: + branches: + - new-resolver-config + ignore_conflicts: true + label_conflicts: conflicts + - name: Add CI label conditions: - or: @@ -27,6 +42,10 @@ pull_request_rules: conditions: - and: - "-draft" + # Maintainers merge resolver backports after reviewing CI and conflicts. + - or: + - base!=new-resolver-config + - -head~=^mergify/bp/new-resolver-config/ # Unit tests - check-success=unit (3.12, 1.75, ubuntu-latest) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3f9cc005..3181dd6c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -9,6 +9,7 @@ Fromager thrives on practical, well-tested contributions. This guide summarizes - [Quick Start](#quick-start) - [Coding Standards](#coding-standards) - [Testing](#testing) +- [Resolver Branch Backports](#resolver-branch-backports) - [Commit Guidelines](#commit-guidelines) - [Before Submitting](#before-submitting) - [Design Patterns Used in Fromager](#design-patterns-used-in-fromager) @@ -225,6 +226,24 @@ hatch run test:coverage-report # Coverage summary --- +## Resolver Branch Backports + +Mergify cherry-picks PRs merged into `main` after the +[baseline sync #1367](https://github.com/python-wheel-build/fromager/pull/1367) +into backport PRs for `new-resolver-config`, using its GitHub App without a personal +token. Maintainers review and manually merge them after applicable CI passes, +merging dependent backports in source order. + +Resolve conflicts and remove the `conflicts` label before merging. To request a +missing backport, check for an existing PR, then comment +`@mergifyio backport new-resolver-config` on the merged source PR. + +Direct pushes and unsupported merge histories need manual backports. Cherry-picks +create new commits, so Git may still report the branch as behind `main`. Remove +the backport rule when the feature branch is retired. + +--- + ## Commit Guidelines Fromager follows [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/).