-
Notifications
You must be signed in to change notification settings - Fork 0
176 lines (162 loc) · 7.15 KB
/
add_all_pr_to_project_cron.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# This workflow finds all PRs in all repos and adds them to the
# project if they have the right label
name: PR automation
on:
# schedule:
# # * is a special character in YAML so you have to quote this string
# - cron: '30 5,17 * * *'
workflow_dispatch:
jobs:
get_repos:
name: Get all repositories
runs-on: ubuntu-latest
outputs:
repos: ${{ steps.get_repo.outputs.repositories }}
steps:
- name: Get current repositories
id: get_repo
env:
GH_TOKEN: ${{ secrets.LAB_PAT }}
MAX_REPO: 50
run: |
repo_list=$(gh repo list $GITHUB_REPOSITORY_OWNER --no-archived -L ${MAX_REPO} --json owner,name --jq '.[] | "\(.owner.login)/\(.name)"' | jq -cnR '[inputs | select(length>0)]')
echo "repositories=${repo_list}" >> $GITHUB_OUTPUT
add2project:
runs-on: ubuntu-latest
name: ${{ matrix.repo }} <- ${{ github.event.label.name }} (${{github.event.action}})
needs: get_repos
strategy:
matrix:
repo: ${{fromJSON(needs.get_repos.outputs.repos)}}
steps:
- name: find all PRs
id: repo_pr
run: |
echo ${{ matrix.repo }}
- name: Check if label of interest is applied
id: preview_label_check
uses: docker://agilepathway/pull-request-label-checker:latest
with:
any_of: _bot,_community
repo_token: ${{ secrets.NB_PROJECT_PAT }}
allow_failure: true
- name: Detect if PR is in project
if: steps.preview_label_check.outputs.label_check == 'success'
id: in_project
env:
GH_TOKEN: ${{ secrets.NB_PROJECT_PAT }}
run: |
gh pr view ${{ github.event.pull_request.html_url }} --json projectItems | jq -r '.projectItems[].title' | grep Neurobagel
continue-on-error: true
- name: Add PR to Project
if: steps.in_project.outcome == 'failure' && steps.preview_label_check.outputs.label_check == 'success'
uses: actions/add-to-project@main
with:
project-url: https://github.com/orgs/neurobagel/projects/1
github-token: ${{ secrets.NB_PROJECT_PAT }}
# Note that in contrast to the graphical github UI,
# once a PR (or other item) is added to a github project,
# project related changes are no longer applied directly to the PR
# but instead to the project card that contains the PR.
# Once the PR is added to the project (and thus has a project card)
# we therefore have to search for the node id of the containing project card
# and then set the Status and Community option on the project card.
#
# This step expects to find the id of the (parent) project card
# and will fail (crashing the entire workflow) otherwise
- name: Find project card container
if: steps.preview_label_check.outputs.label_check == 'success'
id: find_container
env:
GH_TOKEN: ${{ secrets.NB_PROJECT_PAT }}
run: |
out=$(newCursor=""
while true; do
response=$(gh api graphql -f query='{
organization(login: "neurobagel") {
projectV2(number: 1) {
items(first: 100, orderBy: {field: POSITION, direction: DESC}, after: "'"${newCursor}"'") {
edges {
cursor
node {
content {
... on PullRequest {
childID: id
}
}
parentID: id
}
}
}
}
}
}')
# Because we may not be able to find the parent ID in the first 100 items
# we have to keep advancing the cursor to move through the list
# Note: we use 100 items to balance speed and API limits, might have to be changed
while read -r pID cID cursor; do
if [ "$cID" == "${{ github.event.pull_request.node_id }}" ];
then
echo $pID;
exit 0;
fi
newCursor="$cursor"
# Note: we need to use the here string
# to avoid running the while loop in a subshell that would not let us access newCursor
# after the while loop has finished
# see: https://tldp.org/LDP/abs/html/subshells.html
done <<< $(echo "$response" | jq -r '.data.organization.projectV2.items.edges[] | "\(.node.parentID) \(.node.content.childID) \(.cursor)"')
if [ ! -n "$newCursor" ]; then
# We have passed through the entire list of items
# and didn't find the project card for our PR.
# Something is wrong and we will now crash the workflow.
exit 1;
fi
done
)
echo "parent_id=${out}" >> $GITHUB_OUTPUT
# This step expects a custom field called "Status"
# with an option called "Community" to exist in the project.
# We need their IDs as input for our later call to the API
# to move our PR project card to the "Community" column.
#
# We make them available to other steps in this job
# by writing them to the GITHUB_OUTPUT environment variable.
# see: https://docs.github.com/en/actions/using-jobs/defining-outputs-for-jobs
- name: Get IDs for Status field and Community option
if: steps.preview_label_check.outputs.label_check == 'success'
id: get_id
env:
GH_TOKEN: ${{ secrets.NB_PROJECT_PAT }}
FIELD: "Status"
OPTION: "Community"
run: |
response=$(gh api graphql -f query='{
organization(login: "neurobagel") {
projectV2(number: 1) {
field(name: "'"${FIELD}"'") {
... on ProjectV2SingleSelectField {
fieldID: id
options(names: "'"${OPTION}"'") {
optionID: id
}
}
}
}
}
}' | jq '.data.organization.projectV2.field | "\(.fieldID) \(.options[0].optionID)"')
read fieldID optionID <<< "${response//\"}"
echo "fieldID=${fieldID}" >> $GITHUB_OUTPUT
echo "optionID=${optionID}" >> $GITHUB_OUTPUT
- name: Set "Status" of PR to "Community"
if: steps.preview_label_check.outputs.label_check == 'success'
env:
GH_TOKEN: ${{ secrets.NB_PROJECT_PAT }}
run: |
gh api graphql -f query='mutation {
updateProjectV2ItemFieldValue(
input: {projectId: "PVT_kwDOBaeejM4AAQiP", itemId: "${{ steps.find_container.outputs.parent_id }}", fieldId: "${{ steps.get_id.outputs.fieldID }}", value: {singleSelectOptionId: "${{ steps.get_id.outputs.optionID }}"}}
) {
clientMutationId
}
}'