Skip to content
Closed

Dev #10

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
b126e0b
feat(client): migrate transport and models to httpx
Wil-Collier May 13, 2026
c038666
docs: document 0.2 client migration
Wil-Collier May 13, 2026
35fadb4
ci: add uv test workflow
Wil-Collier May 13, 2026
64d77ad
chore: gitignore audit — add .ruff_cache, untrack docker/api_key.txt
Wil-Collier May 16, 2026
fee0c44
docs: add dev-only intent banner to docker/.env, add docker/README.md
Wil-Collier May 16, 2026
4da6f15
chore: add Apache 2.0 LICENSE and NOTICE (copyright 2026 Wil Collier)
Wil-Collier May 16, 2026
e20772e
chore: fill in pyproject.toml metadata — author, license, URLs, py.ty…
Wil-Collier May 16, 2026
b4e5dbb
feat: add _raw_request() and _stream_request() helpers to client.py
Wil-Collier May 16, 2026
f160c8e
refactor: assets.py — use _raw_request()/_stream_request(), remove in…
Wil-Collier May 16, 2026
1a8cb7f
breaking: remove self.session alias — use client._http directly
Wil-Collier May 16, 2026
dc8011f
docs: verify delete_file URL against snipe-it/develop routes/api.php …
Wil-Collier May 16, 2026
1779342
refactor: split assets.py into assets/ package (model, manager, files…
Wil-Collier May 16, 2026
f588417
chore: delete unused docs/*.json schemas (groups/audit/maintenances/r…
Wil-Collier May 16, 2026
a54f01c
docs: document extra=allow typo footgun in README Common Pitfalls + A…
Wil-Collier May 16, 2026
8364cc4
feat: snapshot-and-diff dirty tracking — in-place mutation of nested …
Wil-Collier May 16, 2026
3975fcc
refactor: rewrite all tests to use httpx_mock directly — remove reque…
Wil-Collier May 16, 2026
ea1787a
chore: delete tests/_requests_mock_shim.py — all tests now use httpx_…
Wil-Collier May 16, 2026
6606758
ci: add pydantic version matrix (2.0.x and 2.10.x) to CI
Wil-Collier May 16, 2026
2ee54cc
test: add _apply_server_data regression tests; fix stale extra fields…
Wil-Collier May 16, 2026
8da709c
docs: write 0.3.0 CHANGELOG
Wil-Collier May 16, 2026
10413c2
chore: bump version to 0.3.0; update README What's New section
Wil-Collier May 16, 2026
6dcfaaf
chore: fix ruff lint (unused json imports in test files)
Wil-Collier May 16, 2026
efaed35
fix(docker): bump PHP memory_limit to 512M — seeder fails OOM with de…
Wil-Collier May 16, 2026
afa81ca
fix(Makefile): constrain test-integration to tests/integration path —…
Wil-Collier May 16, 2026
1cca516
test: remove dead-code test files and stub tests (task 1)
Wil-Collier May 16, 2026
0c1f704
test: add parametrised CRUD smoke tests; switch fixture URL to RFC 67…
Wil-Collier May 16, 2026
5e757cd
test: replace 13 duplicated CRUD files with parametrised smoke + spec…
Wil-Collier May 16, 2026
a00a73a
test: add Company and Supplier to repr parametrize (task 4)
Wil-Collier May 16, 2026
f4fe7ba
test: add integration tests for Companies and Suppliers (task 5)
Wil-Collier May 16, 2026
9a573fc
test: strengthen weak assertions; fix hypothesis sentinel; add future…
Wil-Collier May 16, 2026
337120e
test: normalise pytestmark to file-level; fix integration labels skip…
Wil-Collier May 16, 2026
6f42ee8
test: cover URL/token validation, 204 paths, error-message extraction…
Wil-Collier May 16, 2026
ac6a34f
test: cover upload_files validation/error paths and labels validation…
Wil-Collier May 16, 2026
9ced0ea
test: cover list_all no-total, checkout kwargs, localized-404 message…
Wil-Collier May 16, 2026
41dab02
test: convert integration env-var setup to MonkeyPatch.context() (tas…
Wil-Collier May 16, 2026
ea099fd
test: add strict filterwarnings=error to pytest.ini (task 19)
Wil-Collier May 16, 2026
7fd40bd
ci: add mut-quick Makefile target and advisory mutation CI job (task 20)
Wil-Collier May 16, 2026
43fbae8
test: bump coverage gate to 95%; update CHANGELOG (task 21)
Wil-Collier May 16, 2026
a34621a
test(integration): add custom fields e2e, file upload/download round-…
Wil-Collier May 16, 2026
b677c06
fix(docker): ensure api_key.txt is a regular file before bind-mount
Wil-Collier May 16, 2026
ebab8ff
fix(integration): eliminate flakiness; fix e2e tests against real Sni…
Wil-Collier May 16, 2026
063b7df
Update README.md
Wil-Collier May 17, 2026
8f336cd
Delete NOTICE
Wil-Collier May 17, 2026
9992f99
Refactor custom field handling in Asset model
Wil-Collier May 17, 2026
531ac00
feat: refactor custom-field staging on Asset
Wil-Collier May 17, 2026
607dd2c
docs: update README and CHANGELOG for v0.4.0
Wil-Collier May 17, 2026
cf4a786
ci: add integration test job to CI workflow
Wil-Collier May 17, 2026
c906504
chore: repo cleanup before merge
Wil-Collier May 17, 2026
6b2e039
docs: add RELEASING.md with versioning process
Wil-Collier May 17, 2026
7227ed3
Update uv.lock
Wil-Collier May 17, 2026
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
114 changes: 114 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
test:
name: test (py${{ matrix.python-version }}, pydantic${{ matrix.pydantic-version }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.11", "3.12", "3.13"]
pydantic-version: ["~=2.0.0", "~=2.10.0"]

steps:
- uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v4
with:
enable-cache: true

- name: Set up Python ${{ matrix.python-version }}
run: uv python install ${{ matrix.python-version }}

- name: Install deps
run: uv sync --all-extras --python ${{ matrix.python-version }}

- name: Pin pydantic version
run: uv pip install "pydantic${{ matrix.pydantic-version }}"

- name: Lint
run: uv run ruff check .

- name: Type-check
run: uv run pyright

- name: Unit tests
run: uv run pytest tests/unit tests/contract -q -m unit

- name: Coverage
if: matrix.python-version == '3.13' && matrix.pydantic-version == '~=2.10.0'
run: |
uv run coverage run -m pytest tests/unit tests/contract -q -m unit
uv run coverage report -m --fail-under=95

integration:
name: integration tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v4
with:
enable-cache: true

- name: Set up Python
run: uv python install 3.13

- name: Install deps
run: uv sync --all-extras --python 3.13

- name: Start Snipe-IT stack
run: |
rm -rf docker/api_key.txt
touch docker/api_key.txt
cd docker && docker compose up -d

- name: Wait for API key
run: |
echo "Waiting for docker/api_key.txt (up to ~120s)..."
for i in $(seq 1 120); do
if [ -s docker/api_key.txt ]; then break; fi
sleep 1
done
if [ ! -s docker/api_key.txt ]; then
echo "Timed out waiting for docker/api_key.txt"
cd docker && docker compose logs seeder
exit 1
fi

- name: Wait for API readiness
run: |
TOKEN=$(cat docker/api_key.txt)
echo "Waiting for Snipe-IT API (up to ~120s)..."
for i in $(seq 1 120); do
code=$(curl -s -o /dev/null -w "%{http_code}" -m 5 \
-H "Authorization: Bearer $TOKEN" \
-H "Accept: application/json" \
http://localhost:8000/api/v1/users/me 2>/dev/null || echo "000")
if [ "$code" = "200" ]; then
echo "API is ready"
break
fi
sleep 1
done
if [ "$code" != "200" ]; then
echo "Timed out. Last status: $code"
cd docker && docker compose logs app
exit 1
fi

- name: Integration tests
run: uv run pytest tests/integration -q -m integration
44 changes: 44 additions & 0 deletions .github/workflows/mutation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Mutation (advisory)

on:
pull_request:
branches: [main, dev]
workflow_dispatch:

# Advisory job — never blocks merges.
# Results are uploaded as an artifact for review.

jobs:
mutation:
name: mutmut (advisory)
runs-on: ubuntu-latest
continue-on-error: true

steps:
- uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v4
with:
enable-cache: true

- name: Set up Python
run: uv python install 3.13

- name: Install deps
run: uv sync --all-extras --python 3.13

- name: Run mut-quick
run: uv run make mut-quick
continue-on-error: true

- name: Print mutation summary
run: uv run mutmut results || true

- name: Upload mutation cache
uses: actions/upload-artifact@v4
if: always()
with:
name: mutmut-results
path: .mutmut-cache
retention-days: 7
10 changes: 8 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,16 @@ env/

# Local
GEMINI.md
.kiro/
.mutmut-cache
.mutmut-cache/
mutants/
*.bak
*.lock
*.html
*.tmp
*.tmp

# Tool caches
.ruff_cache/

# Docker dev secrets (generated at runtime)
docker/api_key.txt
205 changes: 205 additions & 0 deletions .kiro/settings/lsp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
{
"languages": {
"typescript": {
"name": "typescript-language-server",
"command": "typescript-language-server",
"args": [
"--stdio"
],
"file_extensions": [
"ts",
"js",
"tsx",
"jsx"
],
"file_patterns": [],
"project_patterns": [
"package.json",
"tsconfig.json"
],
"exclude_patterns": [
"**/node_modules/**",
"**/dist/**"
],
"multi_workspace": false,
"initialization_options": {
"preferences": {
"disableSuggestions": false
}
},
"request_timeout_secs": 60
},
"rust": {
"name": "rust-analyzer",
"command": "rust-analyzer",
"args": [],
"file_extensions": [
"rs"
],
"file_patterns": [],
"project_patterns": [
"Cargo.toml"
],
"exclude_patterns": [
"**/target/**"
],
"multi_workspace": false,
"initialization_options": {
"cargo": {
"buildScripts": {
"enable": true
}
},
"diagnostics": {
"enable": true,
"enableExperimental": true
},
"workspace": {
"symbol": {
"search": {
"scope": "workspace"
}
}
}
},
"request_timeout_secs": 60
},
"python": {
"name": "pyright",
"command": "pyright-langserver",
"args": [
"--stdio"
],
"file_extensions": [
"py"
],
"file_patterns": [],
"project_patterns": [
"pyproject.toml",
"setup.py",
"requirements.txt",
"pyrightconfig.json"
],
"exclude_patterns": [
"**/__pycache__/**",
"**/venv/**",
"**/.venv/**",
"**/.pytest_cache/**"
],
"multi_workspace": false,
"initialization_options": {},
"request_timeout_secs": 60
},
"java": {
"name": "jdtls",
"command": "jdtls",
"args": [],
"file_extensions": [
"java"
],
"file_patterns": [],
"project_patterns": [
"pom.xml",
"build.gradle",
"build.gradle.kts",
".project"
],
"exclude_patterns": [
"**/target/**",
"**/build/**",
"**/.gradle/**"
],
"multi_workspace": false,
"initialization_options": {
"settings": {
"java": {
"compile": {
"nullAnalysis": {
"mode": "automatic"
}
},
"configuration": {
"annotationProcessing": {
"enabled": true
}
}
}
}
},
"request_timeout_secs": 60
},
"go": {
"name": "gopls",
"command": "gopls",
"args": [],
"file_extensions": [
"go"
],
"file_patterns": [],
"project_patterns": [
"go.mod",
"go.sum"
],
"exclude_patterns": [
"**/vendor/**"
],
"multi_workspace": false,
"initialization_options": {
"usePlaceholders": true,
"completeUnimported": true
},
"request_timeout_secs": 60
},
"ruby": {
"name": "solargraph",
"command": "solargraph",
"args": [
"stdio"
],
"file_extensions": [
"rb"
],
"file_patterns": [],
"project_patterns": [
"Gemfile",
"Rakefile"
],
"exclude_patterns": [
"**/vendor/**",
"**/tmp/**"
],
"multi_workspace": false,
"initialization_options": {},
"request_timeout_secs": 60
},
"cpp": {
"name": "clangd",
"command": "clangd",
"args": [
"--background-index"
],
"file_extensions": [
"cpp",
"cc",
"cxx",
"c",
"h",
"hpp",
"hxx"
],
"file_patterns": [],
"project_patterns": [
"CMakeLists.txt",
"compile_commands.json",
"Makefile"
],
"exclude_patterns": [
"**/build/**",
"**/cmake-build-**/**"
],
"multi_workspace": false,
"initialization_options": {},
"request_timeout_secs": 60
}
}
}
Loading
Loading