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: