1+ name : Manage project items
2+
3+ on :
4+ issues :
5+ types : [opened, closed]
6+ pull_request :
7+ types : [opened, closed]
8+
9+ jobs :
10+ manage_project_items :
11+ runs-on : ubuntu-latest
12+ steps :
13+ - name : Add issue or pull request to project
14+ if : github.event_name == 'issues' || github.event_name == 'pull_request'
15+ uses : actions/github-script@v7
16+ with :
17+ github-token : ${{ secrets.PROJECT_TOKEN }}
18+ script : |
19+ let nodeId;
20+ let eventType;
21+ if (context.payload.issue) {
22+ nodeId = context.payload.issue.node_id;
23+ eventType = 'Issue';
24+ } else if (context.payload.pull_request) {
25+ nodeId = context.payload.pull_request.node_id;
26+ eventType = 'Pull Request';
27+ } else {
28+ console.log('Event is neither an issue nor a pull request.');
29+ return;
30+ }
31+
32+ const projectNumber = ${{ secrets.PROJECT_NUMBER }}; // Replace with your project number
33+
34+ // Fetch the project details using the GraphQL API
35+ const { user } = await github.graphql(`
36+ query($owner: String!, $number: Int!) {
37+ user(login: $owner) {
38+ projectV2(number: $number) {
39+ id
40+ fields(first: 100) {
41+ nodes {
42+ ... on ProjectV2SingleSelectField {
43+ id
44+ name
45+ options {
46+ id
47+ name
48+ }
49+ }
50+ ... on ProjectV2Field {
51+ id
52+ name
53+ }
54+ }
55+ }
56+ }
57+ }
58+ }
59+ `, {
60+ owner: context.repo.owner,
61+ number: projectNumber,
62+ });
63+
64+ if (!user.projectV2) {
65+ console.log(`Project with number "${projectNumber}" not found.`);
66+ return;
67+ }
68+
69+ const projectId = user.projectV2.id;
70+
71+ // Get the field ID and option ID for the status field
72+ const statusField = user.projectV2.fields.nodes.find(field => field.name === 'Status');
73+ const todoOptionId = statusField.options.find(option => option.name === 'Todo').id;
74+ const closedOptionId = statusField.options.find(option => option.name === 'Done').id;
75+
76+ // Get the field ID for the project field
77+ const projectField = user.projectV2.fields.nodes.find(field => field.name === 'Project');
78+
79+ if (context.payload.action === 'opened') {
80+ // Add the issue or pull request to the project with TODO status
81+ const addItemResponse = await github.graphql(`
82+ mutation($projectId: ID!, $nodeId: ID!) {
83+ addProjectV2ItemById(input: {projectId: $projectId, contentId: $nodeId}) {
84+ item {
85+ id
86+ }
87+ }
88+ }
89+ `, {
90+ projectId: projectId,
91+ nodeId: nodeId,
92+ });
93+
94+ const itemId = addItemResponse.addProjectV2ItemById.item.id;
95+
96+ // Update status field to TODO
97+ await github.graphql(`
98+ mutation($projectId: ID!, $itemId: ID!, $statusFieldId: ID!, $statusOptionId: String!) {
99+ updateProjectV2ItemFieldValue(input: {
100+ projectId: $projectId,
101+ itemId: $itemId,
102+ fieldId: $statusFieldId,
103+ value: { singleSelectOptionId: $statusOptionId }
104+ }) {
105+ projectV2Item {
106+ id
107+ }
108+ }
109+ }
110+ `, {
111+ projectId: projectId,
112+ itemId: itemId,
113+ statusFieldId: statusField.id,
114+ statusOptionId: todoOptionId,
115+ });
116+
117+ // Update project field
118+ await github.graphql(`
119+ mutation($projectId: ID!, $itemId: ID!, $projectFieldId: ID!, $repositoryName: String!) {
120+ updateProjectV2ItemFieldValue(input: {
121+ projectId: $projectId,
122+ itemId: $itemId,
123+ fieldId: $projectFieldId,
124+ value: { text: $repositoryName }
125+ }) {
126+ projectV2Item {
127+ id
128+ }
129+ }
130+ }
131+ `, {
132+ projectId: projectId,
133+ itemId: itemId,
134+ projectFieldId: projectField.id,
135+ repositoryName: context.repo.repo,
136+ });
137+
138+ console.log(`${eventType} added to the project with TODO status.`);
139+ }
0 commit comments