Skip to content

chore: Docker image build on CI#386

Merged
tuliomir merged 9 commits intomasterfrom
chore/docker-image-on-ci
Mar 20, 2026
Merged

chore: Docker image build on CI#386
tuliomir merged 9 commits intomasterfrom
chore/docker-image-on-ci

Conversation

@tuliomir
Copy link
Copy Markdown
Contributor

@tuliomir tuliomir commented Mar 19, 2026

Motivation

The Wallet Lib has, since HathorNetwork/hathor-wallet-lib#909 , used a Wallet Service image to run its integration tests, but those images are being built manually.

Having them built with each new tag ensures the integration tests are executed on an updated version of the Wallet Service.

Acceptance Criteria

  • A new Wallet Service image should be published to DockerHub on every release tag
  • It should consist of the sync-daemon, ws-migrator and lambas images.

Notes

This PR proposes two tags: one for the latest dev and other for a pinned version like dev-v1.12.0.

It will also be necessary to manually verify if the DockerHub credentials are available for this repository before the script can actually work.

Checklist

  • If you are requesting a merge into master, confirm this code is production-ready and can be included in future releases as soon as it gets merged
  • Make sure either the unit tests and/or the QA tests are capable of testing the new features
  • Make sure you do not include new dependencies in the project unless strictly necessary and do not include dev-dependencies as production ones. More dependencies increase the possibility of one of them being hijacked and affecting us.

Summary by CodeRabbit

  • Chores
    • Added automated Docker image builds and publishing triggered by release tags: builds multiple service images and publishes them to Docker Hub with both static and versioned tags.
    • Uses build caching to speed up image creation and ensures reproducible builds for one image.
    • Updated packaging ignore rules for a service to streamline build context.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 19, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a GitHub Actions docker job run on tag pushes refs/tags/v* that extracts a version and dev-dependency versions from package.json, sets up QEMU/Buildx, copies package .dockerignore files, then builds and pushes three linux/amd64 Docker images (daemon, lambdas, migrator) to DockerHub with :dev and :dev-${version} tags.

Changes

Cohort / File(s) Summary
CI workflow
/.github/workflows/main.yml
Adds a docker job triggered on tag pushes refs/tags/v*: checks out repo, derives version from the tag, extracts devDependencies (sequelize, sequelize-cli, mysql2) via jq, sets up QEMU & Docker Buildx, logs into DockerHub, copies package .dockerignore files before builds, and builds & pushes three linux/amd64 images (daemon, wallet lambdas, migrator) tagged :dev and :dev-${version} with cache and build-args. Also pins actions/checkout in the test job to a specific commit.
Package dockerignore
packages/wallet-service/.dockerignore
Replaced parent-relative ignore of the repo .github/ (../../.github/) with a package-local entry (.github/) to ignore the package's .github/ directory.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor TagPush as "Tag push (refs/tags/v*)"
  participant GH as "GitHub Actions"
  participant Repo as "Repository (checkout, package.json)"
  participant Buildx as "Buildx / docker/build-push-action"
  participant DockerHub as "DockerHub"

  TagPush->>GH: trigger workflow
  GH->>Repo: checkout code
  GH->>Repo: derive version from GITHUB_REF
  GH->>Repo: read devDependencies (sequelize, sequelize-cli, mysql2) via jq
  GH->>Repo: copy package `.dockerignore` files to repo root
  GH->>Buildx: setup QEMU & Buildx, login to DockerHub
  GH->>Buildx: build daemon image (`packages/daemon/Dockerfile`, target=dev) -> tag :dev, :dev-${version}
  Buildx->>DockerHub: push daemon tags
  GH->>Buildx: build lambdas image (`packages/wallet-service/Dockerfile.dev`) -> tag :dev, :dev-${version}
  Buildx->>DockerHub: push lambdas tags
  GH->>Repo: remove root `.dockerignore`
  GH->>Buildx: build migrator image (`db/Dockerfile.dev`, build-args pinned) -> tag :dev, :dev-${version}
  Buildx->>DockerHub: push migrator tags
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

Poem

🐰 I sniff a tag and hop in cheer,

I pluck the version, dependencies near.
I copy ignores, then spin some images bright,
I nudge them off into DockerHub night.
A rabbit grins — dev builds take flight!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'chore: Docker image build on CI' directly and accurately summarizes the main change: adding Docker image building to the CI pipeline via a new workflow job.
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 chore/docker-image-on-ci
📝 Coding Plan
  • Generate coding plan for human review comments

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.

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.

Actionable comments posted: 2

🧹 Nitpick comments (1)
.github/workflows/main.yml (1)

138-143: Use jq -er to fail fast if dependency keys are missing.

Currently, jq -r returns the string "null" for missing keys, allowing the workflow to continue and fail later during the Docker build. Adding the -e flag makes jq exit with code 1 when a key is absent, catching the problem immediately.

Suggested change
-        echo "sequelize=$(jq -r '.devDependencies["sequelize"]' package.json)" >> "$GITHUB_OUTPUT"
-        echo "sequelize_cli=$(jq -r '.devDependencies["sequelize-cli"]' package.json)" >> "$GITHUB_OUTPUT"
-        echo "mysql2=$(jq -r '.devDependencies["mysql2"]' package.json)" >> "$GITHUB_OUTPUT"
+        echo "sequelize=$(jq -er '.devDependencies["sequelize"]' package.json)" >> "$GITHUB_OUTPUT"
+        echo "sequelize_cli=$(jq -er '.devDependencies["sequelize-cli"]' package.json)" >> "$GITHUB_OUTPUT"
+        echo "mysql2=$(jq -er '.devDependencies["mysql2"]' package.json)" >> "$GITHUB_OUTPUT"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/main.yml around lines 138 - 143, The workflow step
"Extract dependency versions for migrator" (id: deps) currently uses jq -r when
reading devDependencies, which returns "null" for missing keys and allows the
job to continue; update each jq invocation in that step to use jq -er instead
(for sequelize, sequelize-cli, and mysql2 echo lines) so jq exits with code 1 on
missing keys and the workflow fails fast with a clear error when a dependency
key is absent.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/main.yml:
- Around line 157-158: The workflow currently copies other packages'
.dockerignore files into the repository root (the "Copy daemon .dockerignore to
root" and similar steps), leaving the root .dockerignore stateful so the
migrator build inherits the wallet-service rules; fix by ensuring the migrator
build uses its own ignore/context: update the migrator docker build step to use
packages/migrator as the build context (and --file to point to the Dockerfile)
so packages/migrator/.dockerignore is honored, or alternatively copy
packages/migrator/.dockerignore immediately before the migrator build (instead
of relying on prior cp steps); locate the cp steps and the migrator build step
in the workflow and make one of these changes.
- Around line 131-132: Update the GitHub Actions checkout step to use a
supported major version by replacing the pinned reference "actions/checkout@v3"
with a supported release such as "actions/checkout@v4" in the workflow step
named "Checkout code" (and any other occurrences of "actions/checkout@v3");
ensure the step still uses the same inputs and semantic behavior after the
version change so the job runs under the runner's supported action versions.

---

Nitpick comments:
In @.github/workflows/main.yml:
- Around line 138-143: The workflow step "Extract dependency versions for
migrator" (id: deps) currently uses jq -r when reading devDependencies, which
returns "null" for missing keys and allows the job to continue; update each jq
invocation in that step to use jq -er instead (for sequelize, sequelize-cli, and
mysql2 echo lines) so jq exits with code 1 on missing keys and the workflow
fails fast with a clear error when a dependency key is absent.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: acbaa3bd-8b91-416b-9f91-44d4b5f3bd76

📥 Commits

Reviewing files that changed from the base of the PR and between 2cb922e and 9237c68.

📒 Files selected for processing (1)
  • .github/workflows/main.yml

Comment thread .github/workflows/main.yml Outdated
Comment thread .github/workflows/main.yml
@tuliomir tuliomir requested a review from luislhl March 19, 2026 11:45
@tuliomir tuliomir moved this from Todo to In Progress (Done) in Hathor Network Mar 19, 2026
@tuliomir tuliomir requested a review from andreabadesso March 19, 2026 13:10
Comment thread .github/workflows/main.yml Outdated
Comment thread .github/workflows/main.yml Outdated
Comment thread .github/workflows/main.yml Outdated
Comment thread .github/workflows/main.yml Outdated
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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
.github/workflows/main.yml (1)

138-143: Use lockfile-resolved versions for migrator build args to ensure reproducible builds.

Extracting versions from package.json passes semver ranges (e.g., ^6.37.2), which allows minor/patch updates on subsequent rebuilds of the same git tag, compromising reproducibility. Since yarn.lock exists, extract exact resolved versions from it instead. You can use jq to parse the lockfile or pipe yarn list --depth 0 and extract versions before passing them as build args.

This applies to both locations: lines 138-143 and 199-202.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/main.yml around lines 138 - 143, The current GitHub Action
step with id "deps" extracts semver ranges from package.json (echo
"sequelize=...") which yields non‑reproducible build args; change the extraction
to pull the exact resolved versions from the lockfile (yarn.lock) or by running
"yarn list --depth 0" and parsing the output, then echo those resolved versions
into $GITHUB_OUTPUT (for example replace the current echo lines for sequelize,
sequelize_cli, and mysql2 with commands that read yarn.lock or parse yarn list
and emit the exact version strings); apply the same change to the second
location that sets these build args so both use lockfile-resolved versions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/main.yml:
- Line 132: The workflow uses floating major tags for actions
(actions/checkout@v6, docker/setup-qemu-action@v4,
docker/setup-buildx-action@v4, docker/login-action@v4,
docker/build-push-action@v7); update each `uses:` entry to the corresponding
immutable commit SHA instead of the major tag (replace e.g. actions/checkout@v6
with actions/checkout@<full-commit-sha> and do the same for
docker/setup-qemu-action, docker/setup-buildx-action, docker/login-action, and
docker/build-push-action occurrences), verifying the SHAs from the respective
GitHub Action repos and ensuring all listed occurrences are changed.

---

Nitpick comments:
In @.github/workflows/main.yml:
- Around line 138-143: The current GitHub Action step with id "deps" extracts
semver ranges from package.json (echo "sequelize=...") which yields
non‑reproducible build args; change the extraction to pull the exact resolved
versions from the lockfile (yarn.lock) or by running "yarn list --depth 0" and
parsing the output, then echo those resolved versions into $GITHUB_OUTPUT (for
example replace the current echo lines for sequelize, sequelize_cli, and mysql2
with commands that read yarn.lock or parse yarn list and emit the exact version
strings); apply the same change to the second location that sets these build
args so both use lockfile-resolved versions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 62399f05-ff21-41ec-81f4-cbd6bfec734a

📥 Commits

Reviewing files that changed from the base of the PR and between 264ba53 and 82f57d0.

📒 Files selected for processing (1)
  • .github/workflows/main.yml

Comment thread .github/workflows/main.yml Outdated
Comment thread .github/workflows/main.yml
Floating major tags like @v6 can be moved by the action maintainer to
point to any commit. If a maintainer's account is compromised, an
attacker could retag majors to a malicious commit.
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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
.github/workflows/main.yml (1)

35-35: Inconsistent actions/checkout version between jobs.

The test job still uses actions/checkout@v3 while the new docker job uses SHA-pinned v6.0.2. The commit message mentions pinning action versions to SHA, but this line was not updated. Consider aligning both jobs to use the same SHA-pinned version for consistency and to avoid actionlint warnings about unsupported runner versions.

♻️ Suggested fix
     - name: Checkout code
-      uses: actions/checkout@v3
+      uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/main.yml at line 35, Update the `uses:
actions/checkout@v3` line in the test job to match the SHA-pinned checkout
reference used by the docker job (the same `actions/checkout` version/pin, e.g.,
`actions/checkout@v6.0.2` or the exact SHA tag used in the docker job) so both
jobs use the identical pinned action reference and avoid actionlint warnings.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/main.yml:
- Around line 174-188: The .dockerignore entry '../../.github/' will be wrong
after the file is copied to the repo root by the "Copy lambdas .dockerignore to
root" step; update the pattern in packages/wallet-service/.dockerignore to
reference the repository-relative path (e.g. '.github/' or '/.github/') instead
of '../../.github/' so when Docker build uses root context (file:
packages/wallet-service/Dockerfile.dev) the .github directory is correctly
excluded.

---

Nitpick comments:
In @.github/workflows/main.yml:
- Line 35: Update the `uses: actions/checkout@v3` line in the test job to match
the SHA-pinned checkout reference used by the docker job (the same
`actions/checkout` version/pin, e.g., `actions/checkout@v6.0.2` or the exact SHA
tag used in the docker job) so both jobs use the identical pinned action
reference and avoid actionlint warnings.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 57ff96ed-708b-4430-b030-e3837ba270d0

📥 Commits

Reviewing files that changed from the base of the PR and between 82f57d0 and 47a0aee.

📒 Files selected for processing (1)
  • .github/workflows/main.yml

Comment thread .github/workflows/main.yml
tuliomir and others added 2 commits March 19, 2026 17:00
The pattern ../../.github/ was relative to the package directory, but
Docker interprets .dockerignore paths relative to the build context
root. Since the file is copied to the repo root before builds, the
correct pattern is .github/.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Aligns the test job's actions/checkout reference with the docker job
by using the same SHA-pinned v6.0.2 commit.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.

Actionable comments posted: 1

♻️ Duplicate comments (1)
.github/workflows/main.yml (1)

138-143: ⚠️ Potential issue | 🟠 Major

Enforce exact dependency versions for deterministic Docker builds.

At lines 141-143, semver ranges (e.g., ^6.37.2) are extracted from package.json and passed as SEQUELIZE_VERSION, SEQUELIZE_CLI_VERSION, and MYSQL2_VERSION to the migrator Docker build. In db/Dockerfile.dev line 62, these are installed via yarn add sequelize@"$SEQUELIZE_VERSION", which resolves to different versions on each rebuild—breaking image reproducibility for tagged releases.

Add validation to ensure only exact semantic versions are passed to the Docker build:

Validate exact version format
     - name: Extract dependency versions for migrator
       id: deps
       run: |
         echo "sequelize=$(jq -er '.devDependencies["sequelize"]' package.json)" >> "$GITHUB_OUTPUT"
         echo "sequelize_cli=$(jq -er '.devDependencies["sequelize-cli"]' package.json)" >> "$GITHUB_OUTPUT"
         echo "mysql2=$(jq -er '.devDependencies["mysql2"]' package.json)" >> "$GITHUB_OUTPUT"
+        for dep in sequelize sequelize_cli mysql2; do
+          v="$(grep "^${dep}=" "$GITHUB_OUTPUT" | cut -d= -f2-)"
+          [[ "$v" =~ ^[0-9]+\.[0-9]+\.[0-9]+([.-].*)?$ ]] || {
+            echo "Non-exact version for ${dep}: ${v}" >&2
+            exit 1
+          }
+        done
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/main.yml around lines 138 - 143, The workflow currently
exports semver ranges into SEQUELIZE_VERSION, SEQUELIZE_CLI_VERSION, and
MYSQL2_VERSION (step id "deps") which Dockerfile.dev then installs via yarn add
sequelize@"$SEQUELIZE_VERSION"; update the "deps" step to validate that each
extracted version is an exact semantic version (no ^, ~, >=, etc.) using a
strict regex (e.g. ^[0-9]+\.[0-9]+\.[0-9]+(?:-[0-9A-Za-z.]+)?$) and fail the job
with a clear message if any value does not match, then only export the validated
values to GITHUB_OUTPUT so the Docker build receives guaranteed exact versions.
Ensure the validation references the same variables SEQUELIZE_VERSION,
SEQUELIZE_CLI_VERSION, and MYSQL2_VERSION and protects the yarn add lines in
Dockerfile.dev from receiving ranged versions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/main.yml:
- Around line 190-197: Add a db/.dockerignore that excludes everything except
the db/ directory (so only files needed by db/Dockerfile.dev are sent in the
build context), and in .github/workflows/main.yml replace the current step that
removes a non-existent root .dockerignore with a step that copies
db/.dockerignore to the repository root (e.g. cp db/.dockerignore .dockerignore)
before the "Build and push migrator dev image" step so the
docker/build-push-action using file: db/Dockerfile.dev will use the lighter
context; reference the workflow step named "Remove stale .dockerignore before
migrator build" and the Dockerfile path db/Dockerfile.dev when making the
change.

---

Duplicate comments:
In @.github/workflows/main.yml:
- Around line 138-143: The workflow currently exports semver ranges into
SEQUELIZE_VERSION, SEQUELIZE_CLI_VERSION, and MYSQL2_VERSION (step id "deps")
which Dockerfile.dev then installs via yarn add sequelize@"$SEQUELIZE_VERSION";
update the "deps" step to validate that each extracted version is an exact
semantic version (no ^, ~, >=, etc.) using a strict regex (e.g.
^[0-9]+\.[0-9]+\.[0-9]+(?:-[0-9A-Za-z.]+)?$) and fail the job with a clear
message if any value does not match, then only export the validated values to
GITHUB_OUTPUT so the Docker build receives guaranteed exact versions. Ensure the
validation references the same variables SEQUELIZE_VERSION,
SEQUELIZE_CLI_VERSION, and MYSQL2_VERSION and protects the yarn add lines in
Dockerfile.dev from receiving ranged versions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f68c89ae-fe55-4249-9eb8-351fdedd67bd

📥 Commits

Reviewing files that changed from the base of the PR and between 47a0aee and edd0ddd.

📒 Files selected for processing (2)
  • .github/workflows/main.yml
  • packages/wallet-service/.dockerignore
✅ Files skipped from review due to trivial changes (1)
  • packages/wallet-service/.dockerignore

Comment thread .github/workflows/main.yml Outdated
tuliomir and others added 2 commits March 19, 2026 17:19
Instead of removing the stale .dockerignore before the migrator build,
copy a dedicated db/.dockerignore that excludes everything except db/.
This reduces the build context sent to the Docker daemon since the
migrator Dockerfile only needs the db/ directory.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
It would only be needed if we were building for archs other than amd64.
@luislhl luislhl moved this from In Progress (Done) to In Review (WIP) in Hathor Network Mar 20, 2026
@tuliomir tuliomir merged commit a7bedbe into master Mar 20, 2026
3 checks passed
@github-project-automation github-project-automation Bot moved this from In Review (WIP) to Waiting to be deployed in Hathor Network Mar 20, 2026
@tuliomir tuliomir deleted the chore/docker-image-on-ci branch March 20, 2026 15:11
@tuliomir tuliomir mentioned this pull request Apr 1, 2026
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Waiting to be deployed

Development

Successfully merging this pull request may close these issues.

3 participants