Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: "Publish"

on:
push:
tags:
# Publish on any tag starting with a `v`, e.g., v0.1.0
- v*

jobs:
run:
runs-on: ubuntu-latest
environment:
name: pypi
permissions:
id-token: write
contents: read
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Install Python 3.12
run: uv python install 3.12
- name: Build
run: uv build
# Check that basic features work and we didn't miss to include crucial files
- name: Smoke test (wheel)
run: uv run --isolated --no-project --with dist/*.whl tests/smoke_test.py
- name: Smoke test (source distribution)
run: uv run --isolated --no-project --with dist/*.tar.gz tests/smoke_test.py
Comment on lines +27 to +30
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider adding timeouts to smoke test steps.

The subprocess calls in tests/smoke_test.py don't have explicit timeouts, which could cause the workflow to hang if the CLI commands fail to respond. Consider adding a timeout-minutes directive to these steps as a safeguard.

🔎 Proposed enhancement
      # Check that basic features work and we didn't miss to include crucial files
      - name: Smoke test (wheel)
+       timeout-minutes: 5
        run: uv run --isolated --no-project --with dist/*.whl tests/smoke_test.py
      - name: Smoke test (source distribution)
+       timeout-minutes: 5
        run: uv run --isolated --no-project --with dist/*.tar.gz tests/smoke_test.py

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In @.github/workflows/publish.yml around lines 27 - 30, Add a timeout to the two
smoke test workflow steps ("Smoke test (wheel)" and "Smoke test (source
distribution)") so a hung CLI won't stall the run; update each job step to
include a timeout-minutes (e.g., timeout-minutes: 10) alongside the existing
name and run keys to ensure the subprocess in tests/smoke_test.py is bounded.

- name: Publish
run: uv publish
Comment on lines +31 to +32
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider adding version tag verification before publishing.

The workflow doesn't verify that the Git tag matches the version in temoa/__about__.py. This could lead to publishing artifacts with mismatched version metadata.

🔎 Proposed verification step

Add this step before the publish step:

      - name: Verify version matches tag
        run: |
          TAG_VERSION="${GITHUB_REF#refs/tags/v}"
          PACKAGE_VERSION=$(uv run python -c "import temoa; print(temoa.__version__)")
          if [ "$TAG_VERSION" != "$PACKAGE_VERSION" ]; then
            echo "Error: Tag version ($TAG_VERSION) doesn't match package version ($PACKAGE_VERSION)"
            exit 1
          fi
          echo "✅ Version verified: $PACKAGE_VERSION"
🤖 Prompt for AI Agents
In @.github/workflows/publish.yml around lines 31 - 32, Add a pre-publish
verification step before the "Publish" run that extracts the tag version from
GITHUB_REF (e.g. strip "refs/tags/v"), reads the package version by running
python -c "import temoa; print(temoa.__version__)", compares the two, and fails
the job (exit 1) with a clear error if they differ; if they match, allow the
workflow to continue to the existing uv publish step and emit a success message.

2 changes: 1 addition & 1 deletion temoa/__about__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import re

__version__ = '4.0.0a1.dev20251201'
__version__ = '4.0.0a1'

# Parse the version string to get major and minor versions
# We use a regex to be robust against versions like "4.1a1" or "4.0.0.dev1"
Expand Down
31 changes: 31 additions & 0 deletions tests/smoke_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import subprocess
import sys
import temoa

def test_import() -> None:
print(f"Importing temoa version: {temoa.__version__}")
assert temoa.__version__ is not None
Comment on lines +5 to +7
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider strengthening the version assertion.

The current assertion only checks for None. Consider verifying it's a non-empty string to catch more potential issues.

🔎 Proposed enhancement
 def test_import() -> None:
     print(f"Importing temoa version: {temoa.__version__}")
-    assert temoa.__version__ is not None
+    assert temoa.__version__ is not None
+    assert isinstance(temoa.__version__, str)
+    assert len(temoa.__version__) > 0
📝 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
def test_import() -> None:
print(f"Importing temoa version: {temoa.__version__}")
assert temoa.__version__ is not None
def test_import() -> None:
print(f"Importing temoa version: {temoa.__version__}")
assert temoa.__version__ is not None
assert isinstance(temoa.__version__, str)
assert len(temoa.__version__) > 0
🤖 Prompt for AI Agents
In @tests/smoke_test.py around lines 5 - 7, The test_import test currently only
asserts temoa.__version__ is not None; strengthen it to ensure temoa.__version__
is a non-empty string by checking its type and that its length is > 0 (e.g.,
assert isinstance(temoa.__version__, str) and assert temoa.__version__.strip()
!= ""), referencing the test_import function and temoa.__version__ to locate and
update the assertion.


def test_cli() -> None:
print("Running temoa --version CLI command...")
result = subprocess.run(["temoa", "--version"], capture_output=True, text=True)
print(f"CLI output: {result.stdout.strip()}")
assert result.returncode == 0
assert "Temoa Version:" in result.stdout
assert temoa.__version__ in result.stdout
Comment on lines +9 to +15
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Add timeout to subprocess calls to prevent hangs.

While the test logic is sound, subprocess calls without timeouts could cause the CI to hang indefinitely if the CLI becomes unresponsive.

🔎 Proposed fix
 def test_cli() -> None:
     print("Running temoa --version CLI command...")
-    result = subprocess.run(["temoa", "--version"], capture_output=True, text=True)
+    result = subprocess.run(["temoa", "--version"], capture_output=True, text=True, timeout=30)
     print(f"CLI output: {result.stdout.strip()}")
     assert result.returncode == 0
     assert "Temoa Version:" in result.stdout
     assert temoa.__version__ in result.stdout
📝 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
def test_cli() -> None:
print("Running temoa --version CLI command...")
result = subprocess.run(["temoa", "--version"], capture_output=True, text=True)
print(f"CLI output: {result.stdout.strip()}")
assert result.returncode == 0
assert "Temoa Version:" in result.stdout
assert temoa.__version__ in result.stdout
def test_cli() -> None:
print("Running temoa --version CLI command...")
result = subprocess.run(["temoa", "--version"], capture_output=True, text=True, timeout=30)
print(f"CLI output: {result.stdout.strip()}")
assert result.returncode == 0
assert "Temoa Version:" in result.stdout
assert temoa.__version__ in result.stdout
🧰 Tools
🪛 Ruff (0.14.10)

11-11: Starting a process with a partial executable path

(S607)

🤖 Prompt for AI Agents
In @tests/smoke_test.py around lines 9 - 15, The subprocess.run call in test_cli
can hang indefinitely; add a timeout (e.g., timeout=10) to the subprocess.run
invocation in the test_cli function and handle subprocess.TimeoutExpired by
failing the test (raise or pytest.fail) with a clear message; update the call
from subprocess.run([...], capture_output=True, text=True) to include timeout=10
and wrap it in try/except subprocess.TimeoutExpired to provide a deterministic
test failure if the CLI is unresponsive.


def test_help() -> None:
print("Running temoa --help CLI command...")
result = subprocess.run(["temoa", "--help"], capture_output=True, text=True)
assert result.returncode == 0
assert "The Temoa Project" in result.stdout
Comment on lines +17 to +21
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Add timeout to subprocess call.

Same recommendation as test_cli() - add a timeout parameter to prevent potential hangs.

🔎 Proposed fix
 def test_help() -> None:
     print("Running temoa --help CLI command...")
-    result = subprocess.run(["temoa", "--help"], capture_output=True, text=True)
+    result = subprocess.run(["temoa", "--help"], capture_output=True, text=True, timeout=30)
     assert result.returncode == 0
     assert "The Temoa Project" in result.stdout
📝 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
def test_help() -> None:
print("Running temoa --help CLI command...")
result = subprocess.run(["temoa", "--help"], capture_output=True, text=True)
assert result.returncode == 0
assert "The Temoa Project" in result.stdout
def test_help() -> None:
print("Running temoa --help CLI command...")
result = subprocess.run(["temoa", "--help"], capture_output=True, text=True, timeout=30)
assert result.returncode == 0
assert "The Temoa Project" in result.stdout
🧰 Tools
🪛 Ruff (0.14.10)

19-19: Starting a process with a partial executable path

(S607)

🤖 Prompt for AI Agents
In @tests/smoke_test.py around lines 17 - 21, The test_help function uses
subprocess.run without a timeout which can hang; update the subprocess.run call
in test_help to include a timeout (match the value used in test_cli, e.g.,
timeout=10) and optionally catch subprocess.TimeoutExpired to fail the test with
a clear message; target the subprocess.run invocation inside test_help.


if __name__ == "__main__":
try:
test_import()
test_cli()
test_help()
print("\n✅ Smoke test passed!")
except Exception as e:
print(f"\n❌ Smoke test failed: {e}")
sys.exit(1)