Skip to content

ci: export pipeline logs to OCI artifacts#226

Open
maskarb wants to merge 1 commit intoopendatahub-io:mainfrom
maskarb:ci-export-pipeline-logs
Open

ci: export pipeline logs to OCI artifacts#226
maskarb wants to merge 1 commit intoopendatahub-io:mainfrom
maskarb:ci-export-pipeline-logs

Conversation

@maskarb
Copy link
Copy Markdown
Contributor

@maskarb maskarb commented Mar 27, 2026

Summary

  • Adds export-pipeline-logs task to the finally block of multi-arch-container-build.yaml
  • Logs are pushed to quay.io/opendatahub/odh-ci-artifacts (same repo as e2e test artifacts), not attached to the build image
  • Downloadable via oras pull quay.io/opendatahub/odh-ci-artifacts:<pipelinerun-name>-<timestamp>-logs

Problem

Build pipeline failures (scan failures, image build errors) are not debuggable after PipelineRun pruning (max-keep-runs: 3). The Konflux UI only shows logs while the run exists on the cluster. Once pruned, all diagnostic information is lost.

The group test pipeline already pushes must-gather artifacts to odh-ci-artifacts via OCI, but the build pipeline has no equivalent — a build failure simply vanishes.

Solution

Uses the upstream export-pipeline-logs task from konflux-ci/tekton-integration-catalog. This task:

  1. Collects all TaskRun pod logs into a single all-logs.txt
  2. Archives as logs.tar.gz
  3. Pushes as an OCI artifact to the configured registry

Pointed at quay.io/opendatahub/odh-ci-artifacts to keep production image repos clean and align with the existing artifact storage pattern from the group test pipeline.

Open questions

  • The pipeline-logs workspace is marked optional. Tekton v1 provides an implicit emptyDir for optional unbound workspaces — need to verify this works in practice or whether callers (.tekton/ PipelineRun configs) need to explicitly bind pipeline-logs: emptyDir: {}
  • Confirm odh-registry-secret is available to the build pipeline's service accounts (it's used in the group test pipeline already)

Test plan

  • Trigger a build on a PR and confirm logs appear in odh-ci-artifacts
  • Trigger a failing build and confirm logs are still exported (finally block)
  • Verify oras pull retrieves the logs artifact
  • Verify the task works without explicit workspace binding from callers

🤖 Generated with Claude Code

Adds the export-pipeline-logs task to the finally block of the
multi-arch-container-build pipeline. Logs are pushed to
quay.io/opendatahub/odh-ci-artifacts rather than attached to the
build image, keeping production artifacts clean.

This addresses a debuggability gap where build failures (scan
failures, image build errors) are lost after PipelineRun pruning
(max-keep-runs: 3). With this change, all task logs are archived
and downloadable via oras pull.

Assisted-by: Claude Code (claude.ai/code)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: maskarb <mskarbek@redhat.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 27, 2026

📝 Walkthrough

Walkthrough

This change adds a new optional task export-pipeline-logs to the multi-arch-container-build.yaml pipeline. The task pulls export-logs-to-quay.yaml from an external Git repository and exports pipeline logs to a Quay registry endpoint, passing the pipeline's run name, namespace, and registry credentials. A new optional workspace pipeline-logs is introduced and wired to the task's shared-data workspace.

Security Issues

External dependency with floating revision — The task is pulled from https://github.com/konflux-ci/tekton-integration-catalog.git at revision main. This creates a supply chain risk; the task definition can change without this pipeline being updated, potentially injecting malicious code. Use a specific commit hash instead of main.

Credential exposure via external task — The odh-registry-secret is passed to an external task in a repository outside your direct control. Verify that export-logs-to-quay.yaml does not log, export, or leak credentials in error messages or logs (CWE-532: Insertion of Sensitive Information into Log File).

Workspace namespace exposure — Pipeline run name and namespace are passed to an external task. Confirm the external task doesn't persist or expose this metadata to untrusted systems.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'ci: export pipeline logs to OCI artifacts' directly and clearly summarizes the main change: adding log export functionality to OCI artifacts in the CI pipeline.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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 and usage tips.

@maskarb maskarb marked this pull request as ready for review March 27, 2026 18:40
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@pipeline/multi-arch-container-build.yaml`:
- Around line 788-790: The task unconditionally binds the workspace named
shared-data to pipeline-logs, causing a silent failure if pipeline-logs is
unbound (especially inside the task's finally block); update the task to check
for the presence/binding of the pipeline-logs workspace before using shared-data
and, if absent, log/emit a clear skip message and exit the task gracefully (or
alternatively make the workspace binding conditional in the task spec),
referencing the workspace identifier shared-data and the workspace key
pipeline-logs and the task's finally/cleanup step so reviewers can locate and
change the check.
- Around line 769-778: The pipeline uses an unpinned git resolver revision
("revision: main") for the export-pipeline-logs task (task name:
export-pipeline-logs, taskRef resolver: git, param name: revision); replace the
symbolic ref with the repository's immutable commit SHA (full 40-char SHA) for
that git resolver param and commit the change, and apply the same replacement
(pin to exact commit SHA) to the other git resolver tasks mentioned in the
review so all git resolver params use immutable SHAs instead of branch names.
🪄 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: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 8a58eca3-536a-4f06-94a1-599d01d19f9c

📥 Commits

Reviewing files that changed from the base of the PR and between 1fe75ba and 56ce349.

📒 Files selected for processing (1)
  • pipeline/multi-arch-container-build.yaml

Comment on lines +769 to +778
- name: export-pipeline-logs
taskRef:
resolver: git
params:
- name: url
value: https://github.com/konflux-ci/tekton-integration-catalog.git
- name: revision
value: main
- name: pathInRepo
value: tasks/export-logs/0.1/export-logs-to-quay.yaml
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check the latest commit on main for the referenced task to suggest a pin
git ls-remote https://github.com/konflux-ci/tekton-integration-catalog.git refs/heads/main | cut -f1

Repository: opendatahub-io/odh-konflux-central

Length of output: 118


🏁 Script executed:

#!/bin/bash
# Check the actual file content at the specified lines
sed -n '769,778p' pipeline/multi-arch-container-build.yaml

Repository: opendatahub-io/odh-konflux-central

Length of output: 379


🏁 Script executed:

#!/bin/bash
# Search for all git resolver usages to confirm the pattern
rg -n "resolver: git" pipeline/multi-arch-container-build.yaml -A 5

Repository: opendatahub-io/odh-konflux-central

Length of output: 878


🏁 Script executed:

#!/bin/bash
# Search for bundle resolver usages to confirm they use SHA digests
rg -n "resolver: bundles" pipeline/multi-arch-container-build.yaml -A 5 | head -50

Repository: opendatahub-io/odh-konflux-central

Length of output: 1148


🏁 Script executed:

#!/bin/bash
# Check workspace definition and binding for pipeline-logs
rg -n "pipeline-logs" pipeline/multi-arch-container-build.yaml -B 2 -A 2

Repository: opendatahub-io/odh-konflux-central

Length of output: 430


🏁 Script executed:

#!/bin/bash
# Get the full bundle resolver definitions to see what they reference
rg -n "resolver: bundles" pipeline/multi-arch-container-build.yaml -A 10 | head -100

Repository: opendatahub-io/odh-konflux-central

Length of output: 2469


🏁 Script executed:

#!/bin/bash
# Get context BEFORE the resolver: bundles line to see the bundle specification
rg -n "resolver: bundles" pipeline/multi-arch-container-build.yaml -B 5 | head -100

Repository: opendatahub-io/odh-konflux-central

Length of output: 4313


Supply chain risk: unpinned git revision (CWE-829)

Using revision: main allows the fetched task to change without notice. A compromise of the upstream repo or a force-push could inject malicious steps into all builds. Bundle resolvers in this pipeline use immutable SHA256 digests; apply the same rigor here.

Pin to a specific commit SHA:

Suggested fix
       - name: revision
-        value: main
+        value: 489cd0a413f52fd3fac90f38694f8fe51871be4a

Also apply this fix to the three other git resolver tasks at lines 145, 752, and 807.

📝 Committable suggestion

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

Suggested change
- name: export-pipeline-logs
taskRef:
resolver: git
params:
- name: url
value: https://github.com/konflux-ci/tekton-integration-catalog.git
- name: revision
value: main
- name: pathInRepo
value: tasks/export-logs/0.1/export-logs-to-quay.yaml
- name: export-pipeline-logs
taskRef:
resolver: git
params:
- name: url
value: https://github.com/konflux-ci/tekton-integration-catalog.git
- name: revision
value: 489cd0a413f52fd3fac90f38694f8fe51871be4a
- name: pathInRepo
value: tasks/export-logs/0.1/export-logs-to-quay.yaml
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pipeline/multi-arch-container-build.yaml` around lines 769 - 778, The
pipeline uses an unpinned git resolver revision ("revision: main") for the
export-pipeline-logs task (task name: export-pipeline-logs, taskRef resolver:
git, param name: revision); replace the symbolic ref with the repository's
immutable commit SHA (full 40-char SHA) for that git resolver param and commit
the change, and apply the same replacement (pin to exact commit SHA) to the
other git resolver tasks mentioned in the review so all git resolver params use
immutable SHAs instead of branch names.

Comment on lines +788 to +790
workspaces:
- name: shared-data
workspace: pipeline-logs
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Silent failure when pipeline-logs workspace is unbound

The workspace is declared optional at line 829-830, but the task unconditionally binds shared-data to it. When callers omit the workspace, the task will fail—silently, since it's in finally. Consider documenting this behavior or adding a task-level check to emit a clear skip message rather than an error.

Also applies to: 829-830

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pipeline/multi-arch-container-build.yaml` around lines 788 - 790, The task
unconditionally binds the workspace named shared-data to pipeline-logs, causing
a silent failure if pipeline-logs is unbound (especially inside the task's
finally block); update the task to check for the presence/binding of the
pipeline-logs workspace before using shared-data and, if absent, log/emit a
clear skip message and exit the task gracefully (or alternatively make the
workspace binding conditional in the task spec), referencing the workspace
identifier shared-data and the workspace key pipeline-logs and the task's
finally/cleanup step so reviewers can locate and change the check.

@jlost
Copy link
Copy Markdown
Contributor

jlost commented Mar 30, 2026

/lgtm But @dchourasia's expertise would be useful here as well

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.

2 participants