Skip to content

chore(ci): add cosign signing to community image builds - #3302

Open
Fortune-Ndlovu wants to merge 6 commits into
redhat-developer:mainfrom
Fortune-Ndlovu:add-cosign-community-images
Open

chore(ci): add cosign signing to community image builds#3302
Fortune-Ndlovu wants to merge 6 commits into
redhat-developer:mainfrom
Fortune-Ndlovu:add-cosign-community-images

Conversation

@Fortune-Ndlovu

@Fortune-Ndlovu Fortune-Ndlovu commented Jul 30, 2026

Copy link
Copy Markdown
Member
  • Add keyless cosign signing to the multi-arch merge job in next-container-build.yaml
  • Community images at quay.io/rhdh-community/operator and operator-catalog will be signed after the multi-arch manifest is created
  • Consumers can verify image provenance with cosign verify using the GitHub Actions OIDC issuer

Resolves: https://redhat.atlassian.net/browse/RHDHBUGS-3542

How to test: https://redhat.atlassian.net/browse/RHDHBUGS-3542?focusedCommentId=17811110

Signed-off-by: Fortune Ndlovu fndlovu@redhat.com

Add keyless cosign signing to the multi-arch merge job so that
community images at quay.io/rhdh-community/operator and
operator-catalog are signed after the multi-arch manifest is
created. This allows consumers to verify image provenance using
cosign verify with the GitHub Actions OIDC issuer.

Signed-off-by: Fortune Ndlovu <fndlovu@redhat.com>
@Fortune-Ndlovu
Fortune-Ndlovu requested a review from a team as a code owner July 30, 2026 13:33
@rhdh-qodo-merge

Copy link
Copy Markdown

PR Summary by Qodo

ci: keyless cosign signing for community multi-arch images

✨ Enhancement ⚙️ Configuration changes 🕐 20-40 Minutes

Grey Divider

AI Description

• Enable GitHub OIDC permissions for keyless cosign signing in the merge job.
• Install cosign and sign published multi-arch operator and catalog image tags.
• Sign by manifest digest to provide verifiable provenance for quay.io community images.
Diagram

graph TD
  A["GHA: merge job"] --> B["Buildx: create multi-arch manifest"] --> C["Inspect manifest digest"] --> D["cosign sign (keyless)"] --> E[("Quay registry")]
  A --> F["GitHub OIDC id-token"] --> D
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Use the official cosign GitHub Action for signing
  • ➕ Less shell scripting and fewer parsing dependencies (jq/format stability)
  • ➕ Often provides clearer inputs/outputs and better error reporting
  • ➖ May be less flexible for signing multiple tags against a single resolved digest
  • ➖ Still requires careful digest handling to avoid signing mutable tags
2. Sign only by digest (one signature per image digest)
  • ➕ Avoids repeated signatures for multiple tags pointing at the same digest
  • ➕ Reduces runtime and signature noise while keeping provenance verifiable
  • ➖ Consumers who verify by tag must still resolve to the digest (tooling usually does, but expectations vary)
  • ➖ If the project expects tag-scoped attestations/signatures, this may not match that convention

Recommendation: The PR’s approach (keyless signing by explicit manifest digest, after the multi-arch manifest is created) is the right default for supply-chain integrity because it avoids signing a mutable tag reference. If workflow maintenance becomes a concern, consider migrating the signing logic to an action wrapper, but keep the digest-pinning behavior.

Files changed (1) +21 / -0

Other (1) +21 / -0
next-container-build.yamlAdd OIDC-based cosign signing to the multi-arch merge job +21/-0

Add OIDC-based cosign signing to the multi-arch merge job

• Adds 'id-token: write' permission so the merge job can request a GitHub Actions OIDC token for keyless cosign. Installs cosign and introduces a signing step that extracts the pushed multi-arch manifest digest and signs all published tags for both the operator and operator-catalog images.

.github/workflows/next-container-build.yaml

@rhdh-qodo-merge

rhdh-qodo-merge Bot commented Jul 30, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (3) 📘 Rule violations (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 18 rules
✅ Cross-repo context
  Not relevant to this PR: redhat-developer/rhdh
  Not relevant to this PR: redhat-developer/rhdh-plugins

Grey Divider


Action required

1. Wrong digest signed ✓ Resolved 🐞 Bug ≡ Correctness
Description
The signing step resolves a digest only from the ${LATEST_NEXT} tag and reuses it to sign
${BASE_VERSION} and ${BASE_VERSION}-${SHORT_SHA}, even though those tags are built as separate
manifest lists and can point at different digests. If they diverge, those tags will remain
effectively unsigned (verification will fail) or be signed with a digest that doesn’t match the
tag’s actual content.
Code

.github/workflows/next-container-build.yaml[R312-318]

+          for image in "${OPERATOR_IMAGE_NAME}" "${OPERATOR_IMAGE_NAME}-catalog"; do
+            DIGEST=$(docker buildx imagetools inspect --format '{{json .Manifest}}' "${REGISTRY_WITH_ORG}/${image}:${LATEST_NEXT}" | jq -r '.digest')
+
+            for tag in "${BASE_VERSION}" "${BASE_VERSION}-${SHORT_SHA}" "${LATEST_NEXT}"; do
+              echo "Signing ${REGISTRY_WITH_ORG}/${image}:${tag}@${DIGEST}"
+              cosign sign --yes "${REGISTRY_WITH_ORG}/${image}:${tag}@${DIGEST}"
+            done
Relevance

●●● Strong

Close precedent: they accepted fixes ensuring image tags/manifests point to the correct content;
wrong-digest signing is similar.

PR-#3055

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The workflow creates three separate manifest lists from different per-arch tag inputs, but the
signing step only inspects ${LATEST_NEXT} to obtain a digest and then reuses that digest when
signing all tags, so the signed digest may not match the digest behind ${BASE_VERSION} or
${BASE_VERSION}-${SHORT_SHA}.

.github/workflows/next-container-build.yaml[279-299]
.github/workflows/next-container-build.yaml[307-318]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The workflow computes `DIGEST` from `${image}:${LATEST_NEXT}` and then uses that digest when signing *other* tags (`${BASE_VERSION}`, `${BASE_VERSION}-${SHORT_SHA}`). Since those tags are created via separate `imagetools create` commands (and can therefore have different manifest digests), this can publish tags that are not actually signed.

### Issue Context
In the `merge` job, three manifest lists are created independently (for `${BASE_VERSION}`, `${BASE_VERSION}-${SHORT_SHA}`, and `${LATEST_NEXT}`). The signing step should either (a) resolve and sign each tag’s own digest, or (b) enforce/verify that all tags point to the same digest before signing once.

### Fix Focus Areas
- .github/workflows/next-container-build.yaml[279-323]

### Suggested change (one approach)
- Move digest resolution inside the `for tag in ...` loop:
 - `DIGEST=$(docker buildx imagetools inspect --format '...' "${REGISTRY_WITH_ORG}/${image}:${tag}" ...)`
 - `cosign sign --yes "${REGISTRY_WITH_ORG}/${image}@${DIGEST}"`
- Optionally dedupe digests (if multiple tags resolve to the same digest) to avoid producing multiple signatures for the same digest in one run.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Signing gate checks wrong var ✓ Resolved 🐞 Bug ≡ Correctness ⭐ New
Description
HAS_QUAY_AUTH is computed from secrets.QUAY_USERNAME, but the workflow logs into the registry using
vars.QUAY_USERNAME; if the username is configured as a variable (as other workflows do),
HAS_QUAY_AUTH stays false and image signing is skipped.
Code

.github/workflows/next-container-build.yaml[248]

+      HAS_QUAY_AUTH: ${{ secrets.QUAY_USERNAME != '' && secrets.QUAY_TOKEN != '' }}
Relevance

●●● Strong

They commonly accept workflow correctness fixes, especially in next-container-build.yaml; gating
mismatch likely to be fixed.

PR-#3055
PR-#2293

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The signing gate depends on HAS_QUAY_AUTH, which currently checks a secret username, but the
workflow’s actual login uses a variable username; this can make HAS_QUAY_AUTH false even when login
credentials exist, skipping signing.

.github/workflows/next-container-build.yaml[248-260]
.github/workflows/pr-container-build.yaml[84-90]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`HAS_QUAY_AUTH` is derived from `secrets.QUAY_USERNAME`, but the workflow uses `vars.QUAY_USERNAME` for registry login. This mismatch can prevent the signing step from running even when Quay credentials are correctly configured.

### Issue Context
- Merge job sets `HAS_QUAY_AUTH` using `secrets.QUAY_USERNAME`.
- The same job logs in with `vars.QUAY_USERNAME` and `secrets.QUAY_TOKEN`.
- Other workflows also use `vars.QUAY_USERNAME`, suggesting that is the intended configuration.

### Fix
Update `HAS_QUAY_AUTH` to check the same sources used for login, e.g.:
- `HAS_QUAY_AUTH: ${{ vars.QUAY_USERNAME != '' && secrets.QUAY_TOKEN != '' }}`

### Fix Focus Areas
- .github/workflows/next-container-build.yaml[248-260]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Digest inspect failure aborts step 🐞 Bug ☼ Reliability ⭐ New
Description
The signing step uses set -euo pipefail, but DIGEST is assigned via `$(docker buildx imagetools
inspect ...)` without guarding failures; if inspect exits non-zero (e.g., transient registry error),
the step exits before reaching the warning/continue branch.
Code

.github/workflows/next-container-build.yaml[R315-320]

+            DIGEST=$(docker buildx imagetools inspect "${REGISTRY_WITH_ORG}/${image}:${LATEST_NEXT}" --format '{{println .Digest}}')
+
+            if [ -z "$DIGEST" ] || [ "$DIGEST" = "null" ]; then
+              echo "::warning::Could not resolve digest for ${REGISTRY_WITH_ORG}/${image}:${LATEST_NEXT}, skipping signing"
+              continue
+            fi
Relevance

●●● Strong

Team has accepted hardening workflows against transient/command failures; guarding inspect under set
-e fits this pattern.

PR-#2828
PR-#3169

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The signing step enables set -euo pipefail and then runs docker buildx imagetools inspect inside
command substitution; under -e, a non-zero exit stops the script before the later `if [ -z
"$DIGEST" ] ...` can run.

.github/workflows/next-container-build.yaml[308-320]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
With `set -e`, a failing `docker buildx imagetools inspect ...` in a command substitution will terminate the script immediately, so the subsequent empty/`null` digest check (and warning+continue behavior) is never reached.

### Issue Context
The code appears to intend to skip signing (with a warning) when a digest can’t be resolved, but it currently only handles the case where the command succeeds and prints an empty/`null` value.

### Fix
Guard the inspect call so failures don’t abort the step, for example:
```bash
if ! DIGEST=$(docker buildx imagetools inspect "${REGISTRY_WITH_ORG}/${image}:${LATEST_NEXT}" --format '{{println .Digest}}'); then
 echo "::warning::Failed to inspect ${REGISTRY_WITH_ORG}/${image}:${LATEST_NEXT}, skipping signing"
 continue
fi
```
(or `DIGEST=$(... 2>/dev/null || true)` plus a check).

### Fix Focus Areas
- .github/workflows/next-container-build.yaml[315-320]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


4. Missing env var validation ✓ Resolved 📘 Rule violation ≡ Correctness
Description
The new image-signing run block uses required environment variables without validating they are
non-empty, which can lead to signing incorrect image references or failing in non-obvious ways.
Compliance requires failing parameter expansion checks before first use.
Code

.github/workflows/next-container-build.yaml[R309-318]

+          set -euo pipefail
+          export REGISTRY_WITH_ORG="${REGISTRY}/${REGISTRY_ORG}"
+
+          for image in "${OPERATOR_IMAGE_NAME}" "${OPERATOR_IMAGE_NAME}-catalog"; do
+            DIGEST=$(docker buildx imagetools inspect --format '{{json .Manifest}}' "${REGISTRY_WITH_ORG}/${image}:${LATEST_NEXT}" | jq -r '.digest')
+
+            for tag in "${BASE_VERSION}" "${BASE_VERSION}-${SHORT_SHA}" "${LATEST_NEXT}"; do
+              echo "Signing ${REGISTRY_WITH_ORG}/${image}:${tag}@${DIGEST}"
+              cosign sign --yes "${REGISTRY_WITH_ORG}/${image}:${tag}@${DIGEST}"
+            done
Relevance

●●● Strong

Repo has prior (partial) acceptance of adding failing parameter-expansion checks for required env
vars in workflows.

PR-#3169
PR-#3055

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 14 requires validating required environment variables with failing parameter
expansion before first use. The added signing script uses variables like REGISTRY, REGISTRY_ORG,
LATEST_NEXT, BASE_VERSION, SHORT_SHA to construct image references and tags, but contains no
: "${VAR:?...}" checks prior to use.

Rule 14: Validate required environment variables in bash using failing parameter expansion
.github/workflows/next-container-build.yaml[309-318]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The workflow step `Sign the published images` relies on environment variables (e.g., `REGISTRY`, `REGISTRY_ORG`, `LATEST_NEXT`, `BASE_VERSION`, `SHORT_SHA`) but does not validate that they are set and non-empty using failing parameter expansion.

## Issue Context
`set -euo pipefail` will fail on unset variables, but it will not fail when variables are set to an empty string. This can produce malformed image references (e.g., missing org/tag components) and create hard-to-debug CI failures.

## Fix Focus Areas
- .github/workflows/next-container-build.yaml[309-318]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View more (2)
5. Digest not validated ✓ Resolved 🐞 Bug ☼ Reliability
Description
DIGEST is used to build the cosign signing reference without any validation that it is non-empty
and looks like a real OCI digest. If digest extraction produces an unexpected value, the step fails
later with a less actionable error (and may attempt to sign an invalid ref).
Code

.github/workflows/next-container-build.yaml[R313-318]

+            DIGEST=$(docker buildx imagetools inspect --format '{{json .Manifest}}' "${REGISTRY_WITH_ORG}/${image}:${LATEST_NEXT}" | jq -r '.digest')
+
+            for tag in "${BASE_VERSION}" "${BASE_VERSION}-${SHORT_SHA}" "${LATEST_NEXT}"; do
+              echo "Signing ${REGISTRY_WITH_ORG}/${image}:${tag}@${DIGEST}"
+              cosign sign --yes "${REGISTRY_WITH_ORG}/${image}:${tag}@${DIGEST}"
+            done
Relevance

●●● Strong

They tend to accept failing fast with clearer errors in workflow scripts; digest sanity check is a
small hardening win.

PR-#3055
PR-#2828

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The new signing step assigns DIGEST from an inspect/jq pipeline and immediately uses it in the
cosign sign reference without checking whether the value is empty/valid.

.github/workflows/next-container-build.yaml[307-318]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The signing script uses `DIGEST` directly after extraction, with no guard that it is present and correctly formatted.

### Issue Context
Even with `set -euo pipefail`, command pipelines can succeed while producing unexpected output. Failing fast with a clear message makes the pipeline easier to debug and prevents constructing invalid signing references.

### Fix Focus Areas
- .github/workflows/next-container-build.yaml[313-318]

### Suggested change
After extracting `DIGEST`, add a check such as:
- `if [[ -z "${DIGEST}" || ! "${DIGEST}" =~ ^sha256:[0-9a-f]{64}$ ]]; then echo "ERROR: Could not resolve manifest digest for ${image}:${tag}"; exit 1; fi`
Then proceed to `cosign sign` only when the digest is valid.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


6. OIDC permission too broad 🐞 Bug ⛨ Security
Description
The merge job now grants id-token: write at the job level, making GitHub OIDC token minting
available to every step (including third-party actions executed before signing). If any step/action
is compromised, it could request an OIDC token and attempt to sign images under the workflow’s
identity using the job’s registry credentials, increasing supply-chain blast radius.
Code

.github/workflows/next-container-build.yaml[246]

+      id-token: write
Relevance

●● Moderate

Security hardening often accepted, but OIDC needs broader refactor (job split/step perms); uncertain
they’ll change.

PR-#3169
PR-#2141
PR-#2293

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The workflow explicitly adds id-token: write to the merge job permissions, and job permissions
apply to all steps in that job, including third-party actions executed before the signing step.

.github/workflows/next-container-build.yaml[236-266]
.github/workflows/next-container-build.yaml[253-265]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The `merge` job has job-wide `permissions: id-token: write`, which applies to all steps in the job. This unnecessarily expands the number of steps/actions that could request GitHub OIDC tokens.

### Issue Context
The job performs registry login and buildx setup using third-party actions, and only later performs cosign signing. Least-privilege is improved by isolating OIDC permissions to the smallest possible job/step set.

### Fix Focus Areas
- .github/workflows/next-container-build.yaml[236-323]

### Suggested fix
- Split signing into a dedicated `sign` job that:
 - `needs: [changes, build, merge]` (or runs after manifest creation)
 - has `permissions: { contents: read, id-token: write }` (and only whatever else is truly required)
 - performs only the minimal steps required to sign (e.g., login + cosign install + signing).
- Remove `id-token: write` from the broader `merge` job so that buildx/manifest creation steps do not have OIDC permissions.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

7. Implicit jq dependency ✓ Resolved 🐞 Bug ☼ Reliability
Description
The new signing step relies on jq to parse the manifest digest but the job never installs jq,
creating a hidden runner-image dependency. This makes the signing logic less portable and more
brittle if the runner image/tooling changes.
Code

.github/workflows/next-container-build.yaml[313]

+            DIGEST=$(docker buildx imagetools inspect --format '{{json .Manifest}}' "${REGISTRY_WITH_ORG}/${image}:${LATEST_NEXT}" | jq -r '.digest')
Relevance

●●● Strong

Hidden runner dependency; installing jq (or avoiding it) is a small deterministic reliability fix.

PR-#3055
PR-#3169
PR-#2141

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The signing step pipes output into jq, but the merge job only sets up Buildx and cosign and
contains no jq installation step.

.github/workflows/next-container-build.yaml[260-265]
.github/workflows/next-container-build.yaml[307-318]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The signing step runs `... | jq -r '.digest'` but the merge job does not explicitly install `jq`. This is an implicit dependency on the runner image.

### Issue Context
Today this may work on GitHub-hosted runners, but it is not guaranteed across runner images or future changes.

### Fix Focus Areas
- .github/workflows/next-container-build.yaml[260-318]

### Suggested fix
Pick one:
1) Install jq explicitly before it’s used (e.g., `sudo apt-get update && sudo apt-get install -y jq`).
2) Avoid jq by extracting the digest via buildx formatting (only if you can confirm the template reliably outputs the digest without extra tooling).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


8. Cosign version unpinned 🐞 Bug ⚙ Maintainability
Description
The workflow installs cosign via sigstore/cosign-installer without specifying an explicit cosign
release/version, which can make signing behavior change unexpectedly over time. Pinning the
installed cosign version improves reproducibility and reduces surprise breakages.
Code

.github/workflows/next-container-build.yaml[R263-265]

+      - name: Install cosign
+        uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2
+
Relevance

●● Moderate

Team has mixed precedent on pinning tool versions; sometimes requested, sometimes rejected as
nonessential.

PR-#1136
PR-#2141

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The added installer step does not include any with: inputs to constrain which cosign binary
version gets installed.

.github/workflows/next-container-build.yaml[263-265]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The new `sigstore/cosign-installer` step does not specify which cosign version to install.

### Issue Context
Even when the installer action is commit-pinned, leaving the installed tool version implicit can lead to non-deterministic behavior as defaults evolve.

### Fix Focus Areas
- .github/workflows/next-container-build.yaml[263-265]

### Suggested change
Add a `with:` section to the installer step to pin a specific cosign release (choose the version you want to support), e.g.:
```yaml
- name: Install cosign
 uses: sigstore/cosign-installer@...
 with:
   cosign-release: 'v2.x.y'
```

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Previous review results

Review updated until commit c05c4f0

Results up to commit 27f5060 ⚖️ Balanced


🐞 Bugs (1) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)


Remediation recommended
1. OIDC permission too broad 🐞 Bug ⛨ Security
Description
The merge job now grants id-token: write at the job level, making GitHub OIDC token minting
available to every step (including third-party actions executed before signing). If any step/action
is compromised, it could request an OIDC token and attempt to sign images under the workflow’s
identity using the job’s registry credentials, increasing supply-chain blast radius.
Code

.github/workflows/next-container-build.yaml[246]

+      id-token: write
Relevance

●● Moderate

Security hardening often accepted, but OIDC needs broader refactor (job split/step perms); uncertain
they’ll change.

PR-#3169
PR-#2141
PR-#2293

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The workflow explicitly adds id-token: write to the merge job permissions, and job permissions
apply to all steps in that job, including third-party actions executed before the signing step.

.github/workflows/next-container-build.yaml[236-266]
.github/workflows/next-container-build.yaml[253-265]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The `merge` job has job-wide `permissions: id-token: write`, which applies to all steps in the job. This unnecessarily expands the number of steps/actions that could request GitHub OIDC tokens.

### Issue Context
The job performs registry login and buildx setup using third-party actions, and only later performs cosign signing. Least-privilege is improved by isolating OIDC permissions to the smallest possible job/step set.

### Fix Focus Areas
- .github/workflows/next-container-build.yaml[236-323]

### Suggested fix
- Split signing into a dedicated `sign` job that:
 - `needs: [changes, build, merge]` (or runs after manifest creation)
 - has `permissions: { contents: read, id-token: write }` (and only whatever else is truly required)
 - performs only the minimal steps required to sign (e.g., login + cosign install + signing).
- Remove `id-token: write` from the broader `merge` job so that buildx/manifest creation steps do not have OIDC permissions.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational
2. Implicit jq dependency ✓ Resolved 🐞 Bug ☼ Reliability
Description
The new signing step relies on jq to parse the manifest digest but the job never installs jq,
creating a hidden runner-image dependency. This makes the signing logic less portable and more
brittle if the runner image/tooling changes.
Code

.github/workflows/next-container-build.yaml[313]

+            DIGEST=$(docker buildx imagetools inspect --format '{{json .Manifest}}' "${REGISTRY_WITH_ORG}/${image}:${LATEST_NEXT}" | jq -r '.digest')
Relevance

●●● Strong

Hidden runner dependency; installing jq (or avoiding it) is a small deterministic reliability fix.

PR-#3055
PR-#3169
PR-#2141

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The signing step pipes output into jq, but the merge job only sets up Buildx and cosign and
contains no jq installation step.

.github/workflows/next-container-build.yaml[260-265]
.github/workflows/next-container-build.yaml[307-318]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The signing step runs `... | jq -r '.digest'` but the merge job does not explicitly install `jq`. This is an implicit dependency on the runner image.

### Issue Context
Today this may work on GitHub-hosted runners, but it is not guaranteed across runner images or future changes.

### Fix Focus Areas
- .github/workflows/next-container-build.yaml[260-318]

### Suggested fix
Pick one:
1) Install jq explicitly before it’s used (e.g., `sudo apt-get update && sudo apt-get install -y jq`).
2) Avoid jq by extracting the digest via buildx formatting (only if you can confirm the template reliably outputs the digest without extra tooling).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Qodo Logo

@rhdh-qodo-merge rhdh-qodo-merge Bot added the enhancement New feature or request label Jul 30, 2026
@Fortune-Ndlovu Fortune-Ndlovu changed the title ci: add cosign signing to community image builds chore(ci): add cosign signing to community image builds Jul 30, 2026
@Fortune-Ndlovu

Copy link
Copy Markdown
Member Author

/build-images

@github-actions

Copy link
Copy Markdown
Contributor

Image build failed

See workflow run for details: https://github.com/redhat-developer/rhdh-operator/actions/runs/30548358272

Triggered by @Fortune-Ndlovu

