yaml can be hard #11
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 }}' | |
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 |