~bigbes/ci-cacher

8a662e226904e90b79034c43f58b1a124770b17e — Eugene Blikh a day ago b659c69
merge .builds/{unit,e2e}.yml into test.yml; cache go + garage image

Single job runs unit tests → smoke build → e2e (against a real Garage
container via testcontainers-go). Unit failure short-circuits before
paying the ~150 MB Garage image pull.

Caches via dogfooded cacher:
* Go tarball — `cacher download --url` fallback, same pattern as
  publish.yml.
* Garage docker image — `cacher download` of the tar; on miss does
  docker pull + save + upload to seed.

Also silences testcontainers' default logger in the garage testutil
(pull progress, container IDs, port mappings); test output now only
shows what the tests print themselves. `-v` dropped from the e2e
`go test` since per-test progress is no longer drowned out and not
worth printing on green runs.

`TESTCONTAINERS_RYUK_DISABLED=true` — VM is torn down at job end,
reaper container is just startup noise.

Verified end-to-end on job #153 (all 8 tasks ✔, cache MISS seeded).
4 files changed, 101 insertions(+), 70 deletions(-)

D .builds/e2e.yml
A .builds/test.yml
D .builds/unit.yml
M internal/testutil/garage/container.go
D .builds/e2e.yml => .builds/e2e.yml +0 -36
@@ 1,36 0,0 @@
# End-to-end tests against a real Garage container via testcontainers-go.
# Requires Docker on the build VM, which is why this is split from unit.yml.
# Pulls dxflrs/garage:v2.3.0 (~150 MB) once per build then runs ~6 subtests
# each against a fresh container — total ~30s after the image pull.
image: ubuntu/noble
packages:
  - curl
  - ca-certificates
  - docker.io
sources:
  - https://git.srht.bigb.es/~bigbes/ci-cacher
environment:
  GO_VERSION: "1.26.3"
  PATH: /home/build/.local/go/bin:/home/build/.local/bin:/usr/local/bin:/usr/bin:/bin
submitter:
  git.sr.ht:
    enabled: true
    allow-refs:
      - refs/heads/master
      - "refs/tags/*"
tasks:
  - install_go: |
      GO_TARBALL="go${GO_VERSION}.linux-amd64.tar.gz"
      mkdir -p ~/.local
      curl -sSL "https://go.dev/dl/$GO_TARBALL" -o "/tmp/$GO_TARBALL"
      tar -xz -C ~/.local -f "/tmp/$GO_TARBALL"
      rm "/tmp/$GO_TARBALL"
      go version
  - docker_start: |
      sudo systemctl start docker
      sudo usermod -aG docker build
      sudo chmod 666 /var/run/docker.sock
      docker version
  - test_e2e: |
      cd ci-cacher
      go test -tags=e2e -timeout=10m -v ./...

A .builds/test.yml => .builds/test.yml +89 -0
@@ 0,0 1,89 @@
# Unit tests + smoke build first, then end-to-end tests against a real
# Garage container via testcontainers-go. Merged into one job so the Go
# install is shared and a unit-test failure short-circuits before paying
# the ~150 MB Garage image pull.
#
# Order: install_cacher → cacher_init → install_go → test → build →
#        docker_start → cache_garage_image → test_e2e.
#
# Dogfoods cacher to cache both the Go tarball (via --url fallback) and
# the Garage docker image tarball (via explicit upload on miss). First
# run seeds the cache from upstream; subsequent runs pull from
# s3.bigb.es and skip the upstream round-trip.
image: ubuntu/noble
packages:
  - curl
  - ca-certificates
  - docker.io
secrets:
  - 7dde4219-0783-4581-a67d-c94749de3600   # ~/.s3-cache-key-id
  - 0e5b3530-6f19-4f30-9b73-9339dd382e46   # ~/.s3-cache-key-secret
sources:
  - https://git.srht.bigb.es/~bigbes/ci-cacher
environment:
  GO_VERSION: "1.26.3"
  PATH: /home/build/.local/go/bin:/home/build/.local/bin:/usr/local/bin:/usr/bin:/bin
  PAGES_DOMAIN: bigbes.pages.srht.bigb.es
  PAGES_SUBPATH: /ci-cacher
  # Keep in sync with internal/testutil/garage/container.go const Image.
  GARAGE_IMAGE: "dxflrs/garage:v2.3.0"
  # No Ryuk reaper — the VM is torn down at job end, so the reaper
  # container only adds startup logs we don't need.
  TESTCONTAINERS_RYUK_DISABLED: "true"
submitter:
  git.sr.ht:
    enabled: true
    allow-refs:
      - refs/heads/master
      - "refs/tags/*"
tasks:
  - install_cacher: |
      mkdir -p ~/.local/bin
      curl -sSL "https://${PAGES_DOMAIN}${PAGES_SUBPATH}/cacher-linux-amd64" \
        -o ~/.local/bin/cacher
      chmod +x ~/.local/bin/cacher
      cacher version
  - cacher_init: |
      cacher init \
        --endpoint    https://s3.bigb.es \
        --region      garage \
        --bucket      docker-cache \
        --prefix      ci-cacher/deps \
        --key-file    ~/.s3-cache-key-id \
        --secret-file ~/.s3-cache-key-secret
  - install_go: |
      GO_TARBALL="go${GO_VERSION}.linux-amd64.tar.gz"
      mkdir -p ~/.local
      cacher download "golang/${GO_TARBALL}" "/tmp/${GO_TARBALL}" \
        --url "https://go.dev/dl/${GO_TARBALL}"
      tar -xz -C ~/.local -f "/tmp/${GO_TARBALL}"
      rm "/tmp/${GO_TARBALL}"
      go version
  - test: |
      cd ci-cacher
      go test ./...
  - build: |
      cd ci-cacher
      go build -ldflags "-X go.bigb.es/cacher/internal/version.version=$(cat VERSION)" -o cacher .
      ./cacher version
  - docker_start: |
      sudo systemctl start docker
      sudo usermod -aG docker build
      sudo chmod 666 /var/run/docker.sock
      docker version
  - cache_garage_image: |
      # Key derived from the image ref so a version bump invalidates
      # the cache automatically: dxflrs/garage:v2.3.0 → dxflrs-garage-v2.3.0
      KEY="garage/$(echo "$GARAGE_IMAGE" | tr '/:' '-').tar"
      if cacher download "$KEY" /tmp/garage.tar; then
        docker load -i /tmp/garage.tar
      else
        docker pull "$GARAGE_IMAGE"
        docker save "$GARAGE_IMAGE" -o /tmp/garage.tar
        cacher upload "$KEY" /tmp/garage.tar
      fi
      rm -f /tmp/garage.tar
      docker images "$GARAGE_IMAGE"
  - test_e2e: |
      cd ci-cacher
      go test -tags=e2e -timeout=10m ./...

D .builds/unit.yml => .builds/unit.yml +0 -34
@@ 1,34 0,0 @@
# Unit tests + smoke build. Runs on every push to master and on tags.
# Pure Go, no docker, so we use ubuntu/noble with a manual Go install
# (matches the style of tarantool-protobuf .builds, which is the
# primary downstream consumer of this binary).
image: ubuntu/noble
packages:
  - curl
  - ca-certificates
sources:
  - https://git.srht.bigb.es/~bigbes/ci-cacher
environment:
  GO_VERSION: "1.26.3"
  PATH: /home/build/.local/go/bin:/home/build/.local/bin:/usr/local/bin:/usr/bin:/bin
submitter:
  git.sr.ht:
    enabled: true
    allow-refs:
      - refs/heads/master
      - "refs/tags/*"
tasks:
  - install_go: |
      GO_TARBALL="go${GO_VERSION}.linux-amd64.tar.gz"
      mkdir -p ~/.local
      curl -sSL "https://go.dev/dl/$GO_TARBALL" -o "/tmp/$GO_TARBALL"
      tar -xz -C ~/.local -f "/tmp/$GO_TARBALL"
      rm "/tmp/$GO_TARBALL"
      go version
  - test: |
      cd ci-cacher
      go test ./...
  - build: |
      cd ci-cacher
      go build -ldflags "-X go.bigb.es/cacher/internal/version.version=$(cat VERSION)" -o cacher .
      ./cacher version

M internal/testutil/garage/container.go => internal/testutil/garage/container.go +12 -0
@@ 20,9 20,21 @@ import (
	"time"

	"github.com/testcontainers/testcontainers-go"
	tclog "github.com/testcontainers/testcontainers-go/log"
	"github.com/testcontainers/testcontainers-go/wait"
)

// Silence testcontainers' default chatty logging (pull progress, container
// IDs, reaper lifecycle, port mappings). Test output should only show what
// the tests themselves print.
func init() {
	tclog.SetDefault(noopLogger{})
}

type noopLogger struct{}

func (noopLogger) Printf(string, ...any) {}

// Image we pull. Pin to a known-good version so test runs are reproducible.
const Image = "dxflrs/garage:v2.3.0"