@Fortune-Ndlovu

Copy link
Copy Markdown
Member Author

/agentic_review

@rhdh-qodo-merge

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 27f5060

Use buildx template for digest retrieval instead of fragile JSON
parsing, add credential guard and null-check for graceful fallback.

Signed-off-by: Fortune Ndlovu <fndlovu@redhat.com>
Signed-off-by: Fortune-Ndlovu <fndlovu@redhat.com>
@Fortune-Ndlovu

Copy link
Copy Markdown
Member Author

/agentic_review

@rhdh-qodo-merge

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit da21d3d

Address review feedback: resolve each tag's digest independently
instead of assuming all tags share one digest, and fail the build
if digest resolution fails rather than silently skipping signing.

Signed-off-by: Fortune Ndlovu <fndlovu@redhat.com>
Signed-off-by: Fortune-Ndlovu <fndlovu@redhat.com>
Fix HAS_QUAY_AUTH to check vars.QUAY_USERNAME (matching the login
step) instead of secrets.QUAY_USERNAME. Add required env var checks
with failing parameter expansion, matching the pattern in other
steps of the same workflow.

Signed-off-by: Fortune Ndlovu <fndlovu@redhat.com>
Signed-off-by: Fortune-Ndlovu <fndlovu@redhat.com>
@Fortune-Ndlovu

Copy link
Copy Markdown
Member Author

/agentic_review

@rhdh-qodo-merge

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 9f9de5c

The preceding "Create manifest lists" step already validates these
variables; they are guaranteed non-empty by the time signing runs.

Signed-off-by: Fortune Ndlovu <fndlovu@redhat.com>
Signed-off-by: Fortune-Ndlovu <fndlovu@redhat.com>
@Fortune-Ndlovu
Fortune-Ndlovu force-pushed the add-cosign-community-images branch from 9f9de5c to 55e7a05 Compare July 31, 2026 14:50
The --format '{{println .Digest}}' template field does not exist in
imagetools inspect. Parse the standard output instead.

Signed-off-by: Fortune Ndlovu <fndlovu@redhat.com>
Signed-off-by: Fortune-Ndlovu <fndlovu@redhat.com>
@sonarqubecloud

Copy link
Copy Markdown

set -euo pipefail
export REGISTRY_WITH_ORG="${REGISTRY}/${REGISTRY_ORG}"

for image in "${OPERATOR_IMAGE_NAME}" "${OPERATOR_IMAGE_NAME}-catalog"; do

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
for image in "${OPERATOR_IMAGE_NAME}" "${OPERATOR_IMAGE_NAME}-catalog"; do
for image in "${OPERATOR_IMAGE_NAME}" "${OPERATOR_IMAGE_NAME}-bundle" "${OPERATOR_IMAGE_NAME}-catalog"; do

Is the bundle image intentionally excluded?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants