Skip to content

ci: optimize Go and Docker layer caching#3213

Open
tac0turtle wants to merge 2 commits intomainfrom
ci/optimize-caching-3196
Open

ci: optimize Go and Docker layer caching#3213
tac0turtle wants to merge 2 commits intomainfrom
ci/optimize-caching-3196

Conversation

@tac0turtle
Copy link
Copy Markdown
Contributor

@tac0turtle tac0turtle commented Mar 30, 2026

Summary

  • Fix apps/testapp/Dockerfile: was copying all source before go mod download, invalidating the download layer on every code change. Now copies go.mod/go.sum first, downloads deps, then copies source — same pattern already used by the evm Dockerfile.
  • Add GHA Docker layer cache to docker-build-push.yml via cache-from/cache-to: type=gha with per-app scopes so the 3 parallel image builds don't evict each other's cache.
  • Add cache-dependency-path: "**/go.sum" to all actions/setup-go steps in test.yml, docker-tests.yml, and lint.yml. This repo has multiple go.mod files; the glob ensures the Go module cache key covers all of them.
  • Add scope to e2e Docker cache in test.yml (scope=ev-node-testapp) to align with the docker-build-push.yml naming and avoid cross-job cache conflicts.

Closes #3196

Test plan

  • Verify Docker build jobs in CI show cache hits on re-runs where only non-go.mod/go.sum files changed
  • Verify Go module cache is restored in setup-go steps (check "Restore cache" step output in Actions logs)
  • All existing tests pass

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores
    • Optimized Docker image build caching in CI to speed up builds and reuse layers
    • Updated Go module dependency caching across workflows for faster test and lint runs
    • Improved Dockerfile build layering to reduce image rebuild time and streamline artifact creation

- Fix apps/testapp/Dockerfile: copy go.mod/go.sum before source so
  the go mod download layer is stable across code-only changes
- Add cache-from/cache-to GHA cache to docker-build-push.yml with
  per-app scopes to prevent cache eviction between parallel builds
- Add cache-dependency-path: "**/go.sum" to all actions/setup-go
  steps in test.yml, docker-tests.yml, and lint.yml so the module
  cache key covers all go.sum files in the multi-module repo
- Add explicit scope to the e2e Docker build cache in test.yml to
  align with the docker-build-push.yml scope naming

Closes #3196

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 30, 2026

The latest Buf updates on your PR. Results from workflow CI / buf-check (pull_request).

BuildFormatLintBreakingUpdated (UTC)
✅ passed⏩ skipped✅ passed✅ passedMar 30, 2026, 5:46 PM

@claude
Copy link
Copy Markdown
Contributor

claude bot commented Mar 30, 2026

Claude finished @tac0turtle's task in 1m 19s —— View job


Code Review

  • Gather context and read changed files
  • Review Dockerfile changes
  • Review GitHub Actions workflow changes
  • Provide final review summary

This is a clean, focused CI optimization PR. The changes are well-scoped and the implementation is correct. Here's my detailed review:

apps/testapp/Dockerfile — Good fix

The restructuring is correct and follows best practices:

-COPY . .
-RUN go mod download && cd apps/testapp && go install .
+COPY go.mod go.sum ./
+COPY apps/testapp/go.mod apps/testapp/go.sum ./apps/testapp/
+RUN go mod download && (cd apps/testapp && go mod download)
+COPY . .
+WORKDIR /ev-node/apps/testapp
+RUN go build -o /go/bin/testapp .

✅ Copies go.mod/go.sum for both root and testapp modules before downloading deps — important since testapp is a separate Go module with its own go.sum
✅ Replaces RUN cd apps/testapp && go install . (hadolint DL3003/DL3062) with proper WORKDIR + go build
✅ Matches the pattern already used by the evm Dockerfile

Minor nit: RUN go mod download && (cd apps/testapp && go mod download) uses a subshell cd. Depending on hadolint version, this might still flag DL3003 in stricter modes. An alternative avoiding this entirely would be two sequential RUN instructions with WORKDIR changes, but the subshell form is widely accepted and your CI passes — this is purely cosmetic.


.github/workflows/docker-build-push.yml — Correct

cache-from: type=gha,scope=${{ matrix.app.name }}
cache-to: type=gha,mode=max,scope=${{ matrix.app.name }}

✅ Uses scope=${{ matrix.app.name }} so parallel matrix builds (testapp, evm, etc.) don't evict each other's cache layers
mode=max caches all layers, not just the final image

Note: The scope here will be the raw matrix.app.name value (e.g., testapp), while test.yml uses scope=ev-node-testapp. These are different jobs with different purposes (push to GHCR vs. load for e2e), so the scope mismatch is intentional and correct — they shouldn't share cache.


.github/workflows/test.yml — Good

✅ All 6 setup-go steps now include cache-dependency-path: "**/go.sum" — correct for a multi-module repo
✅ E2E Docker cache now scoped to ev-node-testapp instead of the default unscoped cache, avoiding conflicts with docker-build-push.yml


.github/workflows/docker-tests.yml and lint.yml — Straightforward

cache-dependency-path: "**/go.sum" added consistently
docker-tests.yml uses go-version-file: ./test/docker-e2e/go.mod (specific module for version) + global **/go.sum glob for cache key — this is the correct combination


Summary

The PR correctly addresses all items in issue #3196. The CodeRabbit concern about missing testapp module files in the cache-priming layer has already been resolved in commit ee1e017. No blocking issues found — this is ready to merge.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 30, 2026

📝 Walkthrough

Walkthrough

