Skip to content

fix(ci): pin node:24-alpine base image by digest - #2004

Merged
LucasSantana-Dev merged 2 commits into
mainfrom
fix/pin-node-base-image
Aug 12, 2026
Merged

LucasSantana-Dev merged 2 commits into
mainfrom
fix/pin-node-base-image

Conversation

@LucasSantana-Dev

@LucasSantana-Dev LucasSantana-Dev commented Aug 12, 2026 •

Copy link
Copy Markdown
Owner

Summary

Change

Pin `NODE_VERSION` to `24-alpine@sha256:d32cdf619f63fe0471182d08996dd516c6275bb5fd31ae06e55a570bd9e1ad43` (current digest, tag kept for readability). Matches this repo's existing convention of SHA-pinning all GitHub Actions.

Test plan


Summary by cubic

Pin the Docker base image node:24-alpine by digest to stop intermittent BuildKit checksum errors in multi-stage COPY and unblock bot/backend CI. Sets ARG NODE_VERSION=24-alpine@sha256:d32cdf619f63fe0471182d08996dd516c6275bb5fd31ae06e55a570bd9e1ad43 (tag kept for readability) and documents the rationale; no runtime changes.

Written for commit 6beda52. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Chores
    • Pinned the build environment to a specific Node.js 24 Alpine image version.
    • Improved build consistency by ensuring deployments use the same base image over time.
    • Retained the readable image tag for easier maintenance and identification.

Build — bot/backend failed repeatedly on #1956 and #1952 with
'failed to calculate checksum of ref ...: "/app/packages/backend/
node_modules": not found' immediately after that exact stage
completed successfully in the same build. Ruled out disk pressure
(110GB free, confirmed via df -h in the run log) and GHA cache
staleness (reproduced with the cache fully emptied, run alone).

Matches a known class of BuildKit bug: a floating base-image tag
(node:24-alpine tracks the latest patch, not a fixed image) can
resolve to a different digest between a stage's build and a later
stage's COPY --from referencing it within the same invocation,
producing exactly this checksum-mismatch error. Pin by digest,
keeping the tag for readability.
@LucasSantana-Dev
LucasSantana-Dev enabled auto-merge (squash) August 12, 2026 03:49
@coderabbitai

coderabbitai Bot commented Aug 12, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: fd44ae5e-895a-475c-a6fc-728906d37929

📥 Commits

Reviewing files that changed from the base of the PR and between 5bcd388 and 6beda52.

📒 Files selected for processing (1)
  • Dockerfile

📝 Walkthrough

Walkthrough

The Dockerfile now pins the Node 24 Alpine base image to a specific digest while retaining the readable image tag and documenting deliberate digest updates.

Changes

Node image pinning

Layer / File(s) Summary
Digest-pinned Node base image
Dockerfile
The NODE_VERSION value now uses a digest-pinned node:24-alpine image. Comments document deliberate digest updates.

Estimated code review effort: 1 (Trivial) | ~5 minutes

🚥 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 states that the Node.js Alpine base image is pinned by digest, which is the main change.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/pin-node-base-image

Warning

Billing warning: we have not been able to collect payment for this subscription for more than 72 hours. Please update the payment method or pay any pending invoices in Billing to avoid service interruption.


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.

@github-actions

Copy link
Copy Markdown

Failed to generate code suggestions for PR

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

No issues found across 1 file

Auto-approved: Pins a floating base-image tag to a specific digest to fix intermittent BuildKit checksum errors in CI; a focused, self-contained build-config fix with no runtime behavior change.

Re-trigger cubic

@graphify-labs graphify-labs Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Graphify reviewed this change.

Looks safe to merge — no coupling regressions and no blocking issues, checked against the code graph (not a self-assessment).


Graphify review — findings

This PR appears to be primarily an infrastructure/tooling change. It updates pinned action SHAs across numerous GitHub Actions workflows (checkout, setup-java, login-action, wrangler-action, codeql-action, etc.) and removes a "Free disk space" step from the reusable docker-build-service composite action. Alongside the CI changes, it touches a broad set of bot and shared-package source files and their specs—including the player "now playing" tracking, external scrobbler handlers (music-bot detection, markdown stripping, voice-channel lookup), the Last.fm link service, and Prometheus monitoring metrics—plus several contributing documentation entries. The surface area is wide, spanning workflow YAML, bot handlers, shared services, and contributor docs; a reviewer should check both the pinned-version bumps and the accompanying source/test/doc edits.

No blocking issues surfaced. 1 lower-confidence candidate did not survive cross-model review.

Analysis details — impact, health, verification

Impact & health

Graphify review

Impact — 121 functions depend on the 99 functions this change touches.

Health — grade A; 9 existing hotspot(s) in the area this change touches (pre-existing, not introduced here):

  • handleEvents() — 5 callers, 15 callees (high)
  • sendNowPlayingEmbed() — 3 callers, 12 callees (high)
  • setupTrackHandlers() — 4 callers, 6 callees (medium)
  • handlePlayerSkip() — 2 callers, 11 callees (medium)
  • handlePlayerStart() — 2 callers, 10 callees (medium)
  • scrobbleCurrentTrackIfLastFm() — 3 callers, 6 callees (medium)
  • handlePlayerFinish() — 2 callers, 8 callees (medium)
  • executePlayHandler() — 1 callers, 14 callees (high)
  • …and 1 more

Verification — 121 functions in the blast radius were not formally verified this run (proofs are advisory here).

Gate & verification

graphify gate

PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.

Advisory (not blocking):

  • verification_scope: 118 function(s) in the blast radius were not formally verified this run

