Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create Project Automation Shared Workflows #168

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
440a283
Add starter reusable project workflows
jarmak-nv Dec 15, 2023
468b09d
Update project-get-item-id.yaml
jarmak-nv Dec 15, 2023
0e08bbc
Update project-get-item-id.yaml
jarmak-nv Dec 15, 2023
a125a60
Update project-get-set-iteration-field.yaml
jarmak-nv Dec 15, 2023
0be7ac1
Support updating linked issues
jarmak-nv Dec 20, 2023
9d2cf7a
Test formatting change
jarmak-nv Dec 20, 2023
39f966a
Revert "Test formatting change"
jarmak-nv Dec 20, 2023
2ccc418
Change itemId to linked issue
jarmak-nv Dec 20, 2023
d494082
Attempt 2 for formatting the issue_id
jarmak-nv Dec 20, 2023
1ad5995
One more time
jarmak-nv Dec 20, 2023
4ebde48
Apply `$` formatting fix to all mutations
jarmak-nv Dec 20, 2023
243aae9
Add Single Select Workflow
jarmak-nv Jan 3, 2024
671bb02
Remove extra `}`
jarmak-nv Jan 3, 2024
c027d36
Add text/date/number field support
jarmak-nv Jan 3, 2024
906cc11
Remove unnecessary variable
jarmak-nv Jan 3, 2024
042ec04
Remove extra `if`
jarmak-nv Jan 3, 2024
de41d0c
Attempt different bash escaping
jarmak-nv Jan 4, 2024
cf1ff2b
Update linked issue bash variable syntax
jarmak-nv Jan 4, 2024
22991aa
More double-quote potential fixes
jarmak-nv Jan 4, 2024
785377f
Revert "More double-quote potential fixes"
jarmak-nv Jan 4, 2024
2afc0d1
Permissions + number field fix
jarmak-nv Jan 4, 2024
2a738f4
Merge branch 'rapidsai:branch-24.02' into project-automation-components
jarmak-nv Jan 4, 2024
60c6b91
Merge branch 'branch-24.02' into project-automation-components
jarmak-nv Jan 22, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions .github/workflows/project-get-item-id.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
name: Project - Get Item ID Within the Project
# This workflow gets the project-specific ID for an item within a project
# All downstream queries and mutations of fields within the project require this ID

on:
workflow_call:
inputs:
PROJECT_ID:
description: "The Project's graphQL node ID"
type: string
required: true

ITEM_NODE_ID:
description: "The issue or PR's graphQL node ID"
type: string
required: true

secrets:
PROJECT_MANAGEMENT_SECRET:
description: "Project Access Token"
required: true

outputs:
ITEM_PROJECT_ID:
description: "The item's project-specific ID"
value: ${{ jobs.get_items_project_id.outputs.ITEM_PROJECT_ID }}

jobs:
get_items_project_id:
runs-on: ubuntu-latest
outputs:
ITEM_PROJECT_ID: ${{ steps.get_item_id.outputs.ITEM_PROJECT_ID }}

steps:
- name: Sleep 1s
id: sleep_1s
run: |
sleep 1 # Ensure the PR is added to the project before we query its ID

- name: Get Item Project ID
id: get_item_id
env:
GH_TOKEN: ${{ secrets.PROJECT_MANAGEMENT_SECRET }}
run: |
# Query up to 10 projects for the PR
# There's no graphQL filter configured to query by a specific project
# So we need to query all projects and filter the result ourselves
gh api graphql -f query='
query {
node(id: "${{ inputs.ITEM_NODE_ID }}") {
... on PullRequest {
projectItems(first: 10) {
nodes {
id
project {
id
}
}
}
}
... on Issue {
projectItems(first: 10) {
nodes {
id
project {
id
}
}
}
}
}
}' > project_data.json

# Use jq to do the actual filtering
item_project_id=$(jq -r '.data.node.projectItems.nodes[] |
select(.project.id == "${{ inputs.PROJECT_ID }}") |
.id' project_data.json)
echo "ITEM_PROJECT_ID=$item_project_id" >> $GITHUB_OUTPUT
continue-on-error: true
132 changes: 132 additions & 0 deletions .github/workflows/project-get-set-iteration-field.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
name: Project - Get Item ID Within the Project
# This workflow gets the project-specific ID for an item within a project
# All downstream queries and mutations of fields within the project require this ID

on:
workflow_call:
inputs:
PROJECT_ID:
description: "The Project's graphQL node ID"
type: string
required: true

ITERATION_FIELD_NAME:
description: "The name of the iteration field"
type: string
required: true

ITERATION_FIELD_ID:
description: "The graphQL node ID of the iteration field"
type: string
required: true

ITEM_PROJECT_ID:
description: "The issue or PR's graphQL project-specific ID"
type: string
required: true

UPDATE_ITEM:
description: "Whether to update the item's iteration field"
default: false
type: boolean

# Optional fields, used if UPDATE_ITEM is set to true
ITEM_NODE_ID:
description: "The issue or PR's graphQL node ID, only needed if updating linked issues"
default: null
type: string

UPDATE_LINKED_ISSUES:
description: "Whether to update the linked issues' iteration fields"
default: false
type: boolean

secrets:
PROJECT_MANAGEMENT_SECRET:
description: "Project Access Token"
required: true

outputs:
ITERATION_OPTION_ID:
value: ${{ jobs.get_set_iteration_option_id.outputs.ITERATION_OPTION_ID }}
description: "The iteration option ID"

jobs:
get_set_iteration_option_id:
runs-on: ubuntu-latest
permissions:
contents: read
outputs:
ITERATION_OPTION_ID: ${{ steps.get_iteration_option_id.outputs.ITERATION_OPTION_ID }}

steps:
- name: Get Iteration Option ID
id: get_iteration_option_id
env:
GH_TOKEN: ${{ secrets.PROJECT_MANAGEMENT_SECRET }}
run: |
# Get current iteration iteration id
# The current iteration is always the first element in the returned list
gh api graphql -f query='
query {
node(id: "${{ inputs.PROJECT_ID }}") {
... on ProjectV2 {
id
field(name: "${{ inputs.ITERATION_FIELD_NAME }}") {
... on ProjectV2IterationField {
id
name
configuration {
iterations {
id
}
}
}
}
}
}
}' > iteration_option_data.json
current_iteration_option_id=$(jq -r '.data.node.field.configuration.iterations[0].id' iteration_option_data.json)
echo "ITERATION_OPTION_ID=$current_iteration_option_id" >> "$GITHUB_OUTPUT"

- name: Update item iteration field
id: update_item_iteration_field
if: ${{ inputs.UPDATE_ITEM == true }}
env:
GH_TOKEN: ${{ secrets.PROJECT_MANAGEMENT_SECRET }}
run: |
# Set the iteration based on the query above
# This overwrites whatever was in it before, we may want to make an "OVERWRITE" option
gh api graphql -f query='
mutation {
updateProjectV2ItemFieldValue(
input: {
projectId: "${{ inputs.PROJECT_ID }}"
itemId: "${{ inputs.ITEM_PROJECT_ID }}"
fieldId: "${{ inputs.ITERATION_FIELD_ID }}"
value: {
iterationId: "${{ steps.get_iteration_option_id.outputs.ITERATION_OPTION_ID }}"
}
}
) {
projectV2Item {
id
}
}
}'
continue-on-error: true

update_linked_issues:
if: ${{ inputs.UPDATE_LINKED_ISSUES == true }}
permissions:
contents: read
uses: ./.github/workflows/project-update-linked-issues.yaml
needs: get_set_iteration_option_id
with:
PROJECT_ID: ${{ inputs.PROJECT_ID }}
PR_PROJECT_ID: ${{ inputs.ITEM_PROJECT_ID }}
PR_NODE_ID: ${{ inputs.ITEM_NODE_ID }}
UPDATE_FIELD_TYPE: "iteration"
UPDATE_FIELD_ID: ${{ inputs.ITERATION_FIELD_ID }}
UPDATE_FIELD_VALUE: ${{ needs.get_set_iteration_option_id.outputs.ITERATION_OPTION_ID }}
secrets: inherit
131 changes: 131 additions & 0 deletions .github/workflows/project-get-set-single-select-field.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
name: Project - Get Item ID Within the Project
# This workflow gets the project-specific ID for an item within a project
# All downstream queries and mutations of fields within the project require this ID

on:
workflow_call:
inputs:
PROJECT_ID:
description: "The Project's graphQL node ID"
type: string
required: true

SINGLE_SELECT_FIELD_NAME:
description: "The name of the single-select field"
type: string
required: true

SINGLE_SELECT_OPTION_VALUE:
description: "The value of the option we'd like to get/set"
type: string
required: true

SINGLE_SELECT_FIELD_ID:
description: "The graphQL node ID of the single-select field"
type: string
required: true

ITEM_PROJECT_ID:
description: "The issue or PR's graphQL project-specific ID"
type: string
required: true

UPDATE_ITEM:
description: "Whether to update the item's single-select field"
default: false
type: boolean

# Optional fields, used if UPDATE_ITEM is set to true
ITEM_NODE_ID:
description: "The issue or PR's graphQL node ID, only needed if updating linked issues"
default: null
type: string

UPDATE_LINKED_ISSUES:
description: "Whether to update the linked issues' single_select fields"
default: false
type: boolean

secrets:
PROJECT_MANAGEMENT_SECRET:
description: "Project Access Token"
required: true

outputs:
SINGLE_SELECT_OPTION_ID:
value: ${{ jobs.get_set_single_select_option_id.outputs.SINGLE_SELECT_OPTION_ID }}
description: "The single_select option ID"

jobs:
get_set_single_select_option_id:
runs-on: ubuntu-latest
permissions:
contents: read
outputs:
SINGLE_SELECT_OPTION_ID: ${{ steps.get_single_select_option_id.outputs.SINGLE_SELECT_OPTION_ID }}

steps:
- name: Get single_select Option ID
id: get_single_select_option_id
env:
GH_TOKEN: ${{ secrets.PROJECT_MANAGEMENT_SECRET }}
run: |
# Get single_select option id
gh api graphql -f query='
query {
node(id: "${{ inputs.PROJECT_ID }}") {
... on ProjectV2 {
id
field(name: "${{ inputs.SINGLE_SELECT_FIELD_NAME }}") {
... on ProjectV2SingleSelectField {
id
options(names: "${{ inputs.SINGLE_SELECT_OPTION_VALUE }}") {id}
}
}
}
}
}' > single_select_option_data.json
current_single_select_option_id=$(jq -r '.data.node.field.options[0].id' single_select_option_data.json)
echo "SINGLE_SELECT_OPTION_ID=$current_single_select_option_id" >> "$GITHUB_OUTPUT"

- name: Update item single_select field
id: update_item_single_select_field
if: ${{ inputs.UPDATE_ITEM == true }}
env:
GH_TOKEN: ${{ secrets.PROJECT_MANAGEMENT_SECRET }}
run: |
# Set the single_select based on the query above
# This overwrites whatever was in it before, we may want to make an "OVERWRITE" option
gh api graphql -f query='
mutation {
updateProjectV2ItemFieldValue(
input: {
projectId: "${{ inputs.PROJECT_ID }}"
itemId: "${{ inputs.ITEM_PROJECT_ID }}"
fieldId: "${{ inputs.SINGLE_SELECT_FIELD_ID }}"
value: {
singleSelectOptionId: "${{ steps.get_single_select_option_id.outputs.SINGLE_SELECT_OPTION_ID }}"
}
}
) {
projectV2Item {
id
}
}
}'
continue-on-error: true

update_linked_issues:
if: ${{ inputs.UPDATE_LINKED_ISSUES == true }}
permissions:
contents: read
uses: ./.github/workflows/project-update-linked-issues.yaml
needs: get_set_single_select_option_id
with:
PROJECT_ID: ${{ inputs.PROJECT_ID }}
PR_PROJECT_ID: ${{ inputs.ITEM_PROJECT_ID }}
PR_NODE_ID: ${{ inputs.ITEM_NODE_ID }}
UPDATE_FIELD_TYPE: "single_select"
UPDATE_FIELD_ID: ${{ inputs.SINGLE_SELECT_FIELD_ID }}
UPDATE_FIELD_VALUE: ${{ needs.get_set_single_select_option_id.outputs.SINGLE_SELECT_OPTION_ID }}
secrets: inherit
Loading