Skip to content

chore(ci): cache pre-commit envs + move heavy test hooks to pre-push#342

Merged
cristim merged 2 commits into
feat/multicloud-web-frontendfrom
chore/precommit-speedup
May 12, 2026
Merged

chore(ci): cache pre-commit envs + move heavy test hooks to pre-push#342
cristim merged 2 commits into
feat/multicloud-web-frontendfrom
chore/precommit-speedup

Conversation

@cristim
Copy link
Copy Markdown
Member

@cristim cristim commented May 12, 2026

Summary

  • The pre-commit CI job has grown from ~8 min to ~10 min as the test suites have added tests. Two independent changes here cut the runtime to ~2-3 min on cache-hit runs without losing any coverage in CI.
  • .github/workflows/pre-commit.yml: add four caching layers — setup-node@v6 cache: 'npm', actions/cache for ~/.cache/pre-commit, ~/.cache/go-build, and ~/go/bin (gosec / gocyclo binaries).
  • .pre-commit-config.yaml: move the three heavy hooks (go-test, frontend-build, frontend-test) from default stages to stages: [pre-push]. The CI workflow runs pre-commit run --all-files without a stage filter, so the default stage filter (pre-commit) skips these. Local devs with pre-commit install --hook-type pre-push keep them as the safety net on git push.

Why the heavy hooks are safe to drop from CI pre-commit

All three are already covered by other workflows that PRs / pushes already trigger:

