Skip to content

Commit 2d475e0

Browse files
authored
Merge pull request #2 from github/projectsv2
Update action for use with projectV2
2 parents e5c124d + 9bb06fe commit 2d475e0

File tree

2 files changed

+84
-51
lines changed

2 files changed

+84
-51
lines changed

README.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ jobs:
2828
runs-on: ubuntu-latest
2929
steps:
3030
- name: Update status
31-
uses: benbalter/update-project-action@v1
31+
uses: benbalter/update-project-action@v2
3232
with:
3333
github_token: ${{ secrets.STATUS_UPDATE_TOKEN }}
3434
organization: github
@@ -51,12 +51,15 @@ The Action is largely feature complete with regards to its initial goals. Find a
5151
* `organization` - The organization that contains the project, defaults to the current repository owner
5252
* `project_number` - The project number from the project's URL
5353
* `value` - The value to set the project field to
54-
5554
### Outputs
5655

5756
* `field_id` - The global ID of the field
58-
* `field_is_select` - Whether or not the field is a select field vs. free-form input
57+
* `field_type` - The updated field's ProjectV2FieldType (text, single_select, number, date, or iteration)
5958
* `item_id` - The global ID of the issue or pull request
6059
* `item_title` - The title of the issue or pull request
6160
* `option_id` - The global ID of the selected option
62-
* `project_id` - The global ID of the project
61+
* `project_id` - The global ID of the project
62+
63+
### V1 vs V2
64+
65+
In June 2022, [GitHub announced a breaking change to the Projects API](https://github.blog/changelog/2022-06-23-the-new-github-issues-june-23rd-update/). As such, the `@v1` tag of this action will cease working on October 1st, 2022. You can upgrade to the `@v2` tag (by updating the reference in your Workflow file) at any time.

action.yml

Lines changed: 77 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ outputs:
3333
field_id:
3434
description: "The global ID of the field"
3535
value: ${{ steps.parse_project_metadata.outputs.field_id }}
36-
field_is_select:
37-
description: "Whether or not the field is a select field vs. free-form input"
38-
value: ${{ steps.parse_project_metadata.outputs.field_is_select }}
36+
field_type:
37+
description: "The updated field's ProjectV2FieldType (text, single_select, number, date, or iteration)"
38+
value: ${{ steps.parse_project_metadata.outputs.field_type }}
3939
option_id:
4040
description: "The global ID of the selected option"
4141
value: ${{ steps.parse_project_metadata.outputs.option_id }}
@@ -52,36 +52,45 @@ runs:
5252
CONTENT_ID: ${{ inputs.content_id }}
5353
VALUE: ${{ inputs.value }}
5454
FILE_NAME: project-${{ inputs.organization }}-${{ inputs.project_number }}.json
55-
shell: bash
56-
run: |
57-
# Fetch project metadata
58-
if [ ! -f "$FILE_NAME" ]; then
59-
gh api graphql --header 'GraphQL-Features: projects_next_graphql' -f query='
60-
query($organization: String!, $project_number: Int!) {
61-
organization(login: $organization) {
62-
projectNext(number: $project_number) {
63-
id
64-
items(first: 100) {
65-
nodes {
66-
id
67-
content {
68-
... on Issue {
69-
id
70-
title
71-
}
55+
QUERY: |
56+
query ($organization: String!, $project_number: Int!) {
57+
organization(login: $organization) {
58+
projectV2(number: $project_number) {
59+
id
60+
items(first: 100) {
61+
nodes {
62+
id
63+
content {
64+
... on Issue {
65+
id
66+
title
7267
}
7368
}
7469
}
75-
fields(first: 25) {
76-
nodes {
70+
}
71+
fields(first: 25) {
72+
nodes {
73+
... on ProjectV2FieldCommon {
7774
id
7875
name
79-
settings
76+
dataType
77+
}
78+
... on ProjectV2SingleSelectField {
79+
options {
80+
id
81+
name
82+
}
8083
}
8184
}
8285
}
8386
}
84-
}' -F project_number=$PROJECT_NUMBER -f organization=$ORGANIZATION > "$FILE_NAME"
87+
}
88+
}
89+
shell: bash
90+
run: |
91+
# Fetch project metadata
92+
if [ ! -f "$FILE_NAME" ]; then
93+
gh api graphql -f query="$QUERY" -F project_number=$PROJECT_NUMBER -F organization=$ORGANIZATION > "$FILE_NAME"
8594
else
8695
echo "Using cached project metadata from '$FILE_NAME'"
8796
fi
@@ -98,12 +107,12 @@ runs:
98107
FILE_NAME: ${{ steps.fetch_project_metadata.outputs.file_name }}
99108
run: |
100109
# Parse project metadata
101-
echo '::set-output name=project_id::'$(jq -r '.data.organization.projectNext.id' "$FILE_NAME")
102-
echo '::set-output name=item_id::'$(jq -r '.data.organization.projectNext.items.nodes[] | select(.content.id==$CONTENT_ID) | .id' "$FILE_NAME" --arg CONTENT_ID "$CONTENT_ID")
103-
echo '::set-output name=item_title::'$(jq -r '.data.organization.projectNext.items.nodes[] | select(.content.id==$CONTENT_ID) | .content.title' "$FILE_NAME" --arg CONTENT_ID "$CONTENT_ID")
104-
echo '::set-output name=field_id::'$(jq -r '.data.organization.projectNext.fields.nodes[] | select(.name==$FIELD) | .id' "$FILE_NAME" --arg FIELD "$FIELD")
105-
echo '::set-output name=field_is_select::'$(jq -r '.data.organization.projectNext.fields.nodes[] | select(.name==$FIELD) | .settings | fromjson | has("options")' "$FILE_NAME" --arg FIELD "$FIELD")
106-
echo '::set-output name=option_id::'$(jq -r '.data.organization.projectNext.fields.nodes[] | select(.name==$FIELD) | .settings | fromjson | .options[]? | select(.name | contains($VALUE)) | .id' "$FILE_NAME" --arg VALUE "$VALUE" --arg FIELD "$FIELD")
110+
echo '::set-output name=project_id::'$(jq -r '.data.organization.projectV2.id' "$FILE_NAME")
111+
echo '::set-output name=item_id::'$(jq -r '.data.organization.projectV2.items.nodes[] | select(.content.id==$CONTENT_ID) | .id' "$FILE_NAME" --arg CONTENT_ID "$CONTENT_ID")
112+
echo '::set-output name=item_title::'$(jq -r '.data.organization.projectV2.items.nodes[] | select(.content.id==$CONTENT_ID) | .content.title' "$FILE_NAME" --arg CONTENT_ID "$CONTENT_ID")
113+
echo '::set-output name=field_id::'$(jq -r '.data.organization.projectV2.fields.nodes[] | select(.name==$FIELD) | .id' "$FILE_NAME" --arg FIELD "$FIELD")
114+
echo '::set-output name=field_type::'$(jq -r '.data.organization.projectV2.fields.nodes[] | select(.name==$FIELD) | .dataType | ascii_downcase' "$FILE_NAME" --arg FIELD "$FIELD")
115+
echo '::set-output name=option_id::'$(jq -r '.data.organization.projectV2.fields.nodes[] | select(.name==$FIELD) | .options[]? | select(.name | contains($VALUE)) | .id' "$FILE_NAME" --arg VALUE "$VALUE" --arg FIELD "$FIELD")
107116
108117
- name: Ensure project, item, field, and option were found
109118
env:
@@ -115,53 +124,74 @@ runs:
115124
PROJECT_ID: ${{ steps.parse_project_metadata.outputs.project_id }}
116125
ITEM_ID: ${{ steps.parse_project_metadata.outputs.item_id }}
117126
FIELD_ID: ${{ steps.parse_project_metadata.outputs.field_id }}
118-
FIELD_IS_SELECT: ${{ steps.parse_project_metadata.outputs.field_is_select }}
127+
FIELD_TYPE: ${{ steps.parse_project_metadata.outputs.field_type }}
119128
OPTION_ID: ${{ steps.parse_project_metadata.outputs.option_id }}
120129
shell: bash
121130
run: |
122131
# Ensure project, item, field, and option were found
123132
if [ -z "$PROJECT_ID" ] || [ "$PROJECT_ID" = "null" ]; then echo "Project '$PROJECT_NUMBER' not found for organization '$ORGANIZATION'"; exit 1; fi
124133
if [ -z "$ITEM_ID" ]; then echo "Item not found with ID '$CONTENT_ID'"; exit 1; fi
125134
if [ -z "$FIELD_ID" ]; then echo "Field '$FIELD' not found"; exit 1; fi
126-
if [[ "$FIELD_IS_SELECT" = "true" && -z "$OPTION_ID" ]]; then echo "Option not found with value '$VALUE'"; exit 1; fi
135+
if [[ "$FIELD_TYPE" = "single_select" && -z "$OPTION_ID" ]]; then echo "Option not found with value '$VALUE'"; exit 1; fi
136+
137+
- name: Parse value
138+
shell: bash
139+
id: parse_value
140+
env:
141+
FIELD_TYPE: ${{ steps.parse_project_metadata.outputs.field_type }}
142+
OPTION_ID: ${{ steps.parse_project_metadata.outputs.option_id }}
143+
VALUE: ${{ inputs.value }}
144+
run: |
145+
# Parse value
146+
if [ "$FIELD_TYPE" = "single_select" ]; then
147+
echo "::set-output name=value_to_set::$OPTION_ID"
148+
echo '::set-output name=value_type::singleSelectOptionId'
149+
else
150+
echo "::set-output name=value_to_set::$VALUE"
151+
echo "::set-output name=value_type::$FIELD_TYPE"
152+
fi
153+
154+
# Set GraphQL Field Type
155+
if [ "$FIELD_TYPE" = "date" ]; then
156+
echo '::set-output name=value_graphql_type::Date'
157+
elif [ "$FIELD_TYPE" = "number" ]; then
158+
echo '::set-output name=value_graphql_type::Float'
159+
else
160+
echo '::set-output name=value_graphql_type::String'
161+
fi
127162
128163
- name: Update field
129164
env:
130165
GITHUB_TOKEN: ${{ inputs.github_token }}
131166
FIELD: ${{ inputs.field }}
132-
VALUE: ${{ inputs.value }}
133167
PROJECT_ID: ${{ steps.parse_project_metadata.outputs.project_id }}
134168
ITEM_ID: ${{ steps.parse_project_metadata.outputs.item_id }}
135169
FIELD_ID: ${{ steps.parse_project_metadata.outputs.field_id }}
136-
FIELD_IS_SELECT: ${{ steps.parse_project_metadata.outputs.field_is_select }}
137-
OPTION_ID: ${{ steps.parse_project_metadata.outputs.option_id }}
138170
ITEM_TITLE: ${{ steps.parse_project_metadata.outputs.item_title }}
171+
VALUE_TO_SET: ${{ steps.parse_value.outputs.value_to_set }}
172+
VALUE: ${{ inputs.value }}
139173
QUERY: |
140-
mutation($project: ID!, $item: ID!, $field: ID!, $value: String!) {
141-
updateProjectNextItemField(
174+
mutation($project: ID!, $item: ID!, $field: ID!, $value: ${{ steps.parse_value.outputs.value_graphql_type }}) {
175+
updateProjectV2ItemFieldValue(
142176
input: {
143177
projectId: $project
144178
itemId: $item
145179
fieldId: $field
146-
value: $value
180+
value: {
181+
${{ steps.parse_value.outputs.value_type }}: $value
182+
}
147183
}
148184
) {
149-
projectNextItem {
185+
projectV2Item {
150186
id
151187
}
152188
}
153189
}
154190
155191
shell: bash
156192
run: |
157-
# Update field
158-
if [ "$FIELD_IS_SELECT" = "true" ]; then
159-
export VALUE_TO_SET="$OPTION_ID"
160-
else
161-
export VALUE_TO_SET="$VALUE"
162-
fi
163-
164-
gh api graphql --header 'GraphQL-Features: projects_next_graphql' -f query="$QUERY" -f project=$PROJECT_ID -f item=$ITEM_ID -f field=$FIELD_ID -f value="$VALUE_TO_SET"
193+
# Update project
194+
gh api graphql -f query="$QUERY" -F project=$PROJECT_ID -F item=$ITEM_ID -F field=$FIELD_ID -F value="$VALUE_TO_SET"
165195
166196
echo ""
167197
echo "Updated field '$FIELD' on '$ITEM_TITLE' to '$VALUE'. Happy reporting! 📈"

0 commit comments

Comments
 (0)