[Newbie] I want to make Auto-Closing of My Repo A's Issues when linked Other User's Repo B's PRs are being closed. #194981
Replies: 8 comments 8 replies
-
|
GitHub’s automatic issue closing keywords ( For cross-repository cases like: the issue may not auto-close depending on repository permissions and how the PR is linked. If you want consistent cross-repo auto-closing behavior, the most reliable approach is usually to use a GitHub Actions workflow triggered on PR merge/close events. For multiple PRs connected to one issue, you could also:
The built-in auto-close behavior is somewhat limited for multi-repo and multi-PR workflows. |
Beta Was this translation helpful? Give feedback.
-
|
Yeah, for that kind of “master issue tracker repo” setup, GitHub’s built-in closing keywords become pretty limited — especially when the PRs live in third-party repositories. In most cases, GitHub only guarantees automatic closing behavior within the same repository network, so cross-user / third-party repo tracking usually needs custom automation. Your idea is still possible though — the usual approach is:
So instead of relying entirely on You could also maintain linked PR references using:
because GitHub Projects alone usually won’t fully automate multi-repo dependency closing logic for third-party repositories. So your use case is definitely valid — it just needs custom workflow automation rather than the default keyword behavior. |
Beta Was this translation helpful? Give feedback.
-
|
Got it. Let me explain it in a simpler way. Your setup is:
You want the Issue in Repo A to close automatically when the related PRs in Repo B are merged. The reason this is difficult is because GitHub’s normal closing keywords like: mostly work reliably inside the same repository. Cross-repository and multi-PR tracking is much more limited. For your use case, the best solution is usually a small GitHub Actions workflow. The workflow idea is:
A basic workflow starts with: on:
pull_request:
types: [closed]That simply means the automation runs whenever a PR is closed or merged. So in short, GitHub’s built-in closing keywords are usually not enough for advanced multi-repository workflows like yours. GitHub Actions is the correct approach for this type of setup. |
Beta Was this translation helpful? Give feedback.
-
|
I think the important part here is this: If Repo B is not owned by you, then GitHub cannot fully automate this using only the normal Those keywords mainly work reliably inside the same repository or repository network. For your exact use case, the best practical solution is:
This works even if Repo B belongs to another user, as long as the PRs are publicly readable. A simple setup would look like this. Inside the issue in Repo A: Then create this workflow in Repo A: name: Auto-close linked issues
on:
schedule:
- cron: "*/10 * * * *"
workflow_dispatch:
permissions:
issues: write
contents: read
jobs:
check-linked-prs:
runs-on: ubuntu-latest
steps:
- name: Check PR status
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const owner = context.repo.owner;
const repo = context.repo.repo;
const issues = await github.paginate(
github.rest.issues.listForRepo,
{
owner,
repo,
state: "open",
per_page: 100,
}
);
const regex =
/https:\/\/github\.com\/([^/]+)\/([^/]+)\/pull\/(\d+)/g;
for (const issue of issues) {
const body = issue.body || "";
const matches = [...body.matchAll(regex)];
if (!matches.length) continue;
let allMerged = true;
for (const match of matches) {
const prOwner = match[1];
const prRepo = match[2];
const prNumber = Number(match[3]);
const pr = await github.rest.pulls.get({
owner: prOwner,
repo: prRepo,
pull_number: prNumber,
});
if (!pr.data.merged_at) {
allMerged = false;
break;
}
}
if (allMerged) {
await github.rest.issues.update({
owner,
repo,
issue_number: issue.number,
state: "closed",
});
}
}What this workflow does:
So this solves:
The only limitation is: Otherwise, this setup should work for your case. |
Beta Was this translation helpful? Give feedback.
This comment was marked as low quality.
This comment was marked as low quality.
-
|
Ah, that makes much more sense now 😄 In that case, the approach Gecko51 posted is actually the correct direction for your setup. When you link PRs through GitHub’s Development section, GitHub creates cross-reference timeline events internally. Those events can be read through the GitHub API, which means you do not need to manually store PR URLs inside the issue body. So the workflow works like this:
That is actually a much cleaner solution than manually storing PR links as text. The important limitation is still the same though:
So for your exact use case:
I think the workflow Gecko51 shared is probably the closest possible implementation for what you want. |
Beta Was this translation helpful? Give feedback.
-
|
Yes, usually you need to add keywords like If the issue is in another repository, use the full reference format like: For your second question: Otherwise, the issue would be closed as soon as the first PR gets merged. |
Beta Was this translation helpful? Give feedback.
-
|
The core question that's still unanswered is the workflow that reads PRs from the Development section specifically, not from text in the issue body. vshivam1729 mentioned Gecko51's approach but that comment got hidden — so here's the actual working solution for your exact setup. When you link PRs via the Development section, GitHub records them as name: Auto-close issue when all linked PRs are merged
on:
schedule:
- cron: "*/10 * * * *"
workflow_dispatch:
permissions:
issues: write
contents: read
jobs:
check-linked-prs:
runs-on: ubuntu-latest
steps:
- name: Check Development-linked PRs
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const owner = context.repo.owner;
const repo = context.repo.repo;
const issues = await github.paginate(
github.rest.issues.listForRepo,
{ owner, repo, state: "open", per_page: 100 }
);
for (const issue of issues) {
const timeline = await github.paginate(
github.rest.issues.listEventsForTimeline,
{ owner, repo, issue_number: issue.number, per_page: 100 }
);
const connectedPRs = timeline.filter(
e => e.event === 'connected' && e.source?.issue?.pull_request
);
if (!connectedPRs.length) continue;
let allMerged = true;
for (const event of connectedPRs) {
const prUrl = event.source.issue.pull_request.url;
const match = prUrl.match(/repos\/([^/]+)\/([^/]+)\/pulls\/(\d+)/);
if (!match) { allMerged = false; break; }
const pr = await github.rest.pulls.get({
owner: match[1],
repo: match[2],
pull_number: Number(match[3])
});
if (!pr.data.merged_at) {
allMerged = false;
break;
}
}
if (allMerged) {
await github.rest.issues.update({
owner, repo,
issue_number: issue.number,
state: "closed"
});
}
}This runs every 10 minutes, reads every PR you linked through the Development section, and only closes the issue when all of them are merged — not just one. For the GitHub Project "Done" status — once the issue closes, your Project's built-in workflow should move it automatically. Just make sure it's enabled: go to your Project → Workflows → turn on "Item closed" → set status to Done. That's it, no extra automation needed for that part. Since Repo B is public this should work without any extra tokens or permissions. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
🏷️ Discussion Type
Question
💬 Feature/Topic Area
Other
Body
Hello!
I want to make sure that if linked to an Issue PR is being closed, same applies to the mentioned Issue.
I already had checked Option in Repo A's General Settings, but it didn't work.
Should I add "Closes <$(Me)/$(Repo A)#$(Issue Number)>" to every PR?
And how to deal with it if I have several PRs that should close one Issue if merged all, but not only one of them?
Didn't found a similar Discussion in there, so I'm asking it like this.
Beta Was this translation helpful? Give feedback.
All reactions