-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature: user based project support (#13)
* implemented user based project beta support * Update action.yml * Added user field * Removed organization requirement * Added precondition checks for user and organization field * Added user based project beta execution * added documentation related to user based project automation
- Loading branch information
1 parent
35944de
commit e71cc18
Showing
4 changed files
with
274 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,8 @@ Note: GITHUB_TOKEN does not have the necessary scopes to access projects (beta). | |
You must create a token with ***org:write*** scope and save it as a secret in your repository or organization. | ||
In the following workflow, replace ***YOUR_TOKEN*** with the name of the secret. For more information, see [Creating a personal access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token). | ||
|
||
Organization based: | ||
|
||
```yaml | ||
name: Project automations | ||
on: | ||
|
@@ -30,7 +32,7 @@ jobs: | |
if: github.event_name == 'issues' && github.event.action == 'opened' || github.event.action == 'reopened' | ||
steps: | ||
- name: 'Move issue to "Todo"' | ||
uses: leonsteinhaeuser/[email protected].1 | ||
uses: leonsteinhaeuser/[email protected].2 | ||
with: | ||
gh_token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} | ||
organization: sample-org | ||
|
@@ -43,7 +45,7 @@ jobs: | |
if: github.event_name == 'issues' && github.event.action == 'closed' | ||
steps: | ||
- name: 'Moved issue to "Done"' | ||
uses: leonsteinhaeuser/[email protected].1 | ||
uses: leonsteinhaeuser/[email protected].2 | ||
with: | ||
gh_token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} | ||
organization: sample-org | ||
|
@@ -56,7 +58,7 @@ jobs: | |
if: github.event_name == 'pull_request' && github.event.action == 'opened' || github.event.action == 'reopened' || github.event.action == 'review_requested' | ||
steps: | ||
- name: 'Move PR to "In Progress"' | ||
uses: leonsteinhaeuser/[email protected].1 | ||
uses: leonsteinhaeuser/[email protected].2 | ||
with: | ||
gh_token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} | ||
organization: sample-org | ||
|
@@ -69,7 +71,7 @@ jobs: | |
if: github.event_name == 'pull_request' && github.event.action == 'ready_for_review' | ||
steps: | ||
- name: 'Move PR to "Ready for Review"' | ||
uses: leonsteinhaeuser/[email protected].1 | ||
uses: leonsteinhaeuser/[email protected].2 | ||
with: | ||
gh_token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} | ||
organization: sample-org | ||
|
@@ -82,11 +84,96 @@ jobs: | |
if: github.event_name == 'pull_request' && github.event.action == 'closed' | ||
steps: | ||
- name: 'Move PR to "Closed"' | ||
uses: leonsteinhaeuser/[email protected].1 | ||
uses: leonsteinhaeuser/[email protected].2 | ||
with: | ||
gh_token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} | ||
organization: sample-org | ||
project_id: 1 | ||
resource_node_id: ${{ github.event.pull_request.node_id }} | ||
status_value: "Done" | ||
``` | ||
User based: | ||
```yaml | ||
name: Project automations | ||
on: | ||
issues: | ||
types: | ||
- opened | ||
- reopened | ||
- closed | ||
pull_request: | ||
types: | ||
- opened | ||
- ready_for_review | ||
- reopened | ||
- review_requested | ||
- closed | ||
jobs: | ||
issue_opened_and_reopened: | ||
name: issue_opened_and_reopened | ||
runs-on: ubuntu-latest | ||
if: github.event_name == 'issues' && github.event.action == 'opened' || github.event.action == 'reopened' | ||
steps: | ||
- name: 'Move issue to "Todo"' | ||
uses: leonsteinhaeuser/[email protected] | ||
with: | ||
gh_token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} | ||
user: sample-user | ||
project_id: 1 | ||
resource_node_id: ${{ github.event.issue.node_id }} | ||
status_value: "Todo" | ||
issue_closed: | ||
name: issue_closed | ||
runs-on: ubuntu-latest | ||
if: github.event_name == 'issues' && github.event.action == 'closed' | ||
steps: | ||
- name: 'Moved issue to "Done"' | ||
uses: leonsteinhaeuser/[email protected] | ||
with: | ||
gh_token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} | ||
user: sample-user | ||
project_id: 1 | ||
resource_node_id: ${{ github.event.issue.node_id }} | ||
status_value: "Done" | ||
pr_opened_reopened_review_requested: | ||
name: pr_opened_reopened_review_requested | ||
runs-on: ubuntu-latest | ||
if: github.event_name == 'pull_request' && github.event.action == 'opened' || github.event.action == 'reopened' || github.event.action == 'review_requested' | ||
steps: | ||
- name: 'Move PR to "In Progress"' | ||
uses: leonsteinhaeuser/[email protected] | ||
with: | ||
gh_token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} | ||
user: sample-user | ||
project_id: 1 | ||
resource_node_id: ${{ github.event.pull_request.node_id }} | ||
status_value: "In Progress" | ||
pr_ready_for_review: | ||
name: pr_ready_for_review | ||
runs-on: ubuntu-latest | ||
if: github.event_name == 'pull_request' && github.event.action == 'ready_for_review' | ||
steps: | ||
- name: 'Move PR to "Ready for Review"' | ||
uses: leonsteinhaeuser/[email protected] | ||
with: | ||
gh_token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} | ||
user: sample-user | ||
project_id: 1 | ||
resource_node_id: ${{ github.event.pull_request.node_id }} | ||
status_value: "Ready for Review" | ||
pr_closed: | ||
name: pr_closed | ||
runs-on: ubuntu-latest | ||
if: github.event_name == 'pull_request' && github.event.action == 'closed' | ||
steps: | ||
- name: 'Move PR to "Closed"' | ||
uses: leonsteinhaeuser/[email protected] | ||
with: | ||
gh_token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} | ||
user: sample-user | ||
project_id: 1 | ||
resource_node_id: ${{ github.event.pull_request.node_id }} | ||
status_value: "Done" | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#!/bin/bash | ||
|
||
organization_name=$1 # organization name | ||
organization_project_id=$2 # organization id | ||
resource_id=$3 # pr or issue node id | ||
status_value=$4 # text representation of the card | ||
|
||
# load lib bash functions | ||
source gh_api_lib_user.sh | ||
|
||
# request gh api and returns the project settings | ||
getProject $organization_name $organization_project_id | ||
|
||
PROJECT_ID=$(extractProjectID) | ||
|
||
ITEM_ID=$(getItemID $PROJECT_ID $resource_id) | ||
|
||
STATUS_FIELD_ID=$(extractStatusFieldID) | ||
# select field values | ||
status_value_OPTION_ID=$(extractStatusFieldNodeSettingsByValue "$status_value") | ||
|
||
echo "PROJECT_ID: $PROJECT_ID" | ||
echo "ITEM_ID: $ITEM_ID" | ||
echo "STATUS_FIELD_ID: $STATUS_FIELD_ID" | ||
echo "status_value_OPTION_ID: $status_value_OPTION_ID" | ||
|
||
# update single select field | ||
updateSingleSelectField "$PROJECT_ID" "$ITEM_ID" "$STATUS_FIELD_ID" "$status_value_OPTION_ID" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
#!/bin/bash | ||
|
||
TMP_STORE_LOCATION=/tmp/api_response.json | ||
|
||
# getProject queries the github api for the specific project | ||
function getProject() { | ||
local USER=$1 | ||
local PROJECT_NUMBER=$2 | ||
gh api graphql --header 'GraphQL-Features: projects_next_graphql' -f query=' | ||
query($user: String!, $number: Int!) { | ||
user(login: $user){ | ||
projectNext(number: $number) { | ||
id | ||
fields(first:20) { | ||
nodes { | ||
id | ||
name | ||
settings | ||
} | ||
} | ||
} | ||
} | ||
}' -f user=$USER -F number=$PROJECT_NUMBER > $TMP_STORE_LOCATION | ||
} | ||
|
||
# extractProjectID returns the project id | ||
function extractProjectID() { | ||
echo $(jq '.data.user.projectNext.id' $TMP_STORE_LOCATION | sed -e "s+\"++g") | ||
} | ||
|
||
# extractStatusFieldID returns the status field id | ||
function extractStatusFieldID() { | ||
echo $(jq '.data.user.projectNext.fields.nodes[] | select(.name== "Status") | .id' $TMP_STORE_LOCATION | sed -e "s+\"++g") | ||
} | ||
|
||
# extractStatusFieldNodeSettingsByValue returns a list of available settings | ||
function extractStatusFieldNodeSettingsByValue() { | ||
local STATUS_NAME=$1 | ||
jq ".data.user.projectNext.fields.nodes[] | select(.name== \"Status\") | .settings | fromjson.options[] | select(.name==\"$STATUS_NAME\") |.id" $TMP_STORE_LOCATION | sed -e "s+\"++g" | ||
} | ||
|
||
# getItemID queries the github api for the specific item_id | ||
# Required arguments: | ||
# 1: project id | ||
# 2: resource node id | ||
function getItemID() { | ||
local project_id=$1 | ||
local resource_id=$2 | ||
gh api graphql --header 'GraphQL-Features: projects_next_graphql' -f query=' | ||
mutation($project:ID!, $resource_id:ID!) { | ||
addProjectNextItem(input: {projectId: $project, contentId: $resource_id}) { | ||
projectNextItem { | ||
id | ||
} | ||
} | ||
}' -f project=$project_id -f resource_id=$resource_id --jq '.data.addProjectNextItem.projectNextItem.id' | sed -e "s+\"++g" | ||
} | ||
|
||
# updateSingleSelectField updates the given item field with the defined value | ||
# Required arguments: | ||
# 1: project id | ||
# 2: project item id | ||
# 3: field id | ||
# 4: field option id | ||
function updateSingleSelectField() { | ||
local project_id=$1 | ||
local item_id=$2 | ||
local field_id=$3 | ||
local field_option=$4 | ||
echo $(gh api graphql --header 'GraphQL-Features: projects_next_graphql' -f query=' | ||
mutation ( | ||
$project: ID! | ||
$item: ID! | ||
$fieldid: ID! | ||
$fieldOption: ID! | ||
) { | ||
updateProjectNextItemField( | ||
input: { | ||
projectId: $project | ||
itemId: $item | ||
fieldId: $fieldid | ||
value: $fieldOption | ||
} | ||
) | ||
{ | ||
projectNextItem { | ||
id | ||
} | ||
} | ||
}' -f project=$project_id -f item=$item_id -f fieldid=$field_id -f fieldOption=$field_option | sed -e "s+\"++g") | ||
} | ||
|
||
# updateNonSingleSelectField updates the given item field with the defined value | ||
# Required arguments: | ||
# 1: project id | ||
# 2: project item id | ||
# 3: field id | ||
# 4: field value | ||
function updateNonSingleSelectField() { | ||
local PROJECT_ID=$1 | ||
local ITEM_ID=$2 | ||
local FIELD_ID=$3 | ||
local FIELD_VALUE$4 | ||
echo $(gh api graphql --header 'GraphQL-Features: projects_next_graphql' -f query=' | ||
mutation ( | ||
$project: ID! | ||
$item: ID! | ||
$fieldid: ID! | ||
$fieldOption: String! | ||
) { | ||
updateProjectNextItemField( | ||
input: { | ||
projectId: $project | ||
itemId: $item | ||
fieldId: $fieldid | ||
value: $fieldOption | ||
} | ||
) | ||
{ | ||
projectNextItem { | ||
id | ||
} | ||
} | ||
}' -f project=$PROJECT_ID -f item=$ITEM_ID -f fieldid=$FIELD_ID -f fieldOption=$FIELD_VALUE | sed -e "s+\"++g") | ||
} |