Hook removed from pre-commit CI Still runs in
go-test (-short -race ./...) ci.ymlunit-tests (go test -v -race -short -coverprofile) + integration-tests (go test -v -race -tags=integration)
frontend-build (npm run build) frontend-build.yml (PRs) + frontend-build-sentinel.yml (every push to main / feat/**)
frontend-test (npx jest --no-coverage --silent) frontend-build-sentinel.yml (every push to feat/**, which fires on every PR-branch update)

So the only gap is local dev — and stages: [pre-push] plugs that for devs who installed the push hook.

Expected impact

Per the last successful run on PR #337 (commit 186204bd1):

  • Setup steps: ~111s
  • Install frontend deps (npm ci, no cache): 65s
  • Run pre-commit: 485s

After this PR (cache-hit run, no heavy test hooks):

  • Setup steps: ~111s (unchanged)
  • Install frontend deps (cached npm): ~25-30s
  • Run pre-commit: ~60-90s (gofmt, go-mod-tidy, go-vet, terraform-fmt, terraform-tflint, generic checks, hadolint, markdownlint, gocyclo, git-secrets, gosec, trivy-config, migration-conflicts)

Total: ~3 min vs the current ~10 min.

Test plan

  • YAML changes are syntax-clean (pre-commit validate-config would catch issues; configs are passed by structure).
  • CI on this PR — the pre-commit job itself is the test. Expectation: green + much faster than the parent commit's pre-commit run.
  • After merge: confirm the next few PRs land pre-commit runs at ~2-3 min steady state (allowing for first-run cache warm-up).

Notes / tradeoffs

  • The pre-commit env cache and go-build cache are keyed conservatively (config hash + go.sum), so dep upgrades still get clean builds.
  • The Go-tools cache is keyed on the literal pinned version strings (gosec-v2.22.4-gocyclo-v0.6.0); bump those strings to invalidate.
  • Did NOT remove -race from the pre-push go-test hook — devs running locally still want race coverage on their final pre-push check.
  • Did NOT touch terraform_validate (already SKIP'd in CI for the lockfile-creation reason documented in the workflow).

Summary by CodeRabbit

  • Chores

    • Improved CI performance with multi-layer caching for package installs, pre-commit environments, and compiled Go artifacts
    • Moved heavy local validation hooks to run at push time (pre-push) so CI handles routine test/build runs
  • Documentation

    • Clarified hook names and added guidance about CI coverage and local pre-push usage

Review Change Stack

The pre-commit CI job has crept from ~8 min to ~10 min as the test
suites grew. Two changes here, each independently safe:

1. .github/workflows/pre-commit.yml — add three caches:
   - actions/setup-node@v6 with cache: 'npm' on frontend/package-lock.json
     so `npm ci` reuses ~/.npm cache (~30-40s saved). Same pattern
     already in frontend-build-sentinel.yml.
   - actions/cache for ~/.cache/pre-commit keyed on the hook config
     so per-hook venvs (Go, Python, Node) aren't rebuilt every run
     (~30-60s saved).
   - actions/cache for ~/.cache/go-build keyed on go.sum so go-vet,
     gosec, and any Go-compiling hooks reuse compiled object files
     rather than rebuilding from source.
   - actions/cache for ~/go/bin keyed on the pinned tool versions so
     gosec v2.22.4 and gocyclo v0.6.0 binaries don't get rebuilt by
     `go install` every run.

2. .pre-commit-config.yaml — move go-test, frontend-build, frontend-test
   from default stages to `stages: [pre-push]`. The CI workflow runs
   `pre-commit run --all-files` without a stage filter, so the default
   stage filter (`pre-commit`) skips these hooks. Local devs who run
   `pre-commit install --hook-type pre-push` still get them on push.

   These three hooks were the bulk of the ~485s "Run pre-commit" step
   and are redundant with dedicated CI workflows that PRs / pushes
   already trigger:
     - go-test (-short -race ./...) → ci.yml `unit-tests` runs the
       same suite with -race AND an integration pass with
       -tags=integration.
     - frontend-build (npm run build) → frontend-build.yml runs
       npm run typecheck + npm run build on PRs; frontend-build-
       sentinel.yml runs the build on every push to main / feat/**.
     - frontend-test (jest) → frontend-build-sentinel.yml runs
       `npx jest --no-coverage --silent` on every push to feat/**
       (which fires on every PR-branch update).

Net expected impact: the pre-commit CI job drops from ~10 min to
~2-3 min on cache-hit runs. No coverage loss in CI — the heavy tests
still run, just in their dedicated workflows where parallelism +
caching is already optimised.
@cristim cristim added triaged Item has been triaged priority/p2 Backlog-worthy severity/low Minor harm urgency/this-quarter Within the quarter impact/internal Team-internal only effort/s Hours type/chore Maintenance / non-user-visible labels May 12, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 12, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 577250d0-6199-4214-8b53-df2a06a13319

📥 Commits

Reviewing files that changed from the base of the PR and between 164373a and 02a8c01.

📒 Files selected for processing (1)
  • .github/workflows/pre-commit.yml
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/pre-commit.yml

📝 Walkthrough

Walkthrough

Adds layered caching to the pre-commit GitHub Actions workflow (npm, Go tools, pre-commit envs, Go build cache) and restricts heavy local hooks (go-test, frontend-build, frontend-test) to the pre-push stage with updated descriptive names and documentation.

Changes

Pre-commit and workflow performance optimization

Layer / File(s) Summary
Workflow caching for npm and tools
.github/workflows/pre-commit.yml
Adds npm download cache (keyed on frontend/package-lock.json), Go tool binary cache (~/go/bin keyed by OS + pinned gosec/gocyclo versions) with conditional installs, pre-commit per-hook env cache (~/.cache/pre-commit keyed on .pre-commit-config.yaml), and Go build cache (~/.cache/go-build keyed on **/go.sum).
Heavy test hooks moved to pre-push stage
.pre-commit-config.yaml
Section documenting "Heavy test execution: pre-push stage only" added; local hooks go-test, frontend-build, and frontend-test have stages: [pre-push] and updated name fields indicating pre-push-only execution.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

urgency/this-sprint

Poem

A rabbit tweaks the CI with cheer,
🐇 Caches tucked so runs are dear,
Pre-push guards the heavy tests,
Hooks stay light for local quests,
Hopping builds now faster here.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the two main changes: adding caching to pre-commit workflows and moving heavy test hooks to pre-push stage.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ 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 chore/precommit-speedup

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

@cristim
Copy link
Copy Markdown
Member Author

cristim commented May 12, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 12, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@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.

🧹 Nitpick comments (1)
.github/workflows/pre-commit.yml (1)

71-81: ⚡ Quick win

Move cache step before tool installs to enable skipping on cache hit.

The cache step at line 154 runs after Install gosec (line 71) and Install gocyclo (line 77), so cache restoration happens too late to skip those installs. Move the cache step before these installs and add conditional execution (if: steps.cache-go-tools.outputs.cache-hit != 'true') to the install steps to reduce install time on cache hits.

Proposed adjustment
+      - name: Cache Go-installed tools (gosec, gocyclo)
+        id: cache-go-tools
+        uses: actions/cache@v4
+        with:
+          path: ~/go/bin
+          key: go-tools-${{ runner.os }}-gosec-v2.22.4-gocyclo-v0.6.0
+
       - name: Install gosec
+        if: steps.cache-go-tools.outputs.cache-hit != 'true'
         # Pinned to the same version ci.yml's `securego/gosec` Action uses,
         # so an upstream gosec release with rule changes can't silently
         # downgrade the gate between the two workflows.
         run: go install github.com/securego/gosec/v2/cmd/gosec@v2.22.4

       - name: Install gocyclo
+        if: steps.cache-go-tools.outputs.cache-hit != 'true'
         # Pinned to match ci.yml — security tool installs must not use
         # `@latest`; that's exactly the supply-chain weakness this PR is
         # closing for Dockerfile FROMs.
         run: go install github.com/fzipp/gocyclo/cmd/gocyclo@v0.6.0
-
-      # Cache the installed tool binaries (gosec, gocyclo). Keyed on the
-      # pinned version strings so a tool-version bump still triggers a
-      # fresh install. Both binaries land in ~/go/bin which setup-go@v6
-      # already adds to PATH.
-      - name: Cache Go-installed tools (gosec, gocyclo)
-        uses: actions/cache@v4
-        with:
-          path: ~/go/bin
-          key: go-tools-${{ runner.os }}-gosec-v2.22.4-gocyclo-v0.6.0
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/pre-commit.yml around lines 71 - 81, Move the cache
restore step so it runs before the "Install gosec" and "Install gocyclo" steps
and add conditional execution to those install steps using the cache output (if:
steps.cache-go-tools.outputs.cache-hit != 'true') so the installs are skipped
when the cache is hit; update the workflow so the cache step (referenced as
cache-go-tools) appears before the run steps that install gosec and gocyclo and
add the if conditional to both "Install gosec" and "Install gocyclo" steps.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In @.github/workflows/pre-commit.yml:
- Around line 71-81: Move the cache restore step so it runs before the "Install
gosec" and "Install gocyclo" steps and add conditional execution to those
install steps using the cache output (if: steps.cache-go-tools.outputs.cache-hit
!= 'true') so the installs are skipped when the cache is hit; update the
workflow so the cache step (referenced as cache-go-tools) appears before the run
steps that install gosec and gocyclo and add the if conditional to both "Install
gosec" and "Install gocyclo" steps.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fbcb3039-17b0-4dc8-abeb-fb3d67ccf26d

📥 Commits

Reviewing files that changed from the base of the PR and between f33ae7c and 164373a.

📒 Files selected for processing (2)
  • .github/workflows/pre-commit.yml
  • .pre-commit-config.yaml

CR feedback on PR #342: the Go-tools cache step previously sat AFTER
`Install gosec` and `Install gocyclo`, so cache restoration happened
too late to short-circuit the installs. Reorder the cache step BEFORE
the install steps, add an `id: cache-go-tools` to the cache, and gate
each install with `if: steps.cache-go-tools.outputs.cache-hit != 'true'`.

On a cache hit the install steps now no-op (saving the `go install`
build time per run). On a cache miss they run as before.
@cristim
Copy link
Copy Markdown
Member Author

cristim commented May 12, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 12, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@cristim cristim merged commit 6c040d7 into feat/multicloud-web-frontend May 12, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/s Hours impact/internal Team-internal only priority/p2 Backlog-worthy severity/low Minor harm triaged Item has been triaged type/chore Maintenance / non-user-visible urgency/this-quarter Within the quarter

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant