-
Notifications
You must be signed in to change notification settings - Fork 0
187 lines (149 loc) · 5.9 KB
/
pipeline.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
name: 'Pipeline'
# Do not run when PR is created - only after it is merged into one of these branches
# main branch is prod
on:
push:
branches:
- main
- stage
permissions:
contents: read
env:
RELEASE_REVISION: "pr-${{ github.event.pull_request.number }}-${{ github.event.pull_request.head.sha }}"
SHA_SHORT: "latest"
ENVIRONMENT: ${{ github.ref_name == 'stage' && 'stage' || github.ref_name == 'main' && 'prod' || 'unknown' }}
jobs:
test:
name: 'Test: ${{ github.ref_name }} - Python ${{matrix.python-version}}'
runs-on: ubuntu-latest
if: github.ref_name == 'main' || github.ref_name == 'stage'
# (would like to use env.ENVIRONMENT here, but it is not allowed)
environment: ${{ github.ref_name == 'stage' && 'stage' || github.ref_name == 'main' && 'prod' || 'unknown' }}
defaults:
run:
shell: bash
# run tests on mutliple versions of Python
strategy:
matrix:
python-version: [3.8, 3.9]
steps:
# Checkout the code.
- name: Checkout code
uses: actions/checkout@v3
########################
# Run unit tests
########################
# Init python, install dependencies, and test our app.
- name: Initialize Python versions
uses: actions/setup-python@v5
with:
python-version: ${{matrix.python-version}}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Test app
run: |
pytest src/
build:
name: 'Build: ${{ github.ref_name }}'
needs: test # do not build if tests fail
runs-on: ubuntu-latest
if: github.ref_name == 'main' || github.ref_name == 'stage'
environment: ${{ github.ref_name == 'stage' && 'stage' || github.ref_name == 'main' && 'prod' || 'unknown' }}
defaults:
run:
shell: bash
steps:
# Checkout the code.
- name: Checkout code
uses: actions/checkout@v3
########################
# Build and push image
########################
# Generate a SBOM with Anchore.
# An SBOM (Software Bill of Materials) is a detailed list of all components, libraries,
# and dependencies that make up a software project. It is useful for security purposes, auditing
- name: Generate SBOM
uses: anchore/sbom-action@v0
with:
path: ./
# create and boot a builder for multi-platform images
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
# Setup QEMU (Quick Emulator) to support cross-platform emulation
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
# Log in to GHCR
- name: Log in to GHCR
uses: docker/login-action@v2
with:
registry: ghcr.io
username: "setheliot"
password: ${{ secrets.GHCR_TOKEN }}
# Generate version label for the image
- name: Set Short SHA
run: echo "SHA_SHORT=${GITHUB_SHA::7}" >> $GITHUB_ENV
# Build and push our image with the latest tag.
- name: Build and push
uses: docker/build-push-action@v3
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags:
ghcr.io/setheliot/xyz-demo-app:latest,
ghcr.io/setheliot/xyz-demo-app:${{env.SHA_SHORT}},
ghcr.io/setheliot/xyz-demo-app:${{env.ENVIRONMENT}}
######################
terraform:
name: 'Terraform: ${{ github.ref_name }}'
needs: build # This ensures terraform runs after build completes
runs-on: ubuntu-latest
if: github.ref_name == 'main' || github.ref_name == 'stage'
environment: ${{ github.ref_name == 'stage' && 'stage' || github.ref_name == 'main' && 'prod' || 'unknown' }}
defaults:
run:
shell: bash
working-directory: ./terraform
steps:
- name: Checkout code
uses: actions/checkout@v3
# Generate version label for the image
- name: Set Short SHA
run: echo "SHA_SHORT=${GITHUB_SHA::7}" >> $GITHUB_ENV
# Supply an IAM User for AWS credentials.
# ToDo: update to use IAM Role (short lived credentials) instead
# Region is required here, but not used by Terraform - we specify Region in the Terraform provider
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
# Setup Terraform
- name: Set up Terraform
uses: hashicorp/setup-terraform@v3
# Initialize a new or existing Terraform working directory by creating initial files, loading any remote state, downloading modules, etc.
- name: Terraform Init
run: terraform init
# Checks that all Terraform configuration files adhere to a canonical format
- name: Terraform Format
run: terraform fmt -check
# If the workspace does not exist, then create it
- name: Ensure workspace exists for this branch (for this environment)
run: |
if ! terraform workspace list | grep -q "${{ github.ref_name }}"; then
terraform workspace new "${{ github.ref_name }}"
fi
# Checks select the appropriate workspace - ensures separate state files for each env
- name: Terraform Workspace
run: terraform workspace select ${{ github.ref_name }}
# Generates an execution plan for Terraform
- name: Terraform Plan
run: terraform plan -var-file=environment/${{ github.ref_name }}.tfvars
- name: Terraform Apply
run: |
terraform apply -auto-approve -input=false \
-var="app_image=ghcr.io/setheliot/xyz-demo-app:${{env.SHA_SHORT}}" \
-var-file=environment/${{ github.ref_name }}.tfvars