OCPEDGE-2815: tekton: add production and staging final pipelines#2884
OCPEDGE-2815: tekton: add production and staging final pipelines#2884jeff-roche wants to merge 2 commits into
Conversation
Use quay.io/redhat-user-workloads/logical-volume-manag-tenant/lvm-operator-bundle for tag listing and candidate digest resolution instead of registry.stage.redhat.io, avoiding the need for a staging registry pull secret in automation. The staging registry path is still used when writing the candidate template's output image references. Assisted-by: Claude <noreply@anthropic.com> Signed-off-by: Jeff Roche <jeroche@redhat.com>
Add two Konflux final pipelines to keep OLM catalog templates current across the release lifecycle: - operator-version-bump-production-final-pipeline: runs after a successful operator production release. Bumps OPERATOR_VERSION in release/container-build.args and opens a PR. Does not touch catalog templates; merging the PR triggers the normal build cascade (operator rebuild, then bundle rebuild) that eventually reaches the bundle's staging release. - catalog-candidate-update-staging-final-pipeline: runs after the lvm-operator-bundle component releases to staging. Regenerates both catalog templates via generate_catalog_template.sh and opens or updates a persistent PR if anything changed; skips cleanly otherwise. Both pipelines authenticate as a GitHub App and create commits via the GitHub GraphQL createCommitOnBranch mutation so they are signed/verified by GitHub without needing a separate signing key. PRs are labeled approved/lgtm and titled with the NO-JIRA: prefix to match existing automation conventions in this repo. Assisted-by: Claude <noreply@anthropic.com> Signed-off-by: Jeff Roche <jeroche@redhat.com>
WalkthroughAdds Tekton pipelines for catalog candidate updates and operator version bumps, including signed GitHub commits, pull request management, labels, and results. Catalog generation now uses Quay bundle image data for tags and candidate digests. ChangesCatalog candidate update
Operator version bump
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)Catalog candidate updatesequenceDiagram
participant TektonTask
participant ReleaseBranch
participant GitHubREST
participant GitHubGraphQL
TektonTask->>ReleaseBranch: Clone and regenerate catalog templates
TektonTask->>GitHubREST: Create or reset candidate branch
TektonTask->>GitHubGraphQL: Create signed commit
TektonTask->>GitHubREST: Reuse or create PR and apply labels
Operator version bumpsequenceDiagram
participant TektonTask
participant GitHubREST
participant GitHubGraphQL
TektonTask->>GitHubREST: Read release branch version
TektonTask->>GitHubREST: Create or reset bump branch
TektonTask->>GitHubGraphQL: Create signed version commit
TektonTask->>GitHubREST: Reuse or create PR and apply labels
Possibly related issues
🚥 Pre-merge checks | ✅ 15✅ Passed checks (15 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 |
|
@jeff-roche: This pull request references OCPEDGE-2815 which is a valid jira issue. Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the spike to target the "5.0.0" version, but no target version was set. DetailsIn response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository. |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: jeff-roche The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
|
These pipelines depend on https://redhat.atlassian.net/browse/DPP-21582 which will install the app I created to this repo so that we can add some credentials to konflux for the version bump and catalog regen automations |
|
/hold for DPP app install approval since this relies on that. |
There was a problem hiding this comment.
Actionable comments posted: 10
🤖 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 @.tekton/catalog-candidate-update-staging-final-pipeline.yaml:
- Around line 70-75: Remove the obsolete components-namespace-pull secret
dependency from the pipeline: delete its volume definition, corresponding volume
mount, and any authentication merge referencing it. Keep the
registry-redhat-io-docker configuration and public Quay repository usage
unchanged.
- Around line 182-202: Update the GitHub API workflow around GITHUB_TOKEN
creation and the PR/ref/label operations through the completion output to use
curl --fail-with-body, so HTTP failures stop the pipeline instead of being
treated as successful responses. Validate required response fields, including a
non-empty token and valid PR URL/identifier, before publishing CHANGED=true or
reporting success; preserve the existing successful flow when all API responses
are valid.
- Around line 216-226: Add a signed-off-by trailer to the generated commit by
extending the GraphQL `message` object in the `CreateCommitOnBranch` mutation
with the required body field, while preserving the existing headline and commit
inputs.
- Around line 89-99: Update the tool installation steps around the skopeo and yq
downloads to avoid mutable or unverified artifacts: use a pinned tool image or
fixed release URLs, pin yq to an explicit version instead of querying latest,
and verify each downloaded binary against its published SHA256 checksum before
chmod or use. Keep the existing TOOL_DIR installation flow intact.
- Around line 66-76: Add a shared emptyDir volume for /workspace/tools in the
pipeline pod, then mount it at that path in both the install-tools and
update-and-pr steps so installed binaries are available across containers.
In @.tekton/operator-version-bump-production-final-pipeline.yaml:
- Around line 150-161: Update the branch handling around PR_BRANCH so it first
checks for the matching automation-created PR and verifies the existing branch
belongs to that PR before resetting it. If the branch exists without a matching
PR, fail the pipeline instead of force-resetting it; retain branch creation only
when no branch exists.
- Around line 134-148: Validate NEXT_VERSION after resolving the requested or
auto-incremented value and before writing the result, modifying NEW_CONTENT, or
constructing PR_BRANCH. Require a well-formed semantic version and ensure it is
strictly greater than CURRENT_VERSION; reject malformed, equal, or lower values
with a clear configuration error and stop the task. Use the existing version
components or an appropriate comparison method, and ensure the validated value
is safe for the sed expression and branch name.
- Around line 212-223: Update the PR creation and labeling curl calls in the
pipeline to use fail-on-HTTP-error behavior, then validate that the parsed
PR_URL/html_url and PR_NUMBER/number are non-empty and not null before applying
labels or writing results.PR_URL. Ensure any invalid API response causes the
step to fail rather than continuing with a missing PR reference.
- Around line 165-182: Update the GraphQL payload in the commit-creation block
to extend message beyond headline with a body describing the operator version
bump and a Signed-off-by trailer, using the contributor identity expected by
CONTRIBUTING.md. Keep the existing headline, branch, expectedHeadOid, and
fileChanges fields unchanged.
In `@release/hack/generate_catalog_template.sh`:
- Around line 4-6: Make the tag discovery and digest lookup commands in the
catalog template generation script fail explicitly when either registry query
fails. Validate the result of skopeo list-tags and the later digest lookup
before generating or writing any template updates, and stop execution rather
than allowing empty tag data or an empty “@” reference to be emitted.
🪄 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: Repository YAML (base), Central YAML (inherited)
Review profile: CHILL
Plan: Enterprise
Run ID: fdea3ba7-23d6-47a3-9d57-1f3c40cc007e
📒 Files selected for processing (3)
.tekton/catalog-candidate-update-staging-final-pipeline.yaml.tekton/operator-version-bump-production-final-pipeline.yamlrelease/hack/generate_catalog_template.sh
| volumes: | ||
| - name: github-app-credentials | ||
| secret: | ||
| secretName: github-app-credentials | ||
| - name: registry-redhat-io-docker | ||
| secret: | ||
| secretName: registry-redhat-io-docker | ||
| - name: components-namespace-pull | ||
| secret: | ||
| secretName: components-namespace-pull | ||
| steps: |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file=".tekton/catalog-candidate-update-staging-final-pipeline.yaml"
echo "=== line count ==="
wc -l "$file"
echo
echo "=== lines 1-260 with numbers ==="
cat -n "$file" | sed -n '1,260p'Repository: openshift/lvm-operator
Length of output: 14430
Mount a shared emptyDir for /workspace/tools. install-tools writes the binaries into its own container filesystem, so update-and-pr can’t see them without a shared volume mounted in both steps.
🤖 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 @.tekton/catalog-candidate-update-staging-final-pipeline.yaml around lines 66
- 76, Add a shared emptyDir volume for /workspace/tools in the pipeline pod,
then mount it at that path in both the install-tools and update-and-pr steps so
installed binaries are available across containers.
| - name: registry-redhat-io-docker | ||
| secret: | ||
| secretName: registry-redhat-io-docker | ||
| - name: components-namespace-pull | ||
| secret: | ||
| secretName: components-namespace-pull |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Remove the obsolete Quay pull-secret dependency.
The script now uses the public Quay repository, but this required secret volume still prevents the Task from starting when components-namespace-pull is absent. Remove its volume, mount, and auth merge.
Also applies to: 112-134
🤖 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 @.tekton/catalog-candidate-update-staging-final-pipeline.yaml around lines 70
- 75, Remove the obsolete components-namespace-pull secret dependency from the
pipeline: delete its volume definition, corresponding volume mount, and any
authentication merge referencing it. Keep the registry-redhat-io-docker
configuration and public Quay repository usage unchanged.
| echo "Installing skopeo..." | ||
| curl -sL "https://github.com/lework/skopeo-binary/releases/download/v1.17.0/skopeo-linux-amd64" \ | ||
| -o "$TOOL_DIR/skopeo" | ||
| chmod +x "$TOOL_DIR/skopeo" | ||
|
|
||
| echo "Installing yq..." | ||
| YQ_VER=$(curl -s https://api.github.com/repos/mikefarah/yq/releases/latest \ | ||
| | grep -oP '"tag_name": "\K[^"]+') | ||
| curl -sL "https://github.com/mikefarah/yq/releases/download/${YQ_VER}/yq_linux_amd64" \ | ||
| -o "$TOOL_DIR/yq" | ||
| chmod +x "$TOOL_DIR/yq" |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "File: .tekton/catalog-candidate-update-staging-final-pipeline.yaml"
wc -l .tekton/catalog-candidate-update-staging-final-pipeline.yaml
sed -n '1,180p' .tekton/catalog-candidate-update-staging-final-pipeline.yaml
echo
echo "Search for skopeo/yq/tool install patterns"
rg -n "skopeo|yq|latest|checksum|sha256|TOOL_DIR|curl -sL" .tekton -SRepository: openshift/lvm-operator
Length of output: 23109
Pin the downloaded tools and verify checksums. skopeo is fetched from a third-party release URL without integrity checks, and yq is still resolved from the mutable latest tag. Use a pinned tool image or fixed release URLs with SHA256 checksums.
🤖 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 @.tekton/catalog-candidate-update-staging-final-pipeline.yaml around lines 89
- 99, Update the tool installation steps around the skopeo and yq downloads to
avoid mutable or unverified artifacts: use a pinned tool image or fixed release
URLs, pin yq to an explicit version instead of querying latest, and verify each
downloaded binary against its published SHA256 checksum before chmod or use.
Keep the existing TOOL_DIR installation flow intact.
| GITHUB_TOKEN=$(curl -sS -X POST \ | ||
| -H "Authorization: Bearer ${JWT}" \ | ||
| -H "Accept: application/vnd.github+json" \ | ||
| "https://api.github.com/app/installations/${INSTALLATION_ID}/access_tokens" \ | ||
| | jq -r '.token') | ||
|
|
||
| AUTH_HEADER="Authorization: Bearer ${GITHUB_TOKEN}" | ||
|
|
||
| # ── Create or reset the persistent candidate-update branch to release-branch HEAD ── | ||
| PR_BRANCH="catalog-candidate-update-${Y_STREAM}" | ||
| REF_STATUS=$(curl -sS -o /dev/null -w '%{http_code}' -H "$AUTH_HEADER" \ | ||
| "${API}/git/ref/heads/${PR_BRANCH}") | ||
| if [ "$REF_STATUS" = "200" ]; then | ||
| curl -sS -X PATCH -H "$AUTH_HEADER" -H "Content-Type: application/json" \ | ||
| "${API}/git/refs/heads/${PR_BRANCH}" \ | ||
| -d "{\"sha\":\"${BASE_SHA}\",\"force\":true}" > /dev/null | ||
| else | ||
| curl -sS -X POST -H "$AUTH_HEADER" -H "Content-Type: application/json" \ | ||
| "${API}/git/refs" \ | ||
| -d "{\"ref\":\"refs/heads/${PR_BRANCH}\",\"sha\":\"${BASE_SHA}\"}" > /dev/null | ||
| fi |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Do not report success after failed GitHub API requests.
curl -sS accepts HTTP error responses; token/ref/PR/label failures can therefore reach Lines 270-271 and publish CHANGED=true with a null or invalid PR URL. Use --fail-with-body and validate required response fields before continuing.
Also applies to: 231-268
🤖 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 @.tekton/catalog-candidate-update-staging-final-pipeline.yaml around lines
182 - 202, Update the GitHub API workflow around GITHUB_TOKEN creation and the
PR/ref/label operations through the completion output to use curl
--fail-with-body, so HTTP failures stop the pipeline instead of being treated as
successful responses. Validate required response fields, including a non-empty
token and valid PR URL/identifier, before publishing CHANGED=true or reporting
success; preserve the existing successful flow when all API responses are valid.
| --arg headline "chore: update candidate catalog template for ${Y_STREAM}" \ | ||
| --arg oid "$BASE_SHA" \ | ||
| --argjson additions "$ADDITIONS" \ | ||
| '{ | ||
| query: "mutation($input: CreateCommitOnBranchInput!) { createCommitOnBranch(input: $input) { commit { url oid } } }", | ||
| variables: { | ||
| input: { | ||
| branch: { repositoryNameWithOwner: $repo, branchName: $branch }, | ||
| message: { headline: $headline }, | ||
| expectedHeadOid: $oid, | ||
| fileChanges: { additions: $additions } |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win
Include the required commit sign-off.
The generated commit only supplies a headline. Add a signed-off-by trailer through the GraphQL message body so automated commits satisfy repository policy.
As per coding guidelines, “sign off commits with -s.”
🤖 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 @.tekton/catalog-candidate-update-staging-final-pipeline.yaml around lines
216 - 226, Add a signed-off-by trailer to the generated commit by extending the
GraphQL `message` object in the `CreateCommitOnBranch` mutation with the
required body field, while preserving the existing headline and commit inputs.
Source: Coding guidelines
| # ── Determine next version ── | ||
| NEXT_VERSION="$NEXT_VERSION_PARAM" | ||
| if [ -z "$NEXT_VERSION" ]; then | ||
| IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT_VERSION" | ||
| NEXT_VERSION="${MAJOR}.${MINOR}.$((PATCH + 1))" | ||
| echo "Auto-incremented to: $NEXT_VERSION" | ||
| fi | ||
| echo "Next version: $NEXT_VERSION" | ||
| echo -n "$NEXT_VERSION" > $(results.NEXT_VERSION.path) | ||
|
|
||
| NEW_CONTENT=$(echo "$FILE_CONTENT" | sed "s/^OPERATOR_VERSION=.*/OPERATOR_VERSION=${NEXT_VERSION}/") | ||
| # $(...) strips trailing newlines, so re-add the one the original file had | ||
| NEW_CONTENT_B64=$(printf '%s\n' "$NEW_CONTENT" | base64 -w0) | ||
|
|
||
| PR_BRANCH="bump-operator-version-${NEXT_VERSION}" |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Validate that the requested version is a strict upgrade.
An arbitrary next-version is inserted into the file, branch name, and sed expression. Reject malformed, equal, or lower versions before modifying content; otherwise a configuration error can corrupt or downgrade OPERATOR_VERSION.
🤖 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 @.tekton/operator-version-bump-production-final-pipeline.yaml around lines
134 - 148, Validate NEXT_VERSION after resolving the requested or
auto-incremented value and before writing the result, modifying NEW_CONTENT, or
constructing PR_BRANCH. Require a well-formed semantic version and ensure it is
strictly greater than CURRENT_VERSION; reject malformed, equal, or lower values
with a clear configuration error and stop the task. Use the existing version
components or an appropriate comparison method, and ensure the validated value
is safe for the sed expression and branch name.
| # ── Create or reset the PR branch to point at the release branch's HEAD ── | ||
| REF_STATUS=$(curl -sS -o /dev/null -w '%{http_code}' -H "$AUTH_HEADER" \ | ||
| "${API}/git/ref/heads/${PR_BRANCH}") | ||
| if [ "$REF_STATUS" = "200" ]; then | ||
| curl -sS -X PATCH -H "$AUTH_HEADER" -H "Content-Type: application/json" \ | ||
| "${API}/git/refs/heads/${PR_BRANCH}" \ | ||
| -d "{\"sha\":\"${BRANCH_SHA}\",\"force\":true}" > /dev/null | ||
| else | ||
| curl -sS -X POST -H "$AUTH_HEADER" -H "Content-Type: application/json" \ | ||
| "${API}/git/refs" \ | ||
| -d "{\"ref\":\"refs/heads/${PR_BRANCH}\",\"sha\":\"${BRANCH_SHA}\"}" > /dev/null | ||
| fi |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift
Do not force-reset an arbitrary pre-existing branch.
Any branch named bump-operator-version-${NEXT_VERSION} is overwritten before confirming it belongs to this automation. Check for the matching PR first, and fail rather than force-resetting an unrelated branch.
🤖 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 @.tekton/operator-version-bump-production-final-pipeline.yaml around lines
150 - 161, Update the branch handling around PR_BRANCH so it first checks for
the matching automation-created PR and verifies the existing branch belongs to
that PR before resetting it. If the branch exists without a matching PR, fail
the pipeline instead of force-resetting it; retain branch creation only when no
branch exists.
| GRAPHQL_PAYLOAD=$(jq -n \ | ||
| --arg repo "${OWNER}/${REPO}" \ | ||
| --arg branch "$PR_BRANCH" \ | ||
| --arg headline "chore: bump OPERATOR_VERSION to ${NEXT_VERSION}" \ | ||
| --arg oid "$BRANCH_SHA" \ | ||
| --arg path "$FILE_PATH" \ | ||
| --arg contents "$NEW_CONTENT_B64" \ | ||
| '{ | ||
| query: "mutation($input: CreateCommitOnBranchInput!) { createCommitOnBranch(input: $input) { commit { url oid } } }", | ||
| variables: { | ||
| input: { | ||
| branch: { repositoryNameWithOwner: $repo, branchName: $branch }, | ||
| message: { headline: $headline }, | ||
| expectedHeadOid: $oid, | ||
| fileChanges: { additions: [ { path: $path, contents: $contents } ] } | ||
| } | ||
| } | ||
| }') |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n## File excerpt\n'
sed -n '145,205p' .tekton/operator-version-bump-production-final-pipeline.yaml
printf '\n## Search for commit conventions\n'
rg -n --hidden --glob '!**/.git/**' -e 'Signed-off-by|sign off|sign-off|explain why|commit.*body|createCommitOnBranch|headline' .
printf '\n## Find other GraphQL commit creations\n'
rg -n --hidden --glob '!**/.git/**' -e 'createCommitOnBranch|CreateCommitOnBranchInput|Signed-off-by' .Repository: openshift/lvm-operator
Length of output: 7480
🌐 Web query:
GitHub GraphQL createCommitOnBranch input message body sign-off trailer signed-off-by documentation
💡 Result:
The createCommitOnBranch GraphQL mutation in the GitHub API allows you to create a commit by providing a message object as part of the CreateCommitOnBranchInput [1]. The message object includes the following fields: - headline (String!): The summary line of the commit message. - body (String): The optional extended description of the commit message. There is no dedicated field in the createCommitOnBranch input schema specifically for Git trailers like Signed-off-by [1]. However, Git trailers can be included by appending them to the body field of the message object [1]. When constructing the body string, you should format the trailer according to standard Git conventions (e.g., Signed-off-by: Name <email@example.com>). Because the GitHub GraphQL API does not natively process these as distinct structural fields, they are treated as plain text within the commit message body [1]. GitHub will render them in the commit view, and they will persist as part of the commit's metadata [2]. Key technical notes: - Commits created via createCommitOnBranch are automatically signed by GitHub's web-flow key and will appear as "Verified" in the GitHub UI [3][4][5]. - If you include a Co-authored-by or Signed-off-by trailer in the body, GitHub may mark the commit as "Partially verified" if the signature attests to the API call but not the claims made within the custom trailers [2]. - The API does not allow you to manually specify the author or committer; these are set to the authenticated user or application by default [3][5]. Attribution for other individuals should be managed via trailers like Co-authored-by [2].
Citations:
- 1: https://docs.github.com/en/graphql/reference/commits
- 2: backport: sign commits by publishing via the GitHub GraphQL API grafana/grafana-github-actions#293
- 3: https://stackoverflow.com/questions/11301989/github-api-create-commit
- 4: https://github.blog/changelog/2021-09-13-a-simpler-api-for-authoring-commits/
- 5: https://koki-develop.github.io/magidoc-github-pages-example/mutations/createCommitOnBranch
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n## Repo commit policy docs\n'
rg -n --hidden --glob '!**/.git/**' -e 'Signed-off-by|sign-off|commit message|explain why in the body|body explaining why|automation identity|createCommitOnBranch' README* .tekton docs .github . 2>/dev/null | head -n 200Repository: openshift/lvm-operator
Length of output: 3372
🏁 Script executed:
#!/bin/bash
set -euo pipefail
for f in README.md CONTRIBUTING.md CODEOWNERS .github/pull_request_template.md .github/commit_template.md .tekton/operator-version-bump-production-final-pipeline.yaml; do
if [ -f "$f" ]; then
echo "### $f"
sed -n '1,220p' "$f" | rg -n --no-heading 'Signed-off-by|sign-off|commit message|headline|body|createCommitOnBranch|automation identity|explain why'
fi
doneRepository: openshift/lvm-operator
Length of output: 174
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n## CONTRIBUTING commit guidance\n'
sed -n '225,266p' CONTRIBUTING.md
printf '\n## Pipeline comment around the commit step\n'
sed -n '158,190p' .tekton/operator-version-bump-production-final-pipeline.yamlRepository: openshift/lvm-operator
Length of output: 3195
🏁 Script executed:
#!/bin/bash
set -euo pipefail
sed -n '225,266p' CONTRIBUTING.mdRepository: openshift/lvm-operator
Length of output: 1344
Add a commit body and sign-off trailer
message only sets the headline here; add a body explaining why the bump is needed and a Signed-off-by: footer to match CONTRIBUTING.md.
🤖 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 @.tekton/operator-version-bump-production-final-pipeline.yaml around lines
165 - 182, Update the GraphQL payload in the commit-creation block to extend
message beyond headline with a body describing the operator version bump and a
Signed-off-by trailer, using the contributor identity expected by
CONTRIBUTING.md. Keep the existing headline, branch, expectedHeadOid, and
fileChanges fields unchanged.
Source: Coding guidelines
| PR_RESPONSE=$(curl -sS -X POST -H "$AUTH_HEADER" -H "Content-Type: application/json" "${API}/pulls" -d "$PR_JSON") | ||
| PR_URL=$(echo "$PR_RESPONSE" | jq -r '.html_url') | ||
| PR_NUMBER=$(echo "$PR_RESPONSE" | jq -r '.number') | ||
| echo "Created PR: $PR_URL" | ||
| fi | ||
|
|
||
| # ── Apply labels (idempotent - safe to re-apply on a reused PR) ── | ||
| curl -sS -X POST -H "$AUTH_HEADER" -H "Content-Type: application/json" \ | ||
| "${API}/issues/${PR_NUMBER}/labels" \ | ||
| -d '{"labels":["approved","lgtm"]}' > /dev/null | ||
|
|
||
| echo -n "$PR_URL" > $(results.PR_URL.path) |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file=".tekton/operator-version-bump-production-final-pipeline.yaml"
# Show the surrounding context for the cited lines
nl -ba "$file" | sed -n '180,240p'Repository: openshift/lvm-operator
Length of output: 200
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file=".tekton/operator-version-bump-production-final-pipeline.yaml"
awk 'NR>=180 && NR<=240 { printf "%6d %s\n", NR, $0 }' "$file"Repository: openshift/lvm-operator
Length of output: 3362
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file=".tekton/operator-version-bump-production-final-pipeline.yaml"
awk 'NR>=140 && NR<=180 { printf "%6d %s\n", NR, $0 }' "$file"Repository: openshift/lvm-operator
Length of output: 2788
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file=".tekton/operator-version-bump-production-final-pipeline.yaml"
awk 'NR>=1 && NR<=120 { printf "%6d %s\n", NR, $0 }' "$file"Repository: openshift/lvm-operator
Length of output: 5865
Fail on GitHub API errors in PR creation/labeling. The curl -sS calls here ignore HTTP failures, so the step can still succeed with PR_URL=null and no labels. Use -f and reject empty html_url/number before writing the result.
🤖 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 @.tekton/operator-version-bump-production-final-pipeline.yaml around lines
212 - 223, Update the PR creation and labeling curl calls in the pipeline to use
fail-on-HTTP-error behavior, then validate that the parsed PR_URL/html_url and
PR_NUMBER/number are non-empty and not null before applying labels or writing
results.PR_URL. Ensure any invalid API response causes the step to fail rather
than continuing with a missing PR reference.
| quay_bundle_path="quay.io/redhat-user-workloads/logical-volume-manag-tenant/lvm-operator-bundle" | ||
| staging_bundle_path="registry.stage.redhat.io/lvms4/lvms-operator-bundle" | ||
| lvms_all_tags="$(skopeo list-tags docker://${staging_bundle_path})" | ||
| lvms_all_tags="$(skopeo list-tags docker://${quay_bundle_path})" |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Fail instead of generating incomplete templates when Quay lookup fails.
This script has no errexit; failed tag discovery can silently produce no updates, while a failed digest lookup can write an empty @ reference. Validate both commands before continuing.
Proposed fix
-lvms_all_tags="$(skopeo list-tags docker://${quay_bundle_path})"
+if ! lvms_all_tags="$(skopeo list-tags "docker://${quay_bundle_path}")"; then
+ echo "Failed to list candidate bundle tags" >&2
+ exit 1
+fi
+[[ -n "${lvms_all_tags}" ]] || exit 1
...
- digests["${ver}"]=$(skopeo inspect "docker://${quay_bundle_path}:${ver}" --format "{{.Digest}}")
+ if ! digest=$(skopeo inspect "docker://${quay_bundle_path}:${ver}" --format "{{.Digest}}") ||
+ [[ -z "${digest}" ]]; then
+ echo "Failed to resolve candidate digest for ${ver}" >&2
+ exit 1
+ fi
+ digests["${ver}"]="${digest}"Also applies to: 81-82
🤖 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 `@release/hack/generate_catalog_template.sh` around lines 4 - 6, Make the tag
discovery and digest lookup commands in the catalog template generation script
fail explicitly when either registry query fails. Validate the result of skopeo
list-tags and the later digest lookup before generating or writing any template
updates, and stop execution rather than allowing empty tag data or an empty “@”
reference to be emitted.
|
@jeff-roche: all tests passed! Full PR test history. Your PR dashboard. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here. |
Summary
Adds two Konflux final pipelines to keep OLM catalog templates current across the release lifecycle, and a small supporting change to
generate_catalog_template.sh:operator-version-bump-production-final-pipeline— runs after a successful operator production release. BumpsOPERATOR_VERSIONinrelease/container-build.argsand opens a PR. Does not touch catalog templates directly; merging the PR triggers the normal build cascade (operator rebuild, then bundle rebuild) that eventually reaches the bundle's staging release.catalog-candidate-update-staging-final-pipeline— runs after thelvm-operator-bundlecomponent releases to staging. Regenerates both catalog templates viagenerate_catalog_template.shand opens/updates a persistent PR if anything changed; skips cleanly if there's nothing new.release/hack/generate_catalog_template.sh— candidate bundle tag listing and digest resolution now goes through the publicquay.io/redhat-user-workloads/...tenant workload repo instead ofregistry.stage.redhat.io, avoiding the need for a staging registry pull secret in automation. Output image references still use the staging registry path.Design notes
createCommitOnBranchmutation rather thangit push, so commits are signed/verified by GitHub without a separate signing key.approved/lgtmand titled with theNO-JIRA:prefix, matching this repo's existing mintmaker automation conventions.registry-redhat-io-dockerandcomponents-namespace-pullpull secrets to authenticateskopeoagainst bothregistry.redhat.ioand the private Quay tenant repo in the same run.Post-implementation steps (tracked in OCPEDGE-2815)
Provisioning the
github-app-credentialssecret and wiring both pipelines into their respective Konflux ReleasePlans is tracked separately, since that infrastructure lives outside this repo.AI-Assisted Contribution
This PR was developed collaboratively with Claude Code. The two
.tekton/pipeline YAMLs were AI-generated based on human-directed design discussion (trigger model, auth approach, idempotency, PR-reuse strategy, signed-commit requirement). Thegenerate_catalog_template.shchange was authored directly by the human contributor. All changes have been human-reviewed.Testing
Both pipelines depend on live Konflux infrastructure (ReleasePlans, secrets) that hasn't been provisioned yet, so they haven't been run end-to-end. What was validated locally:
.tekton/conventions in this reposhellcheck(no real issues — only expected false positives from Tekton's$(results.x.path)/$(params.x)templating syntax, which shellcheck reads as literal command substitution)$(...)command substitution) and a missingContent-Type: application/jsonheader on several REST callsA manual test plan for each pipeline (post-secret-provisioning) is documented in a follow-up doc tracked internally.
Summary by CodeRabbit
New Features
Bug Fixes