Skip to content

chore: add caching of container images and related features#1796

Merged
yingbull merged 34 commits into
developfrom
feature/cache-build-workflows
Jan 18, 2026
Merged

chore: add caching of container images and related features#1796
yingbull merged 34 commits into
developfrom
feature/cache-build-workflows

Conversation

@yingbull

@yingbull yingbull commented Jan 18, 2026

Copy link
Copy Markdown

Summary by Sourcery

Introduce a dedicated workflow to build, test, and publish reusable dev container images and update the Maven CI workflow to consume these images with a robust fallback to local builds and improved DB initialization checks.

Enhancements:

  • Update Maven CI jobs to pull pre-built container images from GitHub Container Registry with guarded fallbacks to local Docker builds and conditional layer caching.
  • Strengthen database initialization and verification in CI by switching to a log-based completion check and ensuring all expected databases, including drugref2, exist.
  • Align database initialization scripts with configurable MYSQL_ROOT_PASSWORD while keeping a sensible development default and emitting an explicit completion message for test detection.

CI:

  • Add a container-images workflow that computes content hashes to decide when to rebuild tomcat, mariadb, and drugref dev images, runs basic container health tests, and pushes updated images to ghcr.io only when needed.
  • Configure CI workflows with explicit packages permissions and authenticated registry access for pulling and pushing container images.

Summary by cubic

Adds a GitHub Actions workflow to build and cache dev container images with hash-based freshness, and updates the Maven CI to pull pre-built images with a local build fallback. This speeds up CI runs and makes database initialization checks more reliable.

  • New Features

    • New container-images workflow builds, tests, and pushes images to ghcr.io (tomcat-dev, mariadb-dev, drugref).
    • Hash-based freshness check to skip rebuilds when content hasn’t changed.
    • Optional force_rebuild input for manual rebuilds.
    • Added a clear “Database initialization complete!” log in populate_db.sh for test detection.
  • Refactors

    • Maven workflow now tries to pull pre-built images first; builds locally only if pull fails.
    • Registry login and robust pull error handling; conditional Docker layer caching across jobs.
    • DB init wait switched to log-based check; also verifies drugref2 database exists.
    • populate_db.sh now uses MYSQL_ROOT_PASSWORD with a dev fallback to align with test configuration.
    • Explicit workflow permissions for contents/packages across jobs.

Written for commit 17d4a65. Summary will update on new commits.

Summary by CodeRabbit

  • Chores
    • Added a user-facing "Database initialization complete" message and replaced hard-coded DB passwords with a configurable DB password variable.
  • Chores
    • Added automated build/test/publish for development container images with per-container freshness checks and manual force-rebuild support.
  • Chores
    • Updated CI to prefer pre-built images from a container registry, fall back to local builds when needed, and strengthen database startup, readiness, and verification steps.

✏️ Tip: You can customize this high-level summary in your review settings.

Copilot AI review requested due to automatic review settings January 18, 2026 06:44
@sourcery-ai

sourcery-ai Bot commented Jan 18, 2026

Copy link
Copy Markdown

Reviewer's Guide

Introduces a new GitHub Actions workflow to build/test/push dev container images with hash-based freshness to GHCR, and updates the Maven CI workflow and DB init scripts to prefer pulling these images with robust fallbacks, caching, and more reliable database readiness checks.

Sequence diagram for Maven CI dev container pull-first fallback strategy

sequenceDiagram
  actor Dev as Developer
  participant GitHub as GitHub
  participant MavenWorkflow as maven-project.yml
  participant Runner as GitHub_Actions_Runner
  participant GHCR as GHCR
  participant Docker as Docker_engine

  Dev->>GitHub: Open PR or push
  GitHub->>MavenWorkflow: Trigger workflow
  MavenWorkflow->>Runner: Start build job

  Runner->>Docker: docker login ghcr.io
  Runner->>GHCR: docker pull ghcr.io/IMAGE_PREFIX/openo-tomcat-dev:latest
  alt Image pull succeeds
    GHCR-->>Runner: Image layers
    Runner->>Docker: tag pulled image as openo-tomcat-dev
    Runner->>Runner: Skip Docker layer cache and local build
  else Image not found (manifest unknown)
    GHCR-->>Runner: Not found error
    Runner->>Runner: Enable Docker layer cache
    Runner->>Docker: buildx build openo-tomcat-dev (fallback)
  else Unexpected error
    GHCR-->>Runner: Other pull error
    Runner-->>MavenWorkflow: Set reason=error
    MavenWorkflow->>Runner: Fail job with error message
  end

  opt Successful image available
    Runner->>Docker: run dev container
    Runner->>Runner: execute make install and tests inside container
  end
Loading

Flow diagram for container-images workflow hash-based build and push

flowchart TD
  Start([Start container-images workflow])
  CheckInputs[Check force_rebuild input]

  subgraph Job_check_containers[check-containers job]
    A_checkout[Checkout code]
    A_login[Login to GHCR]
    A_hashes[Compute content hash per container]
    A_pull_inspect[Pull existing image and inspect org.openosp.content-hash label]
    A_compare[Compare hashes and set *_needs_build flags]
  end

  subgraph Job_build_tomcat[build-tomcat job]
    T_cond{{tomcat_needs_build == true?}}
    T_build[Build openo-tomcat-dev:test with labels]
    T_test[Test container: Maven, Java, Tomcat, Node.js]
    T_push{Event is push?}
    T_push_action[Tag and push latest and sha tags]
  end

  subgraph Job_build_mariadb[build-mariadb job]
    M_cond{{mariadb_needs_build == true?}}
    M_build[Build openo-mariadb-dev:test with labels]
    M_test_start[Run container with MYSQL_ROOT_PASSWORD]
    M_wait_ready[Wait for MariaDB readiness]
    M_wait_init[Wait for Database initialization complete! log]
    M_verify_db[Verify oscar, oscar_test, drugref2 databases]
    M_push{Event is push?}
    M_push_action[Tag and push latest and sha tags]
  end

  subgraph Job_build_drugref[build-drugref job]
    D_cond{{drugref_needs_build == true?}}
    D_build[Build openo-drugref:test with labels]
    D_test_start[Run container and wait for Tomcat HTTP response]
    D_verify[Verify Java version and WAR deployment]
    D_push{Event is push?}
    D_push_action[Tag and push latest and sha tags]
  end

  subgraph Job_summary[summary job]
    S_collect[Collect job results]
    S_report[Print per-container build summary and fail on errors]
  end

  Start --> CheckInputs --> A_checkout --> A_login --> A_hashes --> A_pull_inspect --> A_compare

  A_compare --> T_cond
  A_compare --> M_cond
  A_compare --> D_cond

  T_cond -- "true" --> T_build --> T_test --> T_push
  T_cond -- "false" --> M_cond
  T_push -- "yes" --> T_push_action --> M_cond
  T_push -- "no" --> M_cond

  M_cond -- "true" --> M_build --> M_test_start --> M_wait_ready --> M_wait_init --> M_verify_db --> M_push
  M_cond -- "false" --> D_cond
  M_push -- "yes" --> M_push_action --> D_cond
  M_push -- "no" --> D_cond

  D_cond -- "true" --> D_build --> D_test_start --> D_verify --> D_push
  D_cond -- "false" --> S_collect
  D_push -- "yes" --> D_push_action --> S_collect
  D_push -- "no" --> S_collect

  S_collect --> S_report --> End([End workflow])
Loading

File-Level Changes

Change Details Files
Maven CI workflow now prefers pulling pre-built dev images from GHCR with robust error handling and falls back to local Docker builds with conditional layer caching.
  • Added global REGISTRY/IMAGE_PREFIX env configuration and granted packages: read permission to relevant jobs.
  • Inserted docker/login-action steps and pull-first logic for tomcat/mariadb images, tagging pulled images to local names used by the workflow.
  • Implemented differentiation between not-found vs other pull errors, failing early on unexpected errors.
  • Conditionally enabled Docker layer cache restore only when a pre-built image is not found, and gated local build steps with pull-result conditions.
  • Renamed build steps to explicit fallback builds and added logging to clarify when local builds occur.
.github/workflows/maven-project.yml
Database CI checks now rely on explicit log-based completion signals and verify all required databases including drugref2.
  • Reworked DB readiness loop in Maven workflow to watch container logs for the exact completion message and then validate provider table contents, reducing flakiness.
  • Extended post-init validation to assert presence of oscar, oscar_test, and drugref2 databases in CI.
  • Aligned CI DB verification with new initialization semantics used in the dev DB image.
.github/workflows/maven-project.yml
Database initialization script now uses a configurable root password and emits a clear completion marker for log-based readiness checks.
  • Introduced DB_PASSWORD derived from MYSQL_ROOT_PASSWORD with a default of 'password' for development.
  • Replaced hard-coded password usage across createdatabase_on.sh calls, raw mysql invocations, and data load scripts with the new DB_PASSWORD variable.
  • Appended a final "Database initialization complete!" message to signal successful initialization to external watchers.
.devcontainer/db/scripts/populate_db.sh
Added a dedicated container-images workflow that computes content hashes to decide when to rebuild tomcat, mariadb, and drugref images, tests them, and pushes versioned images to GHCR.
  • Created check-containers job that logs into GHCR, computes SHA256 hashes over relevant Dockerfile/context files, compares against org.openosp.content-hash labels on existing images, and outputs per-image rebuild flags and hashes, with optional force_rebuild override.
  • Implemented build-tomcat job that buildx-builds the tomcat-dev image with content-hash and OCI metadata labels, runs basic container smoke tests (Maven/Java/Tomcat/Node presence), and on push events tags and pushes latest and SHA-specific tags to GHCR.
  • Implemented build-mariadb job that builds the mariadb-dev image, runs it with a test root password, waits for MariaDB readiness, validates scripts and DB initialization using the new completion log message, and verifies oscar/oscar_test/drugref2 databases before pushing to GHCR on push events.
  • Implemented build-drugref job that builds the drugref image, verifies Tomcat responsiveness via HTTP, checks Java version and WAR deployment, and pushes latest and SHA tags to GHCR on push events.
  • Added a summary job that reports which containers needed builds, their build results, and fails the workflow if any build job failed.
