# Gitea Actions — the live pipeline for this repository. # # Gitea Actions speaks GitHub Actions syntax, so this is a near-direct port of # .github/workflows/deploy.yml (kept as the OIDC reference in case the repo ever # moves to GitHub or GitLab). # # ONE REAL DIFFERENCE: Gitea is not an AWS OIDC provider, so there is no role to # assume. Deploys authenticate with a SCOPED IAM USER whose key lives only in # this repository's Gitea secrets. See docs/06-deployment.md for the exact IAM # policy — it grants four actions on one bucket and one distribution, nothing # more. Rotate the key quarterly; OIDC would have made that unnecessary. # # Requires a Gitea Actions runner registered to this repo or its organisation. name: Build and deploy on: push: branches: [main] workflow_dispatch: concurrency: group: deploy-production cancel-in-progress: false jobs: build-and-deploy: runs-on: ubuntu-latest env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} AWS_DEFAULT_REGION: ${{ vars.AWS_REGION }} S3_BUCKET: ${{ vars.S3_BUCKET }} CLOUDFRONT_DISTRIBUTION_ID: ${{ vars.CLOUDFRONT_DISTRIBUTION_ID }} steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version-file: .nvmrc cache: npm - name: Install run: npm ci - name: Type and template check run: npm run check - name: Build run: npm run build env: PUBLIC_SITE_URL: https://adr.smlcompany.ca PUBLIC_INTAKE_ENDPOINT: ${{ vars.INTAKE_ENDPOINT }} PUBLIC_BOOKING_URL: ${{ vars.BOOKING_URL }} # Some Gitea runner images ship without the AWS CLI. Install if missing. - name: Ensure AWS CLI run: | if ! command -v aws >/dev/null 2>&1; then curl -fsSL "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o /tmp/awscliv2.zip unzip -q /tmp/awscliv2.zip -d /tmp sudo /tmp/aws/install --update fi aws --version - name: Verify credentials run: aws sts get-caller-identity # Two passes: hashed immutable assets first, HTML last. A visitor must # never fetch a new page whose assets have not landed yet. - name: Sync hashed assets run: | aws s3 sync ./dist "s3://${S3_BUCKET}" \ --exclude "*" \ --include "_astro/*" --include "fonts/*" \ --cache-control "public, max-age=31536000, immutable" \ --no-progress - name: Sync images run: | aws s3 sync ./dist "s3://${S3_BUCKET}" \ --exclude "*" \ --include "*.avif" --include "*.webp" --include "*.jpg" \ --include "*.png" --include "*.svg" \ --cache-control "public, max-age=604800" \ --no-progress - name: Sync HTML and the rest run: | aws s3 sync ./dist "s3://${S3_BUCKET}" \ --exclude "_astro/*" --exclude "fonts/*" \ --cache-control "public, max-age=0, must-revalidate" \ --delete --no-progress - name: Invalidate CloudFront run: | aws cloudfront create-invalidation \ --distribution-id "${CLOUDFRONT_DISTRIBUTION_ID}" \ --paths "/*" - name: Summary run: echo "Deployed to https://adr.smlcompany.ca — commit ${GITHUB_SHA:0:7}"