diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..1981ea8 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,23 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 3 + groups: + actions: + patterns: ["*"] + - package-ecosystem: "uv" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 3 + groups: + dependencies: + patterns: ["*"] + - package-ecosystem: "pip" + directory: "/examples/entitylinkage-coverage" + schedule: + interval: "weekly" + open-pull-requests-limit: 1 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 991bc79..74948a0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,9 +38,15 @@ jobs: - name: Install built wheel run: | python -m venv "$RUNNER_TEMP/package-venv" - "$RUNNER_TEMP/package-venv/bin/python" -m pip install dist/evidencematrix-0.1.1-py3-none-any.whl entitylinkage==0.1.0 - "$RUNNER_TEMP/package-venv/bin/evidencematrix" validate examples/basic - PATH="$RUNNER_TEMP/package-venv/bin:$PATH" bash examples/entitylinkage-coverage/run-example.sh "$RUNNER_TEMP/entitylinkage-coverage-example" + shopt -s nullglob + wheels=(dist/*.whl) + test "${#wheels[@]}" -eq 1 + "$RUNNER_TEMP/package-venv/bin/python" -m pip install "${wheels[0]}" -r examples/entitylinkage-coverage/requirements.txt + export PATH="$RUNNER_TEMP/package-venv/bin:$PATH" + cd "$RUNNER_TEMP" + python -c 'import evidencematrix, pathlib; assert "site-packages" in pathlib.Path(evidencematrix.__file__).resolve().parts' + evidencematrix validate "$GITHUB_WORKSPACE/examples/basic" + bash "$GITHUB_WORKSPACE/examples/entitylinkage-coverage/run-example.sh" "$RUNNER_TEMP/entitylinkage-coverage-example" - name: CLI smoke test shell: bash run: | diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index ce03906..a0de95c 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -26,6 +26,15 @@ jobs: run: | package_version="$(python -c 'import tomllib; print(tomllib.load(open("pyproject.toml", "rb"))["project"]["version"])')" test "$GITHUB_REF_NAME" = "v$package_version" + - name: Test locked release source + env: + PYTHONPATH: src + run: | + set -euo pipefail + uv sync --locked --all-groups --no-install-project --no-build + uv run --locked --no-sync --no-build ruff check . + uv run --locked --no-sync --no-build ruff format --check . + uv run --locked --no-sync --no-build pytest - name: Build distributions run: uv build - name: Check distribution metadata @@ -55,4 +64,4 @@ jobs: name: release-dists path: dist/ - name: Publish to PyPI - uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # release/v1 + uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2 diff --git a/MANIFEST.in b/MANIFEST.in index cd8dfca..e523c58 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,2 +1,2 @@ include LICENSE README.md -recursive-include examples *.yaml *.md *.json *.csv *.py *.sh +recursive-include examples *.yaml *.md *.json *.csv *.py *.sh *.txt diff --git a/README.md b/README.md index 2039373..ce13ca0 100644 --- a/README.md +++ b/README.md @@ -127,3 +127,7 @@ The [synthetic integration example](examples/entitylinkage-coverage/README.md) d ## License EvidenceMatrix is distributed under the [Apache License 2.0](LICENSE). + +## Maintenance + +See [maintenance conventions](docs/maintenance.md) for dependency updates, required CI, Action pinning and release validation. diff --git a/docs/maintenance.md b/docs/maintenance.md new file mode 100644 index 0000000..807d60c --- /dev/null +++ b/docs/maintenance.md @@ -0,0 +1,11 @@ +# Maintenance + +Dependency and GitHub Actions updates are proposed weekly by Dependabot (the native `uv` ecosystem maintains `uv.lock`), with grouped updates and a small open-PR limit. Review behavior changes and merge only after required CI passes; automatic merging and mandatory human approvals are not configured. + +External Actions are pinned to verified full commit SHAs with readable version comments. Update the SHA and comment together. Pinning an Action implementation does not freeze a Rust stable toolchain or every transitive package; committed lockfiles define the resolved test dependencies. Isolated build-backend requirements and clean-wheel consumer dependencies can still resolve separately; these checks do not assert bitwise reproducible builds. + +Main should reject force pushes and deletion and require a pull request with the always-running CI checks listed below. No human approval is required. Required checks must not use workflow-level PR path filters, which can leave documentation or dependency PRs pending indefinitely. Keep check names stable or migrate the ruleset when changing them. + +Release tags must match package and Action binary versions where applicable. Validate tests, build artifacts, metadata and clean installs before publishing. Python packages use PyPI Trusted Publishing; binary Actions verify the selected release archive against its SHA256SUMS before running it. Never replace assets on an already published release. Versioned integration dependencies are updated explicitly and compatibility is checked before adoption. + +Required CI: `Python 3.11`, `Python 3.12` and `Python 3.13`. CI installs the built wheel and runs the EntityLinkage coverage adapter with the version in `examples/entitylinkage-coverage/requirements.txt`. Ambiguous and unresolved links remain review findings; missing relationships remain unknown without an explicit coverage declaration. diff --git a/examples/entitylinkage-coverage/README.md b/examples/entitylinkage-coverage/README.md index 7df890e..5bd470b 100644 --- a/examples/entitylinkage-coverage/README.md +++ b/examples/entitylinkage-coverage/README.md @@ -7,7 +7,7 @@ This fully synthetic example links fictional external catalog records to a small Install the two standalone tools: ```bash -python -m pip install 'entitylinkage==0.1.0' 'evidencematrix==0.1.1' +python -m pip install -r examples/entitylinkage-coverage/requirements.txt 'evidencematrix==0.1.1' bash examples/entitylinkage-coverage/run-example.sh ``` diff --git a/examples/entitylinkage-coverage/requirements.txt b/examples/entitylinkage-coverage/requirements.txt new file mode 100644 index 0000000..1509137 --- /dev/null +++ b/examples/entitylinkage-coverage/requirements.txt @@ -0,0 +1 @@ +entitylinkage==0.1.1