Skip to content

Finish renaming topsail-ng --> forge#7

Merged
kpouget merged 4 commits intoopenshift-psap:mainfrom
kpouget:forge
Apr 2, 2026
Merged

Finish renaming topsail-ng --> forge#7
kpouget merged 4 commits intoopenshift-psap:mainfrom
kpouget:forge

Conversation

@kpouget
Copy link
Copy Markdown
Contributor

@kpouget kpouget commented Apr 1, 2026

Summary by CodeRabbit

  • Refactor

    • Renamed project branding from TOPSAIL-NG to FORGE across images, runtimes, CI jobs, tooling defaults, and filesystem/layout references.
  • New Features

    • Added a CLI subcommand "post_cleanup" to run post-cleanup tasks.
  • Documentation

    • Updated constitution/title and module headers to reflect FORGE branding.
  • Chores

    • Updated CI/workflow identifiers, secret/config keys, and container/runtime environment names to align with FORGE.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 1, 2026

📝 Walkthrough

Walkthrough

This PR rebands the project from "TOPSAIL(-NG)" to "FORGE": renaming project metadata, container labels and paths, CI/workflow identifiers, default repo constants, environment/secrets keys, runtime/artifact paths, templates, and adds a new CLI subcommand post_cleanup.

Changes

Cohort / File(s) Summary
Project metadata & docs
pyproject.toml, .gitignore, .specify/memory/constitution.md
Project name and description, comments, and headings updated from TOPSAIL/ TOPSAIL-NG → FORGE; trailing newline added to constitution.
GitHub Actions / Workflows
.github/steps/prepare_minimal_ubuntu_image/action.yml, .github/workflows/check_consistency.yml
Composite action and workflow job identifiers/metadata renamed from TOPSAIL → FORGE (metadata only).
Container images
projects/core/image/Containerfile, projects/core/image/Containerfile.lightweight
Image LABELs, WORKDIR/HOME, non-root user/group name, PYTHONPATH, and *_HOME env vars switched to /app/forge/FORGE; lightweight adds build args and updates repo URL/labels.
CI entrypoint & remapping
projects/core/ci_entrypoint/.../pr_args.py, projects/core/ci_entrypoint/prepare_ci.py, projects/core/ci_entrypoint/run_ci.py
DEFAULT_REPO_NAME and env remapping lists/keys renamed from topsail-ng/TOPSAIL_* → forge/FORGE_*; loop logic mostly unchanged (one incorrect replace updated).
Runtime / artifact paths
projects/core/dsl/runtime.py, projects/legacy/library/run.py, projects/legacy/library/env.py
Path markers and constants renamed from topsailforge (relative-path detection, FORGE_HOME constant, artifact dir prefix).
DSL / logging / docs
projects/core/dsl/__init__.py, projects/core/dsl/log.py, projects/core/notifications/__init__.py
Module docstrings/comments updated to reference FORGE; __all__ ordering adjusted (exports unchanged).
Notifications & PR handling
projects/core/notifications/send.py
Exported fallback DEFAULT_REPO_NAME changed to "forge", affecting repo resolution when env var absent.
Jump CI / templates / tasks
projects/jump_ci/testing/config.yaml, projects/jump_ci/toolbox/.../entrypoint.sh.j2, projects/jump_ci/toolbox/jump_ci_prepare_topsail/tasks/main.yml
Secret env key, pod/container names, run paths, workspace checkout dirs, and build labels updated from TOPSAIL → FORGE.
Legacy/helpers
projects/legacy/library/run.py, projects/legacy/library/env.py
Constants and generated artifact directory name prefixes renamed to FORGE variants.
New CLI command
projects/llm_d/orchestration/cli.py
Added post_cleanup Click subcommand that calls prepare_llmd.cleanup() and exits with its return code.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐇 I hopped through names and paths today,
Swapped TOPSAIL sails for FORGE's bright ray.
Labels, envs, and containers align,
I nibble a carrot — the rebrand looks fine. 🥕✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the primary objective of the PR, which is to complete the renaming of the project from 'topsail-ng' to 'forge' across multiple files and configurations.

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

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

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
projects/core/dsl/runtime.py (1)

247-265: ⚠️ Potential issue | 🔴 Critical

The directory renaming to 'forge' is incomplete; the function will not find the expected directory.

The function now searches for a parent directory named 'forge' (line 252), but verification shows no 'forge' directory exists in the repository structure. The function will always fall through to the fallback logic since the condition on line 252 will never match.

The remaining 'topsail-ng' references found in the codebase are not directory path logic and are intentional:

  • projects/jump_ci/toolbox/jump_ci.py line 79 and projects/jump_ci/testing/prepare_jump_ci.py line 62: GitHub repository name strings
  • projects/jump_ci/toolbox/jump_ci_prepare_topsail/tasks/main.yml line 136: container image label filter

Either rename the actual repository directory to 'forge' or update line 252 to match the actual directory name.

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

In `@projects/core/dsl/runtime.py` around lines 247 - 265, The loop that looks for
the repository root checks for a parent directory named 'forge' (using
filename_path.parents and parent.name) but the repo directory is actually named
'topsail-ng', so the check always fails; update the condition (the parent.name
== 'forge' check inside the for parent in filename_path.parents loop) to match
the real directory name (e.g., 'topsail-ng') or refactor to use a
constant/setting (e.g., FORGE_HOME_NAME) and then compute forge_home, rel_path
via filename_path.relative_to(forge_home) as before so the function returns the
correct relative path instead of falling back.
projects/jump_ci/toolbox/jump_ci_prepare_topsail/tasks/main.yml (1)

136-138: ⚠️ Potential issue | 🟡 Minor

Image cleanup filter still references old label name=topsail-ng.

The image pruning filter on line 136 uses --filter label=name=topsail-ng, but the new images are built with --label owner=forge (lines 175, 186). This means:

  1. New images won't be cleaned up by this filter
  2. Only legacy images with the old label will be pruned

Update the filter to match the new label scheme.

🔧 Proposed fix
 - name: List all the old images to delete
   # setting --filter label=preserve!=true in Podman args doesn't work
   shell:
     set -o pipefail;
     podman image ls
        --filter until=4h
-       --filter label=name=topsail-ng
+       --filter label=owner=forge
        --format json
        | jq -r '.[] | select(.Containers == 0) | select(.Labels.preserve != "true") | .Id'
   register: podman_images_to_delete_cmd
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@projects/jump_ci/toolbox/jump_ci_prepare_topsail/tasks/main.yml` around lines
136 - 138, The image-cleanup command still uses the old filter string "--filter
label=name=topsail-ng", so it won't match new images labeled with "--label
owner=forge"; update the filter to "--filter label=owner=forge" in the pipeline
that pipes to jq (the line containing the jq selection '.[] | select(.Containers
== 0) | select(.Labels.preserve != "true") | .Id') — optionally include both
filters (owner=forge and name=topsail-ng) if you want to retain cleanup of
legacy images as well.
🧹 Nitpick comments (2)
projects/core/dsl/__init__.py (1)

9-9: Consider sorting __all__ alphabetically.

The static analyzer suggests applying isort-style alphabetical sorting to __all__ for consistency and maintainability. While the current order may reflect semantic grouping, alphabetical order is a common convention.

♻️ Alphabetically sorted version
-__all__ = ['task', 'retry', 'when', 'always', 'execute_tasks', 'clear_tasks', 'shell']
+__all__ = ['always', 'clear_tasks', 'execute_tasks', 'retry', 'shell', 'task', 'when']
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@projects/core/dsl/__init__.py` at line 9, The __all__ list is unsorted;
update the module-level symbol list named __all__ to be alphabetically ordered
so static analyzers and import conventions are satisfied — reorder the entries
currently in __all__ ('task', 'retry', 'when', 'always', 'execute_tasks',
'clear_tasks', 'shell') into alphabetical order (e.g., 'always', 'clear_tasks',
'execute_tasks', 'retry', 'shell', 'task', 'when') while preserving the same
variable name and semantics.
projects/core/ci_entrypoint/run_ci.py (1)

38-38: Style: Multiple statements on one line.

Per static analysis (Ruff E701), the if not value: continue should be on separate lines for clarity.

♻️ Proposed fix
 for env_name in FORGE_ENV:
     value = os.environ.get(env_name)
-    if not value: continue
+    if not value:
+        continue
     os.environ[env_name.replace("FORGE", "FORGE")] = value
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@projects/core/ci_entrypoint/run_ci.py` at line 38, The single-line
conditional "if not value: continue" should be split into two lines to satisfy
Ruff E701; replace it with a standard block form using the same indentation: "if
not value:" on one line and "continue" on the next (indented once), preserving
surrounding loop/context and behavior for the variable `value`.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@projects/core/ci_entrypoint/run_ci.py`:
- Around line 36-39: The loop in run_ci.py that iterates FORGE_ENV (for env_name
in FORGE_ENV) is dead code because env_name.replace("FORGE", "FORGE") is a
no-op; remove the entire loop block (the for env_name in FORGE_ENV: ... lines)
from run_ci.py to eliminate the redundant environment variable copy, ensuring no
other code depends on that copy behavior and updating any tests or callers if
they expect legacy TOPSAIL->FORGE mapping.