.github/workflows/container-images.yml

Possibly linked issues

  • #[Feature]: Create a drugref container: PR creates and tests an openo-drugref Java 11 container and supporting CI, fulfilling the drugref container feature.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@github-actions

github-actions Bot commented Jan 18, 2026

Copy link
Copy Markdown

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Snapshot Warnings

⚠️: No snapshots were found for the head SHA 17d4a65.
Ensure that dependencies are being submitted on PR branches and consider enabling retry-on-snapshot-warnings. See the documentation for more information and troubleshooting advice.

OpenSSF Scorecard

PackageVersionScoreDetails
actions/docker/login-action 3.*.* 🟢 5.1
Details
CheckScoreReason
Security-Policy🟢 9security policy file detected
Maintained🟢 68 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 6
Binary-Artifacts🟢 10no binaries found in the repo
Code-Review🟢 5Found 2/4 approved changesets -- score normalized to 5
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Packaging⚠️ -1packaging workflow not detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
License🟢 10license file detected
Fuzzing⚠️ 0project is not fuzzed
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ -1internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Vulnerabilities⚠️ 010 existing vulnerabilities detected
SAST🟢 9SAST tool detected but not run on all commits

Scanned Files

  • .github/workflows/maven-project.yml

Comment thread .github/workflows/container-images.yml Fixed
…tain permissions

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Jan 18, 2026

Copy link
Copy Markdown

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

Adds DB_PASSWORD (defaulting from MYSQL_ROOT_PASSWORD) and a completion echo to the DB init script; introduces a new GitHub Actions workflow to compute content hashes and conditionally build/test/push three dev images; and extends the Maven CI workflow to pull pre-built images with registry login, fallback local builds, and enhanced DB readiness/verification including drugref2.

Changes

Cohort / File(s) Summary
Database initialization script
\.devcontainer/db/scripts/populate_db.sh``
Adds DB_PASSWORD (defaults from MYSQL_ROOT_PASSWORD or 'password'), replaces hard-coded passwords with "$DB_PASSWORD" for DB creation and script loading, preserves exit-on-failure behavior, and appends echo 'Database initialization complete!'.
New container images workflow
\.github/workflows/container-images.yml``
Adds workflow to compute per-image content-hashes, decide rebuilds, conditionally build/test openo-tomcat-dev, openo-mariadb-dev, openo-drugref, label images (content-hash/source/revision), log into GHCR, and push latest and sha tags when applicable; includes build/test/push and a summary job.
Maven CI workflow enhancements
\.github/workflows/maven-project.yml``
Adds REGISTRY/IMAGE_PREFIX, registry login and attempts to pull pre-built images with success/not-found/error branching, conditional Docker layer caching, fallback local container builds, Docker network and DB container startup, log-based DB readiness detection, and verification of additional DBs (including drugref2).

Sequence Diagram(s)

sequenceDiagram
    actor Dev as Developer
    participant GH as GitHub Actions
    participant Reg as ghcr.io
    participant Builder as Buildx
    participant Tester as Test Container
    participant Summary as Summary Job

    Dev->>GH: Trigger container-images workflow (push/dispatch/PR)
    GH->>GH: Compute content-hash from Dockerfile/context
    GH->>Reg: Attempt to pull existing image and read content-hash label
    alt Image up-to-date
        Reg-->>GH: Image up-to-date
        GH->>Summary: Mark skip for that image
    else Needs rebuild / not found
        Reg-->>GH: Not found or hash mismatch
        GH->>Builder: Build image (label with content-hash)
        Builder-->>Tester: Run containerized validation checks
        Tester-->>GH: Validation result
        alt Tests pass and event is push
            GH->>Reg: Push tags (latest + sha)
            Reg-->>GH: Confirm push
        end
        GH->>Summary: Record build outcome
    end
Loading
sequenceDiagram
    participant MavenJob as Maven Job
    participant Reg as ghcr.io
    participant LocalBuild as Local Docker Build
    participant Network as Docker Network
    participant DB as DB Container
    participant Tests as Test Suite

    MavenJob->>Reg: Try pull pre-built `openo-tomcat-dev`
    alt Pull succeeded
        Reg-->>MavenJob: Use pulled image
    else Not found
        Reg-->>MavenJob: 404 Not Found
        MavenJob->>LocalBuild: Build dev container (fallback)
        LocalBuild-->>MavenJob: Image built
    else Pull error
        Reg-->>MavenJob: Error -> conditional fail step
    end
    MavenJob->>Network: Create network (legacy path)
    MavenJob->>DB: Start DB container(s) (uses `DB_PASSWORD`)
    DB->>DB: Initialize databases and emit readiness logs
    DB-->>MavenJob: Readiness detected via logs
    MavenJob->>Tests: Run tests against running containers
    Tests-->>MavenJob: Test results
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 I hopped through CI fields with a twitch and a beat,
I swapped hard-coded secrets for a variable sweet.
I watched hashes climb, builds hum, and tests take a seat —
Then I neatened the garden with: "Database initialization complete!" 🥕

🚥 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 PR title accurately describes the main changes: introducing container image caching and related CI/workflow features across multiple files.
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.


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

Copilot AI 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.

Pull request overview

This PR introduces container image caching to improve CI/CD performance by pre-building and storing development container images in GitHub Container Registry (ghcr.io). The workflow attempts to pull pre-built images first, falling back to local builds when unavailable.

Changes:

  • New container-images.yml workflow that builds, tests, and pushes three container images (tomcat-dev, mariadb-dev, drugref) with content-hash based freshness checking
  • Modified maven-project.yml to pull pre-built images from ghcr.io before building locally, with conditional build steps
  • Updated database initialization script to emit a completion message for easier detection in CI workflows

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 7 comments.

File Description
.github/workflows/container-images.yml New workflow for building and pushing container images to ghcr.io with hash-based caching and comprehensive testing
.github/workflows/maven-project.yml Added image pull logic, registry authentication, and conditional builds; updated database initialization check to use log messages
.devcontainer/db/scripts/populate_db.sh Added completion message to enable log-based initialization detection

Comment thread .github/workflows/container-images.yml Outdated
Comment thread .github/workflows/container-images.yml Outdated
Comment thread .github/workflows/maven-project.yml
Comment thread .github/workflows/maven-project.yml Outdated
Comment thread .github/workflows/maven-project.yml Outdated
Comment thread .github/workflows/container-images.yml Outdated
Comment thread .github/workflows/maven-project.yml Outdated
@claude

claude Bot commented Jan 18, 2026

Copy link
Copy Markdown

Code review

No issues found. Checked for bugs and CLAUDE.md compliance.


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

1 issue found across 3 files

Confidence score: 4/5

  • Safe to merge overall with minimal risk; the issue is a medium-severity caching concern rather than a functional code bug.
  • .github/workflows/container-images.yml omits .devcontainer/development/config/shared/my.cnf from the mariadb cache hash even though the Dockerfile copies it, so image rebuilds may not pick up config changes.
  • Pay close attention to .github/workflows/container-images.yml - ensure the cache hash includes .devcontainer/development/config/shared/my.cnf to avoid stale images.
Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name=".github/workflows/container-images.yml">

<violation number="1" location=".github/workflows/container-images.yml:144">
P2: The mariadb cache hash omits `.devcontainer/development/config/shared/my.cnf`, even though the Dockerfile copies it. Changes to that config won’t trigger a rebuild, so the cached image can drift from the Dockerfile inputs. Include this path in the hash inputs used for `check_container`.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread .github/workflows/container-images.yml Outdated

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

Hey - I've found 2 issues, and left some high level feedback:

  • The GHCR login steps in maven-project.yml run unconditionally; consider guarding them (e.g. only on non-fork events or with continue-on-error) so that PRs from forks don’t fail purely because they can’t authenticate to the registry while still allowing the local build fallback to run.
  • The repeated 'Try to pull pre-built image from ghcr.io' logic across the Maven workflow jobs could be extracted into a reusable composite action or shared step to reduce duplication and make future updates to the pull‑first/fallback behavior easier to maintain.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The GHCR login steps in `maven-project.yml` run unconditionally; consider guarding them (e.g. only on non-fork events or with `continue-on-error`) so that PRs from forks don’t fail purely because they can’t authenticate to the registry while still allowing the local build fallback to run.
- The repeated 'Try to pull pre-built image from ghcr.io' logic across the Maven workflow jobs could be extracted into a reusable composite action or shared step to reduce duplication and make future updates to the pull‑first/fallback behavior easier to maintain.

## Individual Comments

### Comment 1
<location> `.github/workflows/container-images.yml:269-270` </location>
<code_context>
+        id: test
+        run: |
+          echo "Testing container starts correctly..."
+          docker run -d --name test-mariadb \
+            -e MYSQL_ROOT_PASSWORD=testpassword \
+            openo-mariadb-dev:test
+
</code_context>

<issue_to_address>
**issue (bug_risk):** MariaDB test uses a different root password than the init scripts expect, which will cause initialization to fail.

`populate_db.sh` assumes `mysql -u root -ppassword`, but this test starts the container with `MYSQL_ROOT_PASSWORD=testpassword`. With that mismatch, all `mysql -ppassword` calls will fail, the init script won’t reach the "Database initialization complete!" log, and the `initialized` wait loop will time out. Please either set `MYSQL_ROOT_PASSWORD=password` here or change the init scripts to use `$MYSQL_ROOT_PASSWORD` instead of a hard-coded value.
</issue_to_address>

