gitmote

gitmote / .github / workflows / ci.yml  ·  history  ·  branches

4016 bytes · raw

name: ci

on:
  push:
    branches: [master]
  pull_request:
  workflow_dispatch:

jobs:
  ci:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-go@v5
        with:
          go-version-file: go.mod
      - run: make all

  # Self-hosting proof: push/clone the real repo against a gitmote container
  # backed by MinIO (scripts/e2e-local.sh), the litestream cold-start restore
  # (scripts/e2e-restore.sh), and the CI image-build gate (scripts/e2e-build.sh).
  # Gated — builds an image and runs Docker, so it stays off the fast per-PR path
  # and runs on master / on demand.
  e2e:
    if: github.ref == 'refs/heads/master' || github.event_name == 'workflow_dispatch'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0 # push needs the full history, not a shallow clone
      - run: make e2e-local
      - run: make e2e-restore
      - run: make e2e-build

  # Deploy the single writer to Scaleway on every green master push (docs/ops.md).
  # Safety is by lease, not procedure: the server runs in s3lite RoleAuto, so a
  # rolling deploy's brief old+new overlap is one writer + one read-only follower,
  # never two writers (safety.md §1). max-scale=1 is still asserted (read replicas
  # need fresh followers first — a later step).
  deploy:
    if: github.ref == 'refs/heads/master'
    needs: [ci, e2e]
    runs-on: ubuntu-latest
    # packages: write publishes the public image to GHCR via the built-in
    # GITHUB_TOKEN; Scaleway then pulls it anonymously (docs/ops.md). New GHCR
    # packages default to private — flip gitmote to public once by hand.
    permissions:
      contents: read
      packages: write
    steps:
      - uses: actions/checkout@v4
      - uses: docker/setup-qemu-action@v3   # arm64 runtime stage runs apt-get under emulation
      - uses: docker/setup-buildx-action@v3

      - name: Login to GHCR
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Build & push public image (amd64 for Scaleway + arm64 for local dev)
        uses: docker/build-push-action@v6
        with:
          context: .
          platforms: linux/amd64,linux/arm64
          push: true
          build-args: |
            VERSION=${{ github.sha }}
          tags: |
            ghcr.io/atmin/gitmote:master
            ghcr.io/atmin/gitmote:${{ github.sha }}

      - name: Install Scaleway CLI
        run: |
          SCW_URL=$(curl -s https://api.github.com/repos/scaleway/scaleway-cli/releases/latest \
            | grep -o '"browser_download_url": *"[^"]*linux_amd64"' | cut -d'"' -f4)
          sudo curl -fsSL "$SCW_URL" -o /usr/local/bin/scw
          sudo chmod +x /usr/local/bin/scw

      # No drain step: the writer lease makes the rolling deploy safe by
      # construction. The new instance boots as a read-only follower (the old one
      # holds the lease), the old releases on its graceful SIGTERM, then the new
      # promotes — never two writers (safety.md §1, docs/ops.md).
      #
      # A unique (SHA-tagged) image reference makes this a clean replacement, and
      # max-scale=1 (still the steady-state pin) is re-asserted every deploy.
      # min-scale=0 idles to zero between uses. --wait blocks until the new
      # deployment is serving. See docs/ops.md for the single-writer deploy note.
      - name: Deploy (single writer)
        env:
          SCW_SECRET_KEY: ${{ secrets.SCW_SECRET_KEY }}
          SCW_ACCESS_KEY: ${{ secrets.SCW_ACCESS_KEY }}
          SCW_DEFAULT_ORGANIZATION_ID: ${{ secrets.SCW_ORGANIZATION_ID }}
          SCW_DEFAULT_PROJECT_ID: ${{ secrets.SCW_PROJECT_ID }}
          SCW_DEFAULT_REGION: fr-par
        run: |
          scw container container update ${{ secrets.SCW_CONTAINER_ID }} \
            image=ghcr.io/atmin/gitmote:${{ github.sha }} \
            min-scale=0 max-scale=1 --wait