1
+ name : Check PR Project Assignment
2
+
3
+ on :
4
+ pull_request :
5
+ types : [opened, synchronize, reopened]
6
+
7
+ jobs :
8
+ check-project :
9
+ name : Verify PR is in project with iteration
10
+ runs-on : ubuntu-latest
11
+
12
+ steps :
13
+ - name : Check project assignment
14
+ uses : actions/github-script@v7
15
+ with :
16
+ github-token : ${{ secrets.PROJECT_PAT }}
17
+ script : |
18
+ const owner = 'o1-labs';
19
+ const projectNumber = 24; // Rust node project number
20
+
21
+ // Get PR details
22
+ const pr = context.payload.pull_request;
23
+ console.log(`Checking PR #${pr.number}: ${pr.title}`);
24
+
25
+ // GraphQL query to check if PR is in project with iteration
26
+ const query = `
27
+ query($owner: String!, $number: Int!, $prId: ID!) {
28
+ organization(login: $owner) {
29
+ projectV2(number: $number) {
30
+ id
31
+ title
32
+ items(first: 100) {
33
+ nodes {
34
+ id
35
+ content {
36
+ ... on PullRequest {
37
+ id
38
+ number
39
+ title
40
+ }
41
+ }
42
+ fieldValues(first: 20) {
43
+ nodes {
44
+ ... on ProjectV2ItemFieldIterationValue {
45
+ field {
46
+ ... on ProjectV2IterationField {
47
+ name
48
+ }
49
+ }
50
+ title
51
+ startDate
52
+ duration
53
+ }
54
+ }
55
+ }
56
+ }
57
+ }
58
+ }
59
+ }
60
+ }
61
+ `;
62
+
63
+ try {
64
+ const result = await github.graphql(query, {
65
+ owner: owner,
66
+ number: projectNumber,
67
+ prId: pr.node_id
68
+ });
69
+
70
+ const project = result.organization.projectV2;
71
+ console.log(`Found project: ${project.title}`);
72
+
73
+ // Find this PR in the project
74
+ const projectItem = project.items.nodes.find(item =>
75
+ item.content &&
76
+ item.content.number === pr.number
77
+ );
78
+
79
+ if (!projectItem) {
80
+ core.setFailed(`❌ PR #${pr.number} is not added to the "${project.title}" project.\n\n` +
81
+ `Please add this PR to the project at: https://github.com/orgs/${owner}/projects/${projectNumber}\n\n` +
82
+ `Instructions:\n` +
83
+ `1. Go to the project board\n` +
84
+ `2. Click "Add item" button\n` +
85
+ `3. Search for this PR (#${pr.number})\n` +
86
+ `4. Add it to the project\n` +
87
+ `5. Set an iteration for the PR`);
88
+ return;
89
+ }
90
+
91
+ console.log('PR found in project, checking for iteration...');
92
+
93
+ // Check if PR has an iteration assigned
94
+ const iterationField = projectItem.fieldValues.nodes.find(field =>
95
+ field.field && field.field.name === 'Iteration'
96
+ );
97
+
98
+ if (!iterationField || !iterationField.title) {
99
+ core.setFailed(`❌ PR #${pr.number} is in the project but has no iteration assigned.\n\n` +
100
+ `Please assign an iteration to this PR in the project at: https://github.com/orgs/${owner}/projects/${projectNumber}\n\n` +
101
+ `Instructions:\n` +
102
+ `1. Go to the project board\n` +
103
+ `2. Find this PR (#${pr.number})\n` +
104
+ `3. Click on the Iteration field for this item\n` +
105
+ `4. Select the appropriate iteration`);
106
+ return;
107
+ }
108
+
109
+ console.log(`✅ PR #${pr.number} is in project "${project.title}" with iteration: ${iterationField.title}`);
110
+ core.notice(`PR is properly assigned to project with iteration: ${iterationField.title}`);
111
+
112
+ } catch (error) {
113
+ console.error('Error checking project:', error);
114
+ core.setFailed(`Failed to check project assignment: ${error.message}\n\n` +
115
+ `This might happen if:\n` +
116
+ `- The PROJECT_PAT secret is not configured correctly\n` +
117
+ `- The project number (${projectNumber}) is incorrect\n` +
118
+ `- There are API permission issues`);
119
+ }
0 commit comments