### Comment 2
<location> `.github/workflows/maven-project.yml:68-73` </location>
<code_context>
+      - name: Checkout code
+        uses: actions/checkout@v4
+
+      - name: Log in to Container Registry
+        uses: docker/login-action@v3
+        with:
+          registry: ${{ env.REGISTRY }}
+          username: ${{ github.actor }}
+          password: ${{ secrets.GITHUB_TOKEN }}
+
+      - name: Check container freshness
</code_context>

<issue_to_address>
**suggestion:** The registry login + pull logic is duplicated across jobs and could be refactored to reduce maintenance overhead.

Build, test-modern, and test-legacy now repeat the same ghcr.io login, `openo-tomcat-dev:latest` pull, and cache/build fallback steps. Any future change to registry settings, image name, or pull logic would need to be updated in three places. Please consider centralizing this (e.g., reusable workflow, shared action, or YAML anchors) so the login/pull/fallback behavior is defined once.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread .github/workflows/container-images.yml
Comment thread .github/workflows/maven-project.yml
yingbull and others added 3 commits January 18, 2026 11:35
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

Copilot AI commented Jan 18, 2026

Copy link
Copy Markdown

@yingbull I've opened a new pull request, #1798, to work on those changes. Once the pull request is ready, I'll request review from you.

yingbull and others added 3 commits January 18, 2026 11:39
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
- Enhanced all "Try to pull" steps to capture docker pull output
- Added GitHub Actions warnings when pulls fail to help troubleshoot auth/permission issues
- Logs now distinguish between missing images vs authentication/permission errors
- Uses ::warning:: annotations to make failures visible in workflow logs
- Applied to all 4 pull operations: build job, modern-tests job, and both tomcat/mariadb in legacy-tests job

Co-authored-by: yingbull <8680161+yingbull@users.noreply.github.com>

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

1 issue found across 1 file (changes from recent commits).

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name=".github/workflows/maven-project.yml">

<violation number="1" location=".github/workflows/maven-project.yml:95">
P3: The docker pull error output is redirected to a file and then deleted without being printed, so the workflow logs won’t show the real failure reason. Emit the captured stderr before removing the file to aid troubleshooting.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread .github/workflows/maven-project.yml Outdated
yingbull and others added 2 commits January 18, 2026 12:01
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

Copilot AI commented Jan 18, 2026

Copy link
Copy Markdown

@yingbull I've opened a new pull request, #1799, to work on those changes. Once the pull request is ready, I'll request review from you.

yingbull and others added 2 commits January 18, 2026 12:03
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

Copilot AI commented Jan 18, 2026

Copy link
Copy Markdown

@yingbull I've opened a new pull request, #1800, to work on those changes. Once the pull request is ready, I'll request review from you.

Co-authored-by: yingbull <8680161+yingbull@users.noreply.github.com>
@sourcery-ai

sourcery-ai Bot commented Jan 18, 2026

Copy link
Copy Markdown

Hey @yingbull, I've posted a new review for you!

yingbull and others added 2 commits January 18, 2026 12:52
fix: use exact-match grep for database verification in maven-project.yml

Copilot AI commented Jan 18, 2026

Copy link
Copy Markdown

@yingbull I've opened a new pull request, #1804, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI and others added 2 commits January 18, 2026 17:58
…istry

Co-authored-by: yingbull <8680161+yingbull@users.noreply.github.com>
fix: enable image push on manual workflow_dispatch with force_rebuild
@yingbull

Copy link
Copy Markdown
Author

@claude review

@yingbull

Copy link
Copy Markdown
Author

@copilot review

Copilot AI commented Jan 18, 2026

Copy link
Copy Markdown

@yingbull I've opened a new pull request, #1805, to work on those changes. Once the pull request is ready, I'll request review from you.

@yingbull

Copy link
Copy Markdown
Author

@sourcery-ai review

@claude

claude Bot commented Jan 18, 2026

Copy link
Copy Markdown

Claude finished @yingbull's task in 1m 55s —— View job


Code Review Progress

  • Read and analyze changed files
  • Review container-images.yml workflow
  • Review maven-project.yml changes
  • Review populate_db.sh changes
  • Check existing reviewer feedback
  • Provide comprehensive review feedback

Code Review Summary

I've completed a comprehensive review of this PR. Overall, the implementation is solid and introduces a valuable optimization to the CI/CD pipeline. The hash-based container caching strategy is well-designed and the pull-first, build-fallback pattern is correctly implemented.

Multiple sub-PRs have been merged to address issues identified by other reviewers. Most critical bugs have been fixed. However, one caching issue remains unresolved.


Issues Already Fixed ✅

