Skip to content

Reduce number of per-PR CI jobs. #988

Reduce number of per-PR CI jobs.

Reduce number of per-PR CI jobs. #988

# SPDX-FileCopyrightText: Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
name: Synchronize Linked Issues
on:
pull_request_target:
# Run this action when a PR is opened or edited
# Issues do not have a graphQL connection to linked PRs so we can't use that event
types: [edited]
env:
ORG: ${{ github.event.repository.owner.login }}
PR_NUMBER: ${{ github.event.pull_request.number }}
REPO: ${{ github.event.repository.name }}
# The environment vars below are hard-coded from external queries to save time + complexity here
# Note: PVT means Project V2, not "Private"
PROJECT_ID: "PVT_kwDOABpemM4AEhOI"
STATUS_FIELD_ID: "PVTSSF_lADOABpemM4AEhOIzgCmnYc"
WORKING_SPRINT_FIELD_ID: "PVTIF_lADOABpemM4AEhOIzgJlRho"
START_SPRINT_FIELD_ID: "PVTIF_lADOABpemM4AEhOIzgJlRhU"
jobs:
query_and_mutate_project_fields:
runs-on: ubuntu-latest
steps:
- name: Generate token
id: generate_token
uses: tibdex/[email protected]
with:
app_id: ${{ secrets.CCCL_AUTH_APP_ID }}
private_key: ${{ secrets.CCCL_AUTH_APP_PEM }}
- name: Get PR Project ID
id: get_pr_id
env:
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
run: |
# Query up to 10 projects for the PR
gh api graphql -f query='
query {
organization(login: "${{ env.ORG }}") {
repository(name: "${{ env.REPO }}") {
issueOrPullRequest(number: ${{ env.PR_NUMBER }}) {
... on PullRequest {
id
projectItems(first: 10) {
edges {
node {
id
project {
id
}
}
}
}
}
}
}
}
}' > project_data.json
# Filter the json result to only the project-specific ID for the PR
# A PR can be in multiple projects so we need to filter by the project ID we want
pr_id=$(jq -r '.data.organization.repository.issueOrPullRequest.projectItems.edges[] |
select(.node.project.id == "${{ env.PROJECT_ID }}") |
.node.id' project_data.json)
echo "PR_ID=$pr_id" >> $GITHUB_ENV
continue-on-error: true
- name: Get Status, Start Sprint, and Working Sprint Fields from the PR
id: get_pr_status
env:
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
run: |
# Query the PR's status from the project
gh api graphql -f query='
query {
node(id: "${{ env.PR_ID }}") {
... on ProjectV2Item {
id
fieldValueByName(name: "Status") {
... on ProjectV2ItemFieldSingleSelectValue {
optionId
}
}
}
}
}' > status_field_data.json
status_option_id=$(jq -r '.data.node.fieldValueByName.optionId' status_field_data.json)
echo "STATUS_OPTION_ID=$status_option_id" >> $GITHUB_ENV
# Query the PR's start sprint from the project
gh api graphql -f query='
query {
node(id: "${{ env.PR_ID }}") {
... on ProjectV2Item {
id
fieldValueByName(name: "Start Sprint") {
... on ProjectV2ItemFieldIterationValue {
iterationId
}
}
}
}
}' > start_sprint_data.json
start_sprint_iteration_id=$(jq -r '.data.node.fieldValueByName.iterationId' start_sprint_data.json)
echo "START_SPRINT_ITERATION_ID=$start_sprint_iteration_id" >> $GITHUB_ENV
# Query the PR's working sprint from the project
gh api graphql -f query='
query {
node(id: "${{ env.PR_ID }}") {
... on ProjectV2Item {
id
fieldValueByName(name: "Working Sprint") {
... on ProjectV2ItemFieldIterationValue {
iterationId
}
}
}
}
}' > working_sprint_data.json
working_sprint_iteration_id=$(jq -r '.data.node.fieldValueByName.iterationId' working_sprint_data.json)
echo "WORKING_SPRINT_ITERATION_ID=$working_sprint_iteration_id" >> $GITHUB_ENV
continue-on-error: true
- name: Sync Linked Issues
id: update_linked_issues
env:
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
run: |
gh api graphql -f query='
query {
organization(login: "${{ env.ORG }}") {
repository(name: "${{ env.REPO }}") {
issueOrPullRequest(number: ${{ env.PR_NUMBER }}) {
... on PullRequest {
id
closingIssuesReferences(first: 10) {
edges {
node {
id
projectItems(first: 10) {
nodes {
id
}
edges {
node {
id
project {
id
}
}
}
}
}
}
}
}
}
}
}
}' > project_data.json
issue_ids=$(jq -r '.data.organization.repository.issueOrPullRequest.closingIssuesReferences.edges[].node.projectItems.edges[] |
select(.node.project.id == "${{ env.PROJECT_ID }}") |
.node.id' project_data.json)
for issue_id in $issue_ids; do
# The query below is constructed differently than the others due to bash variable syntax + github actions syntax interactions
# Update Status
QUERY="mutation {
updateProjectV2ItemFieldValue(
input: {
projectId: \"$PROJECT_ID\"
itemId: \"$issue_id\"
fieldId: \"$STATUS_FIELD_ID\"
value: {
singleSelectOptionId: \"$STATUS_OPTION_ID\"
}
}
) {
projectV2Item {
id
}
}
}"
gh api graphql --field query="$QUERY"
# Update Start Sprint
QUERY="mutation {
updateProjectV2ItemFieldValue(
input: {
projectId: \"$PROJECT_ID\"
itemId: \"$issue_id\"
fieldId: \"$START_SPRINT_FIELD_ID\"
value: {
iterationId: \"$START_SPRINT_ITERATION_ID\"
}
}
) {
projectV2Item {
id
}
}
}"
gh api graphql --field query="$QUERY"
# Update Working Sprint
QUERY="mutation {
updateProjectV2ItemFieldValue(
input: {
projectId: \"$PROJECT_ID\"
itemId: \"$issue_id\"
fieldId: \"$WORKING_SPRINT_FIELD_ID\"
value: {
iterationId: \"$WORKING_SPRINT_ITERATION_ID\"
}
}
) {
projectV2Item {
id
}
}
}"
gh api graphql --field query="$QUERY"
done
continue-on-error: true