Skip to content

ci: add import-time gate for rogue (<= 1.0s best-of-5 cold imports)#104

Merged
yuval-qf merged 6 commits intoqualifire-dev:mainfrom
MANASAB805:feat/import-time-ci
Oct 20, 2025
Merged

ci: add import-time gate for rogue (<= 1.0s best-of-5 cold imports)#104
yuval-qf merged 6 commits intoqualifire-dev:mainfrom
MANASAB805:feat/import-time-ci

Conversation

@MANASAB805
Copy link
Contributor

Summary

Add a CI job that measures the cold import time of the rogue package and fails the build if the best-of-5 import time exceeds 1.0s.

This is implemented as a new workflow: .github/workflows/import-time.yml.

Motivation

We’ve invested in import-time optimizations (e.g., if TYPE_CHECKING, deferring heavy imports) and want to prevent regressions. Consistently enforcing an upper bound on import time helps preserve fast startup, especially for CLI/TUI entry points and server processes.

What’s Changed

  • New GitHub Actions workflow import-time.yml:
    • Triggers on push and pull_request.
    • Installs the package from the PR via pip install -e ..
    • Measures cold import time by spawning a fresh Python subprocess 5 times.
    • Uses the best (minimum) time to reduce runner noise.
    • Fails if the best time exceeds THRESHOLD_SECONDS (default 1.0s).

Implementation Details

  • “Cold” import is approximated by running:
    • python -c "import importlib, time; t=time.perf_counter(); importlib.import_module('rogue'); print(time.perf_counter()-t)" in a fresh subprocess 5 times.
  • The job prints the best measured import time and exits with non-zero status if above threshold.
  • Threshold is configured via THRESHOLD_SECONDS env var (defaults to 1.0).

Trade-offs

  • This implementation uses pip install -e . in CI for simplicity and isolation of the PR’s code. If project-wide CI is standardized on uv, we can switch to uv run equivalents in a follow-up without changing the measurement approach.
  • CI runner variability can introduce some noise. Using the best-of-5 minimizes flakes while still catching true regressions.

How to Test Locally

# Cold import timing (example local check)
python -c "import importlib, time; t=time.perf_counter(); importlib.import_module('rogue'); print(time.perf_counter()-t)"

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 20, 2025

Caution

Review failed

The pull request is closed.

Summary by CodeRabbit

  • Chores
    • Added automated performance monitoring to ensure package import times remain within acceptable thresholds during continuous integration.

Walkthrough

Added a new GitHub Actions workflow (.github/workflows/import-time.yml) that runs on push/PR/manual, sets PACKAGE_NAME and THRESHOLD_SECONDS, creates a venv, installs the repo and sdks/python, measures package import time across five attempts using /usr/bin/time, and fails if the best time exceeds the threshold.

Changes

Cohort / File(s) Summary
Import Time CI Workflow
.github/workflows/import-time.yml
Added a GitHub Actions workflow "Import Time CI" (triggers: pull_request, push to main, workflow_dispatch). Reads PACKAGE_NAME and THRESHOLD_SECONDS, sets up Python from .python-version, creates a venv, installs the repo (pip install -e .), uninstalls rogue-ai-sdk then installs sdks/python, ensures timing tools (/usr/bin/time, bc) are present, runs five import attempts measuring elapsed time, records per-run times, selects the minimum as best_time, prints results, and exits non-zero if best_time > threshold.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant GH as GitHub Actions
    participant Runner as CI Runner
    participant Shell as Shell (/usr/bin/time)
    participant Py as Python (venv)
    participant PKG as Target Package
    participant SDK as sdks/python

    GH->>Runner: Trigger (push / PR / manual)
    Runner->>Runner: Checkout repo\nread .python-version
    Runner->>Runner: Setup Python & create venv
    Runner->>Runner: pip install -e .
    Runner->>Runner: pip uninstall rogue-ai-sdk (if present)
    Runner->>SDK: pip install sdks/python
    Runner->>Runner: ensure `time` and `bc` available
    Runner->>Shell: Run 5 attempts: /usr/bin/time python -c "import PACKAGE_NAME"
    Shell->>Py: spawn import attempts
    Py->>PKG: import PACKAGE_NAME (repeated 5x)
    PKG-->>Py: import completes
    Shell-->>Runner: emit per-run elapsed times
    Runner->>Runner: pick best_time (min)
    alt best_time <= THRESHOLD_SECONDS
        Runner-->>GH: exit 0 (success)
    else best_time > THRESHOLD_SECONDS
        Runner-->>GH: print failure to stderr\nexit 1 (failure)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • drorIvry

Poem

🐰 I counted hops five times today,

The quickest leap I tucked away;
CI checks my nimble art,
If hops are slow it breaks my heart,
I nibble logs and twitch my sway.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The PR description provides substantive technical content including summary, motivation, detailed changes, and implementation details with testing instructions. However, the description does not follow the repository's required template structure. It is missing critical sections including the "Type of Change" checkbox selection (to categorize the PR), the development practices checklist, the formal "Testing" section with configuration details, and the "Related Issues/PRs" section. While the content quality is good, the failure to adhere to the template structure and complete required sections represents a significant deviation from the repository's guidelines.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The PR title "ci: add import-time gate for rogue (<= 1.0s best-of-5 cold imports)" directly and accurately summarizes the primary change: the addition of a GitHub Actions workflow that enforces an import-time threshold for the rogue package. The title is concise, specific enough for teammates scanning history to understand the main change, and avoids vague or noisy phrasing.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between eed5cbf and da42403.

📒 Files selected for processing (1)
  • .github/workflows/import-time.yml (1 hunks)

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.

@MANASAB805
Copy link
Contributor Author

Hi @drorIvry @yuval-qf — please approve CI workflow runs for this PR.

This adds .github/workflows/import-time.yml to enforce a 1.0s max best-of-5 cold import time for rogue. It installs the package from the PR and measures via subprocess imports to reduce cache effects.

Happy to switch the install to uv to align with the repo’s tooling if preferred.
Fixes #69

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1cc139b and d2f8317.

📒 Files selected for processing (1)
  • .github/workflows/import-time.yml (1 hunks)
🔇 Additional comments (1)
.github/workflows/import-time.yml (1)

47-52: Best-of-5 collection and threshold check look good.

The logic correctly collects the five import times, reports the minimum, and fails the job if the threshold is exceeded. Output formatting is clear and helpful for debugging.

Copy link
Collaborator

@yuval-qf yuval-qf left a comment

Choose a reason for hiding this comment

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

Thanks for this PR!
Left a few comments

Comment on lines 23 to 26
- name: Install package
run: |
python -m pip install --upgrade pip
pip install -e .
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please take a look on how we install rogue in other workflows.
Your method will not include the local sdk in /sdks/python/rogue_sdk which might result in some errors

Comment on lines 30 to 63
run: |
python - << 'PY'
import importlib, os, sys
import subprocess, time

package = os.getenv("PACKAGE_NAME", "rogue")
threshold = float(os.getenv("THRESHOLD_SECONDS", "1.0"))

def cold_import_once(pkg: str) -> float:
code = (
"import importlib, time; "
f"t=time.perf_counter(); importlib.import_module('{pkg}'); "
"print(time.perf_counter()-t)"
)
try:
out = subprocess.check_output([sys.executable, "-c", code], text=True).strip()
return float(out)
except subprocess.CalledProcessError as e:
err = getattr(e, "stderr", None)
if err is None:
err = "(no stderr captured)"
print(f"FAIL: Import subprocess failed with exit code {e.returncode}: {err}", file=sys.stderr)
sys.exit(1)
except ValueError:
print(f"FAIL: Could not parse import time from output: {out!r}", file=sys.stderr)
sys.exit(1)

times = [cold_import_once(package) for _ in range(5)]
best = min(times)
print(f"Best import time for '{package}': {best:.4f} s (threshold {threshold:.2f} s)")
if best > threshold:
print("FAIL: Import time exceeded threshold.", file=sys.stderr)
sys.exit(1)
PY
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think there is a much cleaner, and more readable way to do this:
something like:

apt-get update && apt-get install -y time  # this can be done in a different step


elapsed=$(time -f "%e" python -c "import rogue")
echo "Rogue was imported in $elapsed seconds"

# Need to use `bc` to compare floating point numbers in bash
if echo "$elapsed < $THRESHOLD" | bc -l | grep -q 1; then
    echo "Pass"
else
    echo "Fail"
    exit 1
fi

@MANASAB805
Copy link
Contributor Author

Hi @yuval-qf, thanks for the review — I’ve addressed your comments.

  • Install flow aligned with repo using uv + venv and local SDK:
    • uv venv
    • uv pip install -e .
    • uv pip uninstall -y rogue-ai-sdk || true
    • uv pip install -e sdks/python --force-reinstall
  • Timing approach updated: /usr/bin/time + bc, best-of-5 (Bash).
  • Python version sourced from .python-version via actions/setup-python.

Changes in /.github/workflows/import-time.yml (latest commit: eed5cbf).

If you’d like this to trigger only on PRs (not pushes), I can scope on: to pull_request. I can also sync the branch with main if preferred.
Please re-review when you have a moment.

Copy link
Collaborator

@yuval-qf yuval-qf left a comment

Choose a reason for hiding this comment

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

Thanks for this contribution!
Happy to approve!

@yuval-qf yuval-qf merged commit 8116db0 into qualifire-dev:main Oct 20, 2025
7 of 8 checks passed
This was referenced Oct 21, 2025
@drorIvry drorIvry mentioned this pull request Nov 10, 2025
21 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants