usecaseapi 1.1.0__tar.gz → 1.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/PKG-INFO +1 -1
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/RELEASE.md +6 -5
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/docs/pypi-publishing.md +5 -3
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/pyproject.toml +1 -1
- usecaseapi-1.1.1/tests/test_release_workflow.py +37 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/.gitignore +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/CODE_OF_CONDUCT.md +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/CONTRIBUTING.md +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/LICENSE +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/README.md +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/SECURITY.md +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/docs/api-reference.md +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/docs/assets/brand/favicon-128.png +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/docs/assets/brand/favicon-16.png +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/docs/assets/brand/favicon-180.png +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/docs/assets/brand/favicon-192.png +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/docs/assets/brand/favicon-256.png +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/docs/assets/brand/favicon-32.png +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/docs/assets/brand/favicon-48.png +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/docs/assets/brand/favicon-512.png +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/docs/assets/brand/favicon-64.png +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/docs/assets/brand/favicon.ico +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/docs/assets/brand/icon-circle-dark.png +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/docs/assets/brand/icon-circle-light.png +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/docs/assets/brand/icon-horizontal-on-dark.png +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/docs/assets/brand/icon-square-dark.png +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/docs/assets/brand/icon-square-light.png +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/docs/assets/brand/logo-on-dark.png +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/docs/assets/brand/logo.png +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/docs/assets/brand/mark-circle-light.png +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/docs/assets/brand/mark-circle.png +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/docs/assets/brand/mark-square-dark.png +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/docs/assets/brand/mark-square.png +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/docs/design.md +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/docs/integrations.md +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/docs/llm-manifest-prompt.md +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/docs/manifest.md +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/docs/quickstart.md +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/docs/scaffold.md +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/docs/testing.md +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/docs/versioning.md +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/examples/basic/README.md +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/examples/basic/src/commerce/__init__.py +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/examples/basic/src/commerce/usecases/__init__.py +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/examples/basic/src/commerce/usecases/check_availability/__init__.py +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/examples/basic/src/commerce/usecases/check_availability/v1/__init__.py +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/examples/basic/src/commerce/usecases/check_availability/v1/check_availability_contract.py +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/examples/basic/src/commerce/usecases/check_availability/v1/check_availability_usecase.py +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/examples/basic/src/commerce/usecases/checkout/__init__.py +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/examples/basic/src/commerce/usecases/checkout/v1/__init__.py +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/examples/basic/src/commerce/usecases/checkout/v1/checkout_contract.py +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/examples/basic/src/commerce/usecases/checkout/v1/checkout_usecase.py +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/examples/basic/src/commerce/usecases/place_order/__init__.py +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/examples/basic/src/commerce/usecases/place_order/v1/__init__.py +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/examples/basic/src/commerce/usecases/place_order/v1/place_order_contract.py +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/examples/basic/src/commerce/usecases/place_order/v1/place_order_usecase.py +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/examples/basic/src/composition.py +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/examples/basic/tests/commerce/usecases/check_availability/v1/test_check_availability.py +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/examples/basic/tests/commerce/usecases/checkout/v1/test_checkout.py +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/examples/basic/tests/commerce/usecases/place_order/v1/test_place_order.py +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/examples/basic/tests/conftest.py +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/examples/basic/usecaseapi.ucase.yaml +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/schema/usecaseapi.manifest.v1.schema.yaml +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/scripts/verify_distribution.py +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/scripts/write_coverage_pr_comment.py +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/scripts/write_coverage_summary.py +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/src/usecaseapi/__init__.py +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/src/usecaseapi/api.py +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/src/usecaseapi/cli.py +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/src/usecaseapi/contracts.py +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/src/usecaseapi/errors.py +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/src/usecaseapi/manifest.py +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/src/usecaseapi/model.py +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/src/usecaseapi/py.typed +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/src/usecaseapi/scaffold.py +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/tests/test_call.py +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/tests/test_coverage_pr_comment.py +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/tests/test_full_service_validation.py +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/tests/test_manifest.py +0 -0
- {usecaseapi-1.1.0 → usecaseapi-1.1.1}/tests/test_snapshot_docs_scaffold.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: usecaseapi
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.1
|
|
4
4
|
Summary: FastAPI-style contracts for Python application use cases.
|
|
5
5
|
Project-URL: Homepage, https://github.com/Wisteria30/usecaseapi
|
|
6
6
|
Project-URL: Documentation, https://github.com/Wisteria30/usecaseapi/tree/main/docs
|
|
@@ -34,9 +34,10 @@ The `src/usecaseapi/__init__.py` module intentionally does not define
|
|
|
34
34
|
Publishing is handled by `.github/workflows/release.yml`.
|
|
35
35
|
|
|
36
36
|
On `main`, the workflow detects changes to `pyproject.toml` `[project].version`,
|
|
37
|
-
validates the package, creates the annotated `v{version}` tag,
|
|
38
|
-
|
|
39
|
-
the
|
|
37
|
+
validates the package, creates the annotated `v{version}` tag, creates a GitHub
|
|
38
|
+
Release with generated release notes and distribution artifacts, and publishes
|
|
39
|
+
to PyPI. Pushing a matching `v*` tag or running the workflow manually also
|
|
40
|
+
publishes the current package version.
|
|
40
41
|
|
|
41
42
|
The workflow expects PyPI Trusted Publishing:
|
|
42
43
|
|
|
@@ -55,5 +56,5 @@ The workflow uses GitHub OIDC and `uv publish`; no PyPI API token should be stor
|
|
|
55
56
|
4. Create the `pypi` GitHub environment and require approval if desired.
|
|
56
57
|
5. Review the generated package metadata and README rendering locally.
|
|
57
58
|
6. Update `pyproject.toml` `[project].version` and changelog or GitHub release notes.
|
|
58
|
-
7. Merge the version bump to `main`; GitHub Actions creates the annotated tag and publishes.
|
|
59
|
-
8. Confirm the GitHub Actions release workflow completed and the PyPI project page is correct.
|
|
59
|
+
7. Merge the version bump to `main`; GitHub Actions creates the annotated tag, creates the GitHub Release, and publishes.
|
|
60
|
+
8. Confirm the GitHub Actions release workflow completed, the GitHub Release is correct, and the PyPI project page is correct.
|
|
@@ -12,13 +12,15 @@ This repository is prepared for PyPI publishing through GitHub Actions and PyPI
|
|
|
12
12
|
- `trusted-publishing = "always"` is configured so release publishing fails if OIDC publishing is unavailable.
|
|
13
13
|
- `pyproject.toml` `[project].version` is the release source of truth.
|
|
14
14
|
- `.github/workflows/release.yml` creates `v{version}` when the project version changes on `main`.
|
|
15
|
+
- `.github/workflows/release.yml` creates a GitHub Release with generated notes and distribution artifacts before publishing.
|
|
15
16
|
- `.github/workflows/release.yml` validates tests, coverage, typing, linting, metadata, wheel install, source distribution install, and then publishes.
|
|
16
17
|
- `.github/workflows/ci.yml` reports coverage in the GitHub Actions job summary for pull requests.
|
|
17
18
|
|
|
18
19
|
## Release workflow contract
|
|
19
20
|
|
|
20
21
|
The release workflow watches `main` and creates an annotated `v{version}` tag
|
|
21
|
-
when `pyproject.toml` `[project].version` changes. It
|
|
22
|
+
when `pyproject.toml` `[project].version` changes. It then creates a GitHub
|
|
23
|
+
Release for that tag before publishing to PyPI. It also supports pushed tags
|
|
22
24
|
matching `v*` and manual dispatch.
|
|
23
25
|
|
|
24
26
|
The PyPI Trusted Publisher should match:
|
|
@@ -38,8 +40,8 @@ The PyPI Trusted Publisher should match:
|
|
|
38
40
|
6. Confirm project ownership metadata, maintainer identity, and support expectations.
|
|
39
41
|
7. Update the release version in `pyproject.toml`.
|
|
40
42
|
8. Prepare release notes.
|
|
41
|
-
9. Merge the version bump to `main`; GitHub Actions creates the release tag and publishes.
|
|
42
|
-
10. Review the published PyPI page, verified project links, files, and installation instructions.
|
|
43
|
+
9. Merge the version bump to `main`; GitHub Actions creates the release tag, creates the GitHub Release, and publishes.
|
|
44
|
+
10. Review the GitHub Release, published PyPI page, verified project links, files, and installation instructions.
|
|
43
45
|
|
|
44
46
|
## Local validation command
|
|
45
47
|
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""Release workflow contract tests."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
import yaml
|
|
9
|
+
|
|
10
|
+
WORKFLOW_PATH = Path(__file__).resolve().parents[1] / ".github" / "workflows" / "release.yml"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def load_release_workflow() -> dict[str, Any]:
|
|
14
|
+
"""Load the release workflow as structured YAML."""
|
|
15
|
+
workflow = yaml.safe_load(WORKFLOW_PATH.read_text(encoding="utf-8"))
|
|
16
|
+
assert isinstance(workflow, dict)
|
|
17
|
+
return workflow
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def test_publish_job_creates_github_release_before_publishing_to_pypi() -> None:
|
|
21
|
+
"""Publishing creates a GitHub Release for the version tag before PyPI upload."""
|
|
22
|
+
workflow = load_release_workflow()
|
|
23
|
+
steps = workflow["jobs"]["publish"]["steps"]
|
|
24
|
+
step_names = [step.get("name", "") for step in steps]
|
|
25
|
+
|
|
26
|
+
tag_step_index = step_names.index("Create release tag")
|
|
27
|
+
release_step_index = step_names.index("Create GitHub release")
|
|
28
|
+
publish_step_index = step_names.index("Publish")
|
|
29
|
+
|
|
30
|
+
assert tag_step_index < release_step_index < publish_step_index
|
|
31
|
+
|
|
32
|
+
release_step = steps[release_step_index]
|
|
33
|
+
assert release_step["env"]["GH_TOKEN"] == "${{ github.token }}"
|
|
34
|
+
assert release_step["env"]["TAG_NAME"] == "${{ needs.check-version.outputs.tag_name }}"
|
|
35
|
+
assert 'gh release create "$TAG_NAME"' in release_step["run"]
|
|
36
|
+
assert "--verify-tag" in release_step["run"]
|
|
37
|
+
assert "--generate-notes" in release_step["run"]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{usecaseapi-1.1.0 → usecaseapi-1.1.1}/examples/basic/src/commerce/usecases/checkout/__init__.py
RENAMED
|
File without changes
|
{usecaseapi-1.1.0 → usecaseapi-1.1.1}/examples/basic/src/commerce/usecases/checkout/v1/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{usecaseapi-1.1.0 → usecaseapi-1.1.1}/examples/basic/src/commerce/usecases/place_order/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|