name: CI on: push: pull_request: env: REGISTRY_IMAGE: registry.neko-piranha.ts.net/astral/buzz-sheet REGISTRY_HOST: registry.neko-piranha.ts.net DEPLOY_NAMESPACE: buzz-sheet jobs: verify: name: Verify runs-on: ubuntu-latest timeout-minutes: 20 steps: - name: Check out repository uses: actions/checkout@v4 - name: Set up Bun uses: oven-sh/setup-bun@v2 with: bun-version: 1.3.14 - name: Install dependencies run: bun install --frozen-lockfile - name: Run unit and integration tests env: REDIS_INTEGRATION_URL: ${{ secrets.REDIS_INTEGRATION_URL }} run: bun run test - name: Generate route types and check TypeScript run: bun run typecheck - name: Lint run: bun run lint - name: Set up kubectl uses: azure/setup-kubectl@v4 - name: Validate Kubernetes manifests run: kubectl kustomize k8s/ >/dev/null build-and-deploy: name: Build immutable images and deploy needs: verify if: >- gitea.event_name == 'push' && gitea.ref == 'refs/heads/main' && vars.DEPLOY_ENABLED == 'true' runs-on: ubuntu-latest timeout-minutes: 45 steps: - name: Check out repository uses: actions/checkout@v4 - name: Set up QEMU uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Sign in to the container registry uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY_HOST }} username: ${{ secrets.REGISTRY_USERNAME }} password: ${{ secrets.REGISTRY_PASSWORD }} - name: Build and push application image uses: docker/build-push-action@v6 with: context: . file: Dockerfile target: app platforms: linux/arm64 push: true provenance: false tags: ${{ env.REGISTRY_IMAGE }}:${{ gitea.sha }} build-args: | NEXT_DEPLOYMENT_ID=${{ gitea.sha }} VCS_REF=${{ gitea.sha }} - name: Build and push migration image uses: docker/build-push-action@v6 with: context: . file: Dockerfile target: migration platforms: linux/arm64 push: true provenance: false tags: ${{ env.REGISTRY_IMAGE }}:migrate-${{ gitea.sha }} build-args: VCS_REF=${{ gitea.sha }} - name: Set up kubectl uses: azure/setup-kubectl@v4 - name: Migrate, then roll out the immutable revision env: KUBE_CONFIG_B64: ${{ secrets.KUBE_CONFIG_B64 }} REVISION: ${{ gitea.sha }} shell: bash run: | set -Eeuo pipefail kube_dir="$RUNNER_TEMP/buzz-sheet-kube" mkdir -p "$kube_dir" chmod 700 "$kube_dir" export KUBECONFIG="$kube_dir/config" printf '%s' "$KUBE_CONFIG_B64" | base64 --decode >"$KUBECONFIG" chmod 600 "$KUBECONFIG" revision_short="${REVISION:0:12}" migration_dir="$RUNNER_TEMP/buzz-sheet-migration-$revision_short" migration_manifest="$RUNNER_TEMP/buzz-sheet-migration-$revision_short.yaml" cp -R k8s/migration "$migration_dir" sed -i "s/name: buzz-sheet-migrate$/name: buzz-sheet-migrate-$revision_short/" "$migration_dir/job.yaml" sed -i "s#newName: .*#newName: $REGISTRY_IMAGE#" "$migration_dir/kustomization.yaml" sed -i "s/newTag: .*/newTag: migrate-$REVISION/" "$migration_dir/kustomization.yaml" kubectl kustomize "$migration_dir" >"$migration_manifest" migration_resource="$(kubectl --namespace "$DEPLOY_NAMESPACE" create -f "$migration_manifest" -o name)" if ! kubectl --namespace "$DEPLOY_NAMESPACE" wait \ --for=condition=complete \ --timeout=10m \ "$migration_resource"; then kubectl --namespace "$DEPLOY_NAMESPACE" logs "$migration_resource" --all-containers=true || true exit 1 fi kubectl --namespace "$DEPLOY_NAMESPACE" patch configmap buzz-sheet-config \ --type=merge \ --patch "{\"data\":{\"NEXT_DEPLOYMENT_ID\":\"$REVISION\"}}" kubectl --namespace "$DEPLOY_NAMESPACE" set image \ deployment/buzz-sheet \ app="$REGISTRY_IMAGE:$REVISION" kubectl --namespace "$DEPLOY_NAMESPACE" set image \ deployment/buzz-sheet-worker \ worker="$REGISTRY_IMAGE:$REVISION" kubectl --namespace "$DEPLOY_NAMESPACE" rollout status \ deployment/buzz-sheet \ --timeout=10m kubectl --namespace "$DEPLOY_NAMESPACE" rollout status \ deployment/buzz-sheet-worker \ --timeout=10m