From 5cdbc3c43f75153bca7baab22c53845b3b6bf53f Mon Sep 17 00:00:00 2001 From: jar Date: Fri, 18 Sep 2026 19:28:28 +0000 Subject: [PATCH 1/5] Require next-major targets for breaking changes Committed-By-Agent: goose Orbit-Session-Id: c9e24cd7-9c07-436c-8756-f6998b381745 --- .github/workflows/rules.yml | 69 +++++++++++++++++++++++++++++++++---- 1 file changed, 62 insertions(+), 7 deletions(-) diff --git a/.github/workflows/rules.yml b/.github/workflows/rules.yml index b7d9c0d8b..0e237224a 100644 --- a/.github/workflows/rules.yml +++ b/.github/workflows/rules.yml @@ -4,20 +4,75 @@ name: rules on: workflow_dispatch: {} pull_request: + # expand this list as we add rules, but be careful that rules are properly guarded with necessary null checks or state checks types: - auto_merge_enabled - -permissions: {} + - edited + - opened + - reopened + - synchronize jobs: - require_merge_commit_on_merge_script_pr: - name: Merge script PRs must create merge commits - if: ${{ contains(github.head_ref, '/merge-') }} + check_auto_merge_method_if_enabled: + name: Check auto-merge method if enabled + if: ${{ github.event_name == 'pull_request' && github.event.pull_request.auto_merge }} runs-on: ubuntu-latest steps: - run: | - if ${{ github.event.pull_request.auto_merge.merge_method != 'merge' }}; then - echo "Auto-merge method must be 'merge' instead of '${{github.event.pull_request.auto_merge.merge_method}}'" + expected_merge_method="squash" + # for merge PRs, expect "merge" + if [ ${{ contains(github.head_ref, '/merge-') }} == "true" ]; then + expected_merge_method="merge" + fi + + if [ ${{ github.event.pull_request.auto_merge.merge_method }} != $expected_merge_method ]; then + echo "Auto-merge method must be '$expected_merge_method' instead of '${{github.event.pull_request.auto_merge.merge_method}}'" exit 1 fi + breaking_changefiles_target_next_major: + name: Breaking changes target the next-major branch + if: ${{ github.event_name == 'pull_request' }} + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read + steps: + - uses: actions/checkout@v4 + + - name: Find newly added Hark changefiles + id: changefiles + run: | + set -euo pipefail + + files=$(gh api --paginate --slurp "repos/${GITHUB_REPOSITORY}/pulls/${PR_NUMBER}/files?per_page=100") + paths=$(jq -c '[.[][] | select(.status == "added") | .filename | select(test("^\.hark/changes/[^/]+\.change\.md$"))]' <<< "$files") + echo "paths=$paths" >> "$GITHUB_OUTPUT" + env: + GH_TOKEN: ${{ github.token }} + PR_NUMBER: ${{ github.event.pull_request.number }} + + - uses: stripe/hark/actions/setup-hark@master + name: Setup Hark + if: steps.changefiles.outputs.paths != '[]' + + - name: Check breaking changefile merge target + if: steps.changefiles.outputs.paths != '[]' + run: | + set -euo pipefail + + mapfile -t changefiles < <(jq -r '.[]' <<< "$CHANGEFILE_PATHS") + inspection=$(hark inspect "${changefiles[@]}") + major_paths=$(jq -c '[.[] | select(.semver_level == "major") | .path]' <<< "$inspection") + + if [[ "$major_paths" != "[]" && "$BASE_REF" != "sdk-release/next-major" ]]; then + affected_paths=$(jq -r 'join(", ")' <<< "$major_paths") + echo "::error::Major Hark changefiles must target sdk-release/next-major. Retarget this pull request from '$BASE_REF' to 'sdk-release/next-major'. Affected files: $affected_paths" + exit 1 + fi + + echo "Changefile merge target check passed" + env: + BASE_REF: ${{ github.base_ref }} + CHANGEFILE_PATHS: ${{ steps.changefiles.outputs.paths }} + From e11f91174b1bbb7a2736b91e076c818a1c47e790 Mon Sep 17 00:00:00 2001 From: jar Date: Fri, 18 Sep 2026 19:34:53 +0000 Subject: [PATCH 2/5] Regenerate rules workflow Committed-By-Agent: goose Orbit-Session-Id: c9e24cd7-9c07-436c-8756-f6998b381745 --- .github/workflows/rules.yml | 10 ++++++---- ...09-18_jar_require-next-major-target.change.md | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 4 deletions(-) create mode 100644 .hark/changes/2026-09-18_jar_require-next-major-target.change.md diff --git a/.github/workflows/rules.yml b/.github/workflows/rules.yml index 0e237224a..7e20679d7 100644 --- a/.github/workflows/rules.yml +++ b/.github/workflows/rules.yml @@ -38,21 +38,23 @@ jobs: contents: read pull-requests: read steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 + with: + persist-credentials: false - name: Find newly added Hark changefiles id: changefiles run: | set -euo pipefail - files=$(gh api --paginate --slurp "repos/${GITHUB_REPOSITORY}/pulls/${PR_NUMBER}/files?per_page=100") - paths=$(jq -c '[.[][] | select(.status == "added") | .filename | select(test("^\.hark/changes/[^/]+\.change\.md$"))]' <<< "$files") + files=$(gh api --paginate "repos/${GITHUB_REPOSITORY}/pulls/${PR_NUMBER}/files?per_page=100" --jq '.[]') + paths=$(jq -sc '[.[] | select(.status == "added") | .filename | select(test("^\.hark/changes/[^/]+\.change\.md$"))]' <<< "$files") echo "paths=$paths" >> "$GITHUB_OUTPUT" env: GH_TOKEN: ${{ github.token }} PR_NUMBER: ${{ github.event.pull_request.number }} - - uses: stripe/hark/actions/setup-hark@master + - uses: stripe/hark/actions/setup-hark@master # zizmor: ignore[unpinned-uses] name: Setup Hark if: steps.changefiles.outputs.paths != '[]' diff --git a/.hark/changes/2026-09-18_jar_require-next-major-target.change.md b/.hark/changes/2026-09-18_jar_require-next-major-target.change.md new file mode 100644 index 000000000..d34567b2d --- /dev/null +++ b/.hark/changes/2026-09-18_jar_require-next-major-target.change.md @@ -0,0 +1,16 @@ +--- +title: Require breaking changes to target the next-major branch +pr_url: https://github.com/stripe/stripe-python/pull/1918 +semver_level: patch +--- + + From 463147211d772631c58a0f848d39af6e431e5f4b Mon Sep 17 00:00:00 2001 From: jar Date: Fri, 18 Sep 2026 19:45:56 +0000 Subject: [PATCH 3/5] Fix generated changefile discovery Committed-By-Agent: goose Orbit-Session-Id: c9e24cd7-9c07-436c-8756-f6998b381745 --- .github/workflows/rules.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/rules.yml b/.github/workflows/rules.yml index 7e20679d7..48c58f452 100644 --- a/.github/workflows/rules.yml +++ b/.github/workflows/rules.yml @@ -47,8 +47,14 @@ jobs: run: | set -euo pipefail - files=$(gh api --paginate "repos/${GITHUB_REPOSITORY}/pulls/${PR_NUMBER}/files?per_page=100" --jq '.[]') - paths=$(jq -sc '[.[] | select(.status == "added") | .filename | select(test("^\.hark/changes/[^/]+\.change\.md$"))]' <<< "$files") + if ! files=$(gh api --paginate "repos/${GITHUB_REPOSITORY}/pulls/${PR_NUMBER}/files?per_page=100" --jq '.[]' 2>&1); then + echo "::error::Failed to query pull request files: $files" + exit 1 + fi + if ! paths=$(jq -sc '[.[] | select(.status == "added") | .filename | select(test("^[.]hark/changes/[^/]+[.]change[.]md$"))]' <<< "$files" 2>&1); then + echo "::error::Failed to select newly added Hark changefiles: $paths" + exit 1 + fi echo "paths=$paths" >> "$GITHUB_OUTPUT" env: GH_TOKEN: ${{ github.token }} From 4ae57301bfc139f5d326589bb3b89508fa45829d Mon Sep 17 00:00:00 2001 From: jar Date: Fri, 18 Sep 2026 20:22:59 +0000 Subject: [PATCH 4/5] Default rules workflow permissions to none Committed-By-Agent: goose Orbit-Session-Id: c9e24cd7-9c07-436c-8756-f6998b381745 --- .github/workflows/rules.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/rules.yml b/.github/workflows/rules.yml index 48c58f452..c5038ebb1 100644 --- a/.github/workflows/rules.yml +++ b/.github/workflows/rules.yml @@ -1,6 +1,8 @@ name: rules +permissions: {} + on: workflow_dispatch: {} pull_request: From d1141f9ecc9af4b5eb5a3c661cbd5a3c1e2e0474 Mon Sep 17 00:00:00 2001 From: jar Date: Sat, 19 Sep 2026 01:16:10 +0000 Subject: [PATCH 5/5] Allow next-major release merges into master Committed-By-Agent: goose Orbit-Session-Id: c9e24cd7-9c07-436c-8756-f6998b381745 --- .github/workflows/rules.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/rules.yml b/.github/workflows/rules.yml index c5038ebb1..765294d14 100644 --- a/.github/workflows/rules.yml +++ b/.github/workflows/rules.yml @@ -75,9 +75,9 @@ jobs: inspection=$(hark inspect "${changefiles[@]}") major_paths=$(jq -c '[.[] | select(.semver_level == "major") | .path]' <<< "$inspection") - if [[ "$major_paths" != "[]" && "$BASE_REF" != "sdk-release/next-major" ]]; then + if [[ "$major_paths" != "[]" && "$BASE_REF" != "sdk-release/next-major" && ! ("$HEAD_REF" == "sdk-release/next-major" && "$BASE_REF" == "master") ]]; then affected_paths=$(jq -r 'join(", ")' <<< "$major_paths") - echo "::error::Major Hark changefiles must target sdk-release/next-major. Retarget this pull request from '$BASE_REF' to 'sdk-release/next-major'. Affected files: $affected_paths" + echo "::error::Major Hark changefiles must target sdk-release/next-major unless this pull request merges sdk-release/next-major into master. Retarget this pull request from '$BASE_REF' to 'sdk-release/next-major'. Affected files: $affected_paths" exit 1 fi @@ -85,4 +85,5 @@ jobs: env: BASE_REF: ${{ github.base_ref }} CHANGEFILE_PATHS: ${{ steps.changefiles.outputs.paths }} + HEAD_REF: ${{ github.head_ref }}