-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
198 lines (172 loc) · 8.93 KB
/
ci.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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
name: ci-workflow
# actors
# source repo: official terratest repo (gruntwork-io/terratest)
# forked repo: (e.g., xyz/terratest, abc/terratest)
# pr: created from forked repo, against source repo (gruntwork-io/terratest/pull/{PR NUMBER})
# flow
# developer fork the source repo
# developer creates a branch in the forked repo
# developer does the development 😎
# developer creates a pr
# webhook on source repo calls a webapp when the pr has been created
# this pipeline will be triggered automatically by the webapp, with the following input values
# repo: name of the forked repo (e.g. xyz/terratest)
# branch: branch name on the forked repo (e.g. feature/adding-some-important-module)
# target_repository: home of the target_pr, which is the source repo (gruntwork-io/terratest)
# target_pr: pr number on the source repo (e.g. 14, 25, etc.)
on:
push:
branches: master
workflow_dispatch:
inputs:
repo:
description: 'Repository info'
required: true
branch:
description: 'Name of the branch'
required: true
target_repository:
description: 'Name of the official terratest repo'
required: false
default: 'gruntwork-io/terratest'
target_pr:
description: 'PR number on the official terratest repo'
required: false
skip_provider_registration:
description: 'When set to true, terraform will skip provider registration (see: https://www.terraform.io/docs/providers/azurerm/index.html#skip_provider_registration for more information)'
required: true
default: 'false'
permissions:
contents: read
jobs:
ci-job:
runs-on: [ubuntu-latest]
steps:
- uses: hashicorp/setup-terraform@v1
with:
terraform_version: 0.15.1
terraform_wrapper: false
- name: checkout to repo
uses: actions/checkout@v2
with:
repository: ${{ github.event.inputs.repo }}
ref: ${{ github.event.inputs.branch }}
- name: install golangci-lint binary
run: |
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b ./bin v1.53.2
- name: lint modules/azure folder
id: azure_module_lint
run: |
# list files to be linted
[ -d "modules/azure" ] && ls -li "modules/azure"
# run the linter
./bin/golangci-lint run ./modules/azure/ --build-tags=azure --timeout 5m0s
- name: lint test/azure folder
id: azure_test_lint
run: |
# list files to be linted
[ -d "test/azure" ] && ls -li "test/azure"
# run the linter
./bin/golangci-lint run ./test/azure/ --build-tags=azure --timeout 5m0s
- name: run terraform format
id: azure_terraform_format
run: terraform fmt -check -recursive ./examples/azure
- name: login to azure cli
uses: azure/login@v1.1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: run go unit test for azure
id: azure_unit_test
env:
AZURE_CREDENTIALS: ${{ secrets.AZURE_CREDENTIALS }}
run: |
cd modules
APP_ID=`echo $AZURE_CREDENTIALS | jq -r -c ".clientId"`
APP_PASSWORD=`echo $AZURE_CREDENTIALS | jq -r -c ".clientSecret"`
TENANT_ID=`echo $AZURE_CREDENTIALS | jq -r -c ".tenantId"`
# if clientId, subscriptionId, tenantId doesn't provide to the go tests
# by default, terratest reads them from below environment variables
export ARM_CLIENT_ID="$APP_ID"
export ARM_CLIENT_SECRET="$APP_PASSWORD"
export ARM_SUBSCRIPTION_ID=`az account show --query "id" --output tsv`
export ARM_TENANT_ID="$TENANT_ID"
export ARM_SKIP_PROVIDER_REGISTRATION=${{ github.event.inputs.skip_provider_registration }}
# run the unit tests under the `azure` subfolder
go test ./azure/* -v -timeout 90m
- name: run go test for azure
id: azure_test
env:
AZURE_CREDENTIALS: ${{ secrets.AZURE_CREDENTIALS }}
run: |
cd test/azure
APP_ID=`echo $AZURE_CREDENTIALS | jq -r -c ".clientId"`
APP_PASSWORD=`echo $AZURE_CREDENTIALS | jq -r -c ".clientSecret"`
TENANT_ID=`echo $AZURE_CREDENTIALS | jq -r -c ".tenantId"`
# if clientId, subscriptionId, tenantId doesn't provide to the go tests
# by default, terratest reads them from below environment variables
export ARM_CLIENT_ID="$APP_ID"
export ARM_CLIENT_SECRET="$APP_PASSWORD"
export ARM_SUBSCRIPTION_ID=`az account show --query "id" --output tsv`
export ARM_TENANT_ID="$TENANT_ID"
export ARM_SKIP_PROVIDER_REGISTRATION=${{ github.event.inputs.skip_provider_registration }}
# some resources may require ssh keys (e.g. Kubernetes, VMs, etc.)
# terraform will read below environment variables
# if those values didn't provide to the terraform explicitly
rm -rf ssh_key*
ssh-keygen -m PEM -t rsa -b 4096 -f ./ssh_key -q -N ""
export TF_VAR_ssh_public_key="$PWD/ssh_key.pub"
export TF_VAR_client_id="$APP_ID"
export TF_VAR_client_secret="$APP_PASSWORD"
# run the actual tests under the `azure` subfolder
go test --tags=azure -v -timeout 90m
- name: report back the result
if: always()
env:
CURRENT_REPOSITORY: ${{ github.repository }}
RUN_ID: ${{ github.run_id }}
GITHUB_TOKEN: ${{ secrets.PAT }}
TARGET_REPOSITORY: ${{ github.event.inputs.target_repository }}
TARGET_PR: ${{ github.event.inputs.target_pr }}
TEST_RESULT: ${{ steps.azure_test.conclusion }}
TEST_LINT_RESULT: ${{ steps.azure_test_lint.conclusion }}
MODULE_LINT_RESULT: ${{ steps.azure_module_lint.conclusion }}
run: |
# if no PR number provided, simply exit...
[[ -z "$TARGET_PR" ]] && { echo "No PR Number provided, exiting..." ; exit 0; }
# if no PAT provided, simply exit...
[[ -z "$GITHUB_TOKEN" ]] && { echo "No PAT provided, exiting..." ; exit 0; }
echo "PR Number provided... ${TARGET_REPOSITORY}:#${TARGET_PR}"
BODY_PAYLOAD=""
# if all the previous steps finished successfully, create a comment on the PR with the "success" information
if [ "$TEST_RESULT" == "success" ] && [ "$TEST_LINT_RESULT" == "success" ] && [ "$MODULE_LINT_RESULT" == "success" ]; then
BODY_PAYLOAD="[Microsoft CI Bot] TL;DR; success :thumbsup:\n\nYou can check the status of the CI Pipeline logs here ; https://github.com/${CURRENT_REPOSITORY}/actions/runs/$RUN_ID"
# if at least one of the previous steps failed, create a comment on the PR with the "failure" information
elif [ "$TEST_RESULT" == "failure" ] || [ "$TEST_LINT_RESULT" == "failure" ] || [ "$MODULE_LINT_RESULT" == "failure" ]; then
BODY_PAYLOAD="[Microsoft CI Bot] TL;DR; failure :facepalm:\n\nYou can check the status of the CI Pipeline logs here ; https://github.com/${CURRENT_REPOSITORY}/actions/runs/$RUN_ID"
fi
echo "Comment message is ready..."
echo "${BODY_PAYLOAD}"
# if pipeline has something to report back to the PR
if [[ -z "$BODY_PAYLOAD" ]]
then
echo "BODY_PAYLOAD is empty"
else
echo "Here is the target repository: ${TARGET_REPOSITORY}"
# TARGET_REPOSITORY is in {owner}/{repo format}
[[ $TARGET_REPOSITORY =~ (.*)/(.*)$ ]]
# take the {owner} piece from the TARGET_REPOSITORY variable
TARGET_REPO_OWNER=${BASH_REMATCH[1]}
# take the {repo} piece from the TARGET_REPOSITORY variable
TARGET_REPO_NAME=${BASH_REMATCH[2]}
echo "Target repository is parsed: ${TARGET_REPO_OWNER} <-> ${TARGET_REPO_NAME}"
# create the query string to get the pr id
QUERY_PR_ID="query findPRID { repository(owner: \\\"$TARGET_REPO_OWNER\\\", name: \\\"$TARGET_REPO_NAME\\\") { pullRequest(number: $TARGET_PR) { id } } }"
# get the pr id from github api
PR_ID=$(curl --silent --request POST --header "Authorization: Bearer ${GITHUB_TOKEN}" --data-raw "{\"query\":\"${QUERY_PR_ID}\"}" "https://api.github.com/graphql" | jq -r '.data.repository.pullRequest.id')
echo "Target PR ID is ${PR_ID}"
# create the mutation string to create the comment on the pr
MUTATION_ADD_COMMENT="mutation addComment { addComment(input: {subjectId: \\\"${PR_ID}\\\", body: \\\"${BODY_PAYLOAD}\\\"}) { commentEdge { node { createdAt body } } subject { id } } }"
# call the github api to create the comment
curl --request POST --header "Authorization: Bearer ${GITHUB_TOKEN}" --data-raw "{\"query\":\"${MUTATION_ADD_COMMENT}\"}" "https://api.github.com/graphql"
echo "Comment is created..."
fi