From 1c3b10bdcabad48fc30505e6c9466664dde99c27 Mon Sep 17 00:00:00 2001 From: Nik Afiq Date: Fri, 24 Jul 2026 23:24:59 +0900 Subject: [PATCH] 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. --- .gitea/workflows/ci.yaml | 88 ++++++++++++++++++++++++++++++++++------ CLAUDE.md | 4 +- ai-gateway/Dockerfile | 15 ++++++- discord-bot/Dockerfile | 15 ++++++- go.work.sum | 26 +++++++++++- ha-gateway/Dockerfile | 15 ++++++- tts-gateway/Dockerfile | 14 ++++++- tts-gateway/go.sum | 67 ++++++++++++++++++++++++++++++ 8 files changed, 222 insertions(+), 22 deletions(-) create mode 100644 tts-gateway/go.sum diff --git a/.gitea/workflows/ci.yaml b/.gitea/workflows/ci.yaml index 5702c9b..06989fa 100644 --- a/.gitea/workflows/ci.yaml +++ b/.gitea/workflows/ci.yaml @@ -15,6 +15,58 @@ env: 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: @@ -51,8 +103,8 @@ jobs: cd ../tts-gateway && go test ./... build-ai-gateway: - needs: test - if: github.ref == 'refs/heads/main' + needs: [test, changes] + if: github.ref == 'refs/heads/main' && needs.changes.outputs.ai-gateway == 'true' runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 @@ -71,13 +123,15 @@ jobs: 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 - if: github.ref == 'refs/heads/main' + needs: [test, changes] + if: github.ref == 'refs/heads/main' && needs.changes.outputs.ha-gateway == 'true' runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 @@ -96,13 +150,15 @@ jobs: 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 - if: github.ref == 'refs/heads/main' + needs: [test, changes] + if: github.ref == 'refs/heads/main' && needs.changes.outputs.discord-bot == 'true' runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 @@ -121,13 +177,15 @@ jobs: 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 - if: github.ref == 'refs/heads/main' + needs: [test, changes] + if: github.ref == 'refs/heads/main' && needs.changes.outputs.tts-gateway == 'true' runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 @@ -146,13 +204,15 @@ jobs: 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 - if: github.ref == 'refs/heads/main' + needs: [test, changes] + if: github.ref == 'refs/heads/main' && needs.changes.outputs.tts-sidecar == 'true' runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 @@ -166,14 +226,18 @@ jobs: 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), but expect this job to be - # the slowest one in the pipeline by a wide margin. + # 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 diff --git a/CLAUDE.md b/CLAUDE.md index 0b5d7ee..5c7ba88 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -139,4 +139,6 @@ mutation, and is fine to run. ## CI -`.gitea/workflows/ci.yaml` runs `go vet` and `go test` for all five modules (`gen`, `ai-gateway`, `ha-gateway`, `discord-bot`, `tts-gateway`), then builds and pushes Docker images on pushes to `main`: `ai-gateway`, `ha-gateway`, `discord-bot`, `tts-gateway`, and `tts-sidecar` (the Python/CUDA inference sidecar under `tts-gateway/sidecar/` — a large ~13GB image; it builds fine on a generic runner since only *running* it needs a GPU, not building it). Note that `ai-gateway/Dockerfile`, `ha-gateway/Dockerfile`, `discord-bot/Dockerfile`, and `tts-gateway/Dockerfile` each `COPY` every other service directory (not just their own) because `go.work` lists all five Go modules as workspace members — Go's workspace-mode module resolution needs every listed directory present in the build context, even ones a given service doesn't otherwise depend on. Adding a new module to `go.work` means adding a matching `COPY` line to the other Dockerfiles too, or their builds break. +`.gitea/workflows/ci.yaml` always runs `go vet`/`go test` for all five modules (`gen`, `ai-gateway`, `ha-gateway`, `discord-bot`, `tts-gateway`) on every push/PR. On pushes to `main`, a `changes` job (`dorny/paths-filter`) determines which of the five images actually need rebuilding based on which paths changed, so an edit scoped to one service doesn't rebuild (and re-push) all of them — `gen/`, `go.work`, and `go.work.sum` count as shared and mark every Go-based image as changed, since a dependency bump there can affect all of them. Each `build-*` job is gated on that output and, when it runs, uses `docker/build-push-action`'s registry-based cache (`cache-from`/`cache-to: type=registry,ref=.../:buildcache`) so unchanged Docker layers (e.g. `go mod download`, `apt-get`/`pip install`) don't get redone on every run — the *first* run after adding this has nothing to pull from and builds fully fresh, subsequent ones should be much faster. `tts-sidecar` (the Python/CUDA inference sidecar under `tts-gateway/sidecar/`) is a large ~13GB image; it builds fine on a generic runner since only *running* it needs a GPU, not building it. + +Note that `ai-gateway/Dockerfile`, `ha-gateway/Dockerfile`, `discord-bot/Dockerfile`, and `tts-gateway/Dockerfile` each `COPY` every other service directory (not just their own) because `go.work` lists all five Go modules as workspace members — Go's workspace-mode module resolution needs every listed directory present in the build context, even ones a given service doesn't otherwise depend on. Adding a new module to `go.work` means adding a matching `COPY` line (both the manifest-only and full-source copies, see below) to the other Dockerfiles too, or their builds break. Each of those four Dockerfiles also copies every module's `go.mod`/`go.sum` first and runs `go mod download` *before* copying full source, so that layer's cache survives source-only edits instead of being invalidated by every commit. diff --git a/ai-gateway/Dockerfile b/ai-gateway/Dockerfile index 39d4988..5b857c3 100644 --- a/ai-gateway/Dockerfile +++ b/ai-gateway/Dockerfile @@ -2,6 +2,19 @@ FROM golang:1.26-alpine AS builder WORKDIR /workspace COPY go.work go.work.sum ./ + +# Manifests only, copied first, so `go mod download` gets its own cache layer +# invalidated only by dependency changes - not by every source edit below. +COPY gen/go.mod gen/go.sum ./gen/ +COPY ha-gateway/go.mod ha-gateway/go.sum ./ha-gateway/ +COPY discord-bot/go.mod discord-bot/go.sum ./discord-bot/ +COPY tts-gateway/go.mod tts-gateway/go.sum ./tts-gateway/ +COPY ai-gateway/go.mod ai-gateway/go.sum ./ai-gateway/ + +WORKDIR /workspace/ai-gateway +RUN go mod download + +WORKDIR /workspace COPY gen/ ./gen/ COPY ha-gateway/ ./ha-gateway/ COPY discord-bot/ ./discord-bot/ @@ -9,8 +22,6 @@ COPY tts-gateway/ ./tts-gateway/ COPY ai-gateway/ ./ai-gateway/ WORKDIR /workspace/ai-gateway -RUN go mod download - ARG VERSION=dev RUN CGO_ENABLED=0 GOOS=linux go build \ -ldflags="-s -w -X main.version=${VERSION}" \ diff --git a/discord-bot/Dockerfile b/discord-bot/Dockerfile index 6ee9207..52ec1de 100644 --- a/discord-bot/Dockerfile +++ b/discord-bot/Dockerfile @@ -2,6 +2,19 @@ FROM golang:1.26-alpine AS builder WORKDIR /workspace COPY go.work go.work.sum ./ + +# Manifests only, copied first, so `go mod download` gets its own cache layer +# invalidated only by dependency changes - not by every source edit below. +COPY gen/go.mod gen/go.sum ./gen/ +COPY ai-gateway/go.mod ai-gateway/go.sum ./ai-gateway/ +COPY ha-gateway/go.mod ha-gateway/go.sum ./ha-gateway/ +COPY tts-gateway/go.mod tts-gateway/go.sum ./tts-gateway/ +COPY discord-bot/go.mod discord-bot/go.sum ./discord-bot/ + +WORKDIR /workspace/discord-bot +RUN go mod download + +WORKDIR /workspace COPY gen/ ./gen/ COPY ai-gateway/ ./ai-gateway/ COPY ha-gateway/ ./ha-gateway/ @@ -9,8 +22,6 @@ COPY tts-gateway/ ./tts-gateway/ COPY discord-bot/ ./discord-bot/ WORKDIR /workspace/discord-bot -RUN go mod download - ARG VERSION=dev RUN CGO_ENABLED=0 GOOS=linux go build \ -ldflags="-s -w -X main.version=${VERSION}" \ diff --git a/go.work.sum b/go.work.sum index 68fba69..c8ee978 100644 --- a/go.work.sum +++ b/go.work.sum @@ -1,42 +1,58 @@ cel.dev/expr v0.19.1/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= +cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4= cel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4= cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg= +cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0/go.mod h1:obipzmGjfSjam60XLwGfqUkJsfiheAl+TUjG+4yzyPM= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 h1:sBEjpZlNHzK1voKq9695PJSX2o5NEXl7/OL3coiIY0c= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0= +github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= +github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 h1:6xNmx7iTtyBRev0+D/Tv1FZd4SCg8axKApyNyRsAt/w= github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5/go.mod h1:KdCmV+x/BuvyMxRnYBlmVaq4OLiKW6iRQfvC62cvdkI= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/envoyproxy/go-control-plane v0.13.4/go.mod h1:kDfuBlDVsSj2MjrLEtRWtHlsWIFcGyB2RMO44Dc5GZA= +github.com/envoyproxy/go-control-plane v0.14.0 h1:hbG2kr4RuFj222B6+7T83thSPqLjwBIfQawTkC++2HA= github.com/envoyproxy/go-control-plane v0.14.0/go.mod h1:NcS5X47pLl/hfqxU70yPwL9ZMkUlwlKxtAohpi2wBEU= github.com/envoyproxy/go-control-plane/envoy v1.32.4/go.mod h1:Gzjc5k8JcJswLjAx1Zm+wSYE20UrLtt7JZMWiWQXQEw= +github.com/envoyproxy/go-control-plane/envoy v1.36.0 h1:yg/JjO5E7ubRyKX3m07GF3reDNEnfOboJ0QySbH736g= github.com/envoyproxy/go-control-plane/envoy v1.36.0/go.mod h1:ty89S1YCCVruQAm9OtKeEkQLTb+Lkz0k8v9W0Oxsv98= +github.com/envoyproxy/go-control-plane/ratelimit v0.1.0 h1:/G9QYbddjL25KvtKTv3an9lx6VBE2cnb8wp1vEGNYGI= github.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4= github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU= +github.com/envoyproxy/protoc-gen-validate v1.3.0 h1:TvGH1wof4H33rezVKWSpqKz5NXWg5VPuZ0uONDT6eb4= github.com/envoyproxy/protoc-gen-validate v1.3.0/go.mod h1:HvYl7zwPa5mffgyeTUHA9zHIH36nmrm7oCbo4YKoSWA= -github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs= github.com/go-jose/go-jose/v4 v4.1.3/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/golang/glog v1.2.4/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= +github.com/golang/glog v1.2.5 h1:DrW6hGnjIhtvhOIiAKT6Psh/Kd/ldepEa81DKeiRJ5I= github.com/golang/glog v1.2.5/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/fastuuid v1.2.0 h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi2s= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/spiffe/go-spiffe/v2 v2.6.0 h1:l+DolpxNWYgruGQVV0xsfeya3CsC7m8iBzDnMpsbLuo= github.com/spiffe/go-spiffe/v2 v2.6.0/go.mod h1:gm2SeUoMZEtpnzPNs2Csc0D/gX33k1xIx7lEzqblHEs= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= go.opentelemetry.io/contrib/detectors/gcp v1.34.0/go.mod h1:cV4BMFcscUR/ckqLkbfQmF0PRsq8w/lMGzdbCSveBHo= +go.opentelemetry.io/contrib/detectors/gcp v1.39.0 h1:kWRNZMsfBHZ+uHjiH4y7Etn2FK26LAGkNFw7RHv1DhE= go.opentelemetry.io/contrib/detectors/gcp v1.39.0/go.mod h1:t/OGqzHBa5v6RHZwrDBJ2OirWc+4q/w2fTbLZwAKjTk= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ= go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= @@ -49,18 +65,23 @@ go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4= go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE= +golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk= golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc= golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a h1:nwKuGPlUAt+aR+pcrkfFRrTU1BVrSmYyYMxYbUIVHr0= @@ -75,4 +96,5 @@ google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwl google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/ha-gateway/Dockerfile b/ha-gateway/Dockerfile index 7267034..5fe9a50 100644 --- a/ha-gateway/Dockerfile +++ b/ha-gateway/Dockerfile @@ -2,6 +2,19 @@ FROM golang:1.26-alpine AS builder WORKDIR /workspace COPY go.work go.work.sum ./ + +# Manifests only, copied first, so `go mod download` gets its own cache layer +# invalidated only by dependency changes - not by every source edit below. +COPY gen/go.mod gen/go.sum ./gen/ +COPY ai-gateway/go.mod ai-gateway/go.sum ./ai-gateway/ +COPY discord-bot/go.mod discord-bot/go.sum ./discord-bot/ +COPY tts-gateway/go.mod tts-gateway/go.sum ./tts-gateway/ +COPY ha-gateway/go.mod ha-gateway/go.sum ./ha-gateway/ + +WORKDIR /workspace/ha-gateway +RUN go mod download + +WORKDIR /workspace COPY gen/ ./gen/ COPY ai-gateway/ ./ai-gateway/ COPY discord-bot/ ./discord-bot/ @@ -9,8 +22,6 @@ COPY tts-gateway/ ./tts-gateway/ COPY ha-gateway/ ./ha-gateway/ WORKDIR /workspace/ha-gateway -RUN go mod download - ARG VERSION=dev RUN CGO_ENABLED=0 GOOS=linux go build \ -ldflags="-s -w -X main.version=${VERSION}" \ diff --git a/tts-gateway/Dockerfile b/tts-gateway/Dockerfile index 602f52c..4c9d5e1 100644 --- a/tts-gateway/Dockerfile +++ b/tts-gateway/Dockerfile @@ -8,6 +8,19 @@ FROM golang:1.26-bookworm AS builder WORKDIR /workspace COPY go.work go.work.sum ./ + +# Manifests only, copied first, so `go mod download` gets its own cache layer +# invalidated only by dependency changes - not by every source edit below. +COPY gen/go.mod gen/go.sum ./gen/ +COPY ai-gateway/go.mod ai-gateway/go.sum ./ai-gateway/ +COPY ha-gateway/go.mod ha-gateway/go.sum ./ha-gateway/ +COPY discord-bot/go.mod discord-bot/go.sum ./discord-bot/ +COPY tts-gateway/go.mod tts-gateway/go.sum ./tts-gateway/ + +WORKDIR /workspace/tts-gateway +RUN go mod download + +WORKDIR /workspace COPY gen/ ./gen/ COPY ai-gateway/ ./ai-gateway/ COPY ha-gateway/ ./ha-gateway/ @@ -15,7 +28,6 @@ COPY discord-bot/ ./discord-bot/ COPY tts-gateway/ ./tts-gateway/ WORKDIR /workspace/tts-gateway -RUN go mod download RUN CGO_ENABLED=0 GOOS=linux go build -o /tts-gateway ./cmd/gateway FROM ubuntu:22.04 diff --git a/tts-gateway/go.sum b/tts-gateway/go.sum new file mode 100644 index 0000000..ee382c2 --- /dev/null +++ b/tts-gateway/go.sum @@ -0,0 +1,67 @@ +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 h1:e9Rjr40Z98/clHv5Yg79Is0NtosR5LXRvdr7o/6NwbA= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1/go.mod h1:tIxuGz/9mpox++sgp9fJjHO0+q1X9/UOWd798aAm22M= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 h1:x7wzEgXfnzJcHDwStJT+mxOz4etr2EcexjqhBvmoakw= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0/go.mod h1:rg+RlpR5dKwaS95IyyZqj5Wd4E13lk/msnTS0Xl9lJM= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.35.0 h1:QcFwRrZLc82r8wODjvyCbP7Ifp3UANaBSmhDSFjnqSc= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.35.0/go.mod h1:CXIWhUomyWBG/oY2/r/kLp6K/cmx9e/7DLpBuuGdLCA= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 h1:1fTNlAIJZGWLP5FVu0fikVry1IsiUnXjf7QFvoNN3Xw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0/go.mod h1:zjPK58DtkqQFn+YUMbx0M2XV3QgKU0gS9LeGohREyK4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0 h1:m639+BofXTvcY1q8CGs4ItwQarYtJPOWmVobfM1HpVI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0/go.mod h1:LjReUci/F4BUyv+y4dwnq3h/26iNOeC3wAIqgvTIZVo= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= +go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4= +go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=