1
+ #! /bin/bash
2
+
3
+
4
+ die () {
5
+ echo ::error::${@ }
6
+ exit 1
7
+ }
8
+
9
+ # Check if given required input variables
10
+ # are specified, and abort if not.
11
+ check_input () {
12
+ local varnames=" ${@ } "
13
+ local input_varname
14
+ local env_varname
15
+
16
+ if [ -n " ${varnames} " ]; then
17
+ for input_varname in ${varnames} ; do
18
+ env_varname=" INPUT_${input_varname^^} "
19
+ if [ -z " ${! env_varname} " ]; then
20
+ die " The required '${input_varname} ' input variable is not specified."
21
+ fi
22
+ done
23
+ fi
24
+ }
25
+
26
+ # Check if given required environment variables
27
+ # are specified, and abort if not.
28
+ check_event_env () {
29
+ local env_varname
30
+
31
+ for env_varname in GITHUB_REF GITHUB_EVENT_PATH; do
32
+ if [ -z " ${env_varname} " ]; then
33
+ die " The required '${env_varname} ' env variable is not specified."
34
+ fi
35
+ done
36
+ }
37
+
38
+ # Make a GET request to Github API v3
39
+ # Args:
40
+ # $1: The API path to request, e.g "/user"
41
+ # Environment:
42
+ # INPUT_GITHUB_TOKEN: GitHub token with appropriate scope
43
+ get () {
44
+ curl -sSL -X GET \
45
+ -H " Authorization: token ${INPUT_GITHUB_TOKEN} " \
46
+ -H " Accept: application/vnd.github.v3+json" \
47
+ -H " Accept: application/vnd.github.antiope-preview+json" \
48
+ " https://api.github.com${1} "
49
+ }
50
+
51
+ # Make a POST request to Github API v3
52
+ # Args:
53
+ # $1: The API path to request, e.g "/user"
54
+ # Stdin:
55
+ # POST request body.
56
+ # Environment:
57
+ # INPUT_GITHUB_TOKEN: GitHub token with appropriate scope
58
+ # Returns:
59
+ # HTTP response with numeric status on the last line.
60
+ post () {
61
+ curl -sSL -v -w " %{http_code}" \
62
+ -H " Authorization: token ${INPUT_GITHUB_TOKEN} " \
63
+ -H " Accept: application/vnd.github.v3+json" \
64
+ -H " Accept: application/vnd.github.antiope-preview+json" \
65
+ -d @- \
66
+ " https://api.github.com${1} "
67
+ }
68
+
69
+ _prepare_graphql_query () {
70
+ # Fold newlines and escape the quotes.
71
+ echo " ${1} " \
72
+ | sed -e ' :a' -e ' N' -e ' $!ba' -e ' s/\n/ /g' \
73
+ | sed -e ' s/"/\\"/g'
74
+ }
75
+
76
+ # Make a request to Github GraphQL API
77
+ # Args:
78
+ # $1: GraphQL query.
79
+ gql () {
80
+ local auth_header=" Authorization: bearer ${INPUT_GITHUB_TOKEN} "
81
+ echo {\" query\" : \" $( _prepare_graphql_query " ${1} " ) \" } \
82
+ | curl -sSL -H " ${auth_header} " -d @- " https://api.github.com/graphql"
83
+ }
84
+
85
+ # jq wrapper with raw output by default.
86
+ jqr () {
87
+ jq --raw-output " ${@ } "
88
+ }
89
+
90
+ # Run a jq operation on Github event JSON
91
+ # Args:
92
+ # $@: Arguments to jq.
93
+ jqevent () {
94
+ jqr " ${@ } " " ${GITHUB_EVENT_PATH} "
95
+ }
96
+
97
+ # Wrapper around GPG to make it behave in non-interactive mode.
98
+ # Args:
99
+ # $@: Arguments to gpg.
100
+ gpgb () {
101
+ /gpg-wrapper --batch --no-tty " ${@ } "
102
+ }
103
+
104
+ # Check if the specified user is a maintainer of a given repository.
105
+ # Args:
106
+ # $1: Github username.
107
+ # $2: Organization name.
108
+ # $3: Repository name.
109
+ is_maintainer () {
110
+ local perm
111
+ local request
112
+ local user=" ${1} "
113
+ local org=" ${2} "
114
+ local repo=" ${3} "
115
+
116
+ read -r -d ' ' request << EOF
117
+ {
118
+ organization(login: "${org} ") {
119
+ teams(first: 100, userLogins: ["${user} "]) {
120
+ edges {
121
+ node {
122
+ name
123
+ repositories(first: 100, query: "${repo} ") {
124
+ edges {
125
+ node {
126
+ name
127
+ }
128
+ permission
129
+ }
130
+ }
131
+ }
132
+ }
133
+ }
134
+ }
135
+ }
136
+ EOF
137
+ perm=$( gql " ${request} " \
138
+ | jqr " .data.organization.teams.edges[]?
139
+ | .node.repositories.edges[]
140
+ | select(.node.name == \" ${repo} \" )
141
+ | .permission" )
142
+
143
+ [[ " ${perm} " = * MAINTAIN* || " ${perm} " = * ADMIN* ]]
144
+ }
145
+
146
+ # Import the given GPG private key into the local keychain.
147
+ # Args:
148
+ # $1: GPG private key (suitable for gpg --import)
149
+ # $2: Optional key id to use for signatures. If not specified,
150
+ # and the input key contains only one signing subkey, that subkey
151
+ # is used.
152
+ # Returns:
153
+ # The id of the signing key.
154
+ import_gpg_key () {
155
+ local gpg_key=" ${1} "
156
+ local gpg_key_id=" ${2} "
157
+
158
+ if [ -n " ${gpg_key} " ]; then
159
+ if [ -z " ${gpg_key_id} " ]; then
160
+ gpg_key_id=$( echo " ${gpg_key} " \
161
+ | gpgb --import --import-options show-only --with-colons \
162
+ | grep ' ^sec:' \
163
+ | cut -f 5 -d' :' )
164
+
165
+ if [[ $( echo " ${gpg_key_id} " | wc -l) -gt 1 ]]; then
166
+ die " Multiple keys found in INPUT_GPG_KEY, please specify " \
167
+ " the key id via INPUT_GPG_KEY_ID" .
168
+ fi
169
+ fi
170
+
171
+ echo " ${gpg_key} " \
172
+ | gpgb --import
173
+ fi
174
+
175
+ echo " ${gpg_key_id} "
176
+ }
177
+
178
+ # Import the given SSH private key for the current user.
179
+ # Args:
180
+ # $1: SSH private key.
181
+ import_ssh_key () {
182
+ local ssh_key=" ${1} "
183
+
184
+ if [ -n " ${ssh_key} " ]; then
185
+ mkdir -p " ${HOME} /.ssh"
186
+ echo " ${ssh_key} " > " ${HOME} /.ssh/id_rsa"
187
+ chmod 600 " ${HOME} /.ssh/id_rsa"
188
+ fi
189
+ }
190
+
191
+ # Configure git using the information about the current Github user.
192
+ # Args:
193
+ # $1: Optional GPG key id to use for git object signing.
194
+ # Environment:
195
+ # INPUT_GITHUB_TOKEN: the token of a Github user to use for git operations.
196
+ configure_git () {
197
+ local gpg_key_id=" ${1} "
198
+ local user=$( get /user)
199
+ local login=$( echo " ${user} " | jqr .login)
200
+ local username=$( echo " ${user} " | jqr .name)
201
+ local email=$( echo " ${user} " | jqr .email)
202
+
203
+ git config --global user.name " ${username} "
204
+ git config --global user.email " ${email} "
205
+ git config --global gpg.program " /gpg-wrapper"
206
+ git config --global credential.helper " store --file=${HOME} /.git-credentials"
207
+ git config --global " credential.https://github.com.username" " ${login} "
208
+
209
+ echo " https://${login} :${INPUT_GITHUB_TOKEN} @github.com" \
210
+ >> " ${HOME} /.git-credentials"
211
+
212
+ chmod 600 " ${HOME} /.git-credentials"
213
+
214
+ if [ -n " ${gpg_key_id} " ]; then
215
+ git config --global commit.gpgsign true
216
+ git config --global user.signingkey " ${gpg_key_id} "
217
+ fi
218
+ }
0 commit comments