Nik Afiq 1c3b10bdca
All checks were successful
CI / build-tts-sidecar (push) Has been skipped
CI / changes (push) Successful in 7s
CI / test (push) Successful in 6s
CI / build-ai-gateway (push) Successful in 1m10s
CI / build-ha-gateway (push) Successful in 52s
CI / build-discord-bot (push) Successful in 53s
CI / build-tts-gateway (push) Successful in 5m25s
Enhance CI/CD pipeline and Dockerfile optimizations
- Updated CI workflow to run `go vet` and `go test` for all modules on every push/PR.
- Implemented a `changes` job to rebuild only affected Docker images based on modified paths.
- Introduced caching for Docker builds to speed up subsequent runs by leveraging registry-based cache.
- Modified Dockerfiles for `ai-gateway`, `discord-bot`, `ha-gateway`, and `tts-gateway` to copy `go.mod` and `go.sum` files first, allowing for better caching of dependencies.
- Added `go.sum` file for `tts-gateway` to ensure proper dependency management.
- Ensured that `go mod download` is executed in the correct order to optimize layer caching.
2026-07-24 23:24:59 +09:00

244 lines
8.1 KiB
YAML

name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
env:
REGISTRY: gitea.nik4nao.com
IMAGE_PREFIX: gitea.nik4nao.com/nik
GOPATH: /tmp/go
GOMODCACHE: /tmp/go/pkg/mod
GOCACHE: /tmp/go-build
jobs:
# Determines which images actually need rebuilding for this push, so an
# edit scoped to one service doesn't rebuild (and re-push) all five. `gen/`,
# `go.work`, and `go.work.sum` are treated as shared - a change there can
# affect every Go module's resolved dependencies, so it marks all of them
# as changed rather than trying to model cross-module version unification
# precisely. `test` (go vet/go test) always runs regardless - it's fast and
# correctness-critical, not worth gating.
changes:
runs-on: ubuntu-latest
outputs:
ai-gateway: ${{ steps.filter.outputs.ai-gateway }}
ha-gateway: ${{ steps.filter.outputs.ha-gateway }}
discord-bot: ${{ steps.filter.outputs.discord-bot }}
tts-gateway: ${{ steps.filter.outputs.tts-gateway }}
tts-sidecar: ${{ steps.filter.outputs.tts-sidecar }}
steps:
- uses: actions/checkout@v6
- uses: dorny/paths-filter@v3
id: filter
with:
# Deliberately not using YAML anchors to dedupe the shared
# gen/**+go.work(.sum) paths across filters here - dorny/paths-filter
# parses this block as its own YAML document, and an anchor
# substitutes as a nested array (`[[...], 'x/**']`) rather than a
# flattened one, which risks silently matching nothing. Spelled out
# per-filter instead.
filters: |
ai-gateway:
- 'gen/**'
- 'go.work'
- 'go.work.sum'
- 'ai-gateway/**'
ha-gateway:
- 'gen/**'
- 'go.work'
- 'go.work.sum'
- 'ha-gateway/**'
discord-bot:
- 'gen/**'
- 'go.work'
- 'go.work.sum'
- 'discord-bot/**'
tts-gateway:
- 'gen/**'
- 'go.work'
- 'go.work.sum'
- 'tts-gateway/**'
- '!tts-gateway/sidecar/**'
tts-sidecar:
- 'tts-gateway/sidecar/**'
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: prepare go cache dirs
run: mkdir -p "$GOMODCACHE" "$GOCACHE"
- uses: actions/setup-go@v6
with:
go-version-file: go.work
cache-dependency-path: |
go.work.sum
ai-gateway/go.sum
ha-gateway/go.sum
discord-bot/go.sum
tts-gateway/go.sum
gen/go.sum
- name: go vet
run: |
cd gen && go vet ./...
cd ../ai-gateway && go vet ./...
cd ../ha-gateway && go vet ./...
cd ../discord-bot && go vet ./...
cd ../tts-gateway && go vet ./...
- name: go test
run: |
cd gen && go test ./...
cd ../ai-gateway && go test ./...
cd ../ha-gateway && go test ./...
cd ../discord-bot && go test ./...
cd ../tts-gateway && go test ./...
build-ai-gateway:
needs: [test, changes]
if: github.ref == 'refs/heads/main' && needs.changes.outputs.ai-gateway == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: docker/setup-buildx-action@v4
- uses: docker/login-action@v4
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.REGISTRY_USER }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- uses: docker/build-push-action@v7
with:
context: .
file: ai-gateway/Dockerfile
push: true
platforms: linux/amd64
cache-from: type=registry,ref=${{ env.IMAGE_PREFIX }}/ai-gateway:buildcache
cache-to: type=registry,ref=${{ env.IMAGE_PREFIX }}/ai-gateway:buildcache,mode=max
tags: |
${{ env.IMAGE_PREFIX }}/ai-gateway:${{ github.sha }}
${{ env.IMAGE_PREFIX }}/ai-gateway:latest
build-ha-gateway:
needs: [test, changes]
if: github.ref == 'refs/heads/main' && needs.changes.outputs.ha-gateway == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: docker/setup-buildx-action@v4
- uses: docker/login-action@v4
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.REGISTRY_USER }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- uses: docker/build-push-action@v7
with:
context: .
file: ha-gateway/Dockerfile
push: true
platforms: linux/amd64
cache-from: type=registry,ref=${{ env.IMAGE_PREFIX }}/ha-gateway:buildcache
cache-to: type=registry,ref=${{ env.IMAGE_PREFIX }}/ha-gateway:buildcache,mode=max
tags: |
${{ env.IMAGE_PREFIX }}/ha-gateway:${{ github.sha }}
${{ env.IMAGE_PREFIX }}/ha-gateway:latest
build-discord-bot:
needs: [test, changes]
if: github.ref == 'refs/heads/main' && needs.changes.outputs.discord-bot == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: docker/setup-buildx-action@v4
- uses: docker/login-action@v4
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.REGISTRY_USER }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- uses: docker/build-push-action@v7
with:
context: .
file: discord-bot/Dockerfile
push: true
platforms: linux/amd64
cache-from: type=registry,ref=${{ env.IMAGE_PREFIX }}/discord-bot:buildcache
cache-to: type=registry,ref=${{ env.IMAGE_PREFIX }}/discord-bot:buildcache,mode=max
tags: |
${{ env.IMAGE_PREFIX }}/discord-bot:${{ github.sha }}
${{ env.IMAGE_PREFIX }}/discord-bot:latest
build-tts-gateway:
needs: [test, changes]
if: github.ref == 'refs/heads/main' && needs.changes.outputs.tts-gateway == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: docker/setup-buildx-action@v4
- uses: docker/login-action@v4
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.REGISTRY_USER }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- uses: docker/build-push-action@v7
with:
context: .
file: tts-gateway/Dockerfile
push: true
platforms: linux/amd64
cache-from: type=registry,ref=${{ env.IMAGE_PREFIX }}/tts-gateway:buildcache
cache-to: type=registry,ref=${{ env.IMAGE_PREFIX }}/tts-gateway:buildcache,mode=max
tags: |
${{ env.IMAGE_PREFIX }}/tts-gateway:${{ github.sha }}
${{ env.IMAGE_PREFIX }}/tts-gateway:latest
build-tts-sidecar:
needs: [test, changes]
if: github.ref == 'refs/heads/main' && needs.changes.outputs.tts-sidecar == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: docker/setup-buildx-action@v4
- uses: docker/login-action@v4
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.REGISTRY_USER }}
password: ${{ secrets.REGISTRY_PASSWORD }}
# CUDA base image makes this a large (~13GB) build/push - it doesn't
# need a GPU to build (only to usefully run). Registry cache matters
# most here: requirements.txt/Dockerfile rarely change, so cached runs
# should skip straight past the apt/pip/Cython layers to just the final
# `COPY . .` + re-tagging.
- uses: docker/build-push-action@v7
with:
context: tts-gateway/sidecar
file: tts-gateway/sidecar/Dockerfile
push: true
platforms: linux/amd64
cache-from: type=registry,ref=${{ env.IMAGE_PREFIX }}/tts-sidecar:buildcache
cache-to: type=registry,ref=${{ env.IMAGE_PREFIX }}/tts-sidecar:buildcache,mode=max
tags: |
${{ env.IMAGE_PREFIX }}/tts-sidecar:${{ github.sha }}
${{ env.IMAGE_PREFIX }}/tts-sidecar:latest