-
-
Notifications
You must be signed in to change notification settings - Fork 295
refactor: share is-release-pr check between changelog updates and stale closer #9685
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
cryptodev-2s
wants to merge
23
commits into
main
Choose a base branch
from
chore/share-is-release-pr-action
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
23 commits
Select commit
Hold shift + click to select a range
c2fbff1
chore: auto-close stale release PRs after 3 hours of inactivity
cryptodev-2s 0fd851f
fix: harden stale release PR closer against races and failed closes
cryptodev-2s d9cf151
fix: continue past failed PR refresh and merge-state checks
cryptodev-2s e0f1468
fix: recheck PR activity immediately before close and delete
cryptodev-2s 6495138
fix: verify full label set and branch tip before delete
cryptodev-2s 1538aed
fix: comment after branch delete with accurate status
cryptodev-2s 0c750f5
refactor: extract stale release closer into a script with inline cons…
cryptodev-2s 792c39e
refactor: split stale release closer into scoped helpers and fix JSDo…
cryptodev-2s 7c1b13c
style: format close-stale-release-prs script
cryptodev-2s 9033954
Merge branch 'main' into chore/close-stale-release-prs
cryptodev-2s 365060a
refactor: address clear-win review nits on stale release closer
cryptodev-2s 624f814
refactor: migrate stale release closer to TypeScript with @actions pa…
cryptodev-2s 41a0728
Merge branch 'main' into chore/close-stale-release-prs
cryptodev-2s a2ccde0
fix: make stale release closer an ESM .mts module
cryptodev-2s 364d420
fix: clarify tip-move skip vs delete failure in close comment
cryptodev-2s f2e984d
fix: type listed PRs from Octokit instead of casting
cryptodev-2s 12e7ee4
refactor: drop double-snapshot race dance before stale close
cryptodev-2s 3f8f445
refactor: apply utils helpers and small closer review nits
cryptodev-2s a9dfaae
refactor: rename snapshotLabelNames to pullRequestLabelNames
cryptodev-2s 3457b77
refactor: make merge-in-progress check an explicit boolean
cryptodev-2s 7a05448
refactor: include stale threshold in not-yet-stale skip log
cryptodev-2s 869c4b3
refactor: share is-release-pr detection with stale closer
cryptodev-2s 7c54446
fix: harden stale closer workflow against review findings
cryptodev-2s File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| name: Is release PR | ||
| description: > | ||
| Determine whether a pull request is a release PR using the same check as | ||
| update-changelogs (checkout head, merge-base, MetaMask/action-is-release). | ||
|
|
||
| inputs: | ||
| pr-number: | ||
| description: Pull request number to evaluate. | ||
| required: true | ||
| commit-starts-with: | ||
| description: > | ||
| Comma-separated commit/PR title prefixes. Use `[version]` for the new root | ||
| package version (same as vars.RELEASE_COMMIT_PREFIX). | ||
| required: true | ||
| token: | ||
| description: GitHub token for gh/API access. | ||
| required: false | ||
| default: ${{ github.token }} | ||
|
|
||
| outputs: | ||
| IS_RELEASE: | ||
| description: '"true" when the PR is a release PR, otherwise "false".' | ||
| value: ${{ steps.is-release.outputs.IS_RELEASE }} | ||
| head-sha: | ||
| description: Head commit SHA of the pull request. | ||
| value: ${{ steps.pr-info.outputs.pr-head-sha }} | ||
| head-ref: | ||
| description: Head branch name of the pull request. | ||
| value: ${{ steps.pr-info.outputs.pr-head-ref }} | ||
| base-ref: | ||
| description: Base branch name of the pull request. | ||
| value: ${{ steps.pr-info.outputs.pr-base-ref }} | ||
| merge-base: | ||
| description: Merge-base SHA between the PR head and base branch. | ||
| value: ${{ steps.merge-base.outputs.merge-base }} | ||
|
|
||
| runs: | ||
| using: composite | ||
| steps: | ||
| - name: Get pull request info | ||
| id: pr-info | ||
| shell: bash | ||
| env: | ||
| GH_TOKEN: ${{ inputs.token }} | ||
| PR_NUMBER: ${{ inputs.pr-number }} | ||
| run: | | ||
| set -euo pipefail | ||
| gh pr view "$PR_NUMBER" \ | ||
| --repo "$GITHUB_REPOSITORY" \ | ||
| --json baseRefName,headRefOid,headRefName,title \ | ||
| --jq '"pr-base-ref=\(.baseRefName)\npr-head-sha=\(.headRefOid)\npr-head-ref=\(.headRefName)\npr-title=\(.title)"' \ | ||
| >> "$GITHUB_OUTPUT" | ||
|
|
||
| - name: Checkout repository | ||
| uses: actions/checkout@v7 | ||
| with: | ||
| token: ${{ inputs.token }} | ||
| fetch-depth: 0 | ||
| persist-credentials: false | ||
| ref: ${{ steps.pr-info.outputs.pr-head-sha }} | ||
|
|
||
| - name: Get merge base | ||
| id: merge-base | ||
| shell: bash | ||
| env: | ||
| BASE_REF: ${{ steps.pr-info.outputs.pr-base-ref }} | ||
| run: | | ||
| set -euo pipefail | ||
| MERGE_BASE=$(git merge-base HEAD "refs/remotes/origin/$BASE_REF") | ||
| echo "merge-base=$MERGE_BASE" >> "$GITHUB_OUTPUT" | ||
|
|
||
| - name: Check if the pull request is a release | ||
| id: is-release | ||
| uses: MetaMask/action-is-release@v2 | ||
| with: | ||
| commit-starts-with: ${{ inputs.commit-starts-with }} | ||
| commit-message: ${{ steps.pr-info.outputs.pr-title }} | ||
| before: ${{ steps.merge-base.outputs.merge-base }} | ||
| skip-checkout: true |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,141 @@ | ||
| name: Close Stale Release PRs | ||
|
|
||
| # Release PRs are expected to merge quickly. Abandoned ones block other engineers | ||
| # from starting a new release. This workflow closes inactive release PRs, leaves a | ||
| # comment, and deletes the branch. | ||
| # | ||
| # Release PR detection is shared with update-changelogs via | ||
| # `.github/actions/is-release-pr` (root version bump + RELEASE_COMMIT_PREFIX). | ||
| # `release/*` is only a cheap prefilter before that shared check. | ||
| on: | ||
| schedule: | ||
| # Check twice an hour so the 3h window is reasonably precise. | ||
| - cron: '*/30 * * * *' | ||
| workflow_dispatch: | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| concurrency: | ||
| group: close-stale-release-prs | ||
| cancel-in-progress: false | ||
|
|
||
| jobs: | ||
| find-candidates: | ||
| name: Find release/* PR candidates | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| pull-requests: read | ||
| outputs: | ||
| prs: ${{ steps.list.outputs.prs }} | ||
| steps: | ||
| - name: List same-repo open release/* PRs | ||
| id: list | ||
| env: | ||
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| run: | | ||
| set -euo pipefail | ||
| # Paginate all open PRs; --limit 100 would miss older release/* heads | ||
| # once the repo has many open PRs. | ||
| PRS="$( | ||
| gh api --paginate \ | ||
| "/repos/${GITHUB_REPOSITORY}/pulls?state=open&per_page=100" \ | ||
| --jq '.[] | select(.head.repo != null and .head.repo.fork == false and (.head.ref | startswith("release/"))) | .number' \ | ||
| | jq --compact-output --slurp '.' | ||
| )" | ||
| echo "prs=$PRS" >> "$GITHUB_OUTPUT" | ||
| echo "Candidate PR numbers: $PRS" | ||
|
|
||
| filter-release-prs: | ||
| name: Confirm release PR #${{ matrix.pr }} | ||
| needs: find-candidates | ||
| if: needs.find-candidates.outputs.prs != '[]' | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
| pull-requests: read | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| pr: ${{ fromJson(needs.find-candidates.outputs.prs) }} | ||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v7 | ||
| with: | ||
| persist-credentials: false | ||
|
|
||
| - name: Check if the pull request is a release | ||
| id: is-release | ||
| uses: ./.github/actions/is-release-pr | ||
| with: | ||
| pr-number: ${{ matrix.pr }} | ||
| commit-starts-with: ${{ vars.RELEASE_COMMIT_PREFIX }} | ||
| token: ${{ secrets.GITHUB_TOKEN }} | ||
|
|
||
| - name: Record confirmed release PR | ||
| if: steps.is-release.outputs.IS_RELEASE == 'true' | ||
| env: | ||
| # Pass via env so the value is not expanded into the script text | ||
| # (zizmor template-injection). PR numbers come from open same-repo | ||
| # release/* PRs; write access is enough to create those. | ||
| PR_NUMBER: ${{ matrix.pr }} | ||
| run: | | ||
| set -euo pipefail | ||
| # Unique filename per matrix leg so merge-multiple keeps every PR. | ||
| echo "$PR_NUMBER" > "release-pr-${PR_NUMBER}.txt" | ||
|
|
||
| - name: Upload confirmed release PR artifact | ||
| if: steps.is-release.outputs.IS_RELEASE == 'true' | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: release-pr-${{ matrix.pr }} | ||
| path: release-pr-${{ matrix.pr }}.txt | ||
| if-no-files-found: ignore | ||
|
cursor[bot] marked this conversation as resolved.
|
||
|
|
||
| close-stale-release-prs: | ||
| name: Close stale release PRs | ||
| needs: [find-candidates, filter-release-prs] | ||
| # Still close any PRs that were confirmed even if some matrix legs failed. | ||
| if: always() && needs.find-candidates.result == 'success' && needs.find-candidates.outputs.prs != '[]' && needs.filter-release-prs.result != 'cancelled' | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: write | ||
| pull-requests: write | ||
| steps: | ||
| - name: Checkout and setup environment | ||
| uses: MetaMask/action-checkout-and-setup@v3 | ||
| with: | ||
| is-high-risk-environment: false | ||
| persist-credentials: false | ||
| cache-node-modules: true | ||
|
|
||
| - name: Download confirmed release PR numbers | ||
| uses: actions/download-artifact@v4 | ||
| continue-on-error: true | ||
| with: | ||
| pattern: release-pr-* | ||
| merge-multiple: true | ||
| path: release-pr-numbers | ||
|
|
||
| - name: Build RELEASE_PR_NUMBERS | ||
| id: numbers | ||
| run: | | ||
| set -euo pipefail | ||
| if [ -d release-pr-numbers ]; then | ||
| NUMBERS="$(find release-pr-numbers -type f -print0 | xargs -0 cat | sort -n -u | paste -sd, -)" | ||
| else | ||
| NUMBERS='' | ||
| fi | ||
| echo "numbers=$NUMBERS" >> "$GITHUB_OUTPUT" | ||
| echo "Confirmed release PR numbers: ${NUMBERS:-<none>}" | ||
|
|
||
| - name: Close inactive release PRs | ||
| if: steps.numbers.outputs.numbers != '' | ||
| env: | ||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| RELEASE_PR_NUMBERS: ${{ steps.numbers.outputs.numbers }} | ||
| run: yarn tsx scripts/close-stale-release-prs.mts | ||
|
|
||
| - name: No confirmed release PRs | ||
| if: steps.numbers.outputs.numbers == '' | ||
| run: echo 'No confirmed release PRs to evaluate.' | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.