-
Notifications
You must be signed in to change notification settings - Fork 0
/
action.yaml
284 lines (249 loc) · 11.9 KB
/
action.yaml
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
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
name: 'Deploy Colvin Projects'
description: 'Deploy Colvin projects to Google Cloud Platform'
runs:
using: "composite"
steps:
- name: 'Terraform check changes between branches'
uses: dorny/paths-filter@v2
id: changes
with:
base: ${{ github.ref }}
ref: master
filters: |
terraform:
- 'terraform/**'
if: ${{ env.DIFF_TERRAFORM == 'true' && github.ref_name != 'master' }}
- name: 'Get variables and validations'
run: |
INPUT_WORKSPACE=${{ github.event.inputs.environment }}
SLACK_URL_MSG=""
if [ "${{ github.event_name }}" == "push" ] || [ ${INPUT_WORKSPACE} == "prod" ]
then
# PRODUCTION - Master branch through commit, merge PR or manual deploy to prod
echo "WORKSPACE=prod" >> ${GITHUB_ENV}
echo "TAG_PREFIX=1" >> ${GITHUB_ENV}
else
if [ ! -z ${{ steps.changes.outputs.terraform }} ]
then
# Get terraform folder diff between branches and avoit breaking changes
OUTPUT_FR_TERRAFORM=${{ steps.changes.outputs.terraform }}
if ${OUTPUT_FR_TERRAFORM}
then
echo "::error::There are terraform changes in master, pull from master!"
exit 1
fi
fi
if [ ${INPUT_WORKSPACE} == "dynamic" ]
then
if [[ ! ${GITHUB_REF_NAME} =~ ^[a-z|A-Z]{2,4}-[0-9]+(_|\/).* ]]
then
echo "::error::The branch isn't formatted as expected with a Jira code prefix!"
exit 1
fi
APP_HASH=`echo ${GITHUB_REF_NAME} | awk -F'[/_]' '{print tolower($1)}'`
APP_FILE="${APP_HASH}.txt"
RES="blank"; gsutil -q stat gs://${GCS_DYNAMIC}/${DNS_ZONE}/${APP_FILE} || RES=empty
if [[ ${RES} != "empty" ]]
then
echo "DYNAMIC_INSTALL=false" >> ${GITHUB_ENV}
# Update existent environment
gsutil cp gs://${GCS_DYNAMIC}/${DNS_ZONE}/${APP_FILE} ${APP_FILE}
TMP_APP_NAME=`grep "APP_NAME=" ${APP_FILE} | awk -F'=' '{print $2}'`
TMP_BRANCH=`grep "BRANCH=" ${APP_FILE} | awk -F'=' '{print $2}'`
# Verify that the branch corresponds to the APP and the DNS zone
if [ ${APP_NAME} != ${TMP_APP_NAME} ] || [ ${GITHUB_REF_NAME} != ${TMP_BRANCH} ]
then
echo "::error::This JIRA CODE (${APP_HASH}) is currently in use by another APP (${TMP_APP_NAME}) or BRANCH (${TMP_BRANCH}) under the same DNS zone (${DNS_ZONE})!"
exit 1
fi
else
# Dynamic environtment, first install
echo "DYNAMIC_INSTALL=true" >> ${GITHUB_ENV}
fi
# Disable terraform due a dynamic environment and we use static resources from stage1
echo "SKIP_TERRAFORM=true" >> ${GITHUB_ENV}
echo "APP_HASH=${APP_HASH}" >> ${GITHUB_ENV}
echo "APP_DOMAIN=dyn-${APP_HASH}.${DNS_DOMAIN}" >> ${GITHUB_ENV}
echo "TAG_PREFIX=${APP_HASH}" >> ${GITHUB_ENV}
echo "SLACK_URL_MSG=\\nURL: https://dyn-${APP_HASH}.${DNS_DOMAIN}" >> ${GITHUB_ENV}
else
NUM_STG=`echo ${INPUT_WORKSPACE} | awk -F"stage" '{ print $2 }'`
echo "NUM_STG=${NUM_STG}" >> ${GITHUB_ENV}
echo "TAG_PREFIX=s${NUM_STG}" >> ${GITHUB_ENV}
echo "SLACK_URL_MSG=\\nURL: https://${STAGE_URL_FORMAT/\{STAGE\}/${INPUT_WORKSPACE}}.${DNS_DOMAIN}" >> ${GITHUB_ENV}
fi
# We can make a manual "plan|apply" from master or any branch
echo "WORKSPACE=${INPUT_WORKSPACE}" >> ${GITHUB_ENV}
fi
shell: bash
- name: 'Configure dynamic variables'
run: bash scripts/generate-dynamic-envs.sh
shell: bash
if: ${{ github.event.inputs.environment == 'dynamic' }}
- name: 'Get kubernetes credentials'
run: |
if [ ${WORKSPACE} == "prod" ]
then
echo "CLUSTER=${K8S_PROD}" >> ${GITHUB_ENV}
echo "LOCATION=${GCP_REGION}" >> ${GITHUB_ENV}
else
echo "CLUSTER=${K8S_STG}" >> ${GITHUB_ENV}
if [ ${K8S_STG_LOCATION} == "region" ]; then echo "LOCATION=${GCP_REGION}" >> ${GITHUB_ENV}; else echo "LOCATION=${GCP_ZONE}" >> ${GITHUB_ENV}; fi
fi
shell: bash
- name: 'GCloud get GKE credentials'
id: 'get-credentials'
uses: google-github-actions/get-gke-credentials@v0
with:
project_id: ${{ env.PROJECT_ID }}
cluster_name: ${{ env.CLUSTER }}
location: ${{ env.LOCATION }}
- name: 'Kubernetes check status'
run: |
chmod 600 $KUBECONFIG
if [ ${WORKSPACE} != "prod" ]
then
if [ `kubectl get nodes --selector='mode!=static' -o json | jq '.items | length'` -eq 0 ]; then echo "::error::Stage is stopped. Remember to start it!"; exit 1; fi
fi
shell: bash
- name: 'Terraform decrypt encrypted values'
run: for FILE in `find ${TERRAFORM_PATH}/ -name "*.enc"`; do sops -d ${FILE} > ${FILE::-4}; done
shell: bash
if: ${{ env.EXEC_TERRAFORM == 'true' && env.SKIP_TERRAFORM != 'true' }}
- name: 'Terraform init'
run: terraform -chdir=${TERRAFORM_PATH}/ init -input=false
shell: bash
if: ${{ env.EXEC_TERRAFORM == 'true' && env.SKIP_TERRAFORM != 'true' }}
- name: 'Terraform workspace'
run: |
if [ ${WORKSPACE} == "prod" ]
then
terraform -chdir=${TERRAFORM_PATH}/ workspace select ${K8S_PROD}
else
terraform -chdir=${TERRAFORM_PATH}/ workspace select ${WORKSPACE}
fi
shell: bash
if: ${{ env.EXEC_TERRAFORM == 'true' && env.SKIP_TERRAFORM != 'true' }}
- name: 'Terraform apply'
run: terraform -chdir=${TERRAFORM_PATH}/ apply -auto-approve
shell: bash
if: ${{ env.EXEC_TERRAFORM == 'true' && env.SKIP_TERRAFORM != 'true' }}
- name: 'Get latest tag and auto increment version'
run: |
ARRAY_CONTAINERS=(${CONTAINER_LIST})
REGEX="${TAG_PREFIX}.([0-9]+)"
LAST=`gcloud container images list-tags ${REGISTRY}${ARRAY_CONTAINERS[0]} --sort-by="TAGS" --filter="tags~^${TAG_PREFIX}" | sed '/TIMESTAMP/d' | sort -rVk2 | head -n1 | awk '{print $2}'`
if [[ ${LAST} =~ ${REGEX} ]]; then MINOR="${BASH_REMATCH[1]}"; fi
if [ -z ${MINOR} ]; then MINOR="0"; fi
MINOR=$(echo ${MINOR} + 1 | bc)
echo "TAG_IMG=${TAG_PREFIX}.${MINOR}" >> ${GITHUB_ENV}
shell: bash
if: ${{ env.EXEC_DOCKER == 'true' }}
- name: 'Docker config to pull or push Artifact Registry'
run: gcloud auth configure-docker europe-docker.pkg.dev
shell: bash
if: ${{ env.EXEC_DOCKER == 'true' }}
- name: 'Docker build images'
run: |
ARRAY_CONTAINERS=(${CONTAINER_LIST})
for CONTAINER in "${ARRAY_CONTAINERS[@]}"
do
export TAG_${CONTAINER^^}="${REGISTRY}${CONTAINER}:${TAG_IMG}"
export DOCKER_BUILDKIT=1
if [ ${WORKSPACE} == "prod" ]
then
docker compose -f docker-compose.yml build ${BUILD_ARG_PROD} ${CONTAINER}
elif [ ${WORKSPACE} == "dynamic" ]
then
if ${BUILD_USE_WORKSPACE}
then
docker compose -f docker-compose.yml build ${BUILD_ARG_STG}stage1 ${CONTAINER}
else
docker compose -f docker-compose.yml build ${BUILD_ARG_STG} ${CONTAINER}
fi
else
if ${BUILD_USE_WORKSPACE}
then
docker compose -f docker-compose.yml build ${BUILD_ARG_STG}${WORKSPACE} ${CONTAINER}
else
docker compose -f docker-compose.yml build ${BUILD_ARG_STG} ${CONTAINER}
fi
fi
done
shell: bash
if: ${{ env.EXEC_DOCKER == 'true' }}
- name: 'Docker push to Artifacts Registry'
run: |
ARRAY_CONTAINERS=(${CONTAINER_LIST})
for CONTAINER in "${ARRAY_CONTAINERS[@]}"; do docker push ${REGISTRY}${CONTAINER}:${TAG_IMG}; done
shell: bash
if: ${{ env.EXEC_DOCKER == 'true' }}
- name: 'Replace version in helm values'
run: sed -i "s/TAG_IMG/${TAG_IMG}/g" ${HELM_PATH}/values.yaml ${HELM_PATH}/values.prod.yaml
shell: bash
if: ${{ env.EXEC_DOCKER == 'true' }}
- name: 'Helm dependencies update'
run: helm dependency update ${HELM_PATH}/
shell: bash
if: ${{ env.EXEC_HELM == 'true' }}
- name: 'Helm deploy'
run: |
if [ ${WORKSPACE} == "prod" ]
then
helm secrets upgrade ${APP_NAME} ${HELM_PATH} --install --wait --atomic \
-f ${HELM_PATH}/values.yaml -f ${HELM_PATH}/values.prod.yaml \
-f ${HELM_PATH}/secrets.yaml -f ${HELM_PATH}/secrets.prod.yaml --timeout ${HELM_TIMEOUT}
elif [ ${WORKSPACE} == "dynamic" ]
then
helm secrets upgrade ${APP_NAME}-${APP_HASH} ${HELM_PATH}/ --install --wait --atomic \
-f ${HELM_PATH}/values.yaml -f ${HELM_PATH}/values.dynamic.yaml \
-f ${HELM_PATH}/secrets.yaml -f ${HELM_PATH}/secrets.dynamic.yaml --timeout ${HELM_TIMEOUT}
else
helm secrets upgrade ${APP_NAME}${NUM_STG} ${HELM_PATH}/ --install --wait --atomic \
-f ${HELM_PATH}/values.yaml -f ${HELM_PATH}/values.${WORKSPACE}.yaml \
-f ${HELM_PATH}/secrets.yaml -f ${HELM_PATH}/secrets.${WORKSPACE}.yaml --timeout ${HELM_TIMEOUT}
fi
shell: bash
if: ${{ env.EXEC_HELM == 'true' }}
- name: 'Get HTTP ingress IP and set DNS'
run: |
FINISH=false
while ! ${FINISH}
do
HTTP_IP=`kubectl get ingress dyn-${APP_NAME}-${APP_HASH} -o jsonpath='{.status.loadBalancer.ingress[0].ip}'`
if [[ ${HTTP_IP} =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then FINISH=true; else echo "Waiting for load balancer IP..."; sleep 15; fi
done
echo "HTTP INGRESS IP: ${HTTP_IP}"
gcloud dns --project=${PROJECT_ID} record-sets create ${APP_DOMAIN}. --type="A" --zone="${DNS_ZONE}" --rrdatas="${HTTP_IP}" --ttl="300"
shell: bash
if: ${{ env.EXEC_HELM == 'true' && env.DYNAMIC_INSTALL == 'true' }}
- name: 'Save last state for dynamic environment'
run: |
APP_FILE="${APP_HASH}.txt"
DATE=$(date "+%Y%m%d-%H%M%S")
TIMESTAMP=$(date +%s)
if ! ${DYNAMIC_INSTALL}
then
gsutil cp gs://${GCS_DYNAMIC}/${DNS_ZONE}/${APP_FILE} ${APP_FILE}
UPDATE_NUM=`grep "UPDATE_NUM=" ${APP_FILE} | awk -F'=' '{print $2}'`
sed -i "s/UPDATE_NUM=.*/UPDATE_NUM=$(echo ${UPDATE_NUM} + 1 | bc)/" ${APP_FILE}
sed -i "s/DATE_UPDATE=.*/DATE_UPDATE=${DATE}/" ${APP_FILE}
sed -i "s/TIMESTAMP_UPDATE=.*/TIMESTAMP_UPDATE=${TIMESTAMP}/" ${APP_FILE}
else
# Create non existent environment
echo "DNS_ZONE=${DNS_ZONE}" >> ${APP_FILE}
echo "DNS_DOMAIN=${DNS_DOMAIN}" >> ${APP_FILE}
echo "APP_NAME=${APP_NAME}" >> ${APP_FILE}
echo "APP_DOMAIN=${APP_DOMAIN}" >> ${APP_FILE}
echo "APP_HASH=${APP_HASH}" >> ${APP_FILE}
echo "BRANCH=${GITHUB_REF_NAME}" >> ${APP_FILE}
echo "DATE_INIT=${DATE}" >> ${APP_FILE}
echo "DATE_UPDATE=${DATE}" >> ${APP_FILE}
echo "TIMESTAMP_INIT=${TIMESTAMP}" >> ${APP_FILE}
echo "TIMESTAMP_UPDATE=${TIMESTAMP}" >> ${APP_FILE}
echo "UPDATE_NUM=0" >> ${APP_FILE}
fi
gsutil cp ${APP_FILE} gs://${GCS_DYNAMIC}/${DNS_ZONE}/${APP_FILE}
echo "DYNAMIC URL: https://${APP_DOMAIN}"
shell: bash
if: ${{ github.event.inputs.environment == 'dynamic' }}