Skip to content

refactor(iac): remove unused feature flags and simplify configuration… #216

refactor(iac): remove unused feature flags and simplify configuration…

refactor(iac): remove unused feature flags and simplify configuration… #216

name: CI/CD Pipeline
on:
# Run on pushes to main (all 3 jobs)
push:
branches: [main]
# Run on all PRs (test + build)
pull_request:
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
permissions:
# Required to checkout the code
contents: read
# Required to put a comment into the pull-request
pull-requests: write
env:
NODE_VERSION: 22
TERRAFORM_VERSION: 1.13.3
jobs:
code-quality:
name: ${{ matrix.name }}
runs-on: ubuntu-latest
timeout-minutes: ${{ matrix.job-timeout }}
strategy:
fail-fast: false
matrix:
include:
- name: Type Check (TypeScript)
command: npm run tsc
job-timeout: 15
- name: Lint (Biome)
command: npm run lint
job-timeout: 15
- name: OpenAPI Lint (Spectral)
command: npm run spectral
job-timeout: 10
steps:
- &node-checkout
name: Checkout repository
uses: actions/checkout@v5
- &node-setup
name: Setup Node.js
uses: actions/setup-node@v5
with:
node-version: ${{ env.NODE_VERSION }}
- &node-install-dependencies
name: Install dependencies
run: npm ci
- name: Run ${{ matrix.name }}
run: ${{ matrix.command }}
unit-tests:
name: Tests
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- *node-checkout
- *node-setup
- *node-install-dependencies
- name: Tests
run: npm test
timeout-minutes: 10
- name: "Report Vitest Coverage"
if: always()
uses: davelosert/vitest-coverage-report-action@v2
infra:
name: Infrastructure checks
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- &tf-checkout
name: Checkout repository
uses: actions/checkout@v5
- &tf-setup
name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: ${{ env.TERRAFORM_VERSION }}
cli_config_credentials_token: ${{ secrets.TF_API_TOKEN }}
- name: Check Terraform formatting
working-directory: iac
run: terraform fmt -check -recursive
- &tf-init
name: Terraform init
working-directory: iac
run: terraform init -input=false
- name: Terraform validate
working-directory: iac
run: terraform validate
- name: Setup TFLint
uses: terraform-linters/setup-tflint@v4
- name: Run TFLint
working-directory: iac
run: |
tflint --init
tflint --minimum-failure-severity=error
# - name: Run Trivy config scan
# uses: aquasecurity/trivy-action@0.24.0
# with:
# scan-type: config
# scan-ref: iac
# exit-code: "1"
# ignore-unfixed: true
# severity: HIGH,CRITICAL
# skip-dirs: iac/.terraform
e2e:
name: End-to-end tests
runs-on: ubuntu-latest
timeout-minutes: 15
container:
image: mcr.microsoft.com/playwright:v1.56.0-noble
services:
postgres:
image: postgres:17
ports:
- 5432:5432
env:
POSTGRES_DB: mattis
POSTGRES_USER: mattis
POSTGRES_PASSWORD: mattis
options: >-
--health-cmd "pg_isready -U mattis -d mattis"
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
DATABASE_URL: postgresql://mattis:mattis@postgres:5432/mattis
steps:
- *node-checkout
- *node-setup
- *node-install-dependencies
- &next-cache
name: Cache Next.js build artifacts
uses: actions/cache@v4
with:
path: .next/cache
key: ${{ runner.os }}-next-cache-${{ hashFiles('package-lock.json') }}
restore-keys: |
${{ runner.os }}-next-cache-
- &copy-example-env
name: Copy .env.example to .env
run: cp .env.example .env
- name: Seed database
run: npm run seed
- name: Build application
run: npm run build
- name: Run Playwright tests
run: npm run test:e2e
- name: Upload Playwright report
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: reports/playwright/
retention-days: 30
- name: Dependency Review
if: github.event_name == 'pull_request'
uses: actions/dependency-review-action@v4
accessibility:
name: Accessibility
runs-on: ubuntu-latest
timeout-minutes: 20
services:
postgres:
image: postgres:17
ports:
- 5432:5432
env:
POSTGRES_DB: mattis
POSTGRES_USER: mattis
POSTGRES_PASSWORD: mattis
options: >-
--health-cmd "pg_isready -U mattis -d mattis"
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
DATABASE_URL: postgresql://mattis:mattis@localhost:5432/mattis
NEXT_PUBLIC_APP_URL: http://127.0.0.1:3000
steps:
- *node-checkout
- *node-setup
- *node-install-dependencies
- *copy-example-env
- name: Seed database
run: npm run seed
- name: Build application
run: npm run build
- name: Start application
run: |
PORT=3000 npm run start > /tmp/next.log 2>&1 &
- name: Wait for application
run: |
for i in {1..30}; do
if curl -fsS http://127.0.0.1:3000/ >/dev/null; then
exit 0
fi
sleep 2
done
echo "Application did not start in time"
cat /tmp/next.log
exit 1
- name: Run accessibility checks
run: npm run test:accessibility
build:
name: Build
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- *node-checkout
- *node-setup
- *node-install-dependencies
- *next-cache
- *copy-example-env
- name: Build and package Lambda function
run: npm run build:lambda
- name: Clean up build-time env
working-directory: build
run: rm -f .env
- name: Zip Lambda function
working-directory: build
run: zip -qr function.zip .
# Upload build artifacts for deploy (only on push to main)
- name: Upload Lambda artifact
uses: actions/upload-artifact@v4
with:
name: lambda-function
path: build/function.zip
if-no-files-found: error
retention-days: 3
plan:
name: Plan
runs-on: ubuntu-latest
needs:
- build
if: github.event_name == 'pull_request'
timeout-minutes: 30
steps:
- *tf-checkout
- *tf-setup
- &tf-download-artifact
name: Download Build Artifacts
uses: actions/download-artifact@v5
with:
name: lambda-function
path: iac/build
- *tf-init
- name: Terraform plan
working-directory: iac
run: terraform plan -input=false
deploy:
name: Deploy
runs-on: ubuntu-latest
needs:
- code-quality
- unit-tests
- infra
- e2e
- accessibility
- build
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
environment: production
timeout-minutes: 30
steps:
- *tf-checkout
- *tf-setup
- *tf-download-artifact
- *tf-init
- name: Terraform apply
working-directory: iac
run: terraform apply -auto-approve -input=false
- name: Capture Terraform outputs
id: tf_outputs
working-directory: iac
run: |
echo "database_url=$(terraform output -raw database_url)" >> "$GITHUB_OUTPUT"
- *node-setup
- *node-install-dependencies
- name: Run database migrations
env:
DATABASE_URL: ${{ steps.tf_outputs.outputs.database_url }}
run: npm run db:migrate