Skip to content

ci: GitHub Actions pytest workflow + bundled test fixture - #4

Merged
sowerkoku merged 1 commit into
masterfrom
feature/ci-github-actions
Aug 14, 2026
Merged

sowerkoku merged 1 commit into
masterfrom
feature/ci-github-actions

Conversation

@sowerkoku

Copy link
Copy Markdown
Owner

Description

The repo had no CI configuration. PR #3 was merged with 69 passed / 5 skipped locally but nothing prevented future regressions from going unnoticed.

This PR adds a complete CI setup that makes the test suite reproducible in any clean environment:

What's added

File Purpose
.github/workflows/tests.yml GitHub Actions workflow: pytest on Python 3.11 + 3.12, on push to master and on every PR
tests/conftest.py Routes CMDB_DATA_DIR to the bundled fixture for every pytest run (idempotent — respects user env override)
tests/fixtures/dataset/asset/fixture-server-a.yaml Test asset with 1 relation (for cmdb_impact coverage)
tests/fixtures/dataset/asset/fixture-server-b.yaml Test asset with no relations (for cmdb_list coverage)
tests/fixtures/dataset/software/fixture-software-x.yaml Test software entity (target of the relation)

Diff summary

 .github/workflows/tests.yml                        | 42 ++++++++++++++++++++++
 tests/conftest.py                                  | 28 +++++++++++++++
 tests/fixtures/dataset/asset/fixture-server-a.yaml | 29 +++++++++++++++
 tests/fixtures/dataset/asset/fixture-server-b.yaml | 27 ++++++++++++++
 tests/fixtures/dataset/software/fixture-software-x.yaml | 26 ++++++++++++++
 5 files changed, 152 insertions(+)

Design decisions

  1. Why a bundled fixture instead of mocking? test_acceptance.py reads the real cmdb.api against a real dataset. Mocking would mean rewriting tests, breaking their contract. A small YAML fixture preserves the test surface verbatim and is reusable for any contributor (no ~/knowledge/... required).

  2. Why matrix [3.11, 3.12]? pyproject.toml declares requires-python = ">=3.11". Adding 3.13 would be over-reach without testing it locally first. Stick to the declared minimum + one newer.

  3. Why no pip caching in step 1? Cache config adds noise to the workflow file. Add it after we see the workflow runs cleanly. KISS.

  4. Why doesn't the workflow execute the CLI wrappers? They use os.environ.setdefault("CMDB_DATA_DIR", "~/knowledge/knowledge-kernel") — same as the other 11 wrappers. Running them in CI would either fail (no production dataset) or leak test data into the operator's environment. The workflow verifies they import cleanly, which catches syntax/contract regressions without execution risk.

  5. Why no pip-audit / no ruff / no mypy? pyproject.toml declares ruff + mypy as dev-deps, so they're available. But adding them to CI is scope creep — separate PRs with rationale each. This PR is "tests run on every PR", not "everything runs on every PR".

Verification done locally

  • python3 -m pytest tests/ -q → 69 passed, 5 skipped (same numbers as pre-change)
  • env -u CMDB_DATA_DIR python3 -m pytest tests/ -q → same (conftest.py correctly redirects)
  • python3 -c "import yaml; yaml.safe_load(open('.github/workflows/tests.yml'))" → valid YAML
  • All 5 files explicitly git add-ed (no git add . scope creep)
  • No secrets, no real IPs, no hostnames, no infra data in fixture

Verification pending (happens after merge)

  • First CI run on this PR branch (matrix 3.11 + 3.12)
  • Confirm the workflow file is recognized by GitHub Actions

Checklist

  • Single purpose: add CI
  • No SKILL.md edits
  • No unrelated refactors
  • Branch: feature/ci-github-actions
  • Base: master

The repo had no CI configuration (no .github/workflows). This meant
PRs were merged without automated test verification, depending on the
author's local run. PR #3 was merged with 69 passed / 5 skipped but
nothing prevented a future change from regressing unnoticed.

This commit adds:

1. .github/workflows/tests.yml
   - Triggers: push to master, pull_request to master
   - Matrix: Python 3.11, 3.12 (matches pyproject requires-python >=3.11)
   - Steps: checkout → setup-python → pip install -e '.[dev]' → pytest -v
   - Plus a CLI-wrapper import check (no execution, because the wrappers
     read from the operator's production dataset by default — pytest
     already covers end-to-end via the fixture)

2. tests/conftest.py
   - Routes CMDB_DATA_DIR to tests/fixtures/dataset/ for every pytest run
   - Idempotent: respects user override via env var
   - Local behavior unchanged when CMDB_DATA_DIR is already set

3. tests/fixtures/dataset/
   - 3 minimal entities (2 assets, 1 software) + 1 relation
   - Covers test_acceptance.py requirements:
     * cmdb_list(kind='asset') returns non-empty
     * cmdb_impact can resolve fixture-server-a's runs_on relation
   - Synthetic data — no infrastructure IPs, no hostnames, no secrets
   - All entities tagged 'ci-fixture'

Verified locally:
  - 69 passed, 5 skipped (same numbers as pre-change)
  - YAML lints as valid
  - conftest.py correctly redirects CMDB_DATA_DIR
  - Workflow does NOT execute the wrapper (would read production dataset)

The user's local dataset at ~/knowledge/knowledge-kernel is NOT touched.
The fixture only activates when pytest runs from this repo's tests/.
@sowerkoku
sowerkoku merged commit a3b880e into master Aug 14, 2026
2 checks passed
@sowerkoku
sowerkoku deleted the feature/ci-github-actions branch August 14, 2026 04:55
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