The following issues were identified by other reviewers and have been successfully merged:

  1. ✅ Improved error logging for docker pull failures - Fixed in PR Merge improved error handling for container image pull failures #1798, commit 7c58edb3

    • Now shows stderr output before deleting the error log file
    • Applied to all image pull operations in commit 36590b66
  2. ✅ Password consistency in MariaDB - Fixed in PR Fix MariaDB password mismatch between test workflow and init scripts #1799, commit 5b3c15bc

    • Changed populate_db.sh to use MYSQL_ROOT_PASSWORD environment variable (line 6)
    • Aligns with container configuration across both workflows
    • CI uses password, tests use testpassword consistently
  3. ✅ Database state verification enhanced - Fixed in PR fix: add database state verification to container-images.yml initialization check #1800, commit 4a1c43d9

    • Added dual verification: log message + provider table count check
    • Prevents false positives from container restarts or log reuse
  4. ✅ Exact-match grep for database verification - Fixed in PRs fix: apply improved error handling to all image pull operations #1801, Fix database verification grep to prevent oscar/oscar_test false positives #1802, commit 41b2ae8d

    • Uses grep -x to prevent oscar matching oscar_test
    • Applied to both workflows (.github/workflows/container-images.yml:328-330, .github/workflows/maven-project.yml:464-466)
  5. ✅ workflow_dispatch push permission - Fixed in PR fix: enable image push on manual workflow_dispatch with force_rebuild #1804, commit 332447e6

    • Images now pushed on workflow_dispatch with force_rebuild=true
    • Push condition updated to: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && github.event.inputs.force_rebuild == 'true')

Remaining Issue ⚠️

MariaDB Hash Calculation Missing my.cnf File

Location: .github/workflows/container-images.yml:147

Issue: The MariaDB Dockerfile copies .devcontainer/development/config/shared/my.cnf (line 24 of .devcontainer/db/Dockerfile), but this file is not included in the hash calculation.

Current code:

check_container "mariadb-dev" "mariadb" ".devcontainer/db" "database"

Impact: Changes to my.cnf won't trigger a container rebuild, potentially causing the cached image to drift from the actual Dockerfile inputs. This is a medium-priority caching bug.

Root cause: The check_container function (lines 95-143) only accepts a single extra_context path (line 99), but MariaDB needs multiple paths:

  • .devcontainer/db (main context)
  • database (SQL scripts)
  • .devcontainer/development/config/shared/my.cnf (configuration file)

Recommendation: The check_container function needs to be updated to accept multiple extra context paths. Based on the Cubic reviewer's feedback, this was identified and a sub-PR (#1797) was created, but I cannot find evidence it was merged.

Suggested fix: Modify the function to accept multiple extra paths using bash arrays:

