Skip to content

ci: run the test suite on pull requests via GitHub Actions - #39

Merged
bandrel merged 1 commit into
mainfrom
ci/github-actions
Aug 21, 2026
Merged

bandrel merged 1 commit into
mainfrom
ci/github-actions

Conversation

@bandrel

@bandrel bandrel commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

Adds GitHub Actions CI so pull requests get an automated signal instead of relying on a local pytest run.

What runs

.github/workflows/ci.yml, on pull_request and on pushes to main:

  • Python 3.8–3.13 on ubuntu-latest — every version pyproject.toml declares via requires-python = ">=3.8". Older versions come from uv's managed interpreters, so no version is skipped just because the runner image lacks it.
  • Python 3.12 on macos-latest — the tool is developed on macOS and has its own termios/stty handling, so a Linux-only matrix would leave that untested.
  • uv lock --check — catches a pyproject.toml change that was never locked.
  • uv run --frozen pytest tests/ -v — the same command used locally.

nmap is installed on the Ubuntu jobs. tests/test_nse_integration.py skips its entire module when nmap is absent, so without that step the NSE assertions would report green without ever executing.

Concurrency is keyed on the PR head ref with cancel-in-progress, so a new push supersedes the previous run rather than queueing behind it. permissions: contents: read only.

The 95% coverage floor is deliberately not restated in the workflow — it already comes from addopts in [tool.pytest.ini_options], so a coverage regression fails the test step and there is only one place to change the threshold.

Verification

Locally, in a clean worktree off main:

  • actionlint .github/workflows/ci.yml → 0 errors
  • uv lock --check → lock in sync
  • uv run --frozen pytest tests/ -q → 907 passed, 5 skipped, 99.91% coverage
  • uv run --frozen --python 3.8 pytest tests/ -q → 907 passed, 5 skipped (confirms the oldest matrix entry resolves and passes)

The 5 skips are the expected environment gates: NSE cases whose local port was occupied, and the -sU case that needs root.

Note on the open PRs

Workflows run from the head branch of a PR, so #37 and #38 will not show checks until they pick up main after this merges.

Also worth flagging separately: the push output surfaced a Dependabot alert on this repo (https://github.com/trustedsec/spoonmap/security/dependabot/2) — unrelated to this change, but visible now.

Docs

  • README: CI badge and a new ## Development section covering how to run the suite, the coverage floor, and why an NSE skip is an environment conflict rather than a failure.
  • CLAUDE.md: a short paragraph describing what CI covers.

Adds .github/workflows/ci.yml, triggered on pull_request and on pushes to
main. The suite runs on Python 3.8-3.13 (every version pyproject claims to
support) on Ubuntu, plus Python 3.12 on macOS to cover the termios/stty
paths the tool is developed against.

nmap is installed on the Ubuntu jobs: tests/test_nse_integration.py skips
the whole module when nmap is absent, so without it the NSE assertions
would look green without ever running.

The 95% coverage floor is not restated in the workflow - it already comes
from pytest's addopts in pyproject.toml, so a coverage regression fails the
test step. A uv lock --check step catches a pyproject change that was not
locked.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@bandrel
bandrel merged commit a088328 into main Aug 21, 2026
7 checks passed
@bandrel
bandrel deleted the ci/github-actions branch August 21, 2026 17:19
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