@graphify-labs graphify-labs Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Graphify reviewed this change.

Looks safe to merge — no coupling regressions and no blocking issues, checked against the code graph (not a self-assessment).


Graphify review — findings

This PR pins the base Node image in the Dockerfile to a specific digest (node:24-alpine@sha256:...) instead of using the floating 24-alpine tag. It updates the NODE_VERSION build-arg default and adds an explanatory comment about why the digest pin was introduced and how to bump it going forward. The change touches only the base image reference in the Dockerfile.

No blocking issues surfaced.

Analysis details — impact, health, verification

Impact & health

Graphify review

Impact — 0 functions depend on the 0 functions this change touches.

Health — grade A; no new coupling hotspots.

Verification — 0 functions in the blast radius were not formally verified this run (proofs are advisory here).

Gate & verification

graphify gate

PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.

@sonarqubecloud

Copy link
Copy Markdown

@LucasSantana-Dev
LucasSantana-Dev merged commit f154bfe into main Aug 12, 2026
43 checks passed
@LucasSantana-Dev
LucasSantana-Dev deleted the fix/pin-node-base-image branch August 12, 2026 04:09
LucasSantana-Dev added a commit that referenced this pull request Aug 12, 2026
## Summary

- Root-cause fix for the persistent \`Build — bot\`/\`Build — backend\`
failure blocking #1956 and #1952: \`failed to calculate checksum of ref
...: "/app/packages/backend/node_modules": not found\` on the
\`deps-production\` COPY step, immediately after that stage built
successfully in the same invocation.
- **8 independent causes tested and eliminated with direct evidence**
(see commit body): stale/corrupted GHA cache (purged 478 entries),
cross-PR concurrency (failed running alone), disk pressure (108–110GB
free confirmed at the exact failure point), floating \`node:24-alpine\`
tag (digest-pinned in #2004 — passed on its own diff, still failed
here), buildx \`v0.36.1\` (pinned to \`v0.35.0\` — still failed), npm
workspace symlinks (none exist), lockfile-driven hoisting
(byte-identical backend deps vs main), and the GHA cache backend
entirely (disabled outright — still failed).
- With environmental/version causes exhausted, looked at the
Dockerfile's own stage graph: the single \`deps-production\` stage
copied **all four** packages' node_modules
(root+shared+bot+backend+frontend) into **every** production target
unconditionally — even though \`production-bot\` only ever consumes
root+shared+bot, \`production-backend\` only root+shared+backend, and
\`production-frontend\` doesn't use this stage at all (static build from
\`build-frontend\`).

## Change

Splits \`deps-production\` into \`deps-production-base\` (shared
root+shared setup) plus \`deps-production-bot\` /
\`deps-production-backend\` (each copying only its own package's
node_modules from \`build\`, then pruning). Removes the unnecessary
\`packages/backend/node_modules\` COPY from the bot build (and the
unnecessary bot/frontend copies from backend's build) entirely — the
same COPY that was intermittently failing.

No behavior change to the shipped images: same \`package*.json\` files
copied (workspace resolution unchanged), same \`npm prune --omit=dev
--legacy-peer-deps\` applied, same node_modules content per target as
before.

## Test plan

- [ ] This PR's own \`Build — bot\`/\`Build — backend\`/\`Build — Docker
images\`/\`Build — frontend\`/\`Build — nginx\` checks pass, including
the native-module and nginx-config smoke tests that boot the real image
- [ ] Once merged, #1956 and #1952 sync and build cleanly

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Split the Docker `deps-production` stage into a shared base plus
`deps-production-bot` and `deps-production-backend` so each image only
copies its own workspace `node_modules`. This removes unnecessary COPYs
and fixes the intermittent BuildKit checksum failure in bot/backend CI
builds.

- **Bug Fixes**
- Bot image no longer copies `packages/backend/node_modules`; backend
image no longer copies `packages/bot` or `packages/frontend` deps.
- Runtime deps remain the same: reuse built modules, prune with `npm
prune --omit=dev --legacy-peer-deps`, and keep Prisma engines; no
behavior change to shipped images.

<sup>Written for commit 93e70e6.
Summary will update on new commits.</sup>

<a
href="https://cubic.dev/pr/LucasSantana-Dev/Lucky/pull/2005?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>

<!-- End of auto-generated description by cubic. -->
LucasSantana-Dev added a commit that referenced this pull request Aug 12, 2026
🤖 I have created a release *beep* *boop*
---


<details><summary>2.39.3</summary>

##
[2.39.3](v2.39.2...v2.39.3)
(2026-08-12)


### Bug Fixes

* **bot:** expose degraded-extractor signal and honest play error
([#1999](#1999))
([8348bd6](8348bd6))
* **bot:** unlink dead Last.fm sessions on error 9 and notify once
([#1946](#1946))
([d22b8bd](d22b8bd))
* **ci:** add a second retry for docker-build
([#2007](#2007))
([9347c55](9347c55))
* **ci:** extract node_modules before per-workspace build steps run
([#2006](#2006))
([ae577d1](ae577d1))
* **ci:** free disk space before Docker builds to prevent BuildKit GC
race ([#2003](#2003))
([5bcd388](5bcd388))
* **ci:** isolate docker cache scope by branch
([#2012](#2012))
([5d25ec8](5d25ec8))
* **ci:** pin node:24-alpine base image by digest
([#2004](#2004))
([f154bfe](f154bfe))
* **ci:** skip gha cache-from on docker-build retries
([#2008](#2008))
([89dbb90](89dbb90))
* **ci:** split deps-production per production target
([#2005](#2005))
([43aacce](43aacce))
</details>

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
This was referenced Oct 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant