Skip to content

Overhaul tooling#63

Merged
openshift-merge-bot[bot] merged 1 commit intoopenshift-eng:mainfrom
RadekManak:overhaul-tooling
Apr 23, 2026
Merged

Overhaul tooling#63
openshift-merge-bot[bot] merged 1 commit intoopenshift-eng:mainfrom
RadekManak:overhaul-tooling

Conversation

@RadekManak
Copy link
Copy Markdown
Contributor

@RadekManak RadekManak commented Jun 10, 2025

Summary

  • migrate the project packaging/dev workflow to pyproject.toml + uv.lock, remove legacy setup.py / setup.cfg / requirements*.txt / .pylintrc tooling, and refresh the Makefile / test scripts around the env venv workflow and Ruff-based linting
  • move .openshift-ci/Dockerfile.build_root into this repo so CI image changes can be made and reviewed alongside the code that depends on them, and harden both CI/runtime container definitions by pinning Go 1.25.9 with SHA256 verification for amd64 and arm64
  • add hack/update-go-pins.sh to keep the pinned Go version and hashes in sync across both container definitions, and update docs/tests for the new dev workflow plus hook/conflict-policy coverage already exercised on this branch

@openshift-ci openshift-ci Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jun 10, 2025
@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented Jun 10, 2025

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jun 10, 2025
@RadekManak RadekManak marked this pull request as ready for review June 11, 2025 15:48
@openshift-ci openshift-ci Bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jun 11, 2025
@openshift-ci openshift-ci Bot requested review from damdo and nrb June 11, 2025 15:48
Copy link
Copy Markdown
Contributor

@damdo damdo left a comment

Choose a reason for hiding this comment

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

/approve

Thanks @RadekManak that's a nice update!
I'll add my LGTM once CI is green

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented Jun 16, 2025

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: damdo, RadekManak

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@RadekManak RadekManak force-pushed the overhaul-tooling branch 2 times, most recently from a4a5175 to 6982d0b Compare June 26, 2025 12:26
Comment thread Makefile Outdated
Comment on lines +41 to +44
echo "=== Debug Information ==="
echo "Current working directory: $(pwd)"
echo "Current user: $(whoami)"
echo "Current user ID: $(id)"
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.

IIRC you need to use double dollars in Make to escape shell dollars. e.g. $$(pwd)

@RadekManak RadekManak marked this pull request as draft June 26, 2025 12:35
@openshift-ci openshift-ci Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jun 26, 2025
@RadekManak
Copy link
Copy Markdown
Contributor Author

/retest

@RadekManak
Copy link
Copy Markdown
Contributor Author

/retest

@RadekManak
Copy link
Copy Markdown
Contributor Author

/retest

@RadekManak RadekManak force-pushed the overhaul-tooling branch 2 times, most recently from 1390ce1 to 2be846c Compare June 27, 2025 13:56
@RadekManak
Copy link
Copy Markdown
Contributor Author

/retest

@RadekManak
Copy link
Copy Markdown
Contributor Author

/retest

@openshift-ci openshift-ci Bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Mar 18, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 18, 2026

Important

Review skipped

Auto reviews are limited based on label configuration.

🚫 Review skipped — only excluded labels are configured. (1)
  • do-not-merge/work-in-progress

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b8cb6c07-1e79-47f4-9012-2c67a97bb4a6

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Moved packaging to pyproject.toml with pinned deps and console script; removed legacy setup.py/setup.cfg and extra requirements. Replaced pylint/black/mypy with Ruff + uv in Makefile, added CI build-root Dockerfile and Go pin/update script, and modernized type hints and formatting across code and tests.

Changes

Cohort / File(s) Summary
Packaging & build metadata
pyproject.toml, setup.py, setup.cfg, requirements.txt, requirements-hacking.txt
Added full pyproject.toml (metadata, pinned deps, dev extras, Ruff config, console script). Removed legacy setup.py, setup.cfg, requirements-hacking.txt, and removed several runtime pins from requirements.txt.
Makefile & developer tooling
Makefile, .pylintrc (deleted), hack/configure-hooks.sh (deleted), hack/lint (deleted)
Makefile reworked for CI-awareness, uses Ruff for linting/formatting, venv/uv-based deps flow, added test/build/lint-fix targets, disabled pylint config and removed legacy hook/lint scripts.
CI image & Go toolchain
.openshift-ci/Dockerfile.build_root, Containerfile, hack/update-go-pins.sh
Added OpenShift CI build-root Dockerfile based on UBI9/Python 3.12; bumped GO_VERSION to 1.25.9 and changed Go install to download/extract tarball; added hack/update-go-pins.sh to sync GO_VERSION between files.
Test runner & CI integration
hack/tests.sh, Makefile
hack/tests.sh gains PYTHON_BIN override and disables pytest cacheprovider in CI artifact branch; Makefile test target now passes PYTHON_BIN into tests.
Core code style & typing modernizations
rebasebot/bot.py, rebasebot/cli.py, rebasebot/github.py, rebasebot/lifecycle_hooks.py
Converted many type hints to PEP 604 built-in unions/generics, small API signature updates, added constants and capped lost-line log output in bot.py, tightened formatting and minor control-flow/message changes.
Tests updates
tests/...
tests/conftest.py, tests/test_bot.py, tests/test_cli.py, tests/test_conflict_policy.py, tests/test_rebases.py
Modernized test annotations/imports for PEP 604, formatting/refactors; updated one test to expect PullRequestUpdateException and adjusted fixtures to use repo head for branch creation.
Docs & formatting
README.md, AGENTS.md
Whitespace, spacing, and minor markdown reformatting (fenced blocks, inline code, spacing).
Formatting/tool config
pyproject.toml (Ruff/isort), setup.cfg (deleted)
Added Ruff configuration under pyproject.toml; removed setup.cfg packaging config.
Attention: packaging & runtime deps removed
requirements.txt, setup.py, setup.cfg
Several runtime dependency pins were removed and legacy packaging configs deleted—confirm runtime packaging now relies on pyproject.toml and build tooling.
Attention: exception type change
rebasebot/bot.py, tests/test_bot.py
_update_pr_title now raises PullRequestUpdateException instead of generic Exception; tests updated accordingly—review callers for handling/expectations.
Attention: Go pin sync & extraction
.openshift-ci/Dockerfile.build_root, Containerfile, hack/update-go-pins.sh
Go installation now downloads a tarball to /tmp before extracting; hack/update-go-pins.sh updates GO_VERSION in both Containerfile and the new Dockerfile—verify checksum/versions used by CI.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@openshift-ci openshift-ci Bot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Apr 13, 2026
@openshift-ci openshift-ci Bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Apr 13, 2026
@openshift-ci openshift-ci Bot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Apr 13, 2026
@RadekManak
Copy link
Copy Markdown
Contributor Author

/test all

@RadekManak
Copy link
Copy Markdown
Contributor Author

/test all

@RadekManak
Copy link
Copy Markdown
Contributor Author

/test all

@RadekManak RadekManak force-pushed the overhaul-tooling branch 2 times, most recently from 9d7d57c to 2ba130c Compare April 22, 2026 09:30
@RadekManak RadekManak marked this pull request as ready for review April 22, 2026 09:30
@openshift-ci openshift-ci Bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Apr 22, 2026
@openshift-ci openshift-ci Bot requested a review from racheljpg April 22, 2026 09:31
Copy link
Copy Markdown

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

🧹 Nitpick comments (1)
tests/test_cli.py (1)

51-56: Avoid mutating shared fixture dict in helper.

Line 55 updates valid_args_dict in place. This can make repeated calls within one test stateful and brittle.

Suggested fix
 def get_valid_cli_args(valid_args_dict: dict) -> Callable[[dict | None], list[str]]:
     def _valid_cli_args_getter(extra_args: dict | None = None) -> list[str]:
         extra_args = extra_args or {}
-        valid_args = valid_args_dict
+        valid_args = dict(valid_args_dict)
         valid_args.update(extra_args)
         return args_dict_to_list(valid_args)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/test_cli.py` around lines 51 - 56, The helper get_valid_cli_args
currently mutates the shared valid_args_dict by calling
valid_args.update(extra_args) inside _valid_cli_args_getter; change it to build
a new dict instead (e.g., create a shallow copy of valid_args_dict or use dict
unpacking like {**valid_args_dict, **extra_args}) so valid_args is a fresh dict
per call, then pass that to args_dict_to_list; update references in
get_valid_cli_args and _valid_cli_args_getter accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.openshift-ci/Dockerfile.build_root:
- Around line 8-11: The Dockerfile RUN step that downloads and extracts Go using
GO_VERSION must verify the tarball integrity before extraction: modify the RUN
sequence that uses curl ... go${GO_VERSION}.linux-amd64.tar.gz and tar -C
/usr/local -zxvf - to first download the official checksum (or GPG signature)
for go${GO_VERSION}.linux-amd64.tar.gz, validate the downloaded tarball against
that checksum/signature (e.g., sha256sum or gpg verification), and only on
successful verification proceed to extract to /usr/local; update the commands
around the curl/tar invocation to perform the checksum download, verification,
and fail the build if verification fails.

In `@AGENTS.md`:
- Line 1: The document's first-line heading currently links to
"http://AGENTS.md", producing a broken external URL; update the heading in
AGENTS.md (the first line) to a proper local/relative reference or plain title —
for example change "# [AGENTS.md](http://AGENTS.md)" to either "# AGENTS.md" or
"# [AGENTS.md](./AGENTS.md)" so the link is valid within the repo and no longer
points to an invalid external URL.
- Around line 23-45: The module names in AGENTS.md are using malformed markup
like `\`**rebasebot/bot.py`**`; update the four entries referencing
rebasebot/bot.py, rebasebot/cli.py, rebasebot/github.py, and
rebasebot/lifecycle_hooks.py to valid markdown by removing the stray backslashes
and mismatched asterisks and using proper code formatting (e.g.,
`rebasebot/bot.py`) or bold+code if desired (e.g., **`rebasebot/bot.py`**) so
each module name renders correctly.

In `@Makefile`:
- Around line 13-16: The Makefile currently uses .venv paths (PYTHON_BIN,
conditional on IS_CI) but repo guidance requires a venv target that creates env
and uses env/bin/activate; add a new make target named venv that runs python -m
venv env and ensures env/bin/activate is the intended workflow, update the
PYTHON_BIN variable to reference env/bin/python when IS_CI is false (keep
fallback to python for CI), and replace any other references to .venv (e.g.,
targets around lines 52-60) to use env so all targets (installation, lint, test,
etc.) work with make venv followed by source env/bin/activate.

In `@README.md`:
- Around line 183-187: The README uses mismatched bold and code markers for CLI
flags/env vars (e.g., **--pre-rebase-hook**, **--pre-carry-commit-hook**,
**--post-rebase-hook**, **--pre-push-rebase-branch-hook**,
**--pre-create-pr-hook**) causing broken rendering; locate those token
occurrences (also check the nearby blocks mentioned around lines 249-254 and the
malformed token at line 295) and replace the mixed **...**/backtick usage with
consistent inline code formatting using single backticks (e.g.,
`--pre-rebase-hook`), removing stray bold markers so all flags and env vars
render as code spans.
- Around line 49-61: Update the two fenced code blocks that list GitHub
permissions by adding a language identifier (e.g., "text") after the opening
triple backticks so Markdown linters and renderers treat them as plain text;
specifically modify the block containing "- Contents: Read / - Metadata:
Read-only / - Pull requests: Read & Write" and the block containing "- Contents:
Read & Write / - Metadata: Read-only / - Workflows: Read & Write" to start with
```text instead of just ```.

In `@rebasebot/bot.py`:
- Around line 908-910: The log message in the unknown-title-format branch uses
logging.info with the f-string referencing pull_req.title and has a missing
space between sentences ("format.Keeping"); update that logging.info call to
insert a space (e.g., "format. Keeping the current title.") so the message reads
clearly and preserves pull_req.title usage.

In `@rebasebot/lifecycle_hooks.py`:
- Line 112: The hook-fetch exception messages currently use plain strings with
braces and therefore drop dynamic variables; update the two raise ValueError
calls in the lifecycle_hooks hook-fetch logic so they use proper f-strings (or
.format) to interpolate the dynamic context (e.g., include organization, name,
domain/git_url) into the messages — replace constructs like "Failed to add
remote domain/{organization}/{name}" with f"Failed to add remote
domain/{organization}/{name}" (and likewise for the other message around lines
142-145) so the raised ValueError includes the actual runtime values and chain
the original exception with from e as already done.

In `@tests/test_rebases.py`:
- Line 220: Replace the tuple assignment to args.bot_emails with an actual empty
list so the bot-squash branch isn’t enabled incorrectly: change the assignment
of args.bot_emails from ([],) to [] in the failing test (the variable referenced
is args.bot_emails and the condition that checks len(args.bot_emails) controls
the "bot-squash" branch).

---

Nitpick comments:
In `@tests/test_cli.py`:
- Around line 51-56: The helper get_valid_cli_args currently mutates the shared
valid_args_dict by calling valid_args.update(extra_args) inside
_valid_cli_args_getter; change it to build a new dict instead (e.g., create a
shallow copy of valid_args_dict or use dict unpacking like {**valid_args_dict,
**extra_args}) so valid_args is a fresh dict per call, then pass that to
args_dict_to_list; update references in get_valid_cli_args and
_valid_cli_args_getter accordingly.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 3b72f085-48c8-4e42-a77f-99b07c0c8e71

📥 Commits

Reviewing files that changed from the base of the PR and between fa090a4 and 2ba130c.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (22)
  • .openshift-ci/Dockerfile.build_root
  • .pylintrc
  • AGENTS.md
  • Makefile
  • README.md
  • hack/configure-hooks.sh
  • hack/lint
  • hack/tests.sh
  • pyproject.toml
  • rebasebot/bot.py
  • rebasebot/cli.py
  • rebasebot/github.py
  • rebasebot/lifecycle_hooks.py
  • requirements-hacking.txt
  • requirements.txt
  • setup.cfg
  • setup.py
  • tests/conftest.py
  • tests/test_bot.py
  • tests/test_cli.py
  • tests/test_conflict_policy.py
  • tests/test_rebases.py
💤 Files with no reviewable changes (7)
  • requirements-hacking.txt
  • setup.cfg
  • hack/configure-hooks.sh
  • hack/lint
  • .pylintrc
  • setup.py
  • requirements.txt

Comment thread .openshift-ci/Dockerfile.build_root Outdated
Comment thread AGENTS.md Outdated
Comment thread AGENTS.md Outdated
Comment thread Makefile
Comment thread README.md Outdated
Comment thread README.md Outdated
Comment thread rebasebot/bot.py
Comment thread rebasebot/lifecycle_hooks.py Outdated
Comment thread tests/test_rebases.py Outdated
Copy link
Copy Markdown

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

♻️ Duplicate comments (1)
.openshift-ci/Dockerfile.build_root (1)

11-18: ⚠️ Potential issue | 🟡 Minor

Clean package/pip caches in the same layer.

This RUN step still leaves DNF and pip caches behind. Add cleanup to reduce image bloat and stale package metadata exposure.

Suggested patch
 RUN dnf install -y tar gzip git make && \
     ARCH=$(case "${TARGETARCH:-amd64}" in aarch64) echo "arm64" ;; amd64) echo "amd64" ;; *) echo "${TARGETARCH:-amd64}" ;; esac) && \
     GO_SHA256=$(case "${ARCH}" in amd64) echo "${GO_SHA256_AMD64}" ;; arm64) echo "${GO_SHA256_ARM64}" ;; *) echo "Unsupported TARGETARCH: ${TARGETARCH:-amd64}" >&2; exit 1 ;; esac) && \
     curl -fLsS -o /tmp/go.tar.gz "https://go.dev/dl/go${GO_VERSION}.linux-${ARCH}.tar.gz" && \
     echo "${GO_SHA256}  /tmp/go.tar.gz" | sha256sum -c - && \
     tar -C /usr/local -xzf /tmp/go.tar.gz go/ && \
     rm -f /tmp/go.tar.gz && \
-    python -m pip install uv
+    python -m pip install --no-cache-dir uv && \
+    dnf clean all && rm -rf /var/cache/dnf /tmp/*
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.openshift-ci/Dockerfile.build_root around lines 11 - 18, The RUN layer that
installs packages and Go (the block starting with "RUN dnf install -y tar gzip
git make && \\" and the "python -m pip install uv" invocation) leaves DNF and
pip caches in the image; update that same RUN chain to run "dnf clean all" and
remove DNF caches (e.g., rm -rf /var/cache/dnf /var/cache/yum /var/run/dnf*)
after installs, and install Python packages with pip using --no-cache-dir (or
run "python -m pip cache purge" / rm -rf ~/.cache/pip) so all package manager
caches are deleted in the same layer where GO download and tar extraction occur
(keep the existing rm -f /tmp/go.tar.gz step).
🧹 Nitpick comments (6)
hack/update-go-pins.sh (1)

27-28: Fail fast if pin replacement does not apply.

These in-place regex updates can silently no-op if file formatting changes. Add post-update checks so the script exits non-zero when expected pins are not written.

Suggested patch
 perl -0pi -e 's/^ARG GO_VERSION=.*/ARG GO_VERSION='"${version}"'/m; s/^ARG GO_SHA256_AMD64=.*/ARG GO_SHA256_AMD64='"${sha_amd64}"'/m; s/^ARG GO_SHA256_ARM64=.*/ARG GO_SHA256_ARM64='"${sha_arm64}"'/m' "${CONTAINERFILE}"
 perl -0pi -e 's/^ENV GO_VERSION=.*/ENV GO_VERSION='"${version}"'/m; s/^ENV GO_SHA256_AMD64=.*/ENV GO_SHA256_AMD64='"${sha_amd64}"'/m; s/^ENV GO_SHA256_ARM64=.*/ENV GO_SHA256_ARM64='"${sha_arm64}"'/m' "${BUILD_ROOT_DOCKERFILE}"
+
+grep -q "^ARG GO_VERSION=${version}$" "${CONTAINERFILE}" || { echo "Failed to update GO_VERSION in ${CONTAINERFILE}" >&2; exit 1; }
+grep -q "^ARG GO_SHA256_AMD64=${sha_amd64}$" "${CONTAINERFILE}" || { echo "Failed to update GO_SHA256_AMD64 in ${CONTAINERFILE}" >&2; exit 1; }
+grep -q "^ARG GO_SHA256_ARM64=${sha_arm64}$" "${CONTAINERFILE}" || { echo "Failed to update GO_SHA256_ARM64 in ${CONTAINERFILE}" >&2; exit 1; }
+grep -q "^ENV GO_VERSION=${version}$" "${BUILD_ROOT_DOCKERFILE}" || { echo "Failed to update GO_VERSION in ${BUILD_ROOT_DOCKERFILE}" >&2; exit 1; }
+grep -q "^ENV GO_SHA256_AMD64=${sha_amd64}$" "${BUILD_ROOT_DOCKERFILE}" || { echo "Failed to update GO_SHA256_AMD64 in ${BUILD_ROOT_DOCKERFILE}" >&2; exit 1; }
+grep -q "^ENV GO_SHA256_ARM64=${sha_arm64}$" "${BUILD_ROOT_DOCKERFILE}" || { echo "Failed to update GO_SHA256_ARM64 in ${BUILD_ROOT_DOCKERFILE}" >&2; exit 1; }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@hack/update-go-pins.sh` around lines 27 - 28, After running the in-place perl
replacements, verify the replacements actually applied and fail fast if not: for
each target file (CONTAINERFILE and BUILD_ROOT_DOCKERFILE) check that the
updated ARG/ENV lines containing the variables version, sha_amd64 and sha_arm64
are present (e.g. search for "ARG GO_VERSION=${version}" and corresponding
GO_SHA256_* entries in CONTAINERFILE, and "ENV GO_VERSION=${version}" and
GO_SHA256_* entries in BUILD_ROOT_DOCKERFILE); if any expected line is missing,
print a clear error and exit non-zero so the script fails rather than silently
no-op. Ensure checks reference the same variable names (version, sha_amd64,
sha_arm64) and run immediately after the respective perl commands that modify
each file.
rebasebot/lifecycle_hooks.py (2)

55-59: Consider using !r conversion flag for cleaner repr formatting.

The Ruff linter suggests using explicit conversion flags instead of calling repr() inside f-strings.

Proposed fix
     def __repr__(self):
         return (
             f"LifecycleHookScriptResult(return_code={self.return_code}, "
-            f"stdout={repr(self.stdout)}, stderr={repr(self.stderr)})"
+            f"stdout={self.stdout!r}, stderr={self.stderr!r})"
         )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@rebasebot/lifecycle_hooks.py` around lines 55 - 59, The __repr__ in class
LifecycleHookScriptResult currently calls repr() inside the f-strings; change it
to use the !r conversion flag for cleaner formatting by updating the f-string in
__repr__ to use {self.stdout!r} and {self.stderr!r} (and keep {self.return_code}
as-is) so the representation uses built-in conversion instead of explicit repr()
calls.

243-244: Use explicit str | None for parameter with None default.

PEP 484 prohibits implicit Optional. Since ref_filter defaults to None, its type annotation should reflect that.

Proposed fix
-def _fetch_branch(gitwd: git.Repo, remote: str, branch: str, ref_filter: str = None):
+def _fetch_branch(gitwd: git.Repo, remote: str, branch: str, ref_filter: str | None = None):
     return gitwd.git.fetch(remote, branch, filter=ref_filter)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@rebasebot/lifecycle_hooks.py` around lines 243 - 244, Update the
