name: Server CI/CD on: push: branches: - "main" paths: - "typescript/server/**" - "typescript/common/**" - "typescript/db/**" - "typescript/db-migration-engine/**" - "docker/**" - "db/migrations/**" - ".github/workflows/server.yml" pull_request: branches: - "main" paths: - "typescript/server/**" - "typescript/common/**" - "typescript/db/**" - "typescript/db-migration-engine/**" - "docker/**" - "db/migrations/**" - ".github/workflows/server.yml" workflow_dispatch: permissions: contents: read concurrency: group: "server-${{ github.ref }}-${{ github.workflow }}" cancel-in-progress: false jobs: test: runs-on: ubuntu-latest container: image: ghcr.io/zkldi/tachi-dev:main options: --user root env: NODE_ENV: "test" services: tachi-postgres: image: postgres:18 env: POSTGRES_USER: tachi POSTGRES_PASSWORD: tachi POSTGRES_DB: postgres options: >- --health-cmd "pg_isready -U tachi" --health-interval 5s --health-timeout 5s --health-retries 10 tachi-redis: image: redis:7.4-alpine options: >- --health-cmd "redis-cli ping" --health-interval 5s --health-timeout 5s --health-retries 10 tachi-s3: image: quay.io/minio/minio:RELEASE.2024-10-29T16-01-48Z env: MINIO_ROOT_USER: minio MINIO_ROOT_PASSWORD: password entrypoint: /usr/bin/minio command: server /data --console-address=:9001 options: >- --health-cmd "curl -f http://localhost:9000/minio/health/live" --health-interval 5s --health-timeout 5s --health-retries 10 steps: - name: Checkout uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - name: Link workspace to /tachi # tachidb, just recipes, and .env.test all assume the repo lives at /tachi. # GHA mounts the workspace elsewhere, so we replace the empty /tachi dir # (created by the image's WORKDIR) with a symlink to the real checkout. run: rm -rf /tachi && ln -sf "$GITHUB_WORKSPACE" /tachi - name: Install dependencies run: bun install --frozen-lockfile - name: Lint code run: bun run --filter tachi-server lint - name: Typecheck code run: bun run --filter tachi-server typecheck - name: Run tests run: bun run --filter tachi-server test env: NODE_ENV: "test" PORT: 8080 docker-push: runs-on: ubuntu-latest needs: [test] if: ${{ github.event_name == 'push' || github.event_name == 'workflow_dispatch' }} permissions: contents: read packages: write steps: - name: Checkout uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - name: Log in to GHCR uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Set up Docker Buildx uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3.7.1 - name: Read server package version id: server_version run: | echo "version=$(jq -r .version typescript/server/package.json)" >> "$GITHUB_OUTPUT" - name: Build and push unified server image uses: docker/build-push-action@48aba3b46d1b1fec4febb7c5d0c644b249a11355 # v6.10.0 with: context: . file: docker/Dockerfile.server target: prod push: ${{ github.ref == 'refs/heads/main' }} provenance: true sbom: true tags: | ghcr.io/zkldi/tachi:${{ github.sha }} ghcr.io/zkldi/tachi:main ghcr.io/zkldi/tachi:latest build-args: | VERSION=${{ steps.server_version.outputs.version }} COMMIT_HASH=${{ github.sha }} cache-from: type=gha,scope=server-${{ github.ref_name }} cache-to: type=gha,mode=max,scope=server-${{ github.ref_name }} deploy: runs-on: ubuntu-latest needs: [test, docker-push] if: ${{ github.ref == 'refs/heads/main' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') }} strategy: fail-fast: false max-parallel: 1 matrix: destination: [boku, kamai, dev] permissions: contents: read steps: - name: Enable SSH env: SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} SSH_KNOWN_HOSTS: ${{ secrets.SSH_KNOWN_HOSTS }} run: | mkdir -p ~/.ssh printf '%s' "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa printf '%s' "$SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts - name: Deploy on server env: TACHI_HOST: ${{ secrets.TACHI_HOST }} run: ssh "ci@${TACHI_HOST}" "/home/ci/tachi-deploy/swarm/deploy-server.sh ${{ matrix.destination }} ${{ github.sha }}"