1
+ # Main build pipeline that verifies, builds, and deploys the software
2
+ name : Build and Deploy
3
+ # Events that trigger the workflow
4
+ on :
5
+ # Trigger based on push to all branches - TODO
6
+ push :
7
+ branches :
8
+ - main
9
+ - develop
10
+ - ' release/**'
11
+ - ' feature/**'
12
+ - ' issue/**'
13
+ - ' issues/**'
14
+ - ' dependabot/**'
15
+ tags-ignore :
16
+ - ' *'
17
+ # Do not trigger build if pyproject.toml was the only thing changed
18
+ paths-ignore :
19
+ - ' pyproject.toml'
20
+ - ' poetry.lock'
21
+ # Run workflow manually from the Actions tab
22
+ workflow_dispatch :
23
+ inputs :
24
+ venue :
25
+ type : choice
26
+ description : Venue to deploy to
27
+ options :
28
+ - DEV1
29
+ - DEV2
30
+ - OPS
31
+
32
+ # Only allow 1 execution of this workflow to be running at any given time per-branch.
33
+ concurrency :
34
+ group : ${{ github.workflow }}-${{ github.ref }}
35
+ cancel-in-progress : true
36
+
37
+ # Environment variables
38
+ env :
39
+ APP_NAME_ENV : ' moi'
40
+ POETRY_VERSION : " 2.1.1"
41
+ PYTHON_VERSION : " 3.10"
42
+ REGISTRY : ghcr.io
43
+ IMAGE_NAME : ${{ github.repository }}
44
+
45
+ jobs :
46
+ build :
47
+ name : Build, test, verify
48
+ runs-on : ubuntu-latest
49
+ defaults :
50
+ run :
51
+ shell : bash -el {0}
52
+ outputs :
53
+ app_version : ${{ steps.version.outputs.APP_VERSION }}
54
+ target_env : ${{ steps.version.outputs.TARGET_ENV }}
55
+ steps :
56
+ # Create a release and set deployment environment
57
+ - uses : getsentry/action-github-app-token@v3
58
+ name : PO.DAAC CICD token
59
+ id : podaac-cicd
60
+ with :
61
+ app_id : ${{ secrets.CICD_APP_ID }}
62
+ private_key : ${{ secrets.CICD_APP_PRIVATE_KEY }}
63
+ - uses : actions/checkout@v4
64
+ with :
65
+ repository : ${{ github.repository }}
66
+ token : ${{ steps.podaac-cicd.outputs.token }}
67
+ - uses : actions/setup-python@v5
68
+ with :
69
+ python-version : ${{ env.PYTHON_VERSION }}
70
+ - name : Install poetry
71
+ uses : abatilo/actions-poetry@v3
72
+ with :
73
+ poetry-version : ${{ env.POETRY_VERSION }}
74
+ - name : Setup a local virtual environment
75
+ run : |
76
+ poetry config virtualenvs.create true --local
77
+ poetry config virtualenvs.in-project true --local
78
+
79
+ # Get current version
80
+ - name : Get pre-build version
81
+ id : get-version
82
+ run : |
83
+ echo "poetry version"
84
+ echo "current_version=$(poetry version | awk '{print $2}')" >> $GITHUB_OUTPUT
85
+ echo "pyproject_name=$(poetry version | awk '{print $1}')" >> $GITHUB_ENV
86
+
87
+ - name : Manual build
88
+ # If triggered by workflow dispatch, no version bump
89
+ if : github.event_name == 'workflow_dispatch'
90
+ id : manual
91
+ run : |
92
+ echo "APP_VERSION=${{ steps.get-version.outputs.current_version }}" >> $GITHUB_ENV
93
+ echo "TARGET_ENV=${{ github.event.inputs.venue }}" >> $GITHUB_ENV
94
+ target_env=${{ github.event.inputs.venue }}
95
+ echo "PREFIX_ENV=confluence-$(echo "$target_env" | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV
96
+
97
+ - name : Bump pre-alpha version
98
+ # If triggered by push to a non-tracked branch (DEV1)
99
+ if : |
100
+ github.ref != 'refs/heads/develop' &&
101
+ github.ref != 'refs/heads/main' &&
102
+ !startsWith(github.ref, 'refs/heads/release/')
103
+ run : |
104
+ new_ver="${{ steps.get-version.outputs.current_version }}+$(git rev-parse --short ${GITHUB_SHA})"
105
+ poetry version $new_ver
106
+ echo "APP_VERSION=$new_ver" >> $GITHUB_ENV
107
+ echo "TARGET_ENV=DEV1" >> $GITHUB_ENV
108
+ echo "PREFIX_ENV=confluence-dev1" >> $GITHUB_ENV
109
+
110
+ - name : Bump alpha version
111
+ # If triggered by push to the develop branch (DEV1)
112
+ if : |
113
+ github.ref == 'refs/heads/develop' &&
114
+ steps.manual.conclusion == 'skipped'
115
+ id : alpha
116
+ run : |
117
+ poetry version prerelease
118
+ echo "APP_VERSION=$(poetry version | awk '{print $2}')" >> $GITHUB_ENV
119
+ echo "TARGET_ENV=DEV1" >> $GITHUB_ENV
120
+ echo "PREFIX_ENV=confluence-dev1" >> $GITHUB_ENV
121
+
122
+ - name : Bump rc version
123
+ # If triggered by push to a release branch (DEV2)
124
+ if : |
125
+ startsWith(github.ref, 'refs/heads/release/') &&
126
+ steps.manual.conclusion == 'skipped'
127
+ id : rc
128
+ env :
129
+ # True if the version already has a 'rc' pre-release identifier
130
+ BUMP_RC : ${{ contains(steps.get-version.outputs.current_version, 'rc') }}
131
+ run : |
132
+ if [ "$BUMP_RC" = true ]; then
133
+ poetry version prerelease
134
+ else
135
+ poetry version ${GITHUB_REF#refs/heads/release/}rc1
136
+ fi
137
+ echo "APP_VERSION=$(poetry version | awk '{print $2}')" >> $GITHUB_ENV
138
+ echo "TARGET_ENV=DEV2" >> $GITHUB_ENV
139
+ echo "PREFIX_ENV=confluence-dev2" >> $GITHUB_ENV
140
+
141
+ - name : Release version
142
+ # If triggered by push to the main branch (OPS)
143
+ if : |
144
+ startsWith(github.ref, 'refs/heads/main') &&
145
+ steps.manual.conclusion == 'skipped'
146
+ id : release
147
+ env :
148
+ CURRENT_VERSION : ${{ steps.get-version.outputs.current_version }}
149
+ # Remove rc* from end of version string
150
+ # The ${string%%substring} syntax below deletes the longest match of $substring from back of $string.
151
+ run : |
152
+ poetry version ${CURRENT_VERSION%%rc*}
153
+ echo "APP_VERSION=$(poetry version | awk '{print $2}')" >> $GITHUB_ENV
154
+ echo "TARGET_ENV=OPS" >> $GITHUB_ENV
155
+ echo "PREFIX_ENV=confluence-OPS" >> $GITHUB_ENV
156
+
157
+ # Validate infrastructure terraform files
158
+ - name : Setup terraform
159
+ uses : hashicorp/setup-terraform@v3
160
+
161
+ - name : Validate terraform
162
+ working-directory : terraform/
163
+ run : |
164
+ terraform init -backend=false
165
+ terraform validate -no-color
166
+
167
+ # SNYK IAC scan and report
168
+ - name : Run Snyk IAC to test and report
169
+ uses : snyk/actions/iac@master
170
+ env :
171
+ SNYK_TOKEN : ${{ secrets.SNYK_TOKEN }}
172
+ with :
173
+ command : test
174
+ file : terraform/
175
+ args : >
176
+ --org=${{ secrets.SNYK_ORG_ID }}
177
+ --severity-threshold=high
178
+ --report
179
+
180
+ # SNYK Python
181
+ - name : Run Snyk Python to test
182
+ uses : snyk/actions/python-3.10@master
183
+ env :
184
+ SNYK_TOKEN : ${{ secrets.SNYK_TOKEN }}
185
+ with :
186
+ command : test
187
+ args : >
188
+ --org=${{ secrets.SNYK_ORG_ID }}
189
+ --project-name=${{ github.repository }}
190
+ --severity-threshold=high
191
+ --fail-on=all
192
+ - name : Run Snyk Python to report
193
+ uses : snyk/actions/python-3.10@master
194
+ env :
195
+ SNYK_TOKEN : ${{ secrets.SNYK_TOKEN }}
196
+ with :
197
+ command : monitor
198
+ args : >
199
+ --org=${{ secrets.SNYK_ORG_ID }}
200
+ --project-name=${{ github.repository }}
201
+
202
+ - name : Commit version bump
203
+ # If building an alpha, release candidate, or release then we commit the version bump back to the repo
204
+ if : |
205
+ steps.alpha.conclusion == 'success' ||
206
+ steps.rc.conclusion == 'success' ||
207
+ steps.release.conclusion == 'success'
208
+ run : |
209
+ git config user.name "${GITHUB_ACTOR}"
210
+ git config user.email "${GITHUB_ACTOR}@users.noreply.github.com"
211
+ git commit -am "/version ${{ env.APP_VERSION }}"
212
+ git push
213
+
214
+ - name : Push tag
215
+ if : |
216
+ steps.alpha.conclusion == 'success' ||
217
+ steps.rc.conclusion == 'success' ||
218
+ steps.release.conclusion == 'success'
219
+ run : |
220
+ git config user.name "${GITHUB_ACTOR}"
221
+ git config user.email "${GITHUB_ACTOR}@users.noreply.github.com"
222
+ git tag -a "${{ env.APP_VERSION }}" -m "Version ${{ env.APP_VERSION }}"
223
+ git push origin "${{ env.APP_VERSION }}"
224
+
225
+ - name : Create GH release
226
+ if : |
227
+ steps.alpha.conclusion == 'success' ||
228
+ steps.rc.conclusion == 'success' ||
229
+ steps.release.conclusion == 'success'
230
+ uses : ncipollo/release-action@v1
231
+ with :
232
+ generateReleaseNotes : true
233
+ name : ${{ env.APP_VERSION }}
234
+ prerelease : ${{ steps.alpha.conclusion == 'success' || steps.rc.conclusion == 'success'}}
235
+ tag : ${{ env.APP_VERSION }}
236
+
237
+ - name : Save application version to output
238
+ id : version
239
+ run : |
240
+ echo "APP_VERSION=${{ env.APP_VERSION }}" >> $GITHUB_OUTPUT
241
+ echo "TARGET_ENV=${{ env.TARGET_ENV }}" >> $GITHUB_OUTPUT
242
+
243
+
244
+ container :
245
+ name : Build container image
246
+ # The type of runner that the job will run on
247
+ runs-on : ubuntu-latest
248
+ needs : build
249
+ env :
250
+ APP_VERSION : ${{ needs.build.outputs.app_version }}
251
+ TARGET_ENV : ${{ needs.build.outputs.target_env }}
252
+ steps :
253
+ # Check out GitHub repo
254
+ - uses : actions/checkout@v4
255
+ with :
256
+ repository : ${{ github.repository }}
257
+
258
+ # ghcr.io container image
259
+ - name : Log in to the Container registry
260
+ uses : docker/login-action@v3
261
+ with :
262
+ registry : ${{ env.REGISTRY }}
263
+ username : ${{ github.actor }}
264
+ password : ${{ secrets.GITHUB_TOKEN }}
265
+
266
+ - name : Extract metadata (tags, labels) for Docker
267
+ id : meta
268
+ uses : docker/metadata-action@v5
269
+ with :
270
+ images : ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
271
+ tags : |
272
+ type=pep440,pattern={{version}},value=${{ env.APP_VERSION }}
273
+ type=raw,value=${{ env.TARGET_ENV }}
274
+
275
+ - name : Build and push Docker image
276
+ if : |
277
+ github.ref == 'refs/heads/develop' ||
278
+ github.ref == 'refs/heads/main' ||
279
+ startsWith(github.ref, 'refs/heads/release') ||
280
+ github.event_name == 'workflow_dispatch'
281
+ uses : docker/build-push-action@v5
282
+ with :
283
+ context : .
284
+ file : Dockerfile
285
+ push : true
286
+ pull : true
287
+ tags : ${{ steps.meta.outputs.tags }}
288
+ labels : ${{ steps.meta.outputs.labels }}
289
+
290
+ # # AWS ECR repository
291
+ # - name: Login to AWS ECR
292
+ # id: login-ecr
293
+ # uses: aws-actions/amazon-ecr-login@v2
294
+ # with:
295
+ # mask-password: 'true'
296
+ # - name: Define ECR registry, repository, and image tag names
297
+ # run : |
298
+ # echo "REGISTRY=${{ steps.login-ecr.outputs.registry }}" >> $GITHUB_ENV
299
+ # echo "REPOSITORY=${PREFIX_ENV}-${APP_NAME_ENV}" >> $GITHUB_ENV
300
+ # image_repository=${{ fromJSON(steps.meta.outputs.json).tags[0] }}
301
+ # image_tag=$(echo ${image_repository##*:})
302
+ # echo "IMAGE_TAG=${image_tag}" >> $GITHUB_ENV
303
+
304
+ # # Create ECR repository (if it does not exist)
305
+ # - name: Create AWS ECR Repository
306
+ # run: deploy/deploy-ecr.sh $REGISTRY $REPOSITORY
307
+
308
+ # # Build and push Docker container image by version tag and to latest tag
309
+ # - name: Build and Push to AWS ECR
310
+ # run: |
311
+ # docker tag ${{ fromJSON(steps.meta.outputs.json).tags[0] }} $REGISTRY/$REPOSITORY:$IMAGE_TAG
312
+ # docker push $REGISTRY/$REPOSITORY:$IMAGE_TAG
313
+ # docker tag ${{ fromJSON(steps.meta.outputs.json).tags[0] }} $REGISTRY/$REPOSITORY:latest
314
+ # docker push $REGISTRY/$REPOSITORY:latest
315
+
316
+ deploy :
317
+ name : Deploy module
318
+ # The type of runner that the job will run on
319
+ runs-on : ubuntu-latest
320
+ needs : container
321
+ steps :
322
+
323
+ # Check out GitHub repo
324
+ - uses : actions/checkout@v4
325
+
326
+ # # Configure credentials
327
+ # - name: Configure AWS credentials
328
+ # uses: aws-actions/configure-aws-credentials@v4
329
+ # with:
330
+ # aws-access-key-id: ${{ secrets[format('AWS_ACCESS_KEY_ID_{0}', env.TARGET_ENV)] }}
331
+ # aws-secret-access-key: ${{ secrets[format('AWS_SECRET_ACCESS_KEY_{0}', env.TARGET_ENV)] }}
332
+ # aws-region: us-west-2
333
+ # mask-aws-account-id: true
334
+
335
+ # # Set up Terraform
336
+ # - name: Setup Terraform
337
+ # uses: hashicorp/setup-terraform@v3
338
+
339
+ # - name: Define TF_VAR values
340
+ # run: |
341
+ # echo "TF_VAR_app_version=$APP_VERSION" >> $GITHUB_ENV
342
+ # echo "TF_VAR_environment=$TARGET_ENV" >> $GITHUB_ENV
343
+ # echo "TF_VAR_prefix=$PREFIX_ENV" >> $GITHUB_ENV
344
+ # echo "TF_IN_AUTOMATION=true" >> $GITHUB_ENV
345
+
346
+ # - name: Initialize Terraform
347
+ # working-directory: terraform/
348
+ # run: |
349
+ # terraform init -reconfigure \
350
+ # -backend-config="bucket=${PREFIX_ENV}-tf-state" \
351
+ # -backend-config="key=${APP_NAME_ENV}.tfstate" \
352
+ # -backend-config="region=${AWS_DEFAULT_REGION}"
353
+
354
+ # - name: Validate Terraform
355
+ # working-directory: terraform/
356
+ # run: terraform validate -no-color
357
+
358
+ # # Deploy AWS infrastructure
359
+ # - name: Deploy Terraform
360
+ # working-directory: terraform/
361
+ # run: terraform apply -auto-approve
0 commit comments