Skip to content

Add Docker Publishing Workflows and Update CircleCI Configuration#893

Open
nevil-mathew wants to merge 33 commits into
developfrom
master
Open

Add Docker Publishing Workflows and Update CircleCI Configuration#893
nevil-mathew wants to merge 33 commits into
developfrom
master

Conversation

@nevil-mathew

@nevil-mathew nevil-mathew commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • New Features

    • Added a manual workflow for building and publishing multi-architecture Docker images with validated version tags.
    • Added safeguards to prevent duplicate image and Git tag releases.
    • Added a workflow for promoting approved release candidates to production.
    • Added release summaries with published image tags and digests.
  • Chores

    • Updated CI build infrastructure and SonarCloud tooling.
    • Improved repository checkout behavior for CI analysis.

add: github action to publish docker image
chore(ci): allow Docker build from specified branch with default staging
release: v3.3.24 – develop → staging
release: v3.3.24 – develop → staging
release: v3.3.24 – develop → staging
Refactor version assignment to directly use input.
Simplify version retrieval in Docker workflow
release: v3.4.0-rc.1 – develop → staging
release: v3.4.0-rc.1 – develop → staging
Update Docker Hub auth and add release promotion workflow
release: v3.4.0 – staging →  master
update: upgrade SonarCloud orb and change Ubuntu image version
update: add fetch-depth to checkout step in CircleCI config
release: v3.5.0-rc.1 – develop → staging
release: v3.5.0-rc.2 – develop → staging
@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

Adds manual GitHub Actions workflows for multi-architecture Docker image publishing and RC-to-production promotion, including tag validation and duplicate checks. Updates CircleCI’s SonarCloud orb, executor image, and checkout behavior.

Changes

CI configuration updates

Layer / File(s) Summary
CircleCI executor and analysis configuration
.circleci/config.yml
Updates the SonarCloud orb and Ubuntu executor, enables full checkout, and removes a test comment.

Docker release automation

Layer / File(s) Summary
Docker image publishing workflow
.github/workflows/docker-image.yml
Adds manual inputs, validates Git and Docker Hub tags, builds and pushes multi-architecture images, creates an annotated Git tag, and records publication details.
Promotion input and commit validation
.github/workflows/prod-release.yml
Validates the RC tag, derives the production tag, and confirms the RC commit is contained in main.
Docker Hub promotion checks
.github/workflows/prod-release.yml
Authenticates with Docker Hub and verifies the RC image exists while the production tag is absent.
Production image and Git tag publication
.github/workflows/prod-release.yml
Retags the multi-architecture image, creates and pushes the production Git tag, and records its digest.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Maintainer
  participant GitHubActions
  participant DockerHub
  participant GitRepository
  Maintainer->>GitHubActions: submit version and branch
  GitHubActions->>GitRepository: check Git tag
  GitHubActions->>DockerHub: check image tag
  GitHubActions->>DockerHub: build and push multi-architecture image
  GitHubActions->>GitRepository: create and push annotated tag
Loading
sequenceDiagram
  participant Maintainer
  participant GitHubActions
  participant GitRepository
  participant DockerHub
  Maintainer->>GitHubActions: submit RC tag
  GitHubActions->>GitRepository: verify RC commit is in main
  GitHubActions->>DockerHub: verify RC and production image tags
  GitHubActions->>DockerHub: retag RC image as production image
  GitHubActions->>GitRepository: create and push production tag
Loading

Possibly related PRs

Poem

I’m a rabbit hopping through the release queue,
With Docker tags checked before they’re pushed anew.
RCs bloom into production bright,
CircleCI builds on Ubuntu light.
Safe little steps, all neatly in tune—
A carrot-filled pipeline beneath the moon. 🐇

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
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.
Title Check ✅ Passed Title check skipped as CodeRabbit has written the PR title.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch master

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.

@coderabbitai coderabbitai Bot changed the title @coderabbitai Add Docker Publishing Workflows and Update CircleCI Configuration Jul 15, 2026

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

Actionable comments posted: 4

🧹 Nitpick comments (2)
.circleci/config.yml (2)

7-7: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Pin the machine image for reproducible CI.

ubuntu-2204:current can change independently of repository commits, causing unexpected build or dependency behavior. Prefer a dated image such as ubuntu-2204:2026.05.1, updating it deliberately. (circleci.com)

🤖 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 @.circleci/config.yml at line 7, Pin the machine image in the CircleCI
configuration instead of using the mutable ubuntu-2204:current tag. Update the
image value to a dated ubuntu-2204 release and retain future updates as
deliberate version changes.

3-3: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Upgrade the SonarCloud orb sonarsource/sonarcloud@2.0.0 is two major versions behind the latest 4.0.0; move to a current 4.x release or document why the older major is required.

🤖 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 @.circleci/config.yml at line 3, Update the CircleCI SonarCloud orb
declaration from sonarsource/sonarcloud@2.0.0 to a current 4.x release, such as
4.0.0. If retaining the 2.x version, document the specific compatibility reason
in the configuration.
🤖 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.

Inline comments:
In @.github/workflows/docker-image.yml:
- Line 59: Update the Git reference check in the workflow’s VERSION validation
to resolve only refs/tags/$VERSION rather than the ambiguous $VERSION name.
Preserve the existing success/failure branching while ensuring branches with
matching names cannot satisfy the tag check.
- Around line 43-47: Update the workflow step containing the VERSION assignment
to pass github.event.inputs.tag_version through the step’s environment instead
of interpolating it directly in the bash script. Read the environment variable
within the script, then preserve the existing leading “v” removal behavior
without changing the resulting version value.
- Around line 68-72: Update the LOGIN_RESPONSE curl request in the Docker image
workflow to construct the login payload with jq --arg, passing the Docker Hub
username and token as arguments and emitting valid JSON. Preserve the existing
login endpoint and response handling while avoiding manual interpolation of
secret values.

In @.github/workflows/prod-release.yml:
- Around line 71-80: Update the LOGIN_RESPONSE step to pass DOCKERHUB_USERNAME
and DOCKERHUB_TOKEN through the step’s env mapping, then reference those bash
variables in the jq --arg arguments instead of embedding GitHub secret
expressions directly in the run script. Preserve the existing jq-based JSON
construction and curl request.

---

Nitpick comments:
In @.circleci/config.yml:
- Line 7: Pin the machine image in the CircleCI configuration instead of using
the mutable ubuntu-2204:current tag. Update the image value to a dated
ubuntu-2204 release and retain future updates as deliberate version changes.
- Line 3: Update the CircleCI SonarCloud orb declaration from
sonarsource/sonarcloud@2.0.0 to a current 4.x release, such as 4.0.0. If
retaining the 2.x version, document the specific compatibility reason in the
configuration.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8652989b-9a31-45c8-87aa-25e20cb54967

📥 Commits

Reviewing files that changed from the base of the PR and between ebcd662 and bc7f2be.

📒 Files selected for processing (3)
  • .circleci/config.yml
  • .github/workflows/docker-image.yml
  • .github/workflows/prod-release.yml

Comment on lines +43 to +47
shell: bash
run: |
VERSION="${{ github.event.inputs.tag_version }}"
# Strip leading "v" if present
VERSION="${VERSION#v}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Prevent code injection via template expansion.

Interpolating github.event.inputs.tag_version directly into the bash script can lead to command injection if the input contains malicious characters. Passing the input via an environment variable is the recommended secure pattern.

🛡️ Proposed fix to pass input via environment variable
     - name: Get Docker tag version
       id: get-version
       shell: bash
+      env:
+        TAG_VERSION: ${{ github.event.inputs.tag_version }}
       run: |
-        VERSION="${{ github.event.inputs.tag_version }}"
+        VERSION="$TAG_VERSION"
         # Strip leading "v" if present
         VERSION="${VERSION#v}"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
shell: bash
run: |
VERSION="${{ github.event.inputs.tag_version }}"
# Strip leading "v" if present
VERSION="${VERSION#v}"
shell: bash
env:
TAG_VERSION: ${{ github.event.inputs.tag_version }}
run: |
VERSION="$TAG_VERSION"
# Strip leading "v" if present
VERSION="${VERSION#v}"
🧰 Tools
🪛 zizmor (1.26.1)

[error] 45-45: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)

🤖 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/docker-image.yml around lines 43 - 47, Update the workflow
step containing the VERSION assignment to pass github.event.inputs.tag_version
through the step’s environment instead of interpolating it directly in the bash
script. Read the environment variable within the script, then preserve the
existing leading “v” removal behavior without changing the resulting version
value.

Source: Linters/SAST tools

run: |
VERSION="${{ steps.get-version.outputs.version }}"
git fetch --tags
if git rev-parse "$VERSION" >/dev/null 2>&1; then

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Strictly check for Git tags to avoid branch collisions.

Using git rev-parse "$VERSION" will also return success if a branch exists with the same name as the version. To exclusively check for a tag, prefix the version with refs/tags/.

💚 Proposed fix to check tags strictly
-        if git rev-parse "$VERSION" >/dev/null 2>&1; then
+        if git rev-parse "refs/tags/$VERSION" >/dev/null 2>&1; then
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if git rev-parse "$VERSION" >/dev/null 2>&1; then
if git rev-parse "refs/tags/$VERSION" >/dev/null 2>&1; then
🤖 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/docker-image.yml at line 59, Update the Git reference
check in the workflow’s VERSION validation to resolve only refs/tags/$VERSION
rather than the ambiguous $VERSION name. Preserve the existing success/failure
branching while ensuring branches with matching names cannot satisfy the tag
check.

Comment on lines +68 to +72
LOGIN_RESPONSE=$(curl -s -w "\n%{http_code}" \
-X POST \
-H "Content-Type: application/json" \
-d '{"username": "${{ secrets.DOCKERHUB_USERNAME }}", "password": "${{ secrets.DOCKERHUB_TOKEN }}"}' \
"https://hub.docker.com/v2/users/login")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Build JSON safely to prevent breakage or injection.

Constructing the JSON payload manually with string interpolation breaks if the Docker Hub token contains special characters (like quotes or backslashes), leading to invalid JSON and a failed login. Use jq --arg to safely encode the payload, matching the pattern applied in the promotion workflow (prod-release.yml).

🔧 Proposed fix for robust JSON construction
-        LOGIN_RESPONSE=$(curl -s -w "\n%{http_code}" \
-          -X POST \
-          -H "Content-Type: application/json" \
-          -d '{"username": "${{ secrets.DOCKERHUB_USERNAME }}", "password": "${{ secrets.DOCKERHUB_TOKEN }}"}' \
-          "https://hub.docker.com/v2/users/login")
+        LOGIN_RESPONSE=$(jq -n \
+          --arg username "${{ secrets.DOCKERHUB_USERNAME }}" \
+          --arg password "${{ secrets.DOCKERHUB_TOKEN }}" \
+          '{"username": $username, "password": $password}' \
+          | curl -s -w "\n%{http_code}" \
+              -X POST \
+              -H "Content-Type: application/json" \
+              -d `@-` \
+              "https://hub.docker.com/v2/users/login")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
LOGIN_RESPONSE=$(curl -s -w "\n%{http_code}" \
-X POST \
-H "Content-Type: application/json" \
-d '{"username": "${{ secrets.DOCKERHUB_USERNAME }}", "password": "${{ secrets.DOCKERHUB_TOKEN }}"}' \
"https://hub.docker.com/v2/users/login")
LOGIN_RESPONSE=$(jq -n \
--arg username "${{ secrets.DOCKERHUB_USERNAME }}" \
--arg password "${{ secrets.DOCKERHUB_TOKEN }}" \
'{"username": $username, "password": $password}' \
| curl -s -w "\n%{http_code}" \
-X POST \
-H "Content-Type: application/json" \
-d `@-` \
"https://hub.docker.com/v2/users/login")
🤖 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/docker-image.yml around lines 68 - 72, Update the
LOGIN_RESPONSE curl request in the Docker image workflow to construct the login
payload with jq --arg, passing the Docker Hub username and token as arguments
and emitting valid JSON. Preserve the existing login endpoint and response
handling while avoiding manual interpolation of secret values.

