fix: make QA deployment cleanup import reliably - #60
Conversation
PR Sync
|
📝 WalkthroughWalkthroughThe cleanup CLI now adds the repository root to ChangesQA cleanup CLI import resolution
Estimated code review effort: 2 (Simple) | ~10 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@tests/test_qa_workflows.py`:
- Around line 142-160: Update
test_cleanup_cli_imports_from_outside_repository_without_pythonpath to invoke
the child interpreter with the -S flag, ensuring an isolated environment without
site-packages while retaining the existing PYTHONPATH removal and assertions.
🪄 Autofix
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: 5b96e93b-c72c-444f-b949-ab158cf338c5
📒 Files selected for processing (2)
tests/qa/cleanup_deployments.pytests/test_qa_workflows.py
| def test_cleanup_cli_imports_from_outside_repository_without_pythonpath(self): | ||
| script = ROOT / "tests/qa/cleanup_deployments.py" | ||
| env = os.environ.copy() | ||
| env.pop("PYTHONPATH", None) | ||
|
|
||
| with tempfile.TemporaryDirectory() as temporary_directory: | ||
| result = subprocess.run( | ||
| [sys.executable, str(script), "--help"], | ||
| cwd=temporary_directory, | ||
| env=env, | ||
| capture_output=True, | ||
| text=True, | ||
| timeout=30, | ||
| check=False, | ||
| ) | ||
|
|
||
| self.assertEqual(result.returncode, 0, msg=result.stderr or result.stdout) | ||
| self.assertIn("Clean historical GitHub deployments", result.stdout) | ||
|
|
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- candidate files ---'
git ls-files | rg '(^|/)(tests/test_qa_workflows\.py|cleanup_deployments\.py|project_setup|pyproject\.toml|setup\.py|setup\.cfg|tox\.ini|pytest\.ini|conftest\.py)$' || true
printf '%s\n' '--- test context ---'
sed -n '110,175p' tests/test_qa_workflows.py
printf '%s\n' '--- cleanup script outline ---'
if command -v ast-grep >/dev/null 2>&1; then ast-grep outline tests/qa/cleanup_deployments.py; fi
printf '%s\n' '--- cleanup script imports and bootstrap ---'
sed -n '1,120p' tests/qa/cleanup_deployments.py
printf '%s\n' '--- project_setup references ---'
rg -n --glob '*.py' 'project_setup|REPOSITORY_ROOT|PYTHONPATH|sys\.path|site-packages' .
printf '%s\n' '--- packaging/test configuration ---'
for f in pyproject.toml setup.py setup.cfg tox.ini pytest.ini tests/conftest.py conftest.py; do
if [ -f "$f" ]; then
echo "### $f"
sed -n '1,220p' "$f"
fi
doneRepository: v-Kaefer/Github-Project-Automation
Length of output: 23208
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- imported module and package imports ---'
sed -n '1,100p' project_setup/github.py
if [ -f project_setup/__init__.py ]; then sed -n '1,80p' project_setup/__init__.py; fi
printf '%s\n' '--- standalone -S masking probe ---'
python3 - <<'PY'
import os
import pathlib
import subprocess
import sys
import tempfile
with tempfile.TemporaryDirectory() as td:
root = pathlib.Path(td)
checkout = root / "checkout"
installed = root / "installed"
outside = root / "outside"
for package_root, marker in ((checkout, "checkout"), (installed, "installed")):
package = package_root / "project_setup"
package.mkdir(parents=True)
(package / "__init__.py").write_text("")
(package / "github.py").write_text(f"MARKER = {marker!r}\n")
script = outside / "probe.py"
outside.mkdir()
script.write_text(
"import sys\n"
f"sys.path.insert(0, {str(checkout)!r})\n"
"from project_setup.github import MARKER\n"
"print(MARKER)\n"
)
env = os.environ.copy()
env["PYTHONPATH"] = str(installed)
env.pop("PYTHONHOME", None)
normal = subprocess.run(
[sys.executable, str(script)],
env=env, capture_output=True, text=True, check=False,
)
isolated = subprocess.run(
[sys.executable, "-S", str(script)],
env=env, capture_output=True, text=True, check=False,
)
print("normal:", normal.returncode, normal.stdout.strip(), normal.stderr.strip())
print("-S:", isolated.returncode, isolated.stdout.strip(), isolated.stderr.strip())
assert normal.returncode == 0 and isolated.returncode == 0
assert normal.stdout.strip() == "checkout"
assert isolated.stdout.strip() == "checkout"
PYRepository: v-Kaefer/Github-Project-Automation
Length of output: 3749
🏁 Script executed:
#!/bin/bash
set -eu
python3 - <<'PY'
import os
import pathlib
import subprocess
import sys
import tempfile
with tempfile.TemporaryDirectory() as td:
root = pathlib.Path(td)
startup = root / "startup"
installed = root / "installed"
script = root / "probe.py"
startup.mkdir()
package = installed / "project_setup"
package.mkdir(parents=True)
(package / "__init__.py").write_text("")
(package / "github.py").write_text("MARKER = 'installed'\n")
(startup / "sitecustomize.py").write_text(
f"import sys\nsys.path.insert(0, {str(installed)!r})\n"
)
script.write_text(
"from project_setup.github import MARKER\n"
"print(MARKER)\n"
)
env = os.environ.copy()
env["PYTHONPATH"] = str(startup)
normal = subprocess.run(
[sys.executable, str(script)],
env=env, capture_output=True, text=True, check=False,
)
isolated = subprocess.run(
[sys.executable, "-S", str(script)],
env=env, capture_output=True, text=True, check=False,
)
print("normal:", normal.returncode, normal.stdout.strip(), normal.stderr.strip())
print("-S:", isolated.returncode, isolated.stdout.strip(), isolated.stderr.strip())
assert normal.returncode == 0 and normal.stdout.strip() == "installed"
assert isolated.returncode != 0
PYRepository: v-Kaefer/Github-Project-Automation
Length of output: 388
Use an isolated child interpreter for this regression test.
Removing PYTHONPATH does not remove project_setup from site-packages. Run the child with sys.executable -S; project_setup.github uses only standard-library modules.
🧰 Tools
🪛 ast-grep (0.45.1)
[error] 147-155: Command coming from incoming request
Context: subprocess.run(
[sys.executable, str(script), "--help"],
cwd=temporary_directory,
env=env,
capture_output=True,
text=True,
timeout=30,
check=False,
)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
(subprocess-from-request)
🪛 Ruff (0.16.1)
[error] 148-148: subprocess call: check for execution of untrusted input
(S603)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@tests/test_qa_workflows.py` around lines 142 - 160, Update
test_cleanup_cli_imports_from_outside_repository_without_pythonpath to invoke
the child interpreter with the -S flag, ensuring an isolated environment without
site-packages while retaining the existing PYTHONPATH removal and assertions.
Linked Issue
Milestone
Related PRs
Summary
project_setupnot being importable when the script is executed directly fromtests/qa.PYTHONPATHremoved.How to test
python tests/qa/cleanup_deployments.py --helpfrom an external working directory without an installed package/PYTHONPATH dependency.Evidence
Known risks
DoD checklist
Summary by CodeRabbit
Bug Fixes
Tests