In `@projects/core/notifications/__init__.py`:
- Line 1: Update the module docstring in projects/core/notifications/__init__.py
by correcting the typo: change "FORGE Notifications moduled" to "FORGE
Notifications module" (i.e., fix the word in the module-level comment/docstring
in __init__.py).

In `@projects/jump_ci/toolbox/jump_ci_prepare_step/templates/entrypoint.sh.j2`:
- Line 9: The cleanup in prepare_jump_ci.py is still removing containers named
"topsail-on-{cluster}" causing orphaned forge containers; update the two cleanup
calls that reference the old name to use the new pattern
"forge-on-{jump_ci_prepare_step_cluster}" (or the variable used for cluster in
that module) so they match entrypoint.sh.j2; locate the removal calls in
prepare_jump_ci.py (the two places that build the container name) and replace
the "topsail-on-..." literal with "forge-on-..." using the same cluster variable
interpolation the rest of the template uses.

In `@projects/legacy/library/env.py`:
- Around line 56-57: The env variable usage is inconsistent:
env_topsail_base_dir is built from TOPSAIL_BASE_DIR but the artifact uses a
"forge_" prefix; update this to use FORGE_BASE_DIR for consistency (or
optionally support both). Change the lookup to prefer FORGE_BASE_DIR
(os.environ.get("FORGE_BASE_DIR")) and fall back to TOPSAIL_BASE_DIR if unset,
keep the artifact_dir creation using the forge_ prefix, and update the variable
name from env_topsail_base_dir to something like env_forge_base_dir (or similar)
so identifiers match the FORGE naming; ensure no other code relies on only
TOPSAIL_BASE_DIR without the fallback.

In `@pyproject.toml`:
- Around line 6-8: Update the hardcoded repository name "topsail-ng" to the new
package name "forge" wherever it's used as the repo_name parameter (e.g., the
repo_name variable/argument in jump_ci.py and prepare_jump_ci.py), and also
update the Docker image label string in the Ansible task (the docker image label
constant/value in jump_ci_prepare_topsail/tasks/main.yml) to use "forge" (or the
appropriate new image tag) so all references are consistent; ensure only the
string literal is changed and run a quick config/test to confirm no other
dependent names need adjustment.

---

Outside diff comments:
In `@projects/core/dsl/runtime.py`:
- Around line 247-265: The loop that looks for the repository root checks for a
parent directory named 'forge' (using filename_path.parents and parent.name) but
the repo directory is actually named 'topsail-ng', so the check always fails;
update the condition (the parent.name == 'forge' check inside the for parent in
filename_path.parents loop) to match the real directory name (e.g.,
'topsail-ng') or refactor to use a constant/setting (e.g., FORGE_HOME_NAME) and
then compute forge_home, rel_path via filename_path.relative_to(forge_home) as
before so the function returns the correct relative path instead of falling
back.

In `@projects/jump_ci/toolbox/jump_ci_prepare_topsail/tasks/main.yml`:
- Around line 136-138: The image-cleanup command still uses the old filter
string "--filter label=name=topsail-ng", so it won't match new images labeled
with "--label owner=forge"; update the filter to "--filter label=owner=forge" in
the pipeline that pipes to jq (the line containing the jq selection '.[] |
select(.Containers == 0) | select(.Labels.preserve != "true") | .Id') —
optionally include both filters (owner=forge and name=topsail-ng) if you want to
retain cleanup of legacy images as well.

---

Nitpick comments:
In `@projects/core/ci_entrypoint/run_ci.py`:
- Line 38: The single-line conditional "if not value: continue" should be split
into two lines to satisfy Ruff E701; replace it with a standard block form using
the same indentation: "if not value:" on one line and "continue" on the next
(indented once), preserving surrounding loop/context and behavior for the
variable `value`.

In `@projects/core/dsl/__init__.py`:
- Line 9: The __all__ list is unsorted; update the module-level symbol list
named __all__ to be alphabetically ordered so static analyzers and import
conventions are satisfied — reorder the entries currently in __all__ ('task',
'retry', 'when', 'always', 'execute_tasks', 'clear_tasks', 'shell') into
alphabetical order (e.g., 'always', 'clear_tasks', 'execute_tasks', 'retry',
'shell', 'task', 'when') while preserving the same variable name and semantics.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 13c9a4e8-cdb1-41ad-9da4-284a90041bbc

📥 Commits

Reviewing files that changed from the base of the PR and between b8fb112 and 9348d16.

📒 Files selected for processing (20)
  • .github/steps/prepare_minimal_ubuntu_image/action.yml
  • .github/workflows/check_consistency.yml
  • .gitignore
  • .specify/memory/constitution.md
  • projects/core/ci_entrypoint/github/pr_args.py
  • projects/core/ci_entrypoint/prepare_ci.py
  • projects/core/ci_entrypoint/run_ci.py
  • projects/core/dsl/__init__.py
  • projects/core/dsl/log.py
  • projects/core/dsl/runtime.py
  • projects/core/image/Containerfile
  • projects/core/image/Containerfile.lightweight
  • projects/core/notifications/__init__.py
  • projects/core/notifications/send.py
  • projects/jump_ci/testing/config.yaml
  • projects/jump_ci/toolbox/jump_ci_prepare_step/templates/entrypoint.sh.j2
  • projects/jump_ci/toolbox/jump_ci_prepare_topsail/tasks/main.yml
  • projects/legacy/library/env.py
  • projects/legacy/library/run.py
  • pyproject.toml

Comment thread projects/core/ci_entrypoint/run_ci.py
Comment thread projects/core/notifications/__init__.py
Comment thread projects/legacy/library/env.py
Comment thread pyproject.toml
@openshift-ci
Copy link
Copy Markdown

openshift-ci bot commented Apr 2, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign avasilevskii for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found 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

@kpouget
Copy link
Copy Markdown
Contributor Author

kpouget commented Apr 2, 2026

/test ?

@kpouget
Copy link
Copy Markdown
Contributor Author

kpouget commented Apr 2, 2026

/test llmd-jump-ci llm_d psap_h200
/cluster psap-h200

@openshift-ci
Copy link
Copy Markdown

openshift-ci bot commented Apr 2, 2026

@kpouget: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/llmd-jump-ci ce53453 link true /test llmd-jump-ci

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
projects/core/dsl/runtime.py (1)

246-265: ⚠️ Potential issue | 🟠 Major

Inconsistent _get_forge_relative_path implementations cause path format mismatches.

This function exists in both log.py (line 85) and runtime.py (line 246) with incompatible implementations:

Module For /home/user/forge/projects/foo.py Returns
log.py Uses config.FORGE_HOME projects/foo.py
runtime.py Searches for 'forge' dir in path forge/projects/foo.py

The inconsistency causes problems:

  • metadata.yaml will contain forge/... paths (from runtime.py)
  • log_completion_banner logs paths like projects/... (from log.py)
  • restart.sh script (line 211) will have python "forge/..." which only works when run from the parent directory, not from forge root

Additional issues:

  • Hardcoded directory name 'forge' (line 250) fails if repo is cloned to a different directory name
  • Comment on line 254 claims "so it shows ../forge/..." but relative_to() doesn't produce ../ prefixes
  • Function is duplicated across two modules instead of consolidated

Use config.FORGE_HOME consistently, or consolidate into a shared utility.

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

In `@projects/core/dsl/runtime.py` around lines 246 - 265, Replace the duplicated,
hardcoded implementation of _get_forge_relative_path in runtime.py with a single
shared utility that uses config.FORGE_HOME (rather than searching for a literal
'forge' directory) so both log.py and runtime.py produce the same relative path
format; update _get_forge_relative_path to compute os.path.relpath(filename,
start=config.FORGE_HOME) (falling back to os.path.relpath(filename) if
FORGE_HOME is unset) and remove the incorrect comment about "../forge/..." and
the hardcoded 'forge' string, then have both modules import the shared function
to eliminate duplication and ensure restart.sh and metadata.yaml receive
consistent paths.
♻️ Duplicate comments (1)
projects/core/ci_entrypoint/run_ci.py (1)

30-39: ⚠️ Potential issue | 🟡 Minor

This environment variable remapping block is now dead code.

The env_name.replace("FORGE", "FORGE") on line 39 is a no-op—it replaces "FORGE" with itself. This loop reads each FORGE_* variable from os.environ and writes it back to the same key, achieving nothing.

This was likely replace("TOPSAIL", "FORGE") before the rename to provide backwards compatibility. Now that the rename is complete, this entire block should be removed.

Additionally, line 38 violates the style rule against multiple statements on one line (if not value: continue).

🔧 Suggested fix: remove dead code
-FORGE_ENV = [
-    "FORGE_LIGHT_IMAGE", "FORGE_JUMP_CI_INSIDE_JUMP_HOST", "FORGE_HOME",
-    "FORGE_OPENSHIFT_CI_STEP_DIR",
-    "PSAP_FORGE_JUMP_CI_SECRET_PATH"
-]
-
-for env_name in FORGE_ENV:
-    value = os.environ.get(env_name)
-    if not value: continue
-    os.environ[env_name.replace("FORGE", "FORGE")] = value
-
-
 FORGE_HOME = Path(__file__).resolve().parent.parent.parent.parent

,

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

In `@projects/core/ci_entrypoint/run_ci.py` around lines 30 - 39, Remove the dead
environment remapping loop that iterates over FORGE_ENV and reassigns values to
the same keys (the env_name.replace("FORGE", "FORGE") no-op) — delete the
FORGE_ENV definition and the for env_name in FORGE_ENV: block (including the if
not value: continue single-line statement) from run_ci.py; if any
backwards-compat handling is still required, implement a clear mapping with
correct replace() targets or explicit keys, otherwise eliminate this dead code
and ensure no multi-statement lines remain.
🧹 Nitpick comments (2)
projects/core/image/Containerfile (1)

46-47: Consider centralizing app path/user constants to reduce future rename churn.

/app/forge and forge are repeated in multiple instructions. Defining them once (e.g., via ARG/ENV) would lower maintenance risk for future rebrands.

♻️ Example refactor
+ARG APP_NAME=forge
+ARG APP_HOME=/app/forge
+
-WORKDIR /app/forge
-ENV HOME=/app/forge
+WORKDIR ${APP_HOME}
+ENV HOME=${APP_HOME}
...
-RUN groupadd -g 1001 forge && \
-    useradd -u 1001 -g forge -s /bin/bash -d /app/forge -M forge && \
-    chown -R forge:forge /app/forge
+RUN groupadd -g 1001 ${APP_NAME} && \
+    useradd -u 1001 -g ${APP_NAME} -s /bin/bash -d ${APP_HOME} -M ${APP_NAME} && \
+    chown -R ${APP_NAME}:${APP_NAME} ${APP_HOME}
...
-ENV PYTHONPATH=/app/forge \
+ENV PYTHONPATH=${APP_HOME} \
     PYTHONUNBUFFERED=1 \
-    FORGE_HOME=/app/forge
+    FORGE_HOME=${APP_HOME}

Also applies to: 60-62, 72-74

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

In `@projects/core/image/Containerfile` around lines 46 - 47, The Dockerfile
repeats the application path and user ("WORKDIR /app/forge" and "ENV
HOME=/app/forge" plus other blocks using "/app/forge" and "forge"); introduce
centralized build-time and/or env variables (e.g., ARG APP_DIR and ARG APP_USER
then ENV APP_DIR and HOME referencing APP_DIR) at the top of the Containerfile
and replace all literal occurrences used in WORKDIR, ENV HOME, USER, COPY, and
any RUN steps (references: WORKDIR, ENV HOME, USER, and the COPY/RUN
instructions that currently use "/app/forge" or "forge") so future renames only
require updating the ARG/ENV values once.
projects/core/dsl/__init__.py (1)

9-9: Optional: __all__ is not sorted alphabetically.

Static analysis (RUF022) flags that __all__ is not sorted. This is a minor style nit that can be addressed if you want consistency with isort conventions.

♻️ Proposed fix
-__all__ = ['task', 'retry', 'when', 'always', 'execute_tasks', 'clear_tasks', 'shell']
+__all__ = ['always', 'clear_tasks', 'execute_tasks', 'retry', 'shell', 'task', 'when']
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@projects/core/dsl/__init__.py` at line 9, The __all__ list in
projects/core/dsl/__init__.py is not alphabetically sorted, which triggers
static analysis (RUF022); reorder the entries in the __all__ variable (the list
containing 'task', 'retry', 'when', 'always', 'execute_tasks', 'clear_tasks',
'shell') into alphabetical order so the names are sorted consistently (e.g.,
'always', 'clear_tasks', 'execute_tasks', 'retry', 'shell', 'task', 'when').
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@projects/core/dsl/runtime.py`:
- Around line 246-265: Replace the duplicated, hardcoded implementation of
_get_forge_relative_path in runtime.py with a single shared utility that uses
config.FORGE_HOME (rather than searching for a literal 'forge' directory) so
both log.py and runtime.py produce the same relative path format; update
_get_forge_relative_path to compute os.path.relpath(filename,
start=config.FORGE_HOME) (falling back to os.path.relpath(filename) if
FORGE_HOME is unset) and remove the incorrect comment about "../forge/..." and
the hardcoded 'forge' string, then have both modules import the shared function
to eliminate duplication and ensure restart.sh and metadata.yaml receive
consistent paths.

---

Duplicate comments:
In `@projects/core/ci_entrypoint/run_ci.py`:
- Around line 30-39: Remove the dead environment remapping loop that iterates
over FORGE_ENV and reassigns values to the same keys (the
env_name.replace("FORGE", "FORGE") no-op) — delete the FORGE_ENV definition and
the for env_name in FORGE_ENV: block (including the if not value: continue
single-line statement) from run_ci.py; if any backwards-compat handling is still
required, implement a clear mapping with correct replace() targets or explicit
keys, otherwise eliminate this dead code and ensure no multi-statement lines
remain.

---

Nitpick comments:
In `@projects/core/dsl/__init__.py`:
- Line 9: The __all__ list in projects/core/dsl/__init__.py is not
alphabetically sorted, which triggers static analysis (RUF022); reorder the
entries in the __all__ variable (the list containing 'task', 'retry', 'when',
'always', 'execute_tasks', 'clear_tasks', 'shell') into alphabetical order so
the names are sorted consistently (e.g., 'always', 'clear_tasks',
'execute_tasks', 'retry', 'shell', 'task', 'when').

In `@projects/core/image/Containerfile`:
- Around line 46-47: The Dockerfile repeats the application path and user
("WORKDIR /app/forge" and "ENV HOME=/app/forge" plus other blocks using
"/app/forge" and "forge"); introduce centralized build-time and/or env variables
(e.g., ARG APP_DIR and ARG APP_USER then ENV APP_DIR and HOME referencing
APP_DIR) at the top of the Containerfile and replace all literal occurrences
used in WORKDIR, ENV HOME, USER, COPY, and any RUN steps (references: WORKDIR,
ENV HOME, USER, and the COPY/RUN instructions that currently use "/app/forge" or
"forge") so future renames only require updating the ARG/ENV values once.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 18e1b1b5-6e5e-49b0-8b43-03b13083dad8

📥 Commits

Reviewing files that changed from the base of the PR and between 9348d16 and ce53453.

📒 Files selected for processing (20)
  • .github/steps/prepare_minimal_ubuntu_image/action.yml
  • .github/workflows/check_consistency.yml
  • .gitignore
  • .specify/memory/constitution.md
  • projects/core/ci_entrypoint/github/pr_args.py
  • projects/core/ci_entrypoint/prepare_ci.py
  • projects/core/ci_entrypoint/run_ci.py
  • projects/core/dsl/__init__.py
  • projects/core/dsl/log.py
  • projects/core/dsl/runtime.py
  • projects/core/image/Containerfile
  • projects/core/image/Containerfile.lightweight
  • projects/core/notifications/__init__.py
  • projects/core/notifications/send.py
  • projects/jump_ci/testing/config.yaml
  • projects/jump_ci/toolbox/jump_ci_prepare_step/templates/entrypoint.sh.j2
  • projects/jump_ci/toolbox/jump_ci_prepare_topsail/tasks/main.yml
  • projects/legacy/library/env.py
  • projects/legacy/library/run.py
  • pyproject.toml
✅ Files skipped from review due to trivial changes (10)
  • .gitignore
  • projects/core/dsl/log.py
  • projects/core/notifications/init.py
  • .specify/memory/constitution.md
  • .github/workflows/check_consistency.yml
  • .github/steps/prepare_minimal_ubuntu_image/action.yml
  • projects/jump_ci/testing/config.yaml
  • projects/legacy/library/run.py
  • pyproject.toml
  • projects/jump_ci/toolbox/jump_ci_prepare_step/templates/entrypoint.sh.j2
🚧 Files skipped from review as they are similar to previous changes (6)
  • projects/core/ci_entrypoint/prepare_ci.py
  • projects/legacy/library/env.py
  • projects/core/ci_entrypoint/github/pr_args.py
  • projects/jump_ci/toolbox/jump_ci_prepare_topsail/tasks/main.yml
  • projects/core/notifications/send.py
  • projects/core/image/Containerfile.lightweight

@kpouget
Copy link
Copy Markdown
Contributor Author

kpouget commented Apr 2, 2026

   * could not run steps: step [input:ci-forge-light-latest] failed: failed to wait for importing imagestreamtags on ci-op-8ymk96pi/pipeline:ci-forge-light-latest: failed to reimport the tag ci-op-8ymk96pi/pipeline:ci-forge-light-latest: unable to import tag ci-op-8ymk96pi/pipeline:ci-forge-light-latest with message Internal error occurred: [dockerimage.image.openshift.io "quay.io/openshift/ci:ci_forge-light_latest" not found, dockerimage.image.openshift.io "quay-proxy.ci.openshift.org/openshift/ci:ci_forge-light_latest" not found] on the image stream even after (6) imports: timed out waiting for the condition 

the forge-light image isn't in the CI yet.
I merge this in case it can be picked up

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

♻️ Duplicate comments (1)
projects/core/ci_entrypoint/run_ci.py (1)

30-39: ⚠️ Potential issue | 🟡 Minor

Remove the no-op env remap block.

This block copies each env var to itself (replace("FORGE", "FORGE")), so it has no effect, and Line 38 also triggers Ruff E701. Please delete the block entirely.

🔧 Proposed fix
-FORGE_ENV = [
-    "FORGE_LIGHT_IMAGE", "FORGE_JUMP_CI_INSIDE_JUMP_HOST", "FORGE_HOME",
-    "FORGE_OPENSHIFT_CI_STEP_DIR",
-    "PSAP_FORGE_JUMP_CI_SECRET_PATH"
-]
-
-for env_name in FORGE_ENV:
-    value = os.environ.get(env_name)
-    if not value: continue
-    os.environ[env_name.replace("FORGE", "FORGE")] = value
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@projects/core/ci_entrypoint/run_ci.py` around lines 30 - 39, Remove the
entire no-op environment remapping block in run_ci.py: delete the FORGE_ENV list
and the for env_name in FORGE_ENV: loop (including the os.environ.get(...) check
and the os.environ[env_name.replace("FORGE", "FORGE")] = value line) since it
does nothing and triggers Ruff E701; ensure no other code depends on FORGE_ENV
or that loop before committing.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@projects/core/image/Containerfile.lightweight`:
- Line 29: The WORKDIR is hardcoded to /app/forge causing divergence when
APP_HOME is overridden; update the WORKDIR instruction to use the APP_HOME
variable (e.g., WORKDIR ${APP_HOME}/forge or WORKDIR $APP_HOME/forge) so runtime
paths follow the build-time APP_HOME value and remain consistent with the
existing APP_HOME parameterization referenced elsewhere in the Containerfile
(APP_HOME).

In `@projects/llm_d/orchestration/cli.py`:
- Around line 51-54: post_cleanup currently calls prepare_llmd.cleanup() and
passes its return directly to sys.exit, but prepare_llmd.cleanup() can return
None causing sys.exit(0) and masking failures; update prepare_llmd.cleanup() to
always return an explicit integer status (0 for success, non-zero for failure)
and modify post_cleanup to validate the returned value (e.g., if exit_code is
None or not an int, set a non-zero default such as 1) before calling
sys.exit(exit_code) so cleanup failures are not treated as success; refer to the
post_cleanup function in cli.py and the cleanup function in prepare_llmd.py when
making these changes.

---

Duplicate comments:
In `@projects/core/ci_entrypoint/run_ci.py`:
- Around line 30-39: Remove the entire no-op environment remapping block in
run_ci.py: delete the FORGE_ENV list and the for env_name in FORGE_ENV: loop
(including the os.environ.get(...) check and the
os.environ[env_name.replace("FORGE", "FORGE")] = value line) since it does
nothing and triggers Ruff E701; ensure no other code depends on FORGE_ENV or
that loop before committing.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9c392422-6963-4cb4-97e7-dc2b40d919a9

📥 Commits

Reviewing files that changed from the base of the PR and between ce53453 and b6b8378.

📒 Files selected for processing (21)
  • .github/steps/prepare_minimal_ubuntu_image/action.yml
  • .github/workflows/check_consistency.yml
  • .gitignore
  • .specify/memory/constitution.md
  • projects/core/ci_entrypoint/github/pr_args.py
  • projects/core/ci_entrypoint/prepare_ci.py
  • projects/core/ci_entrypoint/run_ci.py
  • projects/core/dsl/__init__.py
  • projects/core/dsl/log.py
  • projects/core/dsl/runtime.py
  • projects/core/image/Containerfile
  • projects/core/image/Containerfile.lightweight
  • projects/core/notifications/__init__.py
  • projects/core/notifications/send.py
  • projects/jump_ci/testing/config.yaml
  • projects/jump_ci/toolbox/jump_ci_prepare_step/templates/entrypoint.sh.j2
  • projects/jump_ci/toolbox/jump_ci_prepare_topsail/tasks/main.yml
  • projects/legacy/library/env.py
  • projects/legacy/library/run.py
  • projects/llm_d/orchestration/cli.py
  • pyproject.toml
✅ Files skipped from review due to trivial changes (10)
  • .github/steps/prepare_minimal_ubuntu_image/action.yml
  • .gitignore
  • projects/core/notifications/init.py
  • projects/core/dsl/log.py
  • projects/core/dsl/runtime.py
  • .github/workflows/check_consistency.yml
  • projects/core/dsl/init.py
  • projects/core/ci_entrypoint/github/pr_args.py
  • projects/legacy/library/env.py
  • .specify/memory/constitution.md
🚧 Files skipped from review as they are similar to previous changes (7)
  • projects/jump_ci/toolbox/jump_ci_prepare_step/templates/entrypoint.sh.j2
  • projects/jump_ci/testing/config.yaml
  • projects/core/ci_entrypoint/prepare_ci.py
  • projects/core/notifications/send.py
  • pyproject.toml
  • projects/jump_ci/toolbox/jump_ci_prepare_topsail/tasks/main.yml
  • projects/core/image/Containerfile

ENV PYTHONPATH=$HOME

WORKDIR /app/topsail
WORKDIR /app/forge
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Make WORKDIR use APP_HOME to keep the new parameterization functional.

Line 29 hardcodes /app/forge while Lines 18-25/42-44 make home path configurable via APP_HOME. If APP_HOME is overridden at build time, runtime paths diverge and later steps may break.

🔧 Proposed fix
-WORKDIR /app/forge
+WORKDIR ${APP_HOME}
📝 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
WORKDIR /app/forge
WORKDIR ${APP_HOME}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@projects/core/image/Containerfile.lightweight` at line 29, The WORKDIR is
hardcoded to /app/forge causing divergence when APP_HOME is overridden; update
the WORKDIR instruction to use the APP_HOME variable (e.g., WORKDIR
${APP_HOME}/forge or WORKDIR $APP_HOME/forge) so runtime paths follow the
build-time APP_HOME value and remain consistent with the existing APP_HOME
parameterization referenced elsewhere in the Containerfile (APP_HOME).

Comment on lines +51 to +54
def post_cleanup(ctx):
"""Cleanup phase - Clean up resources and finalize."""
exit_code = prepare_llmd.cleanup()
sys.exit(exit_code)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Non-zero cleanup failures can be masked as success

At Line 53-54, this command exits with prepare_llmd.cleanup()’s return value. In projects/llm_d/orchestration/prepare_llmd.py (Line 13-15), cleanup() currently returns None, so sys.exit(None) exits with code 0. That can incorrectly mark failed cleanup as success in CI.

Proposed guard in this command
 def post_cleanup(ctx):
     """Cleanup phase - Clean up resources and finalize."""
     exit_code = prepare_llmd.cleanup()
-    sys.exit(exit_code)
+    if exit_code is None:
+        logger.error("prepare_llmd.cleanup() must return an integer exit code.")
+        sys.exit(1)
+    sys.exit(exit_code)

Also update prepare_llmd.cleanup() to explicitly return 0/non-zero.

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

In `@projects/llm_d/orchestration/cli.py` around lines 51 - 54, post_cleanup
currently calls prepare_llmd.cleanup() and passes its return directly to
sys.exit, but prepare_llmd.cleanup() can return None causing sys.exit(0) and
masking failures; update prepare_llmd.cleanup() to always return an explicit
integer status (0 for success, non-zero for failure) and modify post_cleanup to
validate the returned value (e.g., if exit_code is None or not an int, set a
non-zero default such as 1) before calling sys.exit(exit_code) so cleanup
failures are not treated as success; refer to the post_cleanup function in
cli.py and the cleanup function in prepare_llmd.py when making these changes.

@kpouget kpouget merged commit 288ea4a into openshift-psap:main Apr 2, 2026
3 of 4 checks passed
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.

1 participant