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