Adds persistent Buildx/GHA Docker layer caching and scopes cache entries; configures Go module caching via cache-dependency-path: "**/go.sum" across multiple GitHub Actions workflows; and restructures the apps/testapp/Dockerfile builder stage to improve Docker layer cache reuse by isolating dependency download steps.

Changes

Cohort / File(s) Summary
GitHub Actions workflows
.github/workflows/docker-build-push.yml, .github/workflows/docker-tests.yml, .github/workflows/lint.yml, .github/workflows/test.yml
Added cache-dependency-path: "**/go.sum" to actions/setup-go@v6.3.0 steps for consistent Go module caching; configured Buildx/GHA cache scoping (cache-from/cache-to) in Docker build steps to use scoped GHA cache entries.
Dockerfile build-stage
apps/testapp/Dockerfile
Reworked builder stage to copy go.mod/go.sum (root and app) and run go mod download before copying full source, then use go build -o /go/bin/testapp . to maximize layer caching.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I nibbled deps and stashed a cache,
Layers snug in my burrowed cache,
Workflows hum, less fetch and dash,
Builds hop quick — what a splash! 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'ci: optimize Go and Docker layer caching' directly and concisely summarizes the main changes: improving CI caching for both Go modules and Docker layers across multiple workflow files.
Description check ✅ Passed The description provides clear context with four distinct improvements, includes a link to the related issue (#3196), and provides a comprehensive test plan covering cache validation and test execution.
Linked Issues check ✅ Passed The PR fully addresses issue #3196's objectives: implements GHA runner cache for Docker layers and Go modules, ensures cache invalidation on dependency changes via go.mod/go.sum, and prevents cache eviction through per-app/per-job scoping.
Out of Scope Changes check ✅ Passed All changes are directly scoped to CI optimization: Dockerfile caching improvements, workflow cache configuration additions, and Go module cache setup — all aligned with issue #3196's objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/optimize-caching-3196

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 30, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 61.41%. Comparing base (8d68f9d) to head (ee1e017).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #3213   +/-   ##
=======================================
  Coverage   61.41%   61.41%           
=======================================
  Files         120      120           
  Lines       12474    12474           
=======================================
  Hits         7661     7661           
  Misses       3953     3953           
  Partials      860      860           
Flag Coverage Δ
combined 61.41% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/testapp/Dockerfile`:
- Around line 20-23: The Dockerfile currently only primes the root module cache
(COPY go.mod go.sum ./ and RUN go mod download) and uses a banned cd pattern
(RUN cd apps/testapp && go install .); update the build stage to COPY the
testapp module files (apps/testapp/go.mod and apps/testapp/go.sum) into the
image before running dependency download, switch to using WORKDIR to enter
apps/testapp instead of the cd pattern, and run go mod download / go install
from that WORKDIR (replace RUN cd apps/testapp && go install . with a WORKDIR
apps/testapp and RUN go install ./... or equivalent) so cache invalidation is
correct and hadolint DL3003/DL3062 are resolved.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: bffcc61d-516e-4b29-8a76-25441fe5dcca

📥 Commits

Reviewing files that changed from the base of the PR and between 8d68f9d and 91fd6fa.

📒 Files selected for processing (5)
  • .github/workflows/docker-build-push.yml
  • .github/workflows/docker-tests.yml
  • .github/workflows/lint.yml
  • .github/workflows/test.yml
  • apps/testapp/Dockerfile

…nings

Also copy apps/testapp/go.mod and apps/testapp/go.sum before running
go mod download so the testapp's own dependencies are cached in their
own layer (separate from the root module).

Replace RUN cd ... && go install with WORKDIR + go build to resolve
hadolint DL3003 and DL3062.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
apps/testapp/Dockerfile (1)

24-24: ⚠️ Potential issue | 🟠 Major

Use WORKDIR instead of cd in the dependency download step.

Line 24 still uses cd inside RUN, which triggers hadolint DL3003 and currently fails lint CI. Move directory switching to WORKDIR and run the second go mod download there.

Suggested patch
 COPY go.mod go.sum ./
 COPY apps/testapp/go.mod apps/testapp/go.sum ./apps/testapp/
-RUN go mod download && (cd apps/testapp && go mod download)
+RUN go mod download
+WORKDIR /ev-node/apps/testapp
+RUN go mod download
 
 # Copy the rest of the source and build.
+WORKDIR /ev-node
 COPY . .
 
 WORKDIR /ev-node/apps/testapp
 RUN go build -o /go/bin/testapp .
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/testapp/Dockerfile` at line 24, The RUN line uses "cd" which triggers
hadolint DL3003; replace the inline "cd apps/testapp && go mod download" by
switching the build context to that directory with a WORKDIR instruction (e.g.,
set WORKDIR to the app directory before running the second go mod download) and
then run "go mod download" there; update the Dockerfile so the first go mod
download runs in the repo root, add WORKDIR apps/testapp, run go mod download,
and if needed restore the previous WORKDIR afterward.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@apps/testapp/Dockerfile`:
- Line 24: The RUN line uses "cd" which triggers hadolint DL3003; replace the
inline "cd apps/testapp && go mod download" by switching the build context to
that directory with a WORKDIR instruction (e.g., set WORKDIR to the app
directory before running the second go mod download) and then run "go mod
download" there; update the Dockerfile so the first go mod download runs in the
repo root, add WORKDIR apps/testapp, run go mod download, and if needed restore
the previous WORKDIR afterward.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a3e787ca-8781-4538-bf6a-07bdd5849a21

📥 Commits

Reviewing files that changed from the base of the PR and between 91fd6fa and ee1e017.

📒 Files selected for processing (1)
  • apps/testapp/Dockerfile

@tac0turtle tac0turtle requested a review from auricom March 30, 2026 17:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] CI: optimize CI job

1 participant