From 8c974a49cc2e3725bffa74492a8ec5b0659a9ab3 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Tue, 6 Oct 2026 15:35:32 +0200 Subject: [PATCH] Merge workflows into one CI pipeline - Unit tests, integration tests and the Docker build check run in parallel on branches and pull requests - Integration tests run on every push instead of only manually - Branch builds only build amd64 and check the arm64 cross-compile in the test job; both platforms are built and pushed only for version tags, after all tests pass - Docker layers cached through the runner cache, Go module and build caches mounted in the Dockerfile - A newer push to the same branch cancels the running pipeline --- .gitea/workflows/ci.yaml | 107 ++++++++++++++++++++++++ .gitea/workflows/gitea-build.yaml | 48 ----------- .gitea/workflows/gitea-release.yaml | 50 ----------- .gitea/workflows/integration-tests.yaml | 18 ---- Dockerfile | 8 +- 5 files changed, 112 insertions(+), 119 deletions(-) create mode 100644 .gitea/workflows/ci.yaml delete mode 100644 .gitea/workflows/gitea-build.yaml delete mode 100644 .gitea/workflows/gitea-release.yaml delete mode 100644 .gitea/workflows/integration-tests.yaml diff --git a/.gitea/workflows/ci.yaml b/.gitea/workflows/ci.yaml new file mode 100644 index 0000000..0715065 --- /dev/null +++ b/.gitea/workflows/ci.yaml @@ -0,0 +1,107 @@ +name: CI + +# Branches and pull requests: unit tests, integration tests and a check that the image builds (amd64 only). +# Version tags (v1.2.3): the same tests, then build amd64 + arm64 and push the image. +on: + push: + branches: + - main + - develop + tags: + - "v*.*.*" + pull_request: + workflow_dispatch: + +# A newer push to the same branch cancels the run that is still going. +concurrency: + group: ci-${{ gitea.ref }} + cancel-in-progress: true + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version-file: go.mod + - name: Generate templ components + run: go tool templ generate + - name: Vet + run: go vet ./... && go vet -tags integration ./... + - name: Unit tests + run: go test -race ./... + - name: Cross-compile for arm64 + run: GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -o /dev/null ./cmd + + integration: + runs-on: ubuntu-latest + env: + # The test helper stops its own container, so the reaper container is not needed. + TESTCONTAINERS_RYUK_DISABLED: "true" + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version-file: go.mod + - name: Generate templ components + run: go tool templ generate + - name: Integration tests (PostgreSQL via testcontainers) + run: go test -tags integration -race -timeout 15m ./internal/db/... ./internal/backend/... + + # Checks that the image builds. Runs in parallel with the tests; nothing is pushed. + docker: + if: ${{ !startsWith(gitea.ref, 'refs/tags/') }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: docker/setup-buildx-action@v3 + with: + config-inline: | + [registry."gitea.sanplex.xyz/sansan"] + http = true + insecure = true + - name: Login to Gitea + uses: docker/login-action@v3 + with: + registry: gitea.sanplex.xyz + username: ${{ github.repository_owner }} + password: ${{ secrets.TOKEN }} + - name: Build (amd64) + uses: docker/build-push-action@v6 + with: + context: . + platforms: linux/amd64 + push: false + cache-from: type=gha + cache-to: type=gha,mode=max,ignore-error=true + + # Only for version tags, and only when all tests have passed. + publish: + if: ${{ startsWith(gitea.ref, 'refs/tags/v') }} + needs: [test, integration] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: docker/setup-buildx-action@v3 + with: + config-inline: | + [registry."gitea.sanplex.xyz/sansan"] + http = true + insecure = true + - name: Login to Gitea + uses: docker/login-action@v3 + with: + registry: gitea.sanplex.xyz + username: ${{ github.repository_owner }} + password: ${{ secrets.TOKEN }} + - name: Build and push (amd64 + arm64) + uses: docker/build-push-action@v6 + with: + context: . + platforms: linux/amd64,linux/arm64 + push: true + cache-from: type=gha + tags: | + gitea.sanplex.xyz/sansan/musicserver:${{ gitea.ref_name }} + gitea.sanplex.xyz/sansan/musicserver:latest diff --git a/.gitea/workflows/gitea-build.yaml b/.gitea/workflows/gitea-build.yaml deleted file mode 100644 index 6615834..0000000 --- a/.gitea/workflows/gitea-build.yaml +++ /dev/null @@ -1,48 +0,0 @@ -name: Build - -on: - push: - branches: - - main - - develop - -jobs: - test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 - with: - go-version-file: go.mod - - name: Generate templ components - run: go tool templ generate - - name: Vet - run: go vet ./... - - name: Unit tests - run: go test -race ./... - - docker: - needs: test - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - with: - config-inline: | - [registry."gitea.sanplex.xyz/sansan"] - http = true - insecure = true - - name: Login to Gitea - uses: docker/login-action@v3 - with: - registry: gitea.sanplex.xyz - username: ${{ github.repository_owner }} - password: ${{ secrets.TOKEN }} - - name: Build - uses: docker/build-push-action@v6 - with: - context: . - file: ./Dockerfile - platforms: linux/amd64,linux/arm64 - push: false diff --git a/.gitea/workflows/gitea-release.yaml b/.gitea/workflows/gitea-release.yaml deleted file mode 100644 index 933cb0e..0000000 --- a/.gitea/workflows/gitea-release.yaml +++ /dev/null @@ -1,50 +0,0 @@ -name: Publish - -on: - push: - tags: - - "v*.*.*" - -jobs: - test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 - with: - go-version-file: go.mod - - name: Generate templ components - run: go tool templ generate - - name: Vet - run: go vet ./... - - name: Unit tests - run: go test -race ./... - - publish: - needs: test - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - with: - config-inline: | - [registry."gitea.sanplex.xyz/sansan"] - http = true - insecure = true - - name: Login to Gitea - uses: docker/login-action@v3 - with: - registry: gitea.sanplex.xyz - username: ${{ github.repository_owner }} - password: ${{ secrets.TOKEN }} - - name: Build and push Docker image - uses: docker/build-push-action@v6 - with: - context: . - file: ./Dockerfile - platforms: linux/amd64,linux/arm64 - push: true - tags: | - gitea.sanplex.xyz/sansan/musicserver:${{ gitea.ref_name }} - gitea.sanplex.xyz/sansan/musicserver:latest diff --git a/.gitea/workflows/integration-tests.yaml b/.gitea/workflows/integration-tests.yaml deleted file mode 100644 index 3bb144f..0000000 --- a/.gitea/workflows/integration-tests.yaml +++ /dev/null @@ -1,18 +0,0 @@ -name: Integration Tests - -on: - workflow_dispatch: # Manual trigger only - -jobs: - integration-test: - # Needs access to a Docker daemon: the tests start PostgreSQL with testcontainers. - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 - with: - go-version-file: go.mod - - name: Generate templ components - run: go tool templ generate - - name: Integration tests - run: go test -tags integration -race -timeout 15m ./... diff --git a/Dockerfile b/Dockerfile index 5001ed6..0d87088 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,11 +7,13 @@ FROM --platform=$BUILDPLATFORM golang:1.25-alpine AS build ARG TARGETOS TARGETARCH WORKDIR /app COPY go.mod go.sum ./ -RUN go mod download +RUN --mount=type=cache,target=/go/pkg/mod go mod download COPY cmd/ ./cmd/ COPY internal/ ./internal/ -RUN go tool templ generate -RUN CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH \ +RUN --mount=type=cache,target=/go/pkg/mod --mount=type=cache,target=/root/.cache/go-build \ + go tool templ generate +RUN --mount=type=cache,target=/go/pkg/mod --mount=type=cache,target=/root/.cache/go-build \ + CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH \ go build -trimpath -ldflags="-s -w" -tags timetzdata -o main ./cmd # Stage 2: Frontend static files (the same for every platform)