-
Notifications
You must be signed in to change notification settings - Fork 0
209 lines (185 loc) · 7.38 KB
/
Copy pathpr_ci.yml
File metadata and controls
209 lines (185 loc) · 7.38 KB
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
199
200
201
202
203
204
205
206
207
208
209
name: (sub) PR CI
permissions:
contents: read
id-token: write
on:
workflow_call:
inputs:
terratest_action:
description: The action (name of a test in Terratest) that will be passed to the Makefile's ACTION parameter
type: string
required: true
fail_fast:
description: When set to true, GitHub will cancel all in-progress and queued jobs in the matrix if any job in the matrix fails.
type: boolean
default: true
validate_max_parallel:
description: Maximum parallel jobs in matrix strategy for running validation
type: number
default: 5
test_max_parallel:
description: Maximum parallel jobs in matrix strategy for running Terratest
type: number
default: 5
apply_timeout:
description: Maximum time to run the Terraform apply step
type: number
default: 30
tf_version:
description: A space delimited list of TF versions used to run the code with
type: string
default: latest
cloud:
description: "Decide against which public cloud the code will be run. Possible values: azure, aws, gcp"
type: string
required: true
pre-commit-hooks:
description: "Pre-commit hook list. Possible values are a combination of any of the following: terraform_fmt, terraform_docs, terraform_tflint (space separated)."
type: string
default: terraform_fmt terraform_docs terraform_tflint
jobs:
tf_prereqs:
name: terraform modules discovery
runs-on: ubuntu-latest
outputs:
validate_paths: ${{ steps.format.outputs.validate_diff }}
plan_paths: ${{ steps.format.outputs.apply_diff }}
changed_files: ${{ steps.format.outputs.files_diff }}
steps:
- name: checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v4
with:
fetch-depth: 0
- name: get diff with base branch, modules
id: diff_modules
uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96
with:
separator: "@"
files: modules/**/*.tf
- name: get diff with base branch, examples
id: diff_examples
uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96
with:
separator: "@"
files: examples/**/*.tf
- name: get diff with base branch, examples, varfiles
id: diff_tfvars
uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96
with:
separator: "@"
files: examples/**/*.tfvars
- name: extract paths for tasks
id: format
env:
DIFF_MODULES: ${{ steps.diff_modules.outputs.all_changed_files }}
DIFF_EXAMPLES: ${{ steps.diff_examples.outputs.all_changed_files }}
DIFF_TFVARS: ${{ steps.diff_tfvars.outputs.all_changed_files }}
shell: bash
run: |
DIFF_MODULES_ARRAY=(${DIFF_MODULES//@/ })
DIFF_EXAMPLES_ARRAY=(${DIFF_EXAMPLES//@/ })
DIFF_TFVARS_ARRAY=(${DIFF_TFVARS//@/ })
# extract folder names from DIFFS
DIRS_MODULES=()
for ELEMENT in ${DIFF_MODULES_ARRAY[*]}; do
DIRS_MODULES+=($(echo $ELEMENT | sed -E "s/^(modules)\/(.+)\/.*$/\1\/\2/" ))
done
# deduplicate paths
IFS=$'\n' DIRS_MODULES_DEDUP=($(sort -u <<< "${DIRS_MODULES[*]}"))
unset IFS
DIRS_EXAMPLES=()
for ELEMENT in ${DIFF_EXAMPLES_ARRAY[*]}; do
DIRS_EXAMPLES+=($(echo $ELEMENT | sed -E "s/^(examples)\/(.+)\/.*$/\1\/\2/" ))
done
# deduplicate paths
IFS=$'\n' DIRS_EXAMPLES_DEDUP=($(sort -u <<< "${DIRS_EXAMPLES[*]}"))
unset IFS
DIRS_TFVARS=()
for ELEMENT in ${DIFF_TFVARS_ARRAY[*]}; do
DIRS_TFVARS+=($(echo $ELEMENT | sed -E "s/^(examples)\/(.+)\/.*$/\1\/\2/" ))
done
# deduplicate paths
IFS=$'\n' DIRS_TFVARS_DEDUP=($(sort -u <<< "${DIRS_TFVARS[*]}"))
unset IFS
# use these paths to discover dependencies - find examples using modules from the list
EXAMPLES_DISCOVERED=()
for ELEMENT in ${DIRS_MODULES_DEDUP[*]}; do
EXAMPLES_DISCOVERED+=($(echo $(grep -rl "$ELEMENT" examples/*/main.tf | sed -E "s/^(examples\/.*)\/.*$/\1/g")))
done
# deduplicate list of example paths
IFS=$'\n' EXAMPLES_DISCOVERED_DEDUP=($(sort -u <<< "${EXAMPLES_DISCOVERED[*]}"))
unset IFS
DIRS_VALIDATE=(${DIRS_MODULES_DEDUP[*]} ${DIRS_EXAMPLES_DEDUP[*]})
FILES_PRECOMMIT=(${DIFF_MODULES_ARRAY[*]} ${DIFF_EXAMPLES_ARRAY[*]} ${DIFF_TFVARS_ARRAY[*]})
DIRS_APPLY=(${DIRS_EXAMPLES_DEDUP[*]} ${EXAMPLES_DISCOVERED_DEDUP[*]} ${DIRS_TFVARS_DEDUP[*]})
IFS=$'\n' DIRS_APPLY_DEDUP=($(sort -u <<< "${DIRS_APPLY[*]}"))
unset IFS
VALIDATE_DIFF=$(echo ${DIRS_VALIDATE[*]} | tr ' ' ',')
APPLY_DIFF=$(echo ${DIRS_APPLY_DEDUP[*]} | tr ' ' ',')
# a list of chagned paths, used for validation tasks
echo "validate_diff=$VALIDATE_DIFF" >> $GITHUB_OUTPUT
# a list of affected and changed examples, used for plan/apply tasks
echo "apply_diff=$APPLY_DIFF" >> $GITHUB_OUTPUT
# a list of changed files, used for pre-commit tasks
echo "files_diff=${FILES_PRECOMMIT[*]}" >> $GITHUB_OUTPUT
pre_commit:
name: Pre-Commit
needs: tf_prereqs
if: ${{ needs.tf_prereqs.outputs.changed_files != '' }}
uses: ./.github/workflows/_pre_commit.yml
with:
pre-commit-hooks: ${{ inputs.pre-commit-hooks }}
pre-commit-files: ${{ needs.tf_prereqs.outputs.changed_files }}
validate:
name: validate all changed modules
needs: tf_prereqs
if: ${{ needs.tf_prereqs.outputs.validate_paths != '' }}
uses: ./.github/workflows/_tf_test.yml
permissions:
contents: read
id-token: write
with:
cloud: ${{ inputs.cloud }}
tf_version: ${{ inputs.tf_version }}
paths: ${{ needs.tf_prereqs.outputs.validate_paths }}
terratest_action: Validate
fail_fast: ${{ inputs.fail_fast }}
max_parallel: ${{ inputs.validate_max_parallel }}
secrets: inherit
test:
name: run ${{ inputs.terratest_action }} tests on examples
needs:
- pre_commit
- validate
- tf_prereqs
if: ${{ needs.tf_prereqs.outputs.plan_paths != '' }}
uses: ./.github/workflows/_tf_test.yml
permissions:
contents: read
id-token: write
with:
cloud: ${{ inputs.cloud }}
tf_version: ${{ inputs.tf_version }}
paths: ${{ needs.tf_prereqs.outputs.plan_paths }}
terratest_action: ${{ inputs.terratest_action }}
fail_fast: ${{ inputs.fail_fast }}
max_parallel: ${{ inputs.test_max_parallel }}
apply_timeout: ${{ inputs.apply_timeout }}
pr-id: ${{ github.event.number }}
secrets: inherit
branch_protection_junction:
name: junction point for branch protection
needs:
- validate
- pre_commit
- test
if: always()
permissions:
actions: read
runs-on: ubuntu-latest
steps:
- name: check statuses of other jobs
uses: technote-space/workflow-conclusion-action@45ce8e0eb155657ab8ccf346ade734257fd196a5 # v3
- name: branch protection check validation point
run: |
if [[ "$WORKFLOW_CONCLUSION" == "failure" ]]; then exit 1; fi