Skip to content

fix: neutral state for dashboard kpis #69

fix: neutral state for dashboard kpis

fix: neutral state for dashboard kpis #69

Workflow file for this run

name: CI and Deploy
on:
pull_request:
push:
branches:
- main
workflow_dispatch:
inputs:
rebuild_migrate:
description: Rebuild and publish the migrate image before deploy
required: false
default: false
type: boolean
env:
REGISTRY: ghcr.io
APP_IMAGE_NAME: ${{ github.repository }}
MIGRATE_IMAGE_NAME: ${{ github.repository }}-migrate
jobs:
verify:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@v5
- name: Set up Bun
uses: oven-sh/setup-bun@v2
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Typecheck
run: bun typecheck
- name: Test
run: bun test
- name: Build app bundle
run: bun run build
publish-and-deploy:
if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main'
needs: verify
runs-on: ubuntu-24.04-arm
environment: production
concurrency:
group: production-deploy
cancel-in-progress: true
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v5
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Log in to GHCR
uses: docker/login-action@v4
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Resolve migrate image
id: migrate-image
env:
FORCE_REBUILD_MIGRATE: ${{ github.event_name == 'workflow_dispatch' && inputs.rebuild_migrate || 'false' }}
MIGRATE_IMAGE_TAG: inputs-${{ hashFiles('Dockerfile', 'package.json', 'bun.lock', 'drizzle.config.ts', 'drizzle/**', 'src/db/**') }}
run: |
set -euo pipefail
cache_image="$REGISTRY/$MIGRATE_IMAGE_NAME:$MIGRATE_IMAGE_TAG"
build_migrate=false
if [ "$FORCE_REBUILD_MIGRATE" = "true" ]; then
build_migrate=true
elif ! docker buildx imagetools inspect "$cache_image" >/dev/null 2>&1; then
build_migrate=true
fi
echo "build=$build_migrate" >> "$GITHUB_OUTPUT"
echo "cache_image=$cache_image" >> "$GITHUB_OUTPUT"
- name: Build and push app image
uses: docker/build-push-action@v7
with:
context: .
pull: true
platforms: linux/arm64
push: true
target: release
tags: |
${{ env.REGISTRY }}/${{ env.APP_IMAGE_NAME }}:latest
${{ env.REGISTRY }}/${{ env.APP_IMAGE_NAME }}:sha-${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Build and push migrate image
if: steps.migrate-image.outputs.build == 'true'
uses: docker/build-push-action@v7
with:
context: .
pull: true
platforms: linux/arm64
push: true
target: migrate
tags: |
${{ steps.migrate-image.outputs.cache_image }}
${{ env.REGISTRY }}/${{ env.MIGRATE_IMAGE_NAME }}:latest
${{ env.REGISTRY }}/${{ env.MIGRATE_IMAGE_NAME }}:sha-${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Configure SSH
env:
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
DEPLOY_SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
run: |
install -m 700 -d ~/.ssh
printf '%s\n' "$DEPLOY_SSH_KEY" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
ssh-keyscan -H "$DEPLOY_HOST" > ~/.ssh/known_hosts
- name: Deploy release
env:
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
DEPLOY_PATH: ${{ secrets.DEPLOY_PATH }}
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
APP_IMAGE: ${{ env.REGISTRY }}/${{ env.APP_IMAGE_NAME }}:sha-${{ github.sha }}
GHCR_USERNAME: ${{ github.actor }}
GHCR_TOKEN: ${{ secrets.GITHUB_TOKEN }}
MIGRATE_IMAGE: ${{ steps.migrate-image.outputs.cache_image }}
run: |
printf '%s\n' "$GHCR_TOKEN" | ssh "$DEPLOY_USER@$DEPLOY_HOST" "docker login ghcr.io -u '$GHCR_USERNAME' --password-stdin"
ssh "$DEPLOY_USER@$DEPLOY_HOST" "mkdir -p '$DEPLOY_PATH'"
cat docker-compose.deploy.yml | ssh "$DEPLOY_USER@$DEPLOY_HOST" "cat > '$DEPLOY_PATH/docker-compose.deploy.yml'"
ssh "$DEPLOY_USER@$DEPLOY_HOST" <<EOF
set -e
cd "$DEPLOY_PATH"
export KLEIS_APP_IMAGE="$APP_IMAGE"
export KLEIS_MIGRATE_IMAGE="$MIGRATE_IMAGE"
docker compose -f docker-compose.deploy.yml pull
docker compose -f docker-compose.deploy.yml run --rm --interactive=false migrate
docker compose -f docker-compose.deploy.yml up -d app
docker image prune -af
EOF