Skip to content

Release pipeline - #111

Open
azgabur wants to merge 2 commits into
Kuadrant:mainfrom
azgabur:release-pipeline
Open

Release pipeline#111
azgabur wants to merge 2 commits into
Kuadrant:mainfrom
azgabur:release-pipeline

Conversation

@azgabur

@azgabur azgabur commented Aug 9, 2026

Copy link
Copy Markdown
Member

Closes #88

Adds release pipeline which releases with frozen versions of dependencies and tools. Also adds Ratchet action locking.

Summary by CodeRabbit

  • New Features

    • Added a manually triggered release process with version validation, chart packaging, index updates and Git tag creation.
    • Added safeguards to prevent duplicate releases and coordinate publishing activities.
  • Chores

    • Updated automated workflow actions to newer, securely pinned versions.
    • Improved release workflow reliability while preserving existing chart packaging and deployment behaviour.
    • Reset chart and application versions to 0.0.0 across the available charts.

Signed-off-by: Alex Zgabur <azgabur@redhat.com>
@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b5b7a98d-0b86-4e0a-acf5-3e2a02632366

📥 Commits

Reviewing files that changed from the base of the PR and between 9054c89 and 3f6a01a.

📒 Files selected for processing (1)
  • .github/workflows/manual-release.yml

📝 Walkthrough

Walkthrough

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

Changes

Versioned Helm chart release

Layer / File(s) Summary
Release inputs and chart metadata
.github/workflows/manual-release.yml, charts/*/Chart.yaml
The manual workflow accepts release inputs. All charts now use 0.0.0 for version and appVersion before release packaging.
Release validation and tooling
.github/workflows/manual-release.yml
The workflow validates versions and duplicate tags, installs yq, Helm, and opm, and authenticates to registry.redhat.io.
Freeze versions and package charts
.github/workflows/manual-release.yml
The workflow retrieves frozen operator versions, updates Helm values and chart metadata, selects the operator name, and packages all charts.
Publish repository contents and tag
.github/workflows/manual-release.yml
The workflow updates the gh-pages Helm index, pushes the changes, and creates an annotated Git tag.
Pin existing workflow actions
.github/workflows/helm-lint.yaml, .github/workflows/release.yml
Existing workflows pin checkout, chart-testing, and Helm setup actions to commit SHAs. Branch targets, fetch behaviour, and publishing concurrency remain defined.

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
Loading

Possibly related PRs

Poem

A rabbit packs charts in a neat little row,
Freezing each version before they can go.
Tags leap to branches, the index shines bright,
Pinned actions keep every step tight.
Hop, hop—release time is here!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes implement versioned chart releases and freeze dependency and tool versions as required by issue #88.
Out of Scope Changes check ✅ Passed The workflow changes, chart version updates, and action pinning support the stated release pipeline objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main change: adding and updating the release pipeline.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 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: 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

📥 Commits

Reviewing files that changed from the base of the PR and between 3d12630 and c3661ba.

📒 Files selected for processing (7)
  • .github/workflows/helm-lint.yaml
  • .github/workflows/manual-release.yml
  • .github/workflows/release.yml
  • charts/kuadrant-instances/Chart.yaml
  • charts/kuadrant-operators/Chart.yaml
  • charts/tools-instances/Chart.yaml
  • charts/tools-operators/Chart.yaml

Comment thread .github/workflows/helm-lint.yaml
Comment thread .github/workflows/manual-release.yml
- 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

@coderabbitai coderabbitai Bot Aug 10, 2026

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 | 🔴 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 rendering inputs.kuadrantVersion.
  • .github/workflows/manual-release.yml#L34-L34: validate "$OCP_VERSION" instead of rendering inputs.ocpVersion.
  • .github/workflows/manual-release.yml#L73-L73: build CATALOG_IMAGE from "$OCP_VERSION".
  • .github/workflows/manual-release.yml#L94-L95: use strenv(INDEX_IMAGE) and printf with "$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

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Every env var is quoted

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧩 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.yml

Length 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 || true

Length 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 }}" =~ ... ]]; then

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

Comment thread .github/workflows/manual-release.yml
Comment on lines +46 to +60
- 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

@coderabbitai coderabbitai Bot Aug 10, 2026

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

🧩 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 || true

Repository: 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:


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

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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

@azgabur
azgabur force-pushed the release-pipeline branch 2 times, most recently from 6465331 to 9054c89 Compare August 11, 2026 00:33

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

📥 Commits

Reviewing files that changed from the base of the PR and between c3661ba and 9054c89.

📒 Files selected for processing (2)
  • .github/workflows/manual-release.yml
  • .github/workflows/release.yml

Comment thread .github/workflows/manual-release.yml
Signed-off-by: Alex Zgabur <azgabur@redhat.com>
@azgabur
azgabur force-pushed the release-pipeline branch 3 times, most recently from 3bec9ce to 3f6a01a Compare August 12, 2026 08:30
@azgabur
azgabur requested a review from fabikova August 12, 2026 08:37
- 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

@fabikova fabikova Aug 14, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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

looks good, added a few comments, but they're not a blocker.

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.

Releasing versioned chart

2 participants