Skip to content

Commit c2168a2

Browse files
committed
ci/templates: use parent_id field in template to properly link issues
1 parent 10758f2 commit c2168a2

1 file changed

Lines changed: 98 additions & 0 deletions

File tree

.github/workflows/issue-linker.yml

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
name: Auto-link sub-issue to parent issue
2+
3+
on:
4+
issues:
5+
types: [opened, labeled]
6+
workflow_dispatch:
7+
inputs:
8+
issue_number:
9+
description: 'Issue number to link to parent'
10+
required: true
11+
type: number
12+
parent_number:
13+
description: 'Parent issue number'
14+
required: false
15+
type: number
16+
17+
18+
jobs:
19+
link-to-parent:
20+
runs-on: ubuntu-latest
21+
if: |
22+
(github.event_name == 'workflow_dispatch')
23+
|| (github.event_name == 'issues' && (
24+
contains(toJson(github.event.issue.labels.*.name), '"0. layer: task"')
25+
contains(toJson(github.event.issue.labels.*.name), '"0. layer: story"')
26+
))
27+
permissions:
28+
issues: write
29+
steps:
30+
- name: Link to Parent issue as Sub-issue
31+
uses: actions/github-script@v7
32+
with:
33+
script: |
34+
let issueNumber, issueData;
35+
36+
if (context.eventName === 'workflow_dispatch') {
37+
issueNumber = '${{ inputs.issue_number }}';
38+
39+
40+
const response = await github.rest.issues.get({
41+
owner: context.repo.owner,
42+
repo: context.repo.repo,
43+
issue_number: issueNumber
44+
});
45+
issueData = response.data;
46+
} else {
47+
issueData = context.payload.issue;
48+
issueNumber = issueData?.number;
49+
}
50+
51+
const body = issueData.body || '';
52+
const childId = issueData.node_id;
53+
54+
const parentMatch = body.match(/Parent Story[\s\S]*?#(\d+)/i)
55+
|| body.match(/Parent Epic[\s\S]*?#(\d+)/i);
56+
57+
if (!parentMatch) {
58+
console.log('No parent story found, skipping.');
59+
return;
60+
}
61+
62+
const parentNumber = '${{ inputs.parent_number }}' || parseInt(parentMatch[1]);
63+
const owner = context.repo.owner;
64+
const repo = context.repo.repo;
65+
66+
console.log(`Linking task #${issueNumber} to parent #${parentNumber}`);
67+
68+
try {
69+
const parentResponse = await github.rest.issues.get({
70+
owner,
71+
repo,
72+
issue_number: parentNumber
73+
});
74+
const parentNodeId = parentResponse.data.node_id;
75+
76+
const mutation = `
77+
mutation {
78+
addSubIssue(input: {
79+
issueId: "${parentNodeId}"
80+
subIssueId: "${childId}"
81+
}) {
82+
issue {
83+
number
84+
}
85+
}
86+
}
87+
`;
88+
89+
await github.graphql(mutation);
90+
91+
console.log(`Successfully linked #${issueNumber} as sub-issue of #${parentNumber}`);
92+
} catch (error) {
93+
console.error(`Error linking to parent: ${error.message}`);
94+
95+
if (error.status === 404) {
96+
console.error(`Parent issue #${parentNumber} not found`);
97+
}
98+
}

0 commit comments

Comments
 (0)