_fetch_branch function signature to use an explicit nullable type for ref_filter
(e.g., change its annotation to "str | None" or "Optional[str]") so the default
None is properly typed; adjust any related type hints or imports
(typing.Optional) if you choose Optional[str], and ensure the parameter is still
passed unchanged to gitwd.git.fetch within _fetch_branch.
Makefile (1)

20-22: Consider adding a test alias for discoverability.

Many developers expect make test to run tests. Adding an alias would improve usability.

Proposed addition
 .PHONY: unittests
 unittests: ## Run unit & integration tests
 	PYTHON_BIN=$(PYTHON_BIN) hack/tests.sh
+
+.PHONY: test
+test: unittests ## Alias for unittests
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Makefile` around lines 20 - 22, Add a discoverable alias target named "test"
that invokes the existing "unittests" target so running "make test" runs the
same test flow; update the Makefile to add a PHONY for test (alongside
unittests) and create a `test:` target that depends on or calls `unittests` to
avoid duplicating the test command.
rebasebot/cli.py (1)

342-345: Consider removing redundant str() calls in f-strings.

F-strings automatically call __str__() on objects, making str(e) redundant.

Proposed fix
             logging.error(
-                f"Error running source repo hook: {str(e)}",
+                f"Error running source repo hook: {e}",
                 exc_info=True,
             )  # Log the full stack trace
@@
             logging.error(
-                f"Error occurred while initializing lifecycle hooks: {str(e)}",
+                f"Error occurred while initializing lifecycle hooks: {e}",
                 exc_info=True,
             )

Also applies to: 351-354

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

In `@rebasebot/cli.py` around lines 342 - 345, Remove the redundant str() calls
inside the f-strings used in the logging.error calls (the ones that currently do
f"Error running source repo hook: {str(e)}" and the similar call at the later
logging.error around lines 351-354); replace {str(e)} with {e} (or simply {e!s})
so f-strings rely on the object's __str__ automatically while keeping
exc_info=True unchanged and targeting the existing logging.error calls and
exception variable e.
rebasebot/bot.py (1)

354-354: Use explicit set | None for parameter with None default.

PEP 484 prohibits implicit Optional. Since only_files defaults to None, its type annotation should reflect that.

Proposed fix
-def _check_upstream_content_loss(gitwd: git.Repo, source_branch: str, only_files: set = None) -> list:
+def _check_upstream_content_loss(gitwd: git.Repo, source_branch: str, only_files: set | None = None) -> list:
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@rebasebot/bot.py` at line 354, Update the _check_upstream_content_loss
function signature to explicitly annotate the nullable parameter by changing
only_files: set = None to only_files: set | None = None (or Optional[set] if
your codebase prefers typing.Optional), and adjust any internal references if
type-specific operations require a concrete generic (e.g., cast to set or check
for None before iterating). This makes the parameter's optional nature explicit
per PEP 484/604 and avoids implicit Optional typing for only_files in
_check_upstream_content_loss.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In @.openshift-ci/Dockerfile.build_root:
- Around line 11-18: The RUN layer that installs packages and Go (the block
starting with "RUN dnf install -y tar gzip git make && \\" and the "python -m
pip install uv" invocation) leaves DNF and pip caches in the image; update that
same RUN chain to run "dnf clean all" and remove DNF caches (e.g., rm -rf
/var/cache/dnf /var/cache/yum /var/run/dnf*) after installs, and install Python
packages with pip using --no-cache-dir (or run "python -m pip cache purge" / rm
-rf ~/.cache/pip) so all package manager caches are deleted in the same layer
where GO download and tar extraction occur (keep the existing rm -f
/tmp/go.tar.gz step).

---

Nitpick comments:
In `@hack/update-go-pins.sh`:
- Around line 27-28: After running the in-place perl replacements, verify the
replacements actually applied and fail fast if not: for each target file
(CONTAINERFILE and BUILD_ROOT_DOCKERFILE) check that the updated ARG/ENV lines
containing the variables version, sha_amd64 and sha_arm64 are present (e.g.
search for "ARG GO_VERSION=${version}" and corresponding GO_SHA256_* entries in
CONTAINERFILE, and "ENV GO_VERSION=${version}" and GO_SHA256_* entries in
BUILD_ROOT_DOCKERFILE); if any expected line is missing, print a clear error and
exit non-zero so the script fails rather than silently no-op. Ensure checks
reference the same variable names (version, sha_amd64, sha_arm64) and run
immediately after the respective perl commands that modify each file.

In `@Makefile`:
- Around line 20-22: Add a discoverable alias target named "test" that invokes
the existing "unittests" target so running "make test" runs the same test flow;
update the Makefile to add a PHONY for test (alongside unittests) and create a
`test:` target that depends on or calls `unittests` to avoid duplicating the
test command.

In `@rebasebot/bot.py`:
- Line 354: Update the _check_upstream_content_loss function signature to
explicitly annotate the nullable parameter by changing only_files: set = None to
only_files: set | None = None (or Optional[set] if your codebase prefers
typing.Optional), and adjust any internal references if type-specific operations
require a concrete generic (e.g., cast to set or check for None before
iterating). This makes the parameter's optional nature explicit per PEP 484/604
and avoids implicit Optional typing for only_files in
_check_upstream_content_loss.

In `@rebasebot/cli.py`:
- Around line 342-345: Remove the redundant str() calls inside the f-strings
used in the logging.error calls (the ones that currently do f"Error running
source repo hook: {str(e)}" and the similar call at the later logging.error
around lines 351-354); replace {str(e)} with {e} (or simply {e!s}) so f-strings
rely on the object's __str__ automatically while keeping exc_info=True unchanged
and targeting the existing logging.error calls and exception variable e.

In `@rebasebot/lifecycle_hooks.py`:
- Around line 55-59: The __repr__ in class LifecycleHookScriptResult currently
calls repr() inside the f-strings; change it to use the !r conversion flag for
cleaner formatting by updating the f-string in __repr__ to use {self.stdout!r}
and {self.stderr!r} (and keep {self.return_code} as-is) so the representation
uses built-in conversion instead of explicit repr() calls.
- Around line 243-244: Update the _fetch_branch function signature to use an
explicit nullable type for ref_filter (e.g., change its annotation to "str |
None" or "Optional[str]") so the default None is properly typed; adjust any
related type hints or imports (typing.Optional) if you choose Optional[str], and
ensure the parameter is still passed unchanged to gitwd.git.fetch within
_fetch_branch.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0f6197ea-4eb1-4f6f-aa8f-a1e139dd3c6e

📥 Commits

Reviewing files that changed from the base of the PR and between 2ba130c and b12933b.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (24)
  • .openshift-ci/Dockerfile.build_root
  • .pylintrc
  • AGENTS.md
  • Containerfile
  • Makefile
  • README.md
  • hack/configure-hooks.sh
  • hack/lint
  • hack/tests.sh
  • hack/update-go-pins.sh
  • pyproject.toml
  • rebasebot/bot.py
  • rebasebot/cli.py
  • rebasebot/github.py
  • rebasebot/lifecycle_hooks.py
  • requirements-hacking.txt
  • requirements.txt
  • setup.cfg
  • setup.py
  • tests/conftest.py
  • tests/test_bot.py
  • tests/test_cli.py
  • tests/test_conflict_policy.py
  • tests/test_rebases.py
💤 Files with no reviewable changes (7)
  • requirements-hacking.txt
  • requirements.txt
  • hack/configure-hooks.sh
  • hack/lint
  • .pylintrc
  • setup.cfg
  • setup.py
✅ Files skipped from review due to trivial changes (3)
  • tests/test_conflict_policy.py
  • README.md
  • tests/test_rebases.py
🚧 Files skipped from review as they are similar to previous changes (4)
  • tests/test_bot.py
  • pyproject.toml
  • tests/conftest.py
  • rebasebot/github.py

Copy link
Copy Markdown

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

🧹 Nitpick comments (1)
Makefile (1)

54-68: Consider edge case in deps target.

The deps target has good CI/local separation. However, if someone runs make deps locally without first running make venv, the venv dependency will create the environment, but the subsequent pip install of uv might fail if env/bin/python doesn't exist yet (race condition unlikely but possible if venv creation fails silently).

Also note: in CI mode (line 68), --no-install-project is used which won't install the rebasebot package itself. This is intentional for the read-only checkout, but worth documenting.

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

In `@Makefile` around lines 54 - 68, The deps target can proceed before a usable
virtualenv exists (venv may fail silently), so modify deps (and its commands
that reference env) to explicitly verify the venv was created and abort or
create it if missing: after calling the venv dependency, check for the venv
python binary (e.g. env/bin/python or $(CURDIR)/env/bin/python) and exit with a
clear error if absent (or run python -m venv env again) before running pip/uv;
update the Windows/CI branch accordingly and add a short comment near the deps
and venv targets documenting that CI uses --no-install-project intentionally for
the read‑only checkout.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Makefile`:
- Around line 1-4: The IS_CI detection is wrong: replace the VIRTUAL_ENV check
that sets IS_CI with a check for OPENSHIFT_CI (i.e. set IS_CI := true when
OPENSHIFT_CI == "true") so CI runs see IS_CI=true; update any logic that depends
on IS_CI (targets lint, build, test, deps) so they use the correct PYTHON_BIN
and avoid creating env/ in read-only CI, and add the required --no-cache flag to
RUFF_ARGS when IS_CI is true; touch references: the Makefile variable IS_CI, the
VIRTUAL_ENV check, RUFF_ARGS, and targets lint/build/test/deps (and ensure
hack/tests.sh usage of OPENSHIFT_CI remains consistent).

In `@rebasebot/lifecycle_hooks.py`:
- Around line 86-88: Change the file-permission mask used when writing hook
scripts to be owner-only; replace os.chmod(script_file_path, 0o755) with
os.chmod(script_file_path, 0o700) for the write block that opens
script_file_path and for the similar chmod call around lines 135-140 so fetched
hook scripts are executable only by the owner (refer to the with
open(script_file_path, "w", encoding="latin1") as f: block and the os.chmod
calls).
- Around line 169-170: The regex assigned to self.script_location currently uses
the branch capture group ([^/]*?) which rejects branch names containing slashes;
update that group to allow slash characters and stop at the colon (for example
use ([^:]+?) or (.+?) instead of ([^/]*?)) so branch names like "feature/foo"
are accepted; modify the pattern string
"^git:(https://([^/]+)/([^/]+)/([^/]+))/([^/]*?):(.*)$" accordingly in
lifecycle_hooks.py where self.script_location is set.

---

Nitpick comments:
In `@Makefile`:
- Around line 54-68: The deps target can proceed before a usable virtualenv
exists (venv may fail silently), so modify deps (and its commands that reference
env) to explicitly verify the venv was created and abort or create it if
missing: after calling the venv dependency, check for the venv python binary
(e.g. env/bin/python or $(CURDIR)/env/bin/python) and exit with a clear error if
absent (or run python -m venv env again) before running pip/uv; update the
Windows/CI branch accordingly and add a short comment near the deps and venv
targets documenting that CI uses --no-install-project intentionally for the
read‑only checkout.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b0454221-b350-47d9-a2c1-b8f47b8c4469

📥 Commits

Reviewing files that changed from the base of the PR and between b12933b and 08e48d7.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (24)
  • .openshift-ci/Dockerfile.build_root
  • .pylintrc
  • AGENTS.md
  • Containerfile
  • Makefile
  • README.md
  • hack/configure-hooks.sh
  • hack/lint
  • hack/tests.sh
  • hack/update-go-pins.sh
  • pyproject.toml
  • rebasebot/bot.py
  • rebasebot/cli.py
  • rebasebot/github.py
  • rebasebot/lifecycle_hooks.py
  • requirements-hacking.txt
  • requirements.txt
  • setup.cfg
  • setup.py
  • tests/conftest.py
  • tests/test_bot.py
  • tests/test_cli.py
  • tests/test_conflict_policy.py
  • tests/test_rebases.py
💤 Files with no reviewable changes (7)
  • hack/configure-hooks.sh
  • requirements-hacking.txt
  • hack/lint
  • requirements.txt
  • .pylintrc
  • setup.cfg
  • setup.py
✅ Files skipped from review due to trivial changes (4)
  • README.md
  • .openshift-ci/Dockerfile.build_root
  • tests/test_rebases.py
  • tests/test_conflict_policy.py
🚧 Files skipped from review as they are similar to previous changes (6)
  • tests/test_bot.py
  • hack/update-go-pins.sh
  • Containerfile
  • rebasebot/github.py
  • rebasebot/cli.py
  • rebasebot/bot.py

Comment thread Makefile
Comment thread rebasebot/lifecycle_hooks.py Outdated
Comment thread rebasebot/lifecycle_hooks.py Outdated
Copy link
Copy Markdown

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

🧹 Nitpick comments (1)
hack/tests.sh (1)

24-42: Use an args array instead of unquoted string expansion for pytest arguments.

The unquoted $PYTEST_ARGS on line 42 triggers ShellCheck's SC2086 warning. Refactor to build arguments in an array instead of concatenating strings, then pass "${PYTEST_ARGS_ARRAY[@]}" to pytest.

Proposed refactor
 PYTHON_BIN=${PYTHON_BIN:-python}
 
-PYTEST_ARGS=${PYTEST_ARGS:-"-vv --cov=rebasebot"}
+PYTEST_ARGS=${PYTEST_ARGS:-"-vv --cov=rebasebot"}
+read -r -a PYTEST_ARGS_ARRAY <<< "$PYTEST_ARGS"
@@
-  PYTEST_ARGS="${PYTEST_ARGS} -p no:cacheprovider --cov-report=term --cov-report=html:${ARTIFACT_DIR}/cov-report --junitxml=${ARTIFACT_DIR}/junit_rebasebot_tests.xml"
+  PYTEST_ARGS_ARRAY+=(
+    -p no:cacheprovider
+    --cov-report=term
+    "--cov-report=html:${ARTIFACT_DIR}/cov-report"
+    "--junitxml=${ARTIFACT_DIR}/junit_rebasebot_tests.xml"
+  )
 fi
 
 set -x
-"$PYTHON_BIN" -m pytest $PYTEST_ARGS "$REPO_ROOT"
+"$PYTHON_BIN" -m pytest "${PYTEST_ARGS_ARRAY[@]}" "$REPO_ROOT"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@hack/tests.sh` around lines 24 - 42, The script currently expands PYTEST_ARGS
unquoted (variable PYTEST_ARGS and the final pytest invocation) causing SC2086;
change to use a bash array (e.g., PYTEST_ARGS_ARRAY) instead of a space-joined
string: initialize PYTEST_ARGS_ARRAY from default PYTEST_ARGS split into array
form, in the CI block append additional options to PYTEST_ARGS_ARRAY (do not
concatenate into a string), and replace the final invocation "$PYTHON_BIN" -m
pytest $PYTEST_ARGS "$REPO_ROOT" with "$PYTHON_BIN" -m pytest
"${PYTEST_ARGS_ARRAY[@]}" "$REPO_ROOT"; ensure all references to PYTEST_ARGS
that add flags (inside the CI conditional) push into the array rather than
modifying a plain string.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@hack/tests.sh`:
- Around line 24-42: The script currently expands PYTEST_ARGS unquoted (variable
PYTEST_ARGS and the final pytest invocation) causing SC2086; change to use a
bash array (e.g., PYTEST_ARGS_ARRAY) instead of a space-joined string:
initialize PYTEST_ARGS_ARRAY from default PYTEST_ARGS split into array form, in
the CI block append additional options to PYTEST_ARGS_ARRAY (do not concatenate
into a string), and replace the final invocation "$PYTHON_BIN" -m pytest
$PYTEST_ARGS "$REPO_ROOT" with "$PYTHON_BIN" -m pytest "${PYTEST_ARGS_ARRAY[@]}"
"$REPO_ROOT"; ensure all references to PYTEST_ARGS that add flags (inside the CI
conditional) push into the array rather than modifying a plain string.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2900f366-1e81-412f-a338-a58a655b0131

📥 Commits

Reviewing files that changed from the base of the PR and between 08e48d7 and 8d4f126.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (24)
  • .openshift-ci/Dockerfile.build_root
  • .pylintrc
  • AGENTS.md
  • Containerfile
  • Makefile
  • README.md
  • hack/configure-hooks.sh
  • hack/lint
  • hack/tests.sh
  • hack/update-go-pins.sh
  • pyproject.toml
  • rebasebot/bot.py
  • rebasebot/cli.py
  • rebasebot/github.py
  • rebasebot/lifecycle_hooks.py
  • requirements-hacking.txt
  • requirements.txt
  • setup.cfg
  • setup.py
  • tests/conftest.py
  • tests/test_bot.py
  • tests/test_cli.py
  • tests/test_conflict_policy.py
  • tests/test_rebases.py
💤 Files with no reviewable changes (7)
  • requirements-hacking.txt
  • hack/configure-hooks.sh
  • requirements.txt
  • setup.cfg
  • hack/lint
  • .pylintrc
  • setup.py
✅ Files skipped from review due to trivial changes (6)
  • tests/test_conflict_policy.py
  • README.md
  • tests/test_rebases.py
  • hack/update-go-pins.sh
  • rebasebot/cli.py
  • .openshift-ci/Dockerfile.build_root
🚧 Files skipped from review as they are similar to previous changes (4)
  • tests/test_bot.py
  • Containerfile
  • tests/conftest.py
  • rebasebot/github.py

Copy link
Copy Markdown
Contributor

@damdo damdo left a comment

Choose a reason for hiding this comment

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

LGTM

aside from the SHA part, which looks quite hairy and complex. I don't think we need that level of SHA matching, we should be happy with just the version.

Comment thread hack/update-go-pins.sh Outdated
Comment on lines +1 to +32
#!/bin/bash

set -euo pipefail

REPO_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
CONTAINERFILE="${REPO_ROOT}/Containerfile"
BUILD_ROOT_DOCKERFILE="${REPO_ROOT}/.openshift-ci/Dockerfile.build_root"
RELEASES_URL="https://go.dev/dl/?mode=json&include=all"

command -v curl >/dev/null
command -v jq >/dev/null
command -v perl >/dev/null

version="${1:-$(sed -n 's/^ARG GO_VERSION=//p' "${CONTAINERFILE}")}"
version="${version#go}"
release_version="go${version}"

release_json="$(curl -fsSL "${RELEASES_URL}")"
sha_amd64="$(printf '%s\n' "${release_json}" | jq -r --arg version "${release_version}" '.[] | select(.version == $version) | .files[] | select(.kind == "archive" and .os == "linux" and .arch == "amd64") | .sha256')"
sha_arm64="$(printf '%s\n' "${release_json}" | jq -r --arg version "${release_version}" '.[] | select(.version == $version) | .files[] | select(.kind == "archive" and .os == "linux" and .arch == "arm64") | .sha256')"

if [[ -z "${sha_amd64}" || "${sha_amd64}" == "null" || -z "${sha_arm64}" || "${sha_arm64}" == "null" ]]; then
echo "Could not find linux archive checksums for ${release_version}" >&2
exit 1
fi

perl -0pi -e 's/^ARG GO_VERSION=.*/ARG GO_VERSION='"${version}"'/m; s/^ARG GO_SHA256_AMD64=.*/ARG GO_SHA256_AMD64='"${sha_amd64}"'/m; s/^ARG GO_SHA256_ARM64=.*/ARG GO_SHA256_ARM64='"${sha_arm64}"'/m' "${CONTAINERFILE}"
perl -0pi -e 's/^ENV GO_VERSION=.*/ENV GO_VERSION='"${version}"'/m; s/^ENV GO_SHA256_AMD64=.*/ENV GO_SHA256_AMD64='"${sha_amd64}"'/m; s/^ENV GO_SHA256_ARM64=.*/ENV GO_SHA256_ARM64='"${sha_arm64}"'/m' "${BUILD_ROOT_DOCKERFILE}"

echo "Updated Go pins to ${version}"
echo " amd64: ${sha_amd64}"
echo " arm64: ${sha_arm64}"
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.

I'd reduce this to just a check that verifies the GO VERSION matches between the two.

Comment thread .openshift-ci/Dockerfile.build_root Outdated
Comment on lines +7 to +20
ENV GO_SHA256_AMD64=00859d7bd6defe8bf84d9db9e57b9a4467b2887c18cd93ae7460e713db774bc1
ENV GO_SHA256_ARM64=ec342e7389b7f489564ed5463c63b16cf8040023dabc7861256677165a8c0e2b
ENV PATH="/usr/local/go/bin:$PATH"

RUN dnf install -y tar gzip git make && \
ARCH=$(case "${TARGETARCH:-amd64}" in aarch64) echo "arm64" ;; amd64) echo "amd64" ;; *) echo "${TARGETARCH:-amd64}" ;; esac) && \
GO_SHA256=$(case "${ARCH}" in amd64) echo "${GO_SHA256_AMD64}" ;; arm64) echo "${GO_SHA256_ARM64}" ;; *) echo "Unsupported TARGETARCH: ${TARGETARCH:-amd64}" >&2; exit 1 ;; esac) && \
curl -fLsS -o /tmp/go.tar.gz "https://go.dev/dl/go${GO_VERSION}.linux-${ARCH}.tar.gz" && \
echo "${GO_SHA256} /tmp/go.tar.gz" | sha256sum -c - && \
tar -C /usr/local -xzf /tmp/go.tar.gz go/ && \
rm -f /tmp/go.tar.gz && \
python -m pip install --no-cache-dir uv && \
dnf clean all && \
rm -rf /var/cache/dnf /var/cache/yum /var/run/dnf*
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.

I'd drop the SHA bits

Copy link
Copy Markdown

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

🧹 Nitpick comments (3)
hack/update-go-pins.sh (1)

5-7: Use an absolute REPO_ROOT to avoid cwd-dependent behavior.

Current path derivation is relative and can break when invoked from outside the repository root.

Proposed fix
-REPO_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
+REPO_ROOT="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
 CONTAINERFILE="${REPO_ROOT}/Containerfile"
 BUILD_ROOT_DOCKERFILE="${REPO_ROOT}/.openshift-ci/Dockerfile.build_root"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@hack/update-go-pins.sh` around lines 5 - 7, REPO_ROOT is set using a relative
path which makes script behavior cwd-dependent; change the REPO_ROOT assignment
in hack/update-go-pins.sh to resolve to an absolute path by taking the script
directory (dirname "${BASH_SOURCE[0]}"), moving up one level, and using a
reliable pwd resolution (e.g., cd into that path and capture the physical
absolute path) so CONTAINERFILE and BUILD_ROOT_DOCKERFILE are always derived
from an absolute REPO_ROOT.
hack/tests.sh (1)

26-42: Convert PYTEST_ARGS to an array to prevent word-splitting issues.

Line 42 expands $PYTEST_ARGS unquoted, triggering shellcheck's SC2086 warning. The array-based approach below safely preserves argument boundaries while allowing the CI branch to append additional options.

Proposed diff
-PYTEST_ARGS=${PYTEST_ARGS:-"-vv --cov=rebasebot"}
+PYTEST_ARGS=${PYTEST_ARGS:-"-vv --cov=rebasebot"}
+read -r -a PYTEST_ARGS_ARR <<<"$PYTEST_ARGS"
@@
-  PYTEST_ARGS="${PYTEST_ARGS} -p no:cacheprovider --cov-report=term --cov-report=html:${ARTIFACT_DIR}/cov-report --junitxml=${ARTIFACT_DIR}/junit_rebasebot_tests.xml"
+  PYTEST_ARGS_ARR+=(
+    -p no:cacheprovider
+    --cov-report=term
+    --cov-report=html:${ARTIFACT_DIR}/cov-report
+    --junitxml=${ARTIFACT_DIR}/junit_rebasebot_tests.xml
+  )
 fi
@@
-"$PYTHON_BIN" -m pytest $PYTEST_ARGS "$REPO_ROOT"
+"$PYTHON_BIN" -m pytest "${PYTEST_ARGS_ARR[@]}" "$REPO_ROOT"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@hack/tests.sh` around lines 26 - 42, PYTEST_ARGS is currently a string that
gets expanded unquoted causing word-splitting (SC2086); change it to a shell
array and update how it's set, appended, and invoked: initialize with an array
(e.g. read -r -a PYTEST_ARGS <<< "${PYTEST_ARGS:-'-vv --cov=rebasebot'}" or
PYTEST_ARGS=(-vv --cov=rebasebot)), in the CI branch append options with array
syntax (PYTEST_ARGS+=( -p no:cacheprovider --cov-report=term
--cov-report=html:"${ARTIFACT_DIR}/cov-report"
--junitxml="${ARTIFACT_DIR}/junit_rebasebot_tests.xml" )), and call pytest with
the array expansion ("${PYTEST_ARGS[@]}") in the final command instead of
unquoted $PYTEST_ARGS so argument boundaries are preserved.
rebasebot/lifecycle_hooks.py (1)

325-329: Align fetch_hook_scripts type hints with runtime behavior.

Line 325 annotates github_app_provider as required, but LifecycleHookScript.fetch_script() accepts None and non-GitHub/local flows can work without it. Prefer GithubAppProvider | None for accurate typing.

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

In `@rebasebot/lifecycle_hooks.py` around lines 325 - 329, The type hint for the
parameter github_app_provider on fetch_hook_scripts is inaccurate: update the
signature of fetch_hook_scripts to accept GithubAppProvider | None (or
Optional[GithubAppProvider]) to match LifecycleHookScript.fetch_script which
accepts None and to reflect non-GitHub/local flows; ensure usages inside
fetch_hook_scripts pass the possibly-None value to
script.fetch_script(temp_hook_dir=self.tmp_hook_scripts_dir, gitwd=gitwd,
github=github_app_provider) without changing runtime logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@hack/update-go-pins.sh`:
- Around line 11-12: The script computes version from CONTAINERFILE into the
variable version and then strips a "go" prefix, but it never checks for an empty
result; add a fail-fast check after deriving and normalizing version (after the
lines that set version="${1:-$(sed -n 's/^ARG GO_VERSION=//p'
"${CONTAINERFILE}")}" and version="${version#go}"): if version is empty (test -z
"$version") print a clear error to stderr referencing CONTAINERFILE/GO_VERSION
and exit non‑zero so the script does not proceed to rewrite files with a blank
value.
- Around line 17-23: The script currently only checks that container_go_version
and build_root_go_version match each other which can pass when both are empty;
update the validation to also assert a requested/goal version: read a
requested_go_version (prefer an explicit first script argument or fallback to
REQUESTED_GO_VERSION env var), ensure requested_go_version is non-empty, then
verify container_go_version == requested_go_version AND build_root_go_version ==
requested_go_version (use the existing variable names container_go_version and
build_root_go_version for the comparisons) and fail with a clear error if any
check does not hold.

In `@rebasebot/lifecycle_hooks.py`:
- Around line 165-170: The code calls
_extract_script_details(self.script_location, temp_hook_dir) before validating
the script format, which can cause unpack/split errors for malformed "git:"
values; fix by first matching/validating self.script_location against the
expected patterns (the remote_git_pattern_match and local_git_pattern_match
regexes) and only then call _extract_script_details if a pattern matched,
otherwise raise the intended validation error; update both occurrences around
the lines using remote_git_pattern_match/local_git_pattern_match to perform
validation prior to extracting git_ref, file_path, and self.script_file_path.

---

Nitpick comments:
In `@hack/tests.sh`:
- Around line 26-42: PYTEST_ARGS is currently a string that gets expanded
unquoted causing word-splitting (SC2086); change it to a shell array and update
how it's set, appended, and invoked: initialize with an array (e.g. read -r -a
PYTEST_ARGS <<< "${PYTEST_ARGS:-'-vv --cov=rebasebot'}" or PYTEST_ARGS=(-vv
--cov=rebasebot)), in the CI branch append options with array syntax
(PYTEST_ARGS+=( -p no:cacheprovider --cov-report=term
--cov-report=html:"${ARTIFACT_DIR}/cov-report"
--junitxml="${ARTIFACT_DIR}/junit_rebasebot_tests.xml" )), and call pytest with
the array expansion ("${PYTEST_ARGS[@]}") in the final command instead of
unquoted $PYTEST_ARGS so argument boundaries are preserved.

In `@hack/update-go-pins.sh`:
- Around line 5-7: REPO_ROOT is set using a relative path which makes script
behavior cwd-dependent; change the REPO_ROOT assignment in
hack/update-go-pins.sh to resolve to an absolute path by taking the script
directory (dirname "${BASH_SOURCE[0]}"), moving up one level, and using a
reliable pwd resolution (e.g., cd into that path and capture the physical
absolute path) so CONTAINERFILE and BUILD_ROOT_DOCKERFILE are always derived
from an absolute REPO_ROOT.

In `@rebasebot/lifecycle_hooks.py`:
- Around line 325-329: The type hint for the parameter github_app_provider on
fetch_hook_scripts is inaccurate: update the signature of fetch_hook_scripts to
accept GithubAppProvider | None (or Optional[GithubAppProvider]) to match
LifecycleHookScript.fetch_script which accepts None and to reflect
non-GitHub/local flows; ensure usages inside fetch_hook_scripts pass the
possibly-None value to
script.fetch_script(temp_hook_dir=self.tmp_hook_scripts_dir, gitwd=gitwd,
github=github_app_provider) without changing runtime logic.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 3bf6194d-5fba-49ae-8ac4-c41351ad8f60

📥 Commits

Reviewing files that changed from the base of the PR and between 8d4f126 and 74cd61c.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (24)
  • .openshift-ci/Dockerfile.build_root
  • .pylintrc
  • AGENTS.md
  • Containerfile
  • Makefile
  • README.md
  • hack/configure-hooks.sh
  • hack/lint
  • hack/tests.sh
  • hack/update-go-pins.sh
  • pyproject.toml
  • rebasebot/bot.py
  • rebasebot/cli.py
  • rebasebot/github.py
  • rebasebot/lifecycle_hooks.py
  • requirements-hacking.txt
  • requirements.txt
  • setup.cfg
  • setup.py
  • tests/conftest.py
  • tests/test_bot.py
  • tests/test_cli.py
  • tests/test_conflict_policy.py
  • tests/test_rebases.py
💤 Files with no reviewable changes (7)
  • hack/configure-hooks.sh
  • requirements.txt
  • setup.py
  • hack/lint
  • .pylintrc
  • setup.cfg
  • requirements-hacking.txt
✅ Files skipped from review due to trivial changes (5)
  • README.md
  • .openshift-ci/Dockerfile.build_root
  • tests/test_conflict_policy.py
  • rebasebot/cli.py
  • tests/test_rebases.py
🚧 Files skipped from review as they are similar to previous changes (4)
  • Containerfile
  • rebasebot/bot.py
  • rebasebot/github.py
  • tests/test_bot.py

Comment thread hack/update-go-pins.sh Outdated
Comment thread hack/update-go-pins.sh
Comment thread rebasebot/lifecycle_hooks.py Outdated
Copy link
Copy Markdown
Contributor

@damdo damdo left a comment

Choose a reason for hiding this comment

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

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Apr 23, 2026
@openshift-merge-bot openshift-merge-bot Bot merged commit ff9f99a into openshift-eng:main Apr 23, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. lgtm Indicates that a PR is ready to be merged.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants