From 5d4e7147ceb4851be71973457349974e144fb06d Mon Sep 17 00:00:00 2001 From: Lucas Rayan Date: Fri, 30 Oct 2026 10:07:21 -0300 Subject: [PATCH] ci: cache what is rebuilt on every run npm and Go module caches, the embedded Postgres binaries, Trivy's database, and the daemon's own layer cache for image builds. The webmail Next build is no longer run a second time outside the Dockerfile. Co-Authored-By: Claude Sonnet 5.5 --- .gitea/workflows/ci.yml | 60 ++++++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 053d5b3..2e27a75 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -70,6 +70,17 @@ jobs: docker rm "$cid" >/dev/null exit "$status" - run: go vet ./... + # Module and build caches live under the unprivileged user's home, which + # setup-go's cache does not cover, and the embedded Postgres binaries are + # otherwise downloaded again by every test that starts one. + - uses: actions/cache@v4 + with: + path: | + /home/tester/go/pkg/mod + /home/tester/.cache/go-build + /home/tester/.embedded-postgres-go + key: go-tester-${{ runner.arch }}-${{ hashFiles('services/protocols/go.sum') }} + restore-keys: go-tester-${{ runner.arch }}- # The end-to-end suites start an embedded Postgres, and initdb refuses to # run as root, which is what a job container is. Run the tests as a # throwaway unprivileged user (GitHub's hosted runners already are one). @@ -78,7 +89,7 @@ jobs: TEST_DATABASE_URL: postgres://lambdamail_test:lambdamail_test@localhost:5432/lambdamail_test?sslmode=disable run: | id tester >/dev/null 2>&1 || useradd -m -u 1001 tester - chown -R tester:tester "$GITHUB_WORKSPACE" + chown -R tester:tester "$GITHUB_WORKSPACE" /home/tester runuser -u tester -- env "HOME=/home/tester" "PATH=$PATH" \ "TEST_DATABASE_URL=$TEST_DATABASE_URL" go test ./... -v @@ -105,7 +116,10 @@ jobs: steps: - uses: actions/checkout@v7 - uses: actions/setup-node@v7 - with: { node-version: "20" } + with: + node-version: "20" + cache: npm + cache-dependency-path: services/auth/package-lock.json # The auth suite asserts against real rows: password verification, # lockout, TOTP replay and recovery-code consumption are all decided in # the database, so a mock would prove nothing. @@ -139,13 +153,16 @@ jobs: steps: - uses: actions/checkout@v7 - uses: actions/setup-node@v7 - with: { node-version: "20" } + with: + node-version: "20" + cache: npm + cache-dependency-path: services/storage/package-lock.json - run: npm install - run: npm run lint - run: npm test webmail-build: - name: Build (webmail) + name: Testes (webmail) runs-on: ubuntu-latest defaults: run: @@ -153,11 +170,15 @@ jobs: steps: - uses: actions/checkout@v7 - uses: actions/setup-node@v7 - with: { node-version: "20" } + with: + node-version: "20" + cache: npm + cache-dependency-path: services/webmail/package-lock.json - run: npm install - run: npm run lint - run: npm test - - run: npm run build + # No `npm run build` here: the webmail image job runs the same Next build + # inside its Dockerfile, so building it twice only doubles the wait. security: name: Trivy (dependências, segredos e Dockerfiles) @@ -174,7 +195,7 @@ jobs: # which on Gitea is not GitHub. - name: Repositório run: | - cid=$(docker create --network host -w /src aquasec/trivy:0.70.0 \ + cid=$(docker create --network host -v trivy-cache:/root/.cache/ -w /src aquasec/trivy:0.70.0 \ fs --scanners vuln,secret,misconfig --severity HIGH,CRITICAL --exit-code 1 \ --skip-dirs services/auth/node_modules,services/storage/node_modules,services/webmail/node_modules,services/webmail/.next .) docker cp . "$cid:/src" @@ -195,7 +216,7 @@ jobs: # scanner something people learn to skip. - name: Repositório (MEDIUM, informativo) run: | - cid=$(docker create --network host -w /src aquasec/trivy:0.70.0 \ + cid=$(docker create --network host -v trivy-cache:/root/.cache/ -w /src aquasec/trivy:0.70.0 \ fs --scanners vuln,secret --severity MEDIUM --exit-code 0 \ --skip-dirs services/auth/node_modules,services/storage/node_modules,services/webmail/node_modules,services/webmail/.next .) docker cp . "$cid:/src" @@ -214,18 +235,21 @@ jobs: steps: - uses: actions/checkout@v7 - - uses: docker/setup-buildx-action@v4 - # Built but not pushed: this proves each Dockerfile still works on every # branch, while publishing stays in release.yml. + # + # Plain `docker build` on purpose. setup-buildx would start a fresh + # BuildKit container per job and throw its layer cache away; the daemon's + # own builder keeps the cache in the runner's persistent volume, and the + # "Stack completa" job reuses it for the same Dockerfiles. - name: Build - uses: docker/build-push-action@v7 - with: - context: ${{ (matrix.service == 'migrations' || matrix.service == 'rspamd') && '.' || format('services/{0}', matrix.service) }} - file: services/${{ matrix.service }}/Dockerfile - push: false - load: true - tags: lambdamail-${{ matrix.service }}:ci + run: | + case '${{ matrix.service }}' in + migrations|rspamd) context=. ;; + *) context=services/${{ matrix.service }} ;; + esac + docker build -f services/${{ matrix.service }}/Dockerfile \ + -t lambdamail-${{ matrix.service }}:ci "$context" # Scanned only for the images whose contents we author. migrations and # rspamd add .sql and .conf files to an upstream image and nothing else, @@ -236,7 +260,7 @@ jobs: - name: Trivy na imagem if: matrix.service != 'migrations' && matrix.service != 'rspamd' run: | - docker run --rm --network host -e DOCKER_HOST=tcp://127.0.0.1:2375 aquasec/trivy:0.70.0 \ + docker run --rm --network host -v trivy-cache:/root/.cache/ -e DOCKER_HOST=tcp://127.0.0.1:2375 aquasec/trivy:0.70.0 \ image --severity HIGH,CRITICAL --exit-code 1 lambdamail-${{ matrix.service }}:ci compose-up: