-
Notifications
You must be signed in to change notification settings - Fork 2
/
action.yml
145 lines (132 loc) · 6.79 KB
/
action.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
name: 'ApproveOps - Approvals in IssueOps'
description: 'IssueOps (ChatOps) workflows that require Approvals from someone in a designated GitHub team'
branding:
icon: "user-check"
color: "blue"
inputs:
approve-command:
description: "The command to look for in the comments; e.g.: /approve"
required: true
default: '/approve'
team-name:
description: "The name of the team in GitHub to check for the approval command; e.g.: approver-team"
required: true
token:
description: "GitHub App installation token or PAT that has access to read the comments and check the org team's membership"
required: true
default: ${{ github.token }} # this doesn't allow tagging of the approval team; better to use GitHub App
fail-if-approval-not-found:
description: "Fail the action (i.e. show the action run as red) if the command is not found in the comments from someone in the approver team"
required: true
default: 'true'
post-successful-approval-comment:
description: "Boolean whether to post successful approval comment"
required: true
default: 'true'
successful-approval-comment:
description: "Comment to post if an approval is found"
required: true
default: ":tada: You were able to run the workflow because someone left an approval in the comments!!"
outputs:
approved:
description: "Returns 'true' if the approval command was found in a comment from someone in the approver team, otherwise 'false'"
value: ${{ steps.check-approval.outputs.approved }}
runs:
using: "composite"
steps:
- id: check-approval
name: check if there is an approve command from authorized party
env:
GH_TOKEN: ${{ inputs.token }}
shell: bash
run: |
# "checking for a ${{ inputs.approve-command }} command in the comments from someone in the ${{ inputs.team-name}} team"
# prerequisite check
for cmd in gh jq; do
if ! command -v $cmd &> /dev/null; then
echo "::error title=${cmd} not installed::Could not find \`${cmd}\` on the runner"
exit 1
fi
done
# checking team and getting team membership"
echo "getting team membership for the team: @${{ github.repository_owner }}/${{ inputs.team-name }} ..."
users=$(gh api --paginate '${{ github.event.organization.url }}/teams/${{ inputs.team-name }}/members' --jq '.[].login' 2> /dev/null) || { echo "::error title=Team doesn't exist or token doesn't have access::The ${{ inputs.team-name }} team doesn't exist or the token doesn't have access to it"; exit 1; }
approveCommand="${{ inputs.approve-command }}"
authorized=false
comments=$(gh api --paginate ${{ github.event.issue.comments_url }})
for comment in $(echo $comments | jq -r '.[] | @base64'); do
body=$(echo $comment | base64 --decode | jq -r '.body' | tr -d ' ' | tr -d '\r\n')
actor=$(echo $comment | base64 --decode | jq -r '.user.login')
id=$(echo $comment | base64 --decode | jq -r '.id')
if [[ $body == "$approveCommand" ]]; then
echo "Approval command found in comment id $id ..."
echo $users | grep -q $actor && echo "Found $actor in team: ${{ inputs.team-name }}" && authorized=true || echo "Not found $actor in team: ${{ inputs.team-name }}"
break
else
echo "Approval command not found in comment id $id ..."
fi
done
if $authorized; then
echo "Approval authorized by $actor"
echo "approved=true" >> $GITHUB_OUTPUT
else
echo "Approval not found or not authorized"
echo "approved=false" >> $GITHUB_OUTPUT
if !(${{ inputs.fail-if-approval-not-found }}); then
echo "::notice title=Not Approved::There is no ${{ inputs.approve-command }} command in the comments from someone in the @${{ github.repository_owner }}/${{ inputs.team-name }} team"
fi
fi
- if: ${{ steps.check-approval.outputs.approved == 'false' && inputs.fail-if-approval-not-found == 'true' }}
name: Create completed comment
uses: actions/github-script@v6
with:
github-token: ${{ inputs.token }}
script: |
let commentBody = `Hey, @${{ github.event.comment.user.login }}!
:cry: No one approved your run yet! Have someone from the @${context.repo.owner}/${{ inputs.team-name }} team comment \`${{ inputs.approve-command }}\` and then try your command again
_:no_entry_sign: :no_entry: Marking the [workflow run](${{ github.event.repository.html_url }}/actions/runs/${{ github.run_id }}) as failed_
`
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: commentBody
})
- if: ${{ steps.check-approval.outputs.approved == 'false' && inputs.fail-if-approval-not-found == 'false' }}
name: Create completed comment
uses: actions/github-script@v6
with:
github-token: ${{ inputs.token }}
script: |
let commentBody = `Hey, @${{ github.event.comment.user.login }}!
:cry: No one approved your run yet! Have someone from the @${context.repo.owner}/${{ inputs.team-name }} team run `${{ inputs.approve-command }}` and then try your command again
_:warning: :pause_button: See [workflow run](${{ github.event.repository.html_url }}/actions/runs/${{ github.run_id }}) for reference_
`
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: commentBody
})
- if: ${{ steps.check-approval.outputs.approved == 'true' && inputs.post-successful-approval-comment == 'true' }}
name: Create completed comment
uses: actions/github-script@v6
with:
github-token: ${{ inputs.token }}
script: |
let commentBody = `Hey, @${{ github.event.comment.user.login }}!
${{ inputs.successful-approval-comment }}
`
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: commentBody
})
# if specified, exit with an error if approval is not found
- name: exit and fail workflow if not approved
if: ${{ inputs.fail-if-approval-not-found == 'true' && steps.check-approval.outputs.approved == 'false' }}
uses: actions/github-script@v6
with:
script: |
core.setFailed(`There is no ${{ inputs.approve-command }} command in the comments from someone in the @${context.repo.owner}/${{ inputs.team-name }} team`);