Skip to content

feat: container build context config + full build log preservation#1110

Open
myakove wants to merge 2 commits into
mainfrom
feat/issue-1090-1065-container-build
Open

feat: container build context config + full build log preservation#1110
myakove wants to merge 2 commits into
mainfrom
feat/issue-1090-1065-container-build

Conversation

@myakove

@myakove myakove commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

PR Summary by Qodo

Add container build context option and preserve full redacted build logs
✨ Enhancement 🐞 Bug fix 🧪 Tests ⚙️ Configuration changes 📝 Documentation 🕐 20-40 Minutes

Grey Divider

Walkthroughs

User Description

Summary

Two container build improvements:

Full build log preservation (#1090)

  • Log full redacted build output before truncation for debugging
  • Extract _redact_output() helper for reusable secret redaction
  • Truncation threshold uses ANSI-stripped lengths consistently

Docker build context from non-root directory (#1065)

  • Add context config option under container for non-root build context
  • Path traversal validation prevents context escaping worktree root
  • Schema pattern constraint rejects obviously bad values

Closes #1090
Closes #1065

AI Description
• Add container.context config to build images from a repo subdirectory.
• Validate context stays within the checked-out worktree to prevent path traversal.
• Log full redacted build output before GitHub check-run truncation for debugging.
Diagram
graph TD
  cfg["Container config"] --> loader["Config loader"] --> runner["RunnerHandler"] --> podman["Podman build"]
  runner --> check["CheckRunHandler"] --> gh["GitHub Checks API"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Use commonpath/is_relative_to for context validation
  • ➕ Less error-prone than string prefix checks
  • ➕ More readable intent: “resolved path is within worktree”
  • Path.is_relative_to requires Python 3.9+; commonpath still needs careful normalization/symlink handling
2. Persist full build logs as artifacts instead of debug logs
  • ➕ Avoids flooding debug logs while still preserving full output
  • ➕ Makes large logs easier to browse/download
  • ➖ Requires artifact storage/retention and plumbing (upload, linking, cleanup)
  • ➖ More moving parts than a server-side debug log

Recommendation: The PR’s approach is reasonable: config-driven context selection with realpath-based containment checks, plus pre-truncation redacted logging gated on truncation. If context validation edge cases become a concern, consider switching to os.path.commonpath (or Path.resolve().is_relative_to() where supported) to express containment more directly.

Grey Divider

File Changes

Enhancement (2)
github_api.py Read container context from repo config into webhook runtime +1/-0

Read container context from repo config into webhook runtime

• Extends repository config ingestion to populate 'container_context' from 'container.context', defaulting to empty string when unset.

webhook_server/libs/github_api.py


runner_handler.py Support building containers from a configured subdirectory context +26/-6

Support building containers from a configured subdirectory context

• Uses 'container_context' to select the podman build context directory while keeping the Dockerfile path rooted at the worktree. Adds realpath-based validation to reject contexts that resolve outside the checked-out worktree and fails the check run instead of building.

webhook_server/libs/handlers/runner_handler.py


Bug fix (1)
check_run_handler.py Preserve full redacted output in logs before check-run truncation +38/-18

Preserve full redacted output in logs before check-run truncation

• Extracts a reusable '_redact_output()' helper and uses it both for returned check-run text and for a new debug log that captures the full redacted output when truncation is required. Truncation detection is based on ANSI-stripped lengths to match what is sent to GitHub.

webhook_server/libs/handlers/check_run_handler.py


Tests (3)
test_check_run_handler.py Add tests for pre-truncation full-output logging and redaction +53/-0

Add tests for pre-truncation full-output logging and redaction

• Adds coverage ensuring the full output debug log is emitted only when truncation occurs and that secrets are redacted in the logged content.

webhook_server/tests/test_check_run_handler.py


test_repo_data_from_config.py Test container context config parsing and defaults +27/-0

Test container context config parsing and defaults

• Asserts 'container_context' defaults to empty string and is correctly read when supplied under the 'container' config block.

webhook_server/tests/test_repo_data_from_config.py


test_runner_handler.py Test build context selection and traversal rejection in container builds +96/-0

Test build context selection and traversal rejection in container builds

• Adds tests verifying the podman command uses the configured subdirectory as context, rejects traversal attempts that escape the worktree, and defaults to repo root when context is empty.

webhook_server/tests/test_runner_handler.py


Documentation (1)
config.yaml Document optional container build context setting +1/-0

Document optional container build context setting

• Adds an example/commented 'context' key under 'container' to demonstrate building from a subdirectory instead of repo root.

examples/config.yaml


Other (1)
schema.yaml Add 'container.context' to configuration schema with input constraints +8/-0

Add 'container.context' to configuration schema with input constraints

• Introduces a 'context' string option under 'container' with a conservative allowed-character pattern and a default of empty string (repo root).

webhook_server/config/schema.yaml


Grey Divider

Qodo Logo

@qodo-code-review

qodo-code-review Bot commented Jun 9, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📎 Requirement gaps (0)

Context used

Grey Divider


Action required

1. Truncation leaks partial secrets 🐞 Bug ⛨ Security
Description
get_check_run_text() truncates err/out before calling _redact_output(), so if a secret token is cut
by truncation it will no longer match the exact replacement and can leak partially into the GitHub
check-run text. This is a real credential-exposure risk because redaction is based on full-string
str.replace().
Code

webhook_server/libs/handlers/check_run_handler.py[R253-255]

        # Prepare error part first - we want to preserve it as much as possible
        # If error itself is huge, we might need to truncate it too, but usually it's small
        # If error + wrapper > MAX_LEN, we truncate error
Evidence
The function truncates err_clean/out_clean and only then wraps and redacts; because
_redact_output() uses exact replace(), any secret split by truncation will not be removed.

webhook_server/libs/handlers/check_run_handler.py[205-282]

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

### Issue description
`get_check_run_text()` truncates `err_clean`/`out_clean` and only then applies `_redact_output()` (which uses exact `str.replace`). If a secret appears near the truncation boundary, the returned truncated string may contain only a *substring* of the secret, which will not match the full-token replacement and can leak into the GitHub check run.

### Issue Context
- `_redact_output()` performs exact string replacements.
- Truncation modifies `err_clean`/`out_clean` prior to redaction.

### Fix Focus Areas
- Redact `err_clean` and `out_clean` **before** any truncation/length calculations, then truncate the redacted strings.
- Prefer computing `will_truncate` based on the *final* (redacted + ANSI-stripped) content length.
- After this change, the final `return` should not depend on post-truncation redaction for correctness (it can still be applied idempotently if desired).

### Fix Focus Areas (code references)
- webhook_server/libs/handlers/check_run_handler.py[205-282]

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



Remediation recommended

2. Context masks checkout failure ✓ Resolved 🐞 Bug ≡ Correctness
Description
In RunnerHandler.run_build_container(), container_context validation can return early with a
context-escape failure before checking the success flag from _checkout_worktree(). If
checkout/merge fails, this can incorrectly report a context error and omit the real checkout
stderr/out from the check-run output, slowing debugging.
Code

webhook_server/libs/handlers/runner_handler.py[R405-430]

+            # Use configured context subdirectory for build context (default: repo root)
+            _context = self.github_webhook.container_context
+            if _context:
+                resolved_context = os.path.realpath(os.path.join(worktree_path, _context))
+                resolved_worktree = os.path.realpath(worktree_path)
+                is_under_worktree = resolved_context.startswith(resolved_worktree + os.sep)
+                if not is_under_worktree and resolved_context != resolved_worktree:
+                    self.logger.error(
+                        f"{self.log_prefix} Container context '{_context}' resolves outside "
+                        f"worktree ({resolved_context}), rejecting for security"
+                    )
+                    output["text"] = f"Container build context '{_context}' escapes repository root"
+                    if pull_request and set_check:
+                        await self.check_run_handler.set_check_failure(name=BUILD_CONTAINER_STR, output=output)
+                    return
+                build_context: str = resolved_context
+            else:
+                build_context = worktree_path
+
            build_cmd: str = (
                f"--network=host {no_cache} -f "
                f"{worktree_path}/{self.github_webhook.dockerfile} "
-                f"{worktree_path} -t {_container_repository_and_tag}"
+                f"{build_context} -t {_container_repository_and_tag}"
            )

            oci_annotation_flags = self._build_oci_annotations(pull_request=pull_request, tag=tag)
Evidence
run_build_container() performs context validation and can return (after setting a failure) before
it reaches the if not success: branch that would otherwise report checkout/merge errors from
_checkout_worktree(). _checkout_worktree() explicitly produces success=False along with
out/err when a merge fails, so returning earlier can mask that failure output.

webhook_server/libs/handlers/runner_handler.py[393-451]
webhook_server/libs/handlers/runner_handler.py[150-175]

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

## Issue description
`run_build_container()` validates `container_context` and can `return` before it checks `success` from `_checkout_worktree()`. When `_checkout_worktree()` yields `success=False` (e.g., merge failure), the function should report the checkout error (`out/err`) rather than overriding it with a context-escape message.

## Issue Context
`_checkout_worktree()` can yield `(False, worktree_path, out, err)` on merge failures. Currently, context validation executes before the `if not success:` block, so the checkout failure output may never be surfaced when context is also invalid.

## Fix Focus Areas
- webhook_server/libs/handlers/runner_handler.py[393-451]
- webhook_server/libs/handlers/runner_handler.py[150-175]

## Suggested fix
1. Immediately after entering the `_checkout_worktree(...)` context, handle `if not success:` first (set check failure with `get_check_run_text(out, err)` and return).
2. Only after `success` is confirmed, perform `container_context` resolution/escape validation and build the `podman build` command.
3. (Optional) If you want to keep early context validation for security reasons, include checkout stderr/out in the failure output when `success` is false, so the root cause isn’t lost.

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


3. Full output debug-only and eager 🐞 Bug ➹ Performance
Description
The full pre-truncation output is emitted only via logger.debug(), so with the default INFO
log-level it will not be persisted to logs/JSONL entries and the “full output preservation” won’t
happen unless DEBUG is enabled. Additionally, the code still builds/redacts the full huge string
before calling logger.debug(), so it pays the CPU/memory cost even when DEBUG logging is off.
Code

webhook_server/libs/handlers/check_run_handler.py[R237-251]

+        # Check if truncation will be needed (using ANSI-stripped lengths)
+        full_clean_len = len(err_clean) + len(out_clean) + WRAPPER_OVERHEAD
+        will_truncate = full_clean_len > MAX_LEN
+
+        # Log the full redacted output BEFORE truncation so server logs preserve
+        # the complete build output for debugging.
+        # Redaction runs first to prevent leaking secrets to log aggregation systems.
+        if will_truncate:
+            full_output = f"```\n{err_clean}\n\n{out_clean}\n```"
+            full_redacted = self._redact_output(full_output)
+            self.logger.debug(
+                f"{self.log_prefix} Full check run output ({full_clean_len} chars, "
+                f"will be truncated to {MAX_LEN} for GitHub). "
+                f"Redacted full output:\n{full_redacted}"
+            )
Evidence
The full-output preservation path logs only at DEBUG and eagerly constructs the redacted full
output; the logging system defaults to INFO so DEBUG messages won’t be persisted unless configured,
and the expensive string/redaction work still happens before the debug-level filter can
short-circuit it.

webhook_server/libs/handlers/check_run_handler.py[226-252]
webhook_server/utils/helpers.py[80-127]

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

### Issue description
`get_check_run_text()` constructs `full_output`, runs redaction, and formats a very large f-string unconditionally when `will_truncate` is true, even if the logger is not enabled for DEBUG. Also, because the message is logged at DEBUG, typical deployments using the default INFO log-level will drop this message entirely, so the full output is not actually preserved.

### Issue Context
- Default log level is INFO (`get_logger_with_params()`), and the JSONL handler is attached at that effective level; DEBUG records are not persisted.
- Current code eagerly computes the debug message payload (large string + multiple `.replace()` calls) before `logger.debug()` can filter it.

### Fix Focus Areas
- Wrap the expensive full-output build/redaction behind a level check (e.g., `if will_truncate and self.logger.isEnabledFor(logging.DEBUG): ...`).
- Use lazy logging formatting to avoid eagerly building huge f-strings (e.g., `logger.debug("%s ... %s", prefix, full_redacted)`).
- If full-output persistence is desired under INFO-level deployments, consider logging the preserved full output at INFO/WARNING (still redacted) or making the level configurable.

### Fix Focus Areas (code references)
- webhook_server/libs/handlers/check_run_handler.py[237-252]
- webhook_server/utils/helpers.py[80-127]

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


Grey Divider

Previous review results

Review updated until commit db74d5a

Results up to commit 70d6c49


🐞 Bugs (2) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0)


Action required
1. Truncation leaks partial secrets 🐞 Bug ⛨ Security
Description
get_check_run_text() truncates err/out before calling _redact_output(), so if a secret token is cut
by truncation it will no longer match the exact replacement and can leak partially into the GitHub
check-run text. This is a real credential-exposure risk because redaction is based on full-string
str.replace().
Code

webhook_server/libs/handlers/check_run_handler.py[R253-255]

        # Prepare error part first - we want to preserve it as much as possible
        # If error itself is huge, we might need to truncate it too, but usually it's small
        # If error + wrapper > MAX_LEN, we truncate error
Evidence
The function truncates err_clean/out_clean and only then wraps and redacts; because
_redact_output() uses exact replace(), any secret split by truncation will not be removed.

webhook_server/libs/handlers/check_run_handler.py[205-282]

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

### Issue description
`get_check_run_text()` truncates `err_clean`/`out_clean` and only then applies `_redact_output()` (which uses exact `str.replace`). If a secret appears near the truncation boundary, the returned truncated string may contain only a *substring* of the secret, which will not match the full-token replacement and can leak into the GitHub check run.

### Issue Context
- `_redact_output()` performs exact string replacements.
- Truncation modifies `err_clean`/`out_clean` prior to redaction.

### Fix Focus Areas
- Redact `err_clean` and `out_clean` **before** any truncation/length calculations, then truncate the redacted strings.
- Prefer computing `will_truncate` based on the *final* (redacted + ANSI-stripped) content length.
- After this change, the final `return` should not depend on post-truncation redaction for correctness (it can still be applied idempotently if desired).

### Fix Focus Areas (code references)
- webhook_server/libs/handlers/check_run_handler.py[205-282]

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



Remediation recommended
2. Full output debug-only and eager 🐞 Bug ➹ Performance
Description
The full pre-truncation output is emitted only via logger.debug(), so with the default INFO
log-level it will not be persisted to logs/JSONL entries and the “full output preservation” won’t
happen unless DEBUG is enabled. Additionally, the code still builds/redacts the full huge string
before calling logger.debug(), so it pays the CPU/memory cost even when DEBUG logging is off.
Code

webhook_server/libs/handlers/check_run_handler.py[R237-251]

+        # Check if truncation will be needed (using ANSI-stripped lengths)
+        full_clean_len = len(err_clean) + len(out_clean) + WRAPPER_OVERHEAD
+        will_truncate = full_clean_len > MAX_LEN
+
+        # Log the full redacted output BEFORE truncation so server logs preserve
+        # the complete build output for debugging.
+        # Redaction runs first to prevent leaking secrets to log aggregation systems.
+        if will_truncate:
+            full_output = f"```\n{err_clean}\n\n{out_clean}\n```"
+            full_redacted = self._redact_output(full_output)
+            self.logger.debug(
+                f"{self.log_prefix} Full check run output ({full_clean_len} chars, "
+                f"will be truncated to {MAX_LEN} for GitHub). "
+                f"Redacted full output:\n{full_redacted}"
+            )
Evidence
The full-output preservation path logs only at DEBUG and eagerly constructs the redacted full
output; the logging system defaults to INFO so DEBUG messages won’t be persisted unless configured,
and the expensive string/redaction work still happens before the debug-level filter can
short-circuit it.

webhook_server/libs/handlers/check_run_handler.py[226-252]
webhook_server/utils/helpers.py[80-127]

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

### Issue description
`get_check_run_text()` constructs `full_output`, runs redaction, and formats a very large f-string unconditionally when `will_truncate` is true, even if the logger is not enabled for DEBUG. Also, because the message is logged at DEBUG, typical deployments using the default INFO log-level will drop this message entirely, so the full output is not actually preserved.

### Issue Context
- Default log level is INFO (`get_logger_with_params()`), and the JSONL handler is attached at that effective level; DEBUG records are not persisted.
- Current code eagerly computes the debug message payload (large string + multiple `.replace()` calls) before `logger.debug()` can filter it.

### Fix Focus Areas
- Wrap the expensive full-output build/redaction behind a level check (e.g., `if will_truncate and self.logger.isEnabledFor(logging.DEBUG): ...`).
- Use lazy logging formatting to avoid eagerly building huge f-strings (e.g., `logger.debug("%s ... %s", prefix, full_redacted)`).
- If full-output persistence is desired under INFO-level deployments, consider logging the preserved full output at INFO/WARNING (still redacted) or making the level configurable.

### Fix Focus Areas (code references)
- webhook_server/libs/handlers/check_run_handler.py[237-252]
- webhook_server/utils/helpers.py[80-127]

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


Results up to commit e76a427


🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0)


Remediation recommended
1. Context masks checkout failure ✓ Resolved 🐞 Bug ≡ Correctness
Description
In RunnerHandler.run_build_container(), container_context validation can return early with a
context-escape failure before checking the success flag from _checkout_worktree(). If
checkout/merge fails, this can incorrectly report a context error and omit the real checkout
stderr/out from the check-run output, slowing debugging.
Code

webhook_server/libs/handlers/runner_handler.py[R405-430]

+            # Use configured context subdirectory for build context (default: repo root)
+            _context = self.github_webhook.container_context
+            if _context:
+                resolved_context = os.path.realpath(os.path.join(worktree_path, _context))
+                resolved_worktree = os.path.realpath(worktree_path)
+                is_under_worktree = resolved_context.startswith(resolved_worktree + os.sep)
+                if not is_under_worktree and resolved_context != resolved_worktree:
+                    self.logger.error(
+                        f"{self.log_prefix} Container context '{_context}' resolves outside "
+                        f"worktree ({resolved_context}), rejecting for security"
+                    )
+                    output["text"] = f"Container build context '{_context}' escapes repository root"
+                    if pull_request and set_check:
+                        await self.check_run_handler.set_check_failure(name=BUILD_CONTAINER_STR, output=output)
+                    return
+                build_context: str = resolved_context
+            else:
+                build_context = worktree_path
+
            build_cmd: str = (
                f"--network=host {no_cache} -f "
                f"{worktree_path}/{self.github_webhook.dockerfile} "
-                f"{worktree_path} -t {_container_repository_and_tag}"
+                f"{build_context} -t {_container_repository_and_tag}"
            )

            oci_annotation_flags = self._build_oci_annotations(pull_request=pull_request, tag=tag)
Evidence
run_build_container() performs context validation and can return (after setting a failure) before
it reaches the if not success: branch that would otherwise report checkout/merge errors from
_checkout_worktree(). _checkout_worktree() explicitly produces success=False along with
out/err when a merge fails, so returning earlier can mask that failure output.

webhook_server/libs/handlers/runner_handler.py[393-451]
webhook_server/libs/handlers/runner_handler.py[150-175]

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

## Issue description
`run_build_container()` validates `container_context` and can `return` before it checks `success` from `_checkout_worktree()`. When `_checkout_worktree()` yields `success=False` (e.g., merge failure), the function should report the checkout error (`out/err`) rather than overriding it with a context-escape message.

## Issue Context
`_checkout_worktree()` can yield `(False, worktree_path, out, err)` on merge failures. Currently, context validation executes before the `if not success:` block, so the checkout failure output may never be surfaced when context is also invalid.

## Fix Focus Areas
- webhook_server/libs/handlers/runner_handler.py[393-451]
- webhook_server/libs/handlers/runner_handler.py[150-175]

## Suggested fix
1. Immediately after entering the `_checkout_worktree(...)` context, handle `if not success:` first (set check failure with `get_check_run_text(out, err)` and return).
2. Only after `success` is confirmed, perform `container_context` resolution/escape validation and build the `podman build` command.
3. (Optional) If you want to keep early context validation for security reasons, include checkout stderr/out in the failure output when `success` is false, so the root cause isn’t lost.

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


Qodo Logo

@myakove-bot

Copy link
Copy Markdown
Collaborator

Report bugs in Issues

Welcome! 🎉

This pull request will be automatically processed with the following features:

🔄 Automatic Actions

  • Reviewer Assignment: Reviewers are automatically assigned based on the OWNERS file in the repository root
  • Size Labeling: PR size labels (XS, S, M, L, XL, XXL) are automatically applied based on changes
  • Issue Creation: Disabled for this repository
  • Pre-commit Checks: pre-commit runs automatically if .pre-commit-config.yaml exists
  • Branch Labeling: Branch-specific labels are applied to track the target branch
  • Auto-verification: Auto-verified users have their PRs automatically marked as verified
  • Labels: All label categories are enabled (default configuration)

📋 Available Commands

PR Status Management

  • /wip - Mark PR as work in progress (adds WIP: prefix to title)
  • /wip cancel - Remove work in progress status
  • /hold - Block PR merging (approvers only)
  • /hold cancel - Unblock PR merging
  • /verified - Mark PR as verified
  • /verified cancel - Remove verification status
  • /reprocess - Trigger complete PR workflow reprocessing (useful if webhook failed or configuration changed)
  • /regenerate-welcome - Regenerate this welcome message

Review & Approval

  • /lgtm - Approve changes (looks good to me)
  • /approve - Approve PR (approvers only)
  • /automerge - Enable automatic merging when all requirements are met (maintainers and approvers only)
  • /assign-reviewers - Assign reviewers based on OWNERS file
  • /assign-reviewer @username - Assign specific reviewer
  • /check-can-merge - Check if PR meets merge requirements

Testing & Validation

  • /retest tox - Run Python test suite with tox
  • /retest build-container - Rebuild and test container image
  • /retest python-module-install - Test Python package installation
  • /retest pre-commit - Run pre-commit hooks and checks
  • /retest conventional-title - Validate commit message format
  • /retest all - Run all available tests

Container Operations

  • /build-and-push-container - Build and push container image (tagged with PR number)
    • Supports additional build arguments: /build-and-push-container --build-arg KEY=value

Cherry-pick Operations

  • /cherry-pick <branch> - Schedule cherry-pick to target branch when PR is merged
    • Multiple branches: /cherry-pick branch1 branch2 branch3

Label Management

  • /<label-name> - Add a label to the PR
  • /<label-name> cancel - Remove a label from the PR

✅ Merge Requirements

This PR will be automatically approved when the following conditions are met:

  1. Approval: /approve from at least one approver
  2. LGTM Count: Minimum 1 /lgtm from reviewers
  3. Status Checks: All required status checks must pass
  4. No Blockers: No wip, hold, has-conflicts labels and PR must be mergeable (no conflicts)
  5. Verified: PR must be marked as verified

📊 Review Process

Approvers and Reviewers

Approvers:

  • myakove
  • rnetser

Reviewers:

  • myakove
  • rnetser
Available Labels
  • hold
  • verified
  • wip
  • lgtm
  • approve
  • automerge
AI Features
  • Conventional Title: Mode: fix (claude/claude-opus-4-6[1m])
  • Cherry-Pick Conflict Resolution: Enabled (claude/claude-opus-4-6[1m])
  • Test Oracle: Triggers: approved (claude/claude-opus-4-6[1m]); /test-oracle can be used anytime

💡 Tips

  • WIP Status: Use /wip when your PR is not ready for review
  • Verification: The verified label is removed on new commits unless the push is detected as a clean rebase
  • Cherry-picking: Cherry-pick labels are processed when the PR is merged
  • Container Builds: Container images are automatically tagged with the PR number
  • Permission Levels: Some commands require approver permissions
  • Auto-verified Users: Certain users have automatic verification and merge privileges

For more information, please refer to the project documentation or contact the maintainers.

Comment thread webhook_server/libs/handlers/check_run_handler.py
Comment thread webhook_server/libs/handlers/check_run_handler.py Outdated
- Add 'context' config option under container for non-root build context (#1065)
- Log full redacted build output before truncation for debugging (#1090)
- Extract _redact_output() helper for reusable secret redaction
- Add path traversal validation for container context
- Add schema pattern constraint for context value

Closes #1090
Closes #1065
@myakove myakove force-pushed the feat/issue-1090-1065-container-build branch from 70d6c49 to e76a427 Compare June 9, 2026 10:39
@qodo-code-review

qodo-code-review Bot commented Jun 9, 2026

Copy link
Copy Markdown

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

@myakove

myakove commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator Author

@qodo-code-review[bot]

The following review comments were reviewed and a decision was made:

webhook_server/libs/handlers/check_run_handler.py:253 (qodo bug) — Truncation leaks partial secrets

Addressed: Fixed — _redact_output() now runs on err_clean/out_clean BEFORE truncation. Secrets are fully replaced before any truncation boundary can split them. A final idempotent redaction pass remains as defense-in-depth.

webhook_server/libs/handlers/check_run_handler.py:237 (qodo bug) — Full output debug-only and eager

Addressed: Fixed — wrapped debug log behind self.logger.isEnabledFor(logging.DEBUG) guard. The large string is only built when DEBUG logging is active. Since err_clean/out_clean are already redacted before this point, no extra redaction call needed.

Comment thread webhook_server/libs/handlers/runner_handler.py
@qodo-code-review

qodo-code-review Bot commented Jun 9, 2026

Copy link
Copy Markdown

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

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: Build container logs are truncated — full output needed for debugging Support Docker build context from non-root directory

2 participants