Skip to content

Commit c7eb05d

Browse files
authored
Project Automation: set Roadmap project value on issue/pr close and Auto-type new issues (#389)
* Create action to set roadmap on close * Update job name to be more descriptive * [skip ci] fixing #408 * [skip ci] Undoing fix for #408, moving it to #387 * [skip ci] Add action to autoset issue type on open
1 parent ac161d7 commit c7eb05d

File tree

2 files changed

+306
-0
lines changed

2 files changed

+306
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
name: Set Issue Type Single Select
17+
18+
on:
19+
issues:
20+
# Run this action when an issue is opened
21+
types: [opened]
22+
23+
env:
24+
ISSUE_NODE_ID: ${{ github.event.issue.node_id }}
25+
26+
# The environment vars below are hard-coded from external queries to save time + complexity here
27+
# Note: PVT means Project V2, not "Private" - although this is a private project
28+
# PVT = Project V2, PVTSSF = Project V2 Single Select Field, PVTIF = Project V2 Iteration Field
29+
PROJECT_ID: "PVT_kwDOABpemM4AEhOI"
30+
ISSUE_TYPE_FIELD_ID: "PVTSSF_lADOABpemM4AEhOIzgCzg-4"
31+
BUG_OPTION_ID: "e7e7e23f"
32+
FEATURE_OPTION_ID: "f8765953"
33+
DOCS_OPTION_ID: "cb6cb7bf"
34+
EPIC_OPTION_ID: "1d095615"
35+
THEME_OPTION_ID: "22f101c0"
36+
37+
jobs:
38+
update_issue_type_in_project:
39+
runs-on: ubuntu-latest
40+
41+
steps:
42+
- name: Sleep 1s
43+
id: sleep_1s
44+
run: sleep 1 # We sleep to ensure the issue is added to the project before we run this action
45+
46+
- name: Generate token
47+
id: generate_token
48+
uses: tibdex/[email protected]
49+
with:
50+
app_id: ${{ secrets.CCCL_AUTH_APP_ID }}
51+
private_key: ${{ secrets.CCCL_AUTH_APP_PEM }}
52+
53+
- name: Get Issue Project ID
54+
id: get_issue_id
55+
env:
56+
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
57+
run: |
58+
# Query up to 10 projects for the Issue
59+
gh api graphql -f query='
60+
query {
61+
node(id: "${{ env.ISSUE_NODE_ID }}") {
62+
... on Issue {
63+
projectItems(first: 10) {
64+
nodes {
65+
id
66+
project {
67+
id
68+
}
69+
}
70+
}
71+
}
72+
}
73+
}' > project_data.json
74+
75+
# Filter the json result to only the project-specific ID for the PR
76+
# An issue can be in multiple projects so we need to filter by the project ID we want
77+
issue_id=$(jq -r '.data.node.projectItems.nodes[] |
78+
select(.project.id == "${{ env.PROJECT_ID }}") |
79+
.id' project_data.json)
80+
echo "ISSUE_PROJECT_ID=$issue_id" >> $GITHUB_ENV
81+
82+
- name: Extract Issue Type Text
83+
id: extract_issue_type
84+
env:
85+
ISSUE_TITLE: ${{ github.event.issue.title }}
86+
run: |
87+
# Extract the text between two brackets in the issue title
88+
issue_type=$(echo "$ISSUE_TITLE" | grep -o '\[.*\]' | tr -d '[]')
89+
90+
# Set the issue type option ID based on the extracted text
91+
if [ "$issue_type" == "BUG" ]; then
92+
option_id=${{ env.BUG_OPTION_ID }}
93+
elif [ "$issue_type" == "FEA" ]; then
94+
option_id=${{ env.FEATURE_OPTION_ID }}
95+
elif [ "$issue_type" == "DOC" ]; then
96+
option_id=${{ env.DOCS_OPTION_ID }}
97+
elif [ "$issue_type" == "EPIC" ]; then
98+
option_id=${{ env.EPIC_OPTION_ID }}
99+
elif [ "$issue_type" == "THEME" ]; then
100+
option_id=${{ env.THEME_OPTION_ID }}
101+
else
102+
option_id="Undefined"
103+
fi
104+
echo "TYPE_OPTION_ID=$option_id" >> $GITHUB_ENV
105+
106+
- name: Set Issue Type
107+
id: set_issue_type
108+
env:
109+
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
110+
if: ${{ env.TYPE_OPTION_ID }} != "Undefined"
111+
run: |
112+
# Mutation to update the Issue's Issue Type field
113+
gh api graphql -f query='
114+
mutation {
115+
updateProjectV2ItemFieldValue(
116+
input: {
117+
projectId: "${{ env.PROJECT_ID }}"
118+
itemId: "${{ env.ISSUE_PROJECT_ID }}"
119+
fieldId: "${{ env.ISSUE_TYPE_FIELD_ID }}"
120+
value: {
121+
singleSelectOptionId: "${{ env.TYPE_OPTION_ID }}"
122+
}
123+
}
124+
) {
125+
projectV2Item {
126+
id
127+
}
128+
}
129+
}'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
name: Set PR or Issue Roadmap Value on Close
17+
18+
on:
19+
pull_request_target:
20+
# Run this action when a PR is closed
21+
types: [closed]
22+
issues:
23+
# Run this action when an issue is closed
24+
types: [closed]
25+
26+
env:
27+
ORG: ${{ github.event.repository.owner.login }}
28+
PR_NUMBER: ${{ github.event.pull_request.number }} # evaluates to null for issues
29+
ISSUE_NUMBER: ${{ github.event.issue.number }} # evaluates to null for PRs
30+
REPO: ${{ github.event.repository.name }}
31+
32+
# The environment vars below are hard-coded from external queries to save time + complexity here
33+
# Note: PVT means Project V2, not "Private"
34+
# PVT = Project V2, PVTSSF = Project V2 Single Select Field, PVTIF = Project V2 Iteration Field
35+
PROJECT_ID: "PVT_kwDOABpemM4AEhOI"
36+
ROADMAP_FIELD_ID: "PVTSSF_lADOABpemM4AEhOIzgC_MXI"
37+
38+
jobs:
39+
set_roadmap_value:
40+
runs-on: ubuntu-latest
41+
42+
steps:
43+
- name: Generate token
44+
id: generate_token
45+
uses: tibdex/[email protected]
46+
with:
47+
app_id: ${{ secrets.CCCL_AUTH_APP_ID }}
48+
private_key: ${{ secrets.CCCL_AUTH_APP_PEM }}
49+
50+
- name: Get PR Project ID
51+
if: github.event_name == 'pull_request_target'
52+
id: get_pr_id
53+
env:
54+
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
55+
run: |
56+
# Query up to 10 projects for the PR
57+
gh api graphql -f query='
58+
query {
59+
organization(login: "${{ env.ORG }}") {
60+
repository(name: "${{ env.REPO }}") {
61+
issueOrPullRequest(number: ${{ env.PR_NUMBER }}) {
62+
... on PullRequest {
63+
id
64+
projectItems(first: 10) {
65+
edges {
66+
node {
67+
id
68+
project {
69+
id
70+
}
71+
}
72+
}
73+
}
74+
}
75+
}
76+
}
77+
}
78+
}' > project_data.json
79+
80+
# Filter the json result to only the project-specific ID for the PR
81+
# A PR can be in multiple projects so we need to filter by the project ID we want
82+
pr_id=$(jq -r '.data.organization.repository.issueOrPullRequest.projectItems.edges[] |
83+
select(.node.project.id == "${{ env.PROJECT_ID }}") |
84+
.node.id' project_data.json)
85+
echo "ITEM_ID=$pr_id" >> $GITHUB_ENV
86+
continue-on-error: true
87+
88+
- name: Get Issue Project ID
89+
if: github.event_name == 'issues'
90+
id: get_issue_id
91+
env:
92+
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
93+
run: |
94+
# Query up to 10 projects for the Issue
95+
gh api graphql -f query='
96+
query {
97+
organization(login: "${{ env.ORG }}") {
98+
repository(name: "${{ env.REPO }}") {
99+
issueOrPullRequest(number: ${{ env.ISSUE_NUMBER }}) {
100+
... on Issue {
101+
id
102+
projectItems(first: 10) {
103+
edges {
104+
node {
105+
id
106+
project {
107+
id
108+
}
109+
}
110+
}
111+
}
112+
}
113+
}
114+
}
115+
}
116+
}' > project_data.json
117+
118+
# Filter the json result to only the project-specific ID for the PR
119+
# A PR can be in multiple projects so we need to filter by the project ID we want
120+
issue_id=$(jq -r '.data.organization.repository.issueOrPullRequest.projectItems.edges[] |
121+
select(.node.project.id == "${{ env.PROJECT_ID }}") |
122+
.node.id' project_data.json)
123+
echo "ITEM_ID=$issue_id" >> $GITHUB_ENV
124+
continue-on-error: true
125+
126+
- name: Get Current Release
127+
id: get_current_release
128+
env:
129+
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
130+
run: |
131+
# Get current roadmap id
132+
# We maintain the roadmap as a single select field in the project, with the first value being the upcoming release
133+
134+
gh api graphql -f query='
135+
query MyQuery {
136+
node(id: "${{ env.PROJECT_ID }}") {
137+
... on ProjectV2 {
138+
id
139+
field(name: "Roadmap") {
140+
... on ProjectV2SingleSelectField {
141+
id
142+
options {
143+
id
144+
}
145+
}
146+
}
147+
}
148+
}
149+
}' > roadmap_option_data.json
150+
current_roadmap_option_id=$(jq -r '.data.node.field.options[0].id' roadmap_option_data.json)
151+
echo "CURRENT_ROADMAP_OPTION_ID=$current_roadmap_option_id" >> $GITHUB_ENV
152+
continue-on-error: true
153+
154+
- name: Set Item Roadmap
155+
id: set_item_roadmap
156+
env:
157+
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
158+
run: |
159+
# Update the PR status to In Review
160+
gh api graphql -f query='
161+
mutation {
162+
updateProjectV2ItemFieldValue(
163+
input: {
164+
projectId: "${{ env.PROJECT_ID }}"
165+
itemId: "${{ env.ITEM_ID }}"
166+
fieldId: "${{ env.ROADMAP_FIELD_ID }}"
167+
value: {
168+
singleSelectOptionId: "${{ env.CURRENT_ROADMAP_OPTION_ID }}"
169+
}
170+
}
171+
) {
172+
projectV2Item {
173+
id
174+
}
175+
}
176+
}'
177+
continue-on-error: true

0 commit comments

Comments
 (0)