check_container() {
  local name=$1
  local output_name=$2
  local context_path=$3
  shift 3
  local extra_contexts=("$@")  # Accept multiple paths
  
  # ... existing code ...
  
  if [ ${#extra_contexts[@]} -gt 0 ]; then
    HASH=$(find "$context_path" "${extra_contexts[@]}" \( -name 'Dockerfile' ... \) ...)
  else
    HASH=$(find "$context_path" \( -name 'Dockerfile' ... \) ...)
  fi
}

# Usage:
check_container "mariadb-dev" "mariadb" ".devcontainer/db" "database" ".devcontainer/development/config/shared/my.cnf"

Strengths of This Implementation ✅

  1. Excellent documentation: Both workflows have comprehensive header comments explaining purpose, strategy, and usage
  2. Robust error handling: Pull-first logic properly distinguishes between "not found" (expected) and errors (unexpected)
  3. Smart caching strategy: Content-hash based freshness checks prevent unnecessary rebuilds
  4. Comprehensive testing: Each container image has validation tests before push
  5. Security-conscious: Appropriate permissions set for each job (packages: read vs packages: write)
  6. Enhanced DB verification: Dual verification (log message + database state) prevents false positives
  7. Conditional push: Images only pushed on github.event_name == 'push' or manual workflow_dispatch with force_rebuild, not on PRs (prevents registry pollution)
  8. Fork-friendly: continue-on-error: true on pull steps ensures forks without GHCR access gracefully fall back to local builds

Design Decisions Worth Noting 📋

  1. Pull-first, build-fallback pattern: Excellent for both CI speed and fork-friendliness

    • Forks without GHCR access will gracefully fall back to local builds
    • Error handling distinguishes "not found" (expected) from other errors (problematic)
  2. Dual database verification (lines 304-316 in container-images.yml, 442-460 in maven-project.yml):

    • Log message: "Database initialization complete!"
    • Database state: Provider table count > 0
    • Good defense against container restarts or log reuse
  3. Password consistency: After fixes, passwords are now consistent:

    • container-images.yml: Uses testpassword throughout (lines 273, 279, 307, 328-330)
    • maven-project.yml: Uses password throughout (lines 414, 424, 445, 464-466)
    • populate_db.sh: Uses ${MYSQL_ROOT_PASSWORD:-password} (line 6), respecting environment
  4. Exact-match database checks: Using grep -x prevents false positives where oscar would match oscar_test


Minor Observations (Non-blocking) 💡

  1. Code duplication: As noted by Sourcery and acknowledged, the registry login + pull logic is duplicated across jobs. You've noted "Will refactor later" - this is acceptable for now given the complexity of extracting to a reusable action.

  2. Tight polling loop: The database readiness checks poll every 2 seconds for up to 90 iterations (lines 303-316, 441-454). Consider adding --tail or --since to the docker logs command to reduce log volume, or increase the sleep interval slightly.

  3. No permissions issue on workflow file: The GitHub Advanced Security scanner flagged line 492 for missing permissions block on the summary job. This is already set correctly at line 455-457 (contents: read), so this appears to be a false positive from the scanner.


Compliance with CLAUDE.md ✅

  • Workflow security: Appropriate permissions set for each job
  • Documentation: Excellent workflow headers and inline comments
  • Best practices: Follows GitHub Actions patterns
  • No PHI concerns: No healthcare data in CI workflows
  • Security practices: Uses content-based hashing, proper authentication, conditional caching

Final Recommendation

Status: Nearly ready to merge, but one caching issue needs attention.

Action Required:

  1. Address the MariaDB hash calculation issue to include .devcontainer/development/config/shared/my.cnf
  2. This can be done by:
    • Updating the check_container function to accept multiple extra context paths (recommended)
    • Or manually adding the file to the mariadb hash calculation in a different way

Once the hash issue is resolved, this PR represents a significant improvement to CI/CD performance and will be safe to merge.


Summary of Changes


Code Quality Notes

What works well:

  • Error handling and logging throughout
  • Security-conscious design (permissions, authentication)
  • Comprehensive testing before pushing images
  • Clear separation of concerns between workflows
  • Backward compatibility maintained

What could be improved (future work):

  • Extract duplicated pull logic into reusable composite action
  • Consider reducing database polling frequency or log volume
  • Add the missing my.cnf to mariadb hash calculation

View job

@sourcery-ai

sourcery-ai Bot commented Jan 18, 2026

Copy link
Copy Markdown

Sorry @yingbull, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

1 similar comment
@SourceryAI

Copy link
Copy Markdown

Sorry @yingbull, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@yingbull

Copy link
Copy Markdown
Author

@copilot fix the remaining my.cnf related hash issue that claude highlighted

Copilot AI commented Jan 18, 2026

Copy link
Copy Markdown

@yingbull I've opened a new pull request, #1806, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI and others added 3 commits January 18, 2026 18:25
Co-authored-by: yingbull <8680161+yingbull@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
fix: include my.cnf in mariadb-dev container hash calculation
@yingbull

Copy link
Copy Markdown
Author

@claude please give a final review.

@claude

claude Bot commented Jan 18, 2026

Copy link
Copy Markdown

Claude finished @yingbull's task in 1m 39s —— View job


Final Review Progress

  • Read and analyze all changed files
  • Review container-images.yml workflow
  • Review maven-project.yml changes
  • Review populate_db.sh changes
  • Check resolution of previously identified issues
  • Provide comprehensive final review

✅ Final Review: Ready to Merge

I've completed a comprehensive final review of PR #1796. This PR introduces a well-architected container image caching system that will significantly improve CI/CD performance. All previously identified issues have been successfully resolved through merged sub-PRs.


Summary of Changes

Three files modified:

  1. .github/workflows/container-images.yml (NEW - 497 lines)

    • Builds, tests, and pushes 3 dev container images to GHCR
    • Hash-based freshness checking to avoid unnecessary rebuilds
    • Comprehensive validation tests for each container
  2. .github/workflows/maven-project.yml (MODIFIED)

    • Pull-first strategy with fallback to local builds
    • Enhanced database initialization verification
    • Parallel test execution (modern + legacy)
  3. .devcontainer/db/scripts/populate_db.sh (MODIFIED)

    • Uses MYSQL_ROOT_PASSWORD environment variable
    • Emits "Database initialization complete!" for CI detection

Issues Resolved ✅

All issues identified by previous reviewers (Sourcery, Cubic, CodeRabbit, Copilot) have been successfully addressed through the following merged sub-PRs:

PR #1798 - Improved error logging

  • Fixed: Docker pull failures now show stderr output before cleanup
  • Impact: Better troubleshooting for registry issues
  • Commit: 7c58edb3

PR #1799 - Password consistency

  • Fixed: populate_db.sh now uses ${MYSQL_ROOT_PASSWORD:-password}
  • Impact: Aligns with container configuration across workflows
  • Commit: 5b3c15bc

PR #1800 - Enhanced DB verification

  • Fixed: Dual verification (log message + provider table count)
  • Impact: Prevents false positives from container restarts
  • Commit: 4a1c43d9

PR #1801 & #1802 - Exact-match grep

  • Fixed: Uses grep -x to prevent oscar matching oscar_test
  • Impact: Database verification is now precise
  • Commits: 36590b66, 41b2ae8d

PR #1804 - workflow_dispatch push support

  • Fixed: Images now pushed when force_rebuild=true on manual dispatch
  • Impact: Manual rebuilds can update registry
  • Commit: 332447e6

PR #1806 - MariaDB hash includes my.cnf

  • Fixed: Added .devcontainer/development/config/shared/my.cnf to hash calculation
  • Impact: Configuration changes now trigger rebuilds
  • Commit: faee6d14

Code Quality Assessment

Strengths

  1. Excellent documentation - Both workflows have comprehensive header comments explaining purpose, strategy, and usage

  2. Robust error handling - Pull-first logic properly distinguishes between:

    • "Image not found" (expected, falls back to build)
    • Other errors (unexpected, fails fast)
  3. Smart caching strategy - Content-hash based freshness checks:

    • Only rebuilds when Dockerfile/context actually changes
    • Reduces CI minutes and speeds up pipeline
  4. Comprehensive testing - Each container validated before push:

    • Tomcat: Maven, Java, Tomcat, Node.js checks
    • MariaDB: Dual verification (log + database state)
    • DrugRef: HTTP response + deployment verification
  5. Security-conscious design:

    • Appropriate job permissions (packages: read vs packages: write)
    • Authenticated registry access
    • Conditional push (only on branch push or manual force rebuild)
  6. Fork-friendly CI:

    • continue-on-error: true on pull steps
    • Graceful fallback to local builds
    • No disruption to fork PRs without GHCR access
  7. Enhanced database checks:

    • Log-based completion signal: "Database initialization complete!"
    • Provider table count verification (>0 rows)
    • Exact database name matching with grep -x
    • Verifies all 3 databases: oscar, oscar_test, drugref2

Design Decisions Worth Noting

  1. Pull-first, build-fallback pattern (.github/workflows/maven-project.yml:75-106)

    • Excellent for both CI speed and fork compatibility
    • Error classification enables smart fallback behavior
  2. Dual database verification (container-images.yml:306-321, maven-project.yml:439-460)

    • Log message: Signals script completion
    • Database state: Confirms actual initialization
    • Prevents false positives from restarts/log reuse
  3. Password consistency (populate_db.sh:6)

    • DB_PASSWORD="${MYSQL_ROOT_PASSWORD:-password}"
    • Respects environment, defaults for dev
    • CI uses password, tests use testpassword consistently
  4. Conditional push logic (container-images.yml:219, 343, 440)

    • github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && github.event.inputs.force_rebuild == 'true')
    • PRs build/test but don't pollute registry
    • Manual rebuilds can update registry when needed
  5. Multi-path hash support (container-images.yml:106-114)

    • extra_context now supports space-separated paths
    • MariaDB hash includes: .devcontainer/db, database, .devcontainer/development/config/shared
    • Ensures my.cnf changes trigger rebuild

Compliance with CLAUDE.md

Workflow security - Appropriate permissions set for each job
Documentation - Excellent workflow headers and inline comments
Best practices - Follows GitHub Actions patterns
No PHI concerns - No healthcare data in CI workflows
Commit messages - Follow conventional commits format


Minor Observations (Non-blocking)

These are architectural decisions made by the team, documented for awareness:

  1. Code duplication acknowledged - The registry login + pull logic is duplicated across jobs (maven-project.yml:68-99, 188-219, 292-354). Team has noted "will refactor later" which is acceptable given the complexity of extracting to a reusable action.

  2. Tight polling loop - Database readiness checks poll every 2 seconds for up to 90 iterations (container-images.yml:308-321, maven-project.yml:441-454). This is reasonable given initialization complexity, though could optionally use --tail on docker logs to reduce log volume.

  3. Permission block false positive - GitHub Advanced Security scanner flagged line 497 for missing permissions on the summary job. This is a false positive - permissions are correctly set at line 460-461 (contents: read).


Performance Impact

This PR will deliver significant performance improvements:

  • CI speed boost: Pre-built images eliminate container build time on most runs
  • Developer onboarding: New contributors pull cached images instead of building
  • Smart caching: Only rebuilds when content actually changes (hash-based)
  • Parallel execution: Modern and legacy tests run concurrently

Estimated time savings: 5-10 minutes per CI run when images are cached


Security Considerations

Minimal attack surface:

  • Images only pushed from push events or authorized workflow_dispatch
  • Content hashing prevents cache poisoning
  • Registry authentication required for all operations
  • No secrets or PHI in workflows

Audit trail:

  • All images tagged with both :latest and :${{ github.sha }}
  • OCI labels track source and revision
  • Container build jobs tracked in workflow runs

Recommendation

✅ APPROVED - Ready to merge

This PR is production-ready and represents a significant improvement to the CI/CD infrastructure. All identified issues have been resolved, the implementation is robust, and the code quality is excellent.

No blocking issues remain.

The duplicate code in pull logic is acknowledged as future refactoring work, which is an acceptable trade-off for the immediate value this PR provides.


What This Enables

Once merged, this infrastructure enables:

  • Faster CI/CD pipelines through image caching
  • Reduced GitHub Actions minutes consumption
  • Easier local development with pre-built images
  • Better developer onboarding experience
  • Foundation for future container optimizations

View job

@yingbull yingbull merged commit 8bc4e75 into develop Jan 18, 2026
21 of 24 checks passed
@yingbull yingbull deleted the feature/cache-build-workflows branch January 18, 2026 19:29
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.

5 participants