diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml index e931048..6177539 100644 --- a/.github/workflows/claude-code-review.yml +++ b/.github/workflows/claude-code-review.yml @@ -30,6 +30,7 @@ jobs: uses: anthropics/claude-code-action@v1 with: claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} + github_token: ${{ secrets.GITHUB_TOKEN }} prompt: | You are a code review agent for the ptop3 project. diff --git a/.github/workflows/claude-quality-gate.yml b/.github/workflows/claude-quality-gate.yml index bbb3652..f7c61ca 100644 --- a/.github/workflows/claude-quality-gate.yml +++ b/.github/workflows/claude-quality-gate.yml @@ -24,6 +24,7 @@ jobs: - uses: anthropics/claude-code-action@v1 with: claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} + github_token: ${{ secrets.GITHUB_TOKEN }} prompt: | You are a test quality agent for the ptop3 project. @@ -55,6 +56,7 @@ jobs: - uses: anthropics/claude-code-action@v1 with: claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} + github_token: ${{ secrets.GITHUB_TOKEN }} prompt: | You are a documentation quality agent for the ptop3 project. @@ -92,6 +94,7 @@ jobs: - uses: anthropics/claude-code-action@v1 with: claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} + github_token: ${{ secrets.GITHUB_TOKEN }} prompt: | You are a code quality and security agent for the ptop3 project. diff --git a/.github/workflows/publish-testpypi.yml b/.github/workflows/publish-testpypi.yml index 71569f9..a78b7f9 100644 --- a/.github/workflows/publish-testpypi.yml +++ b/.github/workflows/publish-testpypi.yml @@ -15,8 +15,10 @@ jobs: publish: needs: [test] runs-on: ubuntu-latest + environment: testpypi permissions: contents: read # checkout only + id-token: write # required for Trusted Publishing steps: - uses: actions/checkout@v4 @@ -27,7 +29,53 @@ jobs: python-version: "3.12" - name: Install build tools - run: pip install build + run: pip install build packaging + + - name: Set unique TestPyPI version + env: + RUN_NUMBER: ${{ github.run_number }} + run: | + python - <<'PY' + import os + import re + from pathlib import Path + + from packaging.version import Version + + pyproject = Path("pyproject.toml") + init_py = Path("ptop3/__init__.py") + + pyproject_text = pyproject.read_text() + match = re.search(r'^version = "([^"]+)"', pyproject_text, re.M) + if not match: + raise SystemExit("Could not find project version in pyproject.toml") + + base = Version(match.group(1)) + test_version = f"{base.major}.{base.minor}.{base.micro + 1}.dev{os.environ['RUN_NUMBER']}" + + pyproject.write_text( + re.sub( + r'^version = "[^"]+"', + f'version = "{test_version}"', + pyproject_text, + count=1, + flags=re.M, + ) + ) + + init_text = init_py.read_text() + init_py.write_text( + re.sub( + r'^__version__ = "[^"]+"', + f'__version__ = "{test_version}"', + init_text, + count=1, + flags=re.M, + ) + ) + + print(f"Publishing TestPyPI version: {test_version}") + PY - name: Build package run: python -m build @@ -36,5 +84,4 @@ jobs: uses: pypa/gh-action-pypi-publish@release/v1 with: repository-url: https://test.pypi.org/legacy/ - password: ${{ secrets.TEST_PYPI_API_TOKEN }} skip-existing: true diff --git a/.gitignore b/.gitignore index d9fff16..3120dbf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,13 +1,51 @@ __pycache__/ *.py[cod] -*.egg-info/ -dist/ -build/ -.eggs/ +*$py.class + +# Virtual environments .venv/ venv/ -.mypy_cache/ -.ruff_cache/ -.pytest_cache/ +env/ +ENV/ +.python-version + +# Packaging +.Python +build/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +pip-wheel-metadata/ *.egg +*.egg-info/ MANIFEST + +# Test and coverage outputs +.coverage +.coverage.* +htmlcov/ +.pytest_cache/ +.hypothesis/ +.tox/ +.nox/ +coverage.xml +*.cover +*.py,cover + +# Type checkers and linters +.mypy_cache/ +.dmypy.json +dmypy.json +.pyre/ +.ruff_cache/ + +# Notebooks and local tooling +.ipynb_checkpoints/ diff --git a/tests/test_swap_clean.py b/tests/test_swap_clean.py index daf3971..0dd8dd0 100644 --- a/tests/test_swap_clean.py +++ b/tests/test_swap_clean.py @@ -253,10 +253,12 @@ def test_swap_clean_file_by_file_fallback(tmp_path, capsys): safety_mb=1, meminfo_path=str(meminfo), swaps_path=str(swaps), - ) + ) assert rc == 0 - assert "file-by-file" in capsys.readouterr().out + captured = capsys.readouterr() + assert "Not enough RAM to clean all swap at once. Trying file-by-file..." in captured.err + assert "Swap clean completed (file-by-file)." in captured.out called_cmds = [call.args[0] for call in mock_run.call_args_list] assert ["swapoff", "/swap-b"] in called_cmds assert ["swapon", "/swap-b"] in called_cmds