Skip to content

Commit cfcf859

Browse files
authored
Update update-roadmap-project-dates.yml
1 parent 8d86425 commit cfcf859

File tree

1 file changed

+149
-73
lines changed

1 file changed

+149
-73
lines changed
Lines changed: 149 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,110 +1,186 @@
1-
name: Update Project Fields on Label and Status Change
1+
name: Update Roadmap Dates
22

33
on:
44
pull_request:
5-
types:
6-
- labeled
7-
workflow_dispatch:
5+
types: [labeled]
86

97
jobs:
10-
update-project-dates:
8+
update-roadmap-dates:
119
runs-on: ubuntu-latest
10+
if: |
11+
github.event.label.name == 'awaiting_tech_review' ||
12+
github.event.label.name == 'publish'
13+
14+
permissions:
15+
contents: read
16+
pull-requests: read
17+
repository-projects: write
18+
1219
steps:
13-
- name: Check out code
20+
- name: Checkout repository
1421
uses: actions/checkout@v3
1522

16-
- name: Run GitHub Script
17-
uses: actions/github-script@v7
23+
- name: Setup Node.js
24+
uses: actions/setup-node@v3
1825
with:
19-
github-token: ${{ secrets.GITHUB_TOKEN }} # replace with your token secret name
20-
script: |
21-
const projectId = "PVT_kwDOBVR2-M4A2QVf"; // Replace with your actual project node ID
22-
const fieldStartId = "PVTF_lADOBVR2-M4A2QVfzgrvSF4"; // Replace with Start Date field node ID
23-
const fieldPublishId = "PVTF_lADOBVR2-M4A2QVfzgrvSMA"; // Replace with Publish Date field node ID
26+
node-version: '16'
2427

25-
const label = context.payload.label ? context.payload.label.name : null;
28+
- name: Install Octokit
29+
run: npm install @octokit/rest
2630

27-
if (!label) {
28-
console.log("No label found in the payload.");
29-
return;
30-
}
31-
const prNodeId = context.payload.pull_request.node_id;
32-
33-
// Get the project item for this PR
34-
const { repository } = await github.graphql(`
35-
query($owner: String!, $repo: String!, $prNumber: Int!) {
36-
repository(owner: $owner, name: $repo) {
37-
pullRequest(number: $prNumber) {
38-
projectItems(first: 10) {
39-
nodes {
31+
- name: Update Project Board Dates
32+
uses: actions/github-script@v6
33+
with:
34+
github-token: ${{ secrets.PROJECT_TOKEN }}
35+
script:|
36+
const { Octokit } = require('@octokit/rest');
37+
const octokit = new Octokit({ auth:process.env.GITHUB_TOKEN });
38+
39+
const projectNumber = 4; // Your project number
40+
const orgName = 'ArmDeveloperEcosystem';
41+
const prNumber = context.payload.pull_request.number;
42+
const labelName = context.payload.label.name;
43+
44+
async function getProjectItemForPR() {
45+
// Get the project ID
46+
const projectQuery = `
47+
query {
48+
organization(login:"${orgName}") {
49+
projectV2(number:${projectNumber}) {
4050
id
41-
fieldValues(first: 10) {
51+
}
52+
}
53+
}
54+
`;
55+
56+
const projectResponse = await octokit.graphql(projectQuery);
57+
const projectId = projectResponse.organization.projectV2.id;
58+
59+
// Find the PR in the project
60+
const prQuery = `
61+
query {
62+
organization(login:"${orgName}") {
63+
projectV2(number:${projectNumber}) {
64+
items(first:100) {
65+
nodes {
66+
id
67+
content {
68+
... on PullRequest {
69+
number
70+
repository {
71+
name
72+
}
73+
}
74+
}
75+
}
76+
}
77+
}
78+
}
79+
}
80+
`;
81+
82+
const prResponse = await octokit.graphql(prQuery);
83+
const items = prResponse.organization.projectV2.items.nodes;
84+
85+
// Find the item that corresponds to this PR
86+
const item = items.find(item =>
87+
item.content &&
88+
item.content.number === prNumber &&
89+
item.content.repository.name === context.repo.repo
90+
);
91+
92+
return { projectId, itemId: item ? item.id : null };
93+
}
94+
95+
async function getFieldId(projectId, fieldName) {
96+
const fieldsQuery = `
97+
query {
98+
node(id: "${projectId}") {
99+
... on ProjectV2 {
100+
fields(first: 20) {
42101
nodes {
43-
field {
102+
... on ProjectV2Field {
103+
id
44104
name
45105
}
46-
... on ProjectV2ItemFieldDateValue {
47-
date
106+
... on ProjectV2IterationField {
107+
id
108+
name
48109
}
49-
... on ProjectV2ItemFieldTextValue {
50-
text
110+
... on ProjectV2SingleSelectField {
111+
id
112+
name
51113
}
52-
... on ProjectV2ItemFieldSingleSelectValue {
114+
... on ProjectV2DateField {
115+
id
53116
name
54117
}
55118
}
56119
}
57120
}
58-
}
59-
60-
`, {
61-
owner: context.repo.owner,
62-
repo: context.repo.repo,
63-
prNumber: context.issue.number,
64-
});
65-
66-
const item = repository.pullRequest.projectItems.nodes[0];
67-
if (!item) {
68-
console.log("No project item found for this PR.");
69-
return;
70-
}
121+
}
122+
}
123+
`;
71124
72-
const itemId = item.id;
125+
const fieldsResponse = await octokit.graphql(fieldsQuery);
126+
const fields = fieldsResponse.node.fields.nodes;
127+
const field = fields.find(f => f.name === fieldName);
73128
74-
const today = new Date().toISOString().split("T")[0]; // e.g., "2025-04-10"
129+
return field ? field.id : null;
130+
}
75131
76-
if (label === "awaiting_tech_review") {
77-
console.log("Setting Start Date...");
78-
await github.graphql(`
132+
async function updateDateField(projectId, itemId, fieldId, date) {
133+
const mutation = `
79134
mutation {
80-
updateProjectV2ItemFieldValue(input: {
81-
projectId: "${projectId}",
82-
itemId: "${itemId}",
83-
fieldId: "${fieldStartId}",
84-
value: { date: "${today}" }
85-
}) {
135+
updateProjectV2ItemFieldValue(
136+
input: {
137+
projectId: "${projectId}"
138+
itemId: "${itemId}"
139+
fieldId: "${fieldId}"
140+
value: {
141+
date: "${date}"
142+
}
143+
}
144+
) {
86145
projectV2Item {
87146
id
88147
}
89148
}
90149
}
91-
`);
150+
`;
151+
152+
return await octokit.graphql(mutation);
92153
}
93154
94-
if (label === "publish") {
95-
console.log("Setting Publish Date...");
96-
await github.graphql(`
97-
mutation {
98-
updateProjectV2ItemFieldValue(input: {
99-
projectId: "${projectId}",
100-
itemId: "${itemId}",
101-
fieldId: "${fieldPublishId}",
102-
value: { date: "${today}" }
103-
}) {
104-
projectV2Item {
105-
id
106-
}
155+
async function main() {
156+
try {
157+
const { projectId, itemId } = await getProjectItemForPR();
158+
if (!itemId) {
159+
console.log('PR not found in project board');
160+
return;
161+
}
162+
163+
const today = new Date().toISOString().split('T')[0]; // YYYY-MM-DD format
164+
165+
if (labelName === 'awaiting_tech_review') {
166+
const startDateFieldId = await getFieldId(projectId, 'Start Date');
167+
if (startDateFieldId) {
168+
await updateDateField(projectId, itemId, startDateFieldId, today);
169+
console.log('Updated Start Date to', today);
170+
} else {
171+
console.log('Start Date field not found');
172+
}
173+
} else if (labelName === 'publish') {
174+
const publishDateFieldId = await getFieldId(projectId, 'Publish Date');
175+
if (publishDateFieldId) {
176+
await updateDateField(projectId, itemId, publishDateFieldId, today);
177+
console.log('Updated Publish Date to', today);
178+
} else {
179+
console.log('Publish Date field not found');
107180
}
108181
}
109-
`);
182+
} catch (error) {
183+
console.error('Error updating project board:', error);
184+
core.setFailed(`Error updating project board: ${error.message}`);
185+
}
110186
}

0 commit comments

Comments
 (0)