Release pipeline - #111
Conversation
Signed-off-by: Alex Zgabur <azgabur@redhat.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughAdds a manual workflow for versioned Helm chart releases. It freezes operator versions, packages charts, updates the Helm repository, and creates a Git tag. Existing workflows pin action revisions, and chart metadata uses release-time placeholders. ChangesVersioned Helm chart release
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant ReleaseOperator
participant ManualReleaseWorkflow
participant Registry
participant HelmRepository
participant Git
ReleaseOperator->>ManualReleaseWorkflow: Provide release inputs
ManualReleaseWorkflow->>Registry: Retrieve OCP-specific operator index
Registry-->>ManualReleaseWorkflow: Return frozen operator versions
ManualReleaseWorkflow->>HelmRepository: Update values and package charts
HelmRepository-->>ManualReleaseWorkflow: Return packaged charts
ManualReleaseWorkflow->>Git: Push gh-pages changes and release tag
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
4d12638 to
c3661ba
Compare
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 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/helm-lint.yaml:
- Around line 10-12: Disable credential persistence for the source checkout in
.github/workflows/helm-lint.yaml lines 10-12 by adding persist-credentials:
false alongside fetch-depth: 0. Also add a with: block containing
persist-credentials: false to the source checkout in
.github/workflows/release.yml line 13; leave the gh-pages checkout credentials
unchanged for pushing.
In @.github/workflows/manual-release.yml:
- Line 28: Prevent workflow inputs from being rendered directly into shell
source: in .github/workflows/manual-release.yml lines 28-28 and 34-34, expose
the inputs through environment variables and validate the quoted
"$KUADRANT_VERSION" and "$OCP_VERSION"; at lines 73-73, build CATALOG_IMAGE from
"$OCP_VERSION"; at lines 94-95, pass INDEX_IMAGE through the environment, use
strenv(INDEX_IMAGE) in yq, and use printf with the quoted "$INDEX_IMAGE".
- Around line 21-23: Update the release publication jobs in both workflows,
including the release job identified by runs-on: ubuntu-latest, with the same
concurrency.group value. Ensure the shared group serializes Helm gh-pages
publication runs across workflows, preventing concurrent checkout, index
generation, and push operations from racing.
- Around line 39-44: Update the tag existence check in the “Check tag does not
already exist” workflow step to use literal, exact matching for HELM_VERSION
rather than regular-expression matching, so dots and other special characters in
the version cannot match unrelated tags. Preserve the existing error message and
exit behavior when the exact refs/tags/$HELM_VERSION reference is present.
- Around line 46-60: Update the “Set up yq” and “Set up opm” steps to use
reviewed immutable version or commit references instead of resolving latest
releases at runtime. For opm, download the pinned release asset and verify its
checksum before installing it; retain the existing executable installation and
version validation flow.
🪄 Autofix
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: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 357ebd85-ff85-4628-91d8-de467846fe85
📒 Files selected for processing (7)
.github/workflows/helm-lint.yaml.github/workflows/manual-release.yml.github/workflows/release.ymlcharts/kuadrant-instances/Chart.yamlcharts/kuadrant-operators/Chart.yamlcharts/tools-instances/Chart.yamlcharts/tools-operators/Chart.yaml
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # ratchet:actions/checkout@v7 | ||
| - name: Validate kuadrant version format | ||
| run: | | ||
| if ! [[ "${{ inputs.kuadrantVersion }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-rc[0-9]+)*-(k|r)$ ]]; then |
There was a problem hiding this comment.
🔒 Security & Privacy | 🔴 Critical | ⚡ Quick win
Do not render workflow inputs directly into shell source.
A quote or shell metacharacter in an input can alter the command before validation completes. Put inputs in environment variables, then use quoted shell variables. Use strenv(INDEX_IMAGE) for the yq assignment.
.github/workflows/manual-release.yml#L28-L28: validate"$KUADRANT_VERSION"instead of renderinginputs.kuadrantVersion..github/workflows/manual-release.yml#L34-L34: validate"$OCP_VERSION"instead of renderinginputs.ocpVersion..github/workflows/manual-release.yml#L73-L73: buildCATALOG_IMAGEfrom"$OCP_VERSION"..github/workflows/manual-release.yml#L94-L95: usestrenv(INDEX_IMAGE)andprintfwith"$INDEX_IMAGE".
🧰 Tools
🪛 zizmor (1.29.0)
[error] 28-28: code injection via template expansion (template-injection): may expand into attacker-controllable code
(template-injection)
📍 Affects 1 file
.github/workflows/manual-release.yml#L28-L28(this comment).github/workflows/manual-release.yml#L34-L34.github/workflows/manual-release.yml#L73-L73.github/workflows/manual-release.yml#L94-L95
🤖 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/manual-release.yml at line 28, Prevent workflow inputs
from being rendered directly into shell source: in
.github/workflows/manual-release.yml lines 28-28 and 34-34, expose the inputs
through environment variables and validate the quoted "$KUADRANT_VERSION" and
"$OCP_VERSION"; at lines 73-73, build CATALOG_IMAGE from "$OCP_VERSION"; at
lines 94-95, pass INDEX_IMAGE through the environment, use strenv(INDEX_IMAGE)
in yq, and use printf with the quoted "$INDEX_IMAGE".
Source: Linters/SAST tools
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- workflow outline ---'
ast-grep outline .github/workflows/manual-release.yml --items all || true
printf '%s\n' '--- relevant lines ---'
nl -ba .github/workflows/manual-release.yml | sed -n '20,110p'
printf '%s\n' '--- direct workflow-input expressions in run blocks ---'
rg -n -C 3 '\$\{\{\s*inputs\.[A-Za-z0-9_]+\s*\}\}' .github/workflows/manual-release.ymlLength of output: 854
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- relevant workflow section ---'
sed -n '20,115p' .github/workflows/manual-release.yml
printf '%s\n' '--- direct workflow-input expressions ---'
grep -n -C 3 -E '\$\{\{[[:space:]]*inputs\.[[:alnum:]_]+[[:space:]]*\}\}' \
.github/workflows/manual-release.yml || trueLength of output: 5879
@azgabur, the inputs are not environment variables at the reported locations. The workflow renders ${{ inputs.* }} directly into the Bash source.
For example, this is unsafe even though the expression appears between quotes:
if ! [[ "${{ inputs.kuadrantVersion }}" =~ ... ]]; thenGitHub expands the expression before Bash parses the command. An input containing " can terminate the quoted string and change the command.
The workflow must assign inputs through env: and then use quoted shell variables, for example "$KUADRANT_VERSION" and "$OCP_VERSION". The same requirement applies to INDEX_IMAGE; yq must receive it through strenv(INDEX_IMAGE).
The finding remains valid.
You are interacting with an AI system.
| - name: Set up yq | ||
| run: sudo snap install yq | ||
|
|
||
| - name: Set up Helm | ||
| uses: azure/setup-helm@9bc31f4ebc9c6b171d7bfbaa5d006ae7abdb4310 # ratchet:azure/setup-helm@v5 | ||
| with: | ||
| version: v3.18.4 | ||
|
|
||
| - name: Set up opm | ||
| run: | | ||
| OPM_VERSION=$(curl -s https://api.github.com/repos/operator-framework/operator-registry/releases/latest | jq -r '.tag_name') | ||
| curl -Lo opm "https://github.com/operator-framework/operator-registry/releases/download/${OPM_VERSION}/linux-amd64-opm" | ||
| chmod +x opm | ||
| sudo mv opm /usr/local/bin/ | ||
| opm version |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== workflow files =="
git ls-files '.github/workflows/*' || true
echo
echo "== manual-release snippets =="
if [ -f .github/workflows/manual-release.yml ]; then
cat -n .github/workflows/manual-release.yml | sed -n '1,130p'
fi
echo
echo "== yq/opm usage in workflows =="
rg -n "yq|opm|operator-registry|snap install|curl .*opm|versions" .github/workflows || trueRepository: Kuadrant/helm-charts-olm
Length of output: 8468
🌐 Web query:
snap install yq version channel snap install yq documentation
💡 Result:
To install the yq snap, you can use the standard snap install command for the latest stable version, or specify a particular channel to install a different version or track [1][2][3]. Standard Installation To install the latest stable release of yq, run the following command in your terminal: sudo snap install yq [1][4][5] Installing a Specific Version or Channel If you need to install a specific version or major release (such as v3), you can use the --channel flag [6][3]. For example, to install the v3 stable release, you would use: sudo snap install yq --channel=v3/stable [6][3] Key Documentation and Usage Notes The yq snap is distributed with strict confinement, which limits its ability to access files outside of specific system directories [2][6][7]. If you encounter issues reading files (such as root files or files in protected directories), you may need to adjust file permissions or move the target files to a location accessible by the snap [2][7]. You can view available channels, revisions, and more detailed package information by visiting the official yq page on the Snap Store [1]. [1][6][3]
Citations:
- 1: https://snapcraft.io/yq
- 2: https://github.com/mikefarah/yq/blob/fcc04823ca158ecf361317d76986b2d9e6e947b8/README.md
- 3: How can I install latest v3 via snap? mikefarah/yq#625
- 4: https://snapcraft.io/install/yq/ubuntu
- 5: https://snapcraft.io/install/yq/debian
- 6: https://mikefarah.gitbook.io/yq/v3.x
- 7: https://github.com/mikefarah/yq
🌐 Web query:
GitHub operator-framework operator-registry releases github.com/operator-framework/operator-registry/releases/latest linux-amd64-opm binary checksum
💡 Result:
For the latest GitHub release of operator-framework/operator-registry, the linux-amd64 opm binary asset is provided together with a checksums.txt file. The latest release tag is v1.71.0, whose release assets include linux-amd64-opm and checksums.txt. [1] linux-amd64-opm binary (latest release): https://github.com/operator-framework/operator-registry/releases/tag/v1.71.0 (asset listed as “linux-amd64-opm”) [1] checksums.txt (latest release): https://github.com/operator-framework/operator-registry/releases/tag/v1.71.0 (asset listed as “checksums.txt”) [1] To retrieve the exact checksum value for the linux-amd64-opm binary, download checksums.txt from that same release and look up the linux-amd64-opm entry. [1] Example: 1) curl -fsSLO https://github.com/operator-framework/operator-registry/releases/download/v1.71.0/checksums.txt 2) grep -E '^.*linux-amd64-opm$' checksums.txt Note: the sources available here show that checksums.txt exists for the release and that both assets are present, but they do not include the checksum line contents themselves in the retrieved snippets. [1]
Citations:
Pin yq and opm to immutable releases before release processing.
snap install yq installs the current Snap release, and the opm setup resolves and downloads the current upstream release each run. Pin both tools to reviewed commit/tag references for release reproducibility, and verify downloaded binary checksums when downloading opm.
🤖 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/manual-release.yml around lines 46 - 60, Update the “Set
up yq” and “Set up opm” steps to use reviewed immutable version or commit
references instead of resolving latest releases at runtime. For opm, download
the pinned release asset and verify its checksum before installing it; retain
the existing executable installation and version validation flow.
There was a problem hiding this comment.
Latests should be fine. yq is used only for formating and opm to extract information. In the worst case something fails before releasing. Can be fixed than.
There was a problem hiding this comment.
@azgabur, understood. The finding remains valid because this release workflow resolves unreviewed tool versions at release time. This conflicts with the PR objective to freeze tool versions.
A tool update can change generated values or fail after release processing starts. A checksum does not prevent this when the workflow selects a new upstream release first.
🐇 …
✏️ Learnings added
Learnt from: azgabur
Repo: Kuadrant/helm-charts-olm PR: 111
File: .github/workflows/manual-release.yml:51-65
Timestamp: 2026-08-12T08:09:21.469Z
Learning: In `.github/workflows/manual-release.yml`, maintainers consider mutable latest versions acceptable for `yq` because it only formats data and for `opm` because it only extracts operator information. They accept that a changed tool version can fail before a release and can be corrected later.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
You are interacting with an AI system.
6465331 to
9054c89
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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/manual-release.yml:
- Around line 141-155: Update the Commit and push and Create Git tag steps to
create both the gh-pages commit and $HELM_VERSION tag locally before publishing.
Replace the separate pushes with one git push --atomic operation that sends both
refs, preserving the existing commit and tag messages.
🪄 Autofix
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: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 0bc70571-c171-4d2e-843e-8507b591dfa1
📒 Files selected for processing (2)
.github/workflows/manual-release.yml.github/workflows/release.yml
Signed-off-by: Alex Zgabur <azgabur@redhat.com>
3bec9ce to
3f6a01a
Compare
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # ratchet:actions/checkout@v7 | ||
| - name: Validate kuadrant version format | ||
| run: | | ||
| if ! [[ "${{ inputs.kuadrantVersion }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-rc[0-9]+)*-(k|r)$ ]]; then |
There was a problem hiding this comment.
nit: (-rc[0-9]+)* , * allows more RC suffixes together. is it intended? Could you possibly change * to ??
|
|
||
| - name: Check tag does not already exist | ||
| run: | | ||
| if git ls-remote --exit-code --refs --tags origin "refs/tags/$HELM_VERSION" >/dev/null; then |
There was a problem hiding this comment.
The tag existence check is at the beginning, but the tag is created only at the end after publishing to gh-pages. If the run fails between these steps, on a re-run the tag check passes (the tag doesn't exist yet), but the chart is already on gh-pages, and helm repo index --merge might create a duplicate entry in index.yaml. is a re-run safe after a partial failure? shouldn't the check also verify the presence of the chart on gh-pages?
|
|
||
| - name: Set index image | ||
| run: | | ||
| yq -i '.kuadrant.indexImage = "${{ inputs.indexImage }}"' values.yaml |
There was a problem hiding this comment.
indexImage doesn't have any validation. Both kuadrantVersion and ocpVersion are validated via regex, but indexImage is written directly into values.yaml as a string, and the workflow never pulls or renders it anywhere (freezing - redhat-operator-index, not this image). A wrong reference, a typo, or more realistically a stale tag like :v1.4.2 instead of :v1.4.3 would pass through the entire process, the chart would be published, and the error would only show at helm install time when olm fails to pull the CatalogSource image. Probability is low since the image is copy-pasted, but I think it would be quick check (regex format check, or skopeo inspect maybe?).
fabikova
left a comment
There was a problem hiding this comment.
looks good, added a few comments, but they're not a blocker.
Closes #88
Adds release pipeline which releases with frozen versions of dependencies and tools. Also adds Ratchet action locking.
Summary by CodeRabbit
New Features
Chores
0.0.0across the available charts.