Repository navigation
chore(ci): enforce issue dependencies with a blocked label and a pull-request check #1035
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
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
760f712
chore(ci): enforce issue dependencies with a blocked label and a requ…
cemililik 76de1e8
fix(ci): harden the issue-dependency check after review
cemililik edcaab0
fix(ci): strip multi-backtick code spans before reading closing links
cemililik a156682
fix(ci): drop indented code blocks before reading closing links
cemililik 0c943e0
fix(ci): keep block boundaries when reading closing links
cemililik f63da37
fix(ci): let GitHub decide what a pull request closes; isolate sync f…
cemililik 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
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,58 @@ | ||
| name: Issue dependencies | ||
|
|
||
| # Keeps the `blocked` label in step with each issue's native "Blocked by" links (the rules live in | ||
| # tools/issue_dependencies.py and CONTRIBUTING.md, "Dependencies between issues"): | ||
| # - an open issue with a blocker that is not closed as completed gets `blocked`; | ||
| # - every other issue loses it, with one comment when an open issue is unblocked; | ||
| # - a blocker closed as not planned or as a duplicate leaves the issue blocked and asks a maintainer to re-plan it; | ||
| # - every open pull request whose "Issue dependencies" check no longer matches its linked issues (red although | ||
| # they are unblocked, or green although one became blocked) gets that check re-run. | ||
| # | ||
| # GitHub sends no workflow event when a "Blocked by" link is added or removed, so this runs when an issue is closed | ||
| # or reopened (what unblocks or re-blocks its dependents), hourly as the backstop for link edits, and on demand. | ||
| # Every run is a full reconciliation of state, not a reaction to a transition, so the concurrency group may drop a | ||
| # pending run, and a run that fails half-way is finished by the next one. tests/test_issue_dependencies.py pins: | ||
| # - the token holds `contents: read`, `issues: write`, `pull-requests: read`, `checks: read` and `actions: write`, | ||
| # nothing else; | ||
| # - no `${{ }}` appears in a `run:` line; the script reads the environment itself; | ||
| # - the checkout takes the default branch, one file, no stored credentials, pinned to a full commit SHA. | ||
| # | ||
| # Maintainers: to stop it, open Actions > "Issue dependencies" > the "..." menu > "Disable workflow". The links | ||
| # stay; only the label stops following them. | ||
|
|
||
| on: | ||
| issues: | ||
| types: [closed, reopened] | ||
| schedule: | ||
| - cron: "17 * * * *" | ||
| workflow_dispatch: | ||
|
|
||
| permissions: {} | ||
|
|
||
| concurrency: | ||
| group: issue-dependencies | ||
| cancel-in-progress: false | ||
|
|
||
| jobs: | ||
| sync: | ||
| # This repository, and only its default branch: a manual run started from another branch would check out that | ||
| # branch's copy of the script with this job's write token. | ||
| if: ${{ github.repository == 'HodeTech/ForgeLM' && github.ref == 'refs/heads/development' }} | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 10 | ||
| permissions: | ||
| contents: read # the checkout reads one script from the default branch | ||
| issues: write # add or remove `blocked` / `needs-triage`, and post the notices | ||
| pull-requests: read # read the open pull requests and the issues they link | ||
| checks: read # read each one's latest "Issue dependencies" result | ||
| actions: write # re-run that check when the result no longer matches | ||
| steps: | ||
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | ||
| with: | ||
| persist-credentials: false | ||
| sparse-checkout: tools/issue_dependencies.py | ||
| sparse-checkout-cone-mode: false | ||
| - name: Bring the blocked label in step with the Blocked-by links | ||
| env: | ||
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| run: python3 tools/issue_dependencies.py sync |
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,58 @@ | ||
| name: PR dependencies | ||
|
|
||
| # The "Issue dependencies" check: fails while the pull request links an issue that is still blocked (Fixes / Closes / | ||
| # Resolves / Refs #N in its title, description or commits, or a Development-sidebar link), unless GitHub lists every | ||
| # open blocker as closed by the same pull request or a maintainer has labelled it `dependency-override`. Rules: | ||
| # tools/issue_dependencies.py and CONTRIBUTING.md, "Dependencies between issues". The "Issue dependencies" workflow | ||
| # re-runs this check whenever its result no longer matches the issues. | ||
| # | ||
| # Why `pull_request_target`. A `pull_request` run takes this file from the pull request itself, so a pull request | ||
| # could rewrite the check that judges it. `pull_request_target` takes the workflow and the script from the default | ||
| # branch instead. Its known risk is running the pull request's code with a privileged token; this job never does: | ||
| # the checkout has no `ref`, so it reads one file from the default branch; nothing from the pull request is checked | ||
| # out, built or executed; the token is read-only; no secret but GITHUB_TOKEN is used; and the script treats the | ||
| # description as data. tests/test_issue_dependencies.py pins these properties: | ||
| # - `pull_request_target` only, no `paths:` or `branches:` filter (a required check must always report); | ||
| # - the token holds `contents: read`, `issues: read` and `pull-requests: read`, nothing else; | ||
| # - the checkout has no `ref`, takes one file, keeps no credentials and is pinned to a full commit SHA, and no | ||
| # expression in this file names the pull request's head; | ||
| # - no `${{ }}` appears in a `run:` line; the script reads the event file itself. | ||
| # What it cannot stop: a pull request may add a different workflow with a job of the same name, and branch | ||
| # protection cannot tell two GitHub Actions checks of one name apart (true of every required Actions check), so a | ||
| # maintainer reads every change under `.github/` and `tools/` before merging it. | ||
| # | ||
| # Prerequisite: from 2 November 2026 GitHub blocks `pull_request_target` in public repositories unless an Actions | ||
| # policy allows it. This repository's policy (Settings > Actions > Policies) allows it for this file's path only; | ||
| # renaming or moving this file needs the policy updated in the same change, or the check stops reporting. | ||
| # | ||
| # One run per pull request at a time: a newer event cancels the run still going, so a burst of edits costs one run. | ||
|
|
||
| on: | ||
| pull_request_target: | ||
| types: [opened, edited, reopened, synchronize, ready_for_review, labeled, unlabeled] | ||
|
|
||
| permissions: {} | ||
|
|
||
| concurrency: | ||
| group: pr-dependencies-${{ github.event.pull_request.number }} | ||
| cancel-in-progress: true | ||
|
|
||
| jobs: | ||
| issue-dependencies: | ||
| name: Issue dependencies | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 5 | ||
| permissions: | ||
| contents: read # the checkout reads one script from the default branch | ||
| issues: read # read the linked issues, their "Blocked by" links and the label events | ||
| pull-requests: read # read the pull request's current description and labels | ||
| steps: | ||
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | ||
| with: | ||
| persist-credentials: false | ||
| sparse-checkout: tools/issue_dependencies.py | ||
| sparse-checkout-cone-mode: false | ||
| - name: Fail if a linked issue is still blocked | ||
| env: | ||
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| run: python3 tools/issue_dependencies.py check-pr | ||
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.