Comment on lines +71 to +80
# FIX 1: Build JSON safely with jq --arg to avoid special-character injection
LOGIN_RESPONSE=$(jq -n \
--arg username "${{ secrets.DOCKERHUB_USERNAME }}" \
--arg password "${{ secrets.DOCKERHUB_TOKEN }}" \
'{"username": $username, "password": $password}' \
| curl -s -w "\n%{http_code}" \
-X POST \
-H "Content-Type: application/json" \
-d @- \
"https://hub.docker.com/v2/users/login")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Pass secrets via environment variables to prevent shell injection and corruption.

Injecting secrets directly into the run script using ${{ }} evaluates them before bash runs. If the secrets contain special characters (like ", $, or backticks), they will be interpreted by bash, which can silently corrupt the credentials or cause script failures. This undoes the safety gained by using jq --arg.

Instead, map the secrets to the step's env context and reference them as bash variables.

🔒 Proposed fix
     - name: Check RC image exists and production tag is absent on Docker Hub
+      env:
+        DOCKER_USER: ${{ secrets.DOCKERHUB_USERNAME }}
+        DOCKER_PASS: ${{ secrets.DOCKERHUB_TOKEN }}
       run: |
         RC_TAG="${{ steps.version.outputs.rc }}"
         RELEASE_TAG="${{ steps.version.outputs.release }}"
 
         # FIX 1: Build JSON safely with jq --arg to avoid special-character injection
         LOGIN_RESPONSE=$(jq -n \
-          --arg username "${{ secrets.DOCKERHUB_USERNAME }}" \
-          --arg password "${{ secrets.DOCKERHUB_TOKEN }}" \
+          --arg username "$DOCKER_USER" \
+          --arg password "$DOCKER_PASS" \
           '{"username": $username, "password": $password}' \
           | curl -s -w "\n%{http_code}" \
               -X POST \
               -H "Content-Type: application/json" \
               -d `@-` \
               "https://hub.docker.com/v2/users/login")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# FIX 1: Build JSON safely with jq --arg to avoid special-character injection
LOGIN_RESPONSE=$(jq -n \
--arg username "${{ secrets.DOCKERHUB_USERNAME }}" \
--arg password "${{ secrets.DOCKERHUB_TOKEN }}" \
'{"username": $username, "password": $password}' \
| curl -s -w "\n%{http_code}" \
-X POST \
-H "Content-Type: application/json" \
-d @- \
"https://hub.docker.com/v2/users/login")
env:
DOCKER_USER: ${{ secrets.DOCKERHUB_USERNAME }}
DOCKER_PASS: ${{ secrets.DOCKERHUB_TOKEN }}
run: |
# FIX 1: Build JSON safely with jq --arg to avoid special-character injection
LOGIN_RESPONSE=$(jq -n \
--arg username "$DOCKER_USER" \
--arg password "$DOCKER_PASS" \
'{"username": $username, "password": $password}' \
| curl -s -w "\n%{http_code}" \
-X POST \
-H "Content-Type: application/json" \
-d `@-` \
"https://hub.docker.com/v2/users/login")
🤖 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/prod-release.yml around lines 71 - 80, Update the
LOGIN_RESPONSE step to pass DOCKERHUB_USERNAME and DOCKERHUB_TOKEN through the
step’s env mapping, then reference those bash variables in the jq --arg
arguments instead of embedding GitHub secret expressions directly in the run
script. Preserve the existing jq-based JSON construction and curl request.

release: v3.5.0-rc.3 – develop → staging
release: v3.5.0 –  staging → master
@sonarqubecloud

Copy link
Copy Markdown

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.

1 participant