mirror of
https://github.com/whekin/household-bot.git
synced 2026-03-31 13:54:02 +00:00
Update GitHub Actions workflows to rely on repository variables and simplify build/deploy logic. cd.yml: switch secret/project lookups to vars, adjust workflow_run detection for auto-deploy, remove derived secret outputs, resolve Artifact Registry image tags from the triggering SHA, and use vars for Google Cloud auth and project references. ci.yml: add dev to PR branches, condense the quality matrix commands, rework the images job to authenticate and push only on branch pushes while doing build-only on PRs (with proper cache usage), add id-token permission, and introduce a final CI gate job that aggregates job results to block CD when CI fails. Also includes minor formatting and whitespace cleanups.
202 lines
5.6 KiB
YAML
202 lines
5.6 KiB
YAML
name: CI
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- main
|
|
- dev
|
|
pull_request:
|
|
branches:
|
|
- main
|
|
- dev
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
concurrency:
|
|
group: ci-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
quality:
|
|
name: Quality / ${{ matrix.task }}
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 20
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
task:
|
|
- format
|
|
- lint
|
|
- typecheck
|
|
- test
|
|
- build
|
|
- db-check
|
|
- db-migrations
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Setup Bun
|
|
uses: oven-sh/setup-bun@v2
|
|
with:
|
|
bun-version-file: .bun-version
|
|
|
|
- name: Restore Bun cache
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: |
|
|
~/.bun/install/cache
|
|
node_modules
|
|
key: ${{ runner.os }}-bun-${{ hashFiles('bun.lock') }}
|
|
restore-keys: |
|
|
${{ runner.os }}-bun-
|
|
|
|
- name: Install dependencies
|
|
run: bun install --frozen-lockfile
|
|
|
|
- name: Run quality gate
|
|
run: |
|
|
case "${{ matrix.task }}" in
|
|
format) bun run format:check ;;
|
|
lint) bun run lint ;;
|
|
typecheck) bun run typecheck ;;
|
|
test) bun run test ;;
|
|
build) bun run build ;;
|
|
db-check) bun run db:check ;;
|
|
db-migrations) bun run db:migrations:check ;;
|
|
*) echo "Unknown task: ${{ matrix.task }}"; exit 1 ;;
|
|
esac
|
|
|
|
terraform:
|
|
name: Terraform / validate
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 10
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Setup Terraform
|
|
uses: hashicorp/setup-terraform@v3
|
|
with:
|
|
terraform_version: 1.8.5
|
|
|
|
- name: Terraform format check
|
|
run: terraform -chdir=infra/terraform fmt -check -recursive
|
|
|
|
- name: Terraform validate
|
|
run: |
|
|
terraform -chdir=infra/terraform init -backend=false
|
|
terraform -chdir=infra/terraform validate
|
|
|
|
images-pr:
|
|
name: Docker / build (PR)
|
|
if: github.event_name == 'pull_request'
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 20
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
service:
|
|
- bot
|
|
- miniapp
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set up Docker Buildx
|
|
uses: docker/setup-buildx-action@v3
|
|
|
|
- name: Build only
|
|
uses: docker/build-push-action@v6
|
|
with:
|
|
context: .
|
|
file: apps/${{ matrix.service }}/Dockerfile
|
|
push: false
|
|
tags: household-${{ matrix.service }}:ci
|
|
cache-from: type=gha
|
|
cache-to: type=gha,mode=max
|
|
|
|
images-push:
|
|
name: Docker / build & push ${{ matrix.service }}
|
|
if: github.event_name == 'push'
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 20
|
|
environment: ${{ github.ref_name == 'main' && 'Production' || 'Development' }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
service:
|
|
- bot
|
|
- miniapp
|
|
permissions:
|
|
contents: read
|
|
id-token: write
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set up Docker Buildx
|
|
uses: docker/setup-buildx-action@v3
|
|
|
|
- name: Authenticate to Google Cloud
|
|
uses: google-github-actions/auth@v2
|
|
with:
|
|
workload_identity_provider: ${{ vars.GCP_WORKLOAD_IDENTITY_PROVIDER }}
|
|
service_account: ${{ vars.GCP_SERVICE_ACCOUNT }}
|
|
|
|
- name: Configure Artifact Registry auth
|
|
run: |
|
|
gcloud auth configure-docker "${{ vars.GCP_REGION || 'europe-west1' }}-docker.pkg.dev" --quiet
|
|
|
|
- name: Resolve image name
|
|
id: image
|
|
env:
|
|
GCP_REGION: ${{ vars.GCP_REGION || 'europe-west1' }}
|
|
ARTIFACT_REPOSITORY: ${{ vars.ARTIFACT_REPOSITORY || 'household-bot' }}
|
|
run: |
|
|
repo="${GCP_REGION}-docker.pkg.dev/${{ vars.GCP_PROJECT_ID }}/${ARTIFACT_REPOSITORY}"
|
|
echo "name=${repo}/${{ matrix.service }}:${GITHUB_SHA}" >> "$GITHUB_OUTPUT"
|
|
echo "cache_ref=${repo}/${{ matrix.service }}:cache" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Build and push
|
|
uses: docker/build-push-action@v6
|
|
with:
|
|
context: .
|
|
file: apps/${{ matrix.service }}/Dockerfile
|
|
push: true
|
|
tags: ${{ steps.image.outputs.name }}
|
|
cache-from: type=registry,ref=${{ steps.image.outputs.cache_ref }}
|
|
cache-to: type=registry,ref=${{ steps.image.outputs.cache_ref }},mode=max
|
|
|
|
# Gate job: CD triggers on this workflow's conclusion.
|
|
# By depending on all jobs, a failure in any job marks CI as failed,
|
|
# which causes CD's `workflow_run` trigger to see conclusion != 'success'
|
|
# and skip deployment.
|
|
ci:
|
|
name: CI complete
|
|
runs-on: ubuntu-latest
|
|
needs: [quality, terraform, images-pr, images-push]
|
|
if: always()
|
|
steps:
|
|
- name: Check all jobs passed
|
|
run: |
|
|
results='${{ toJSON(needs) }}'
|
|
echo "Job results: $results"
|
|
|
|
failed=false
|
|
for result in $(echo "$results" | jq -r '.[].result'); do
|
|
# 'skipped' is expected — images-pr skips on push, images-push skips on PR
|
|
if [[ "$result" != "success" && "$result" != "skipped" ]]; then
|
|
echo "Job failed with result: $result"
|
|
failed=true
|
|
fi
|
|
done
|
|
|
|
if [[ "$failed" == "true" ]]; then
|
|
echo "One or more CI jobs failed — blocking deployment."
|
|
exit 1
|
|
fi
|
|
|
|
echo "All CI jobs passed."
|