usecaseapi 1.1.0__tar.gz → 1.1.2__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.
Files changed (80) hide show
  1. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/PKG-INFO +3 -3
  2. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/README.md +1 -1
  3. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/RELEASE.md +6 -5
  4. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/docs/pypi-publishing.md +5 -3
  5. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/pyproject.toml +2 -2
  6. usecaseapi-1.1.2/tests/test_release_workflow.py +37 -0
  7. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/.gitignore +0 -0
  8. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/CODE_OF_CONDUCT.md +0 -0
  9. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/CONTRIBUTING.md +0 -0
  10. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/LICENSE +0 -0
  11. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/SECURITY.md +0 -0
  12. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/docs/api-reference.md +0 -0
  13. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/docs/assets/brand/favicon-128.png +0 -0
  14. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/docs/assets/brand/favicon-16.png +0 -0
  15. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/docs/assets/brand/favicon-180.png +0 -0
  16. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/docs/assets/brand/favicon-192.png +0 -0
  17. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/docs/assets/brand/favicon-256.png +0 -0
  18. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/docs/assets/brand/favicon-32.png +0 -0
  19. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/docs/assets/brand/favicon-48.png +0 -0
  20. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/docs/assets/brand/favicon-512.png +0 -0
  21. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/docs/assets/brand/favicon-64.png +0 -0
  22. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/docs/assets/brand/favicon.ico +0 -0
  23. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/docs/assets/brand/icon-circle-dark.png +0 -0
  24. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/docs/assets/brand/icon-circle-light.png +0 -0
  25. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/docs/assets/brand/icon-horizontal-on-dark.png +0 -0
  26. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/docs/assets/brand/icon-square-dark.png +0 -0
  27. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/docs/assets/brand/icon-square-light.png +0 -0
  28. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/docs/assets/brand/logo-on-dark.png +0 -0
  29. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/docs/assets/brand/logo.png +0 -0
  30. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/docs/assets/brand/mark-circle-light.png +0 -0
  31. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/docs/assets/brand/mark-circle.png +0 -0
  32. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/docs/assets/brand/mark-square-dark.png +0 -0
  33. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/docs/assets/brand/mark-square.png +0 -0
  34. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/docs/design.md +0 -0
  35. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/docs/integrations.md +0 -0
  36. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/docs/llm-manifest-prompt.md +0 -0
  37. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/docs/manifest.md +0 -0
  38. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/docs/quickstart.md +0 -0
  39. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/docs/scaffold.md +0 -0
  40. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/docs/testing.md +0 -0
  41. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/docs/versioning.md +0 -0
  42. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/examples/basic/README.md +0 -0
  43. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/examples/basic/src/commerce/__init__.py +0 -0
  44. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/examples/basic/src/commerce/usecases/__init__.py +0 -0
  45. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/examples/basic/src/commerce/usecases/check_availability/__init__.py +0 -0
  46. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/examples/basic/src/commerce/usecases/check_availability/v1/__init__.py +0 -0
  47. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/examples/basic/src/commerce/usecases/check_availability/v1/check_availability_contract.py +0 -0
  48. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/examples/basic/src/commerce/usecases/check_availability/v1/check_availability_usecase.py +0 -0
  49. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/examples/basic/src/commerce/usecases/checkout/__init__.py +0 -0
  50. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/examples/basic/src/commerce/usecases/checkout/v1/__init__.py +0 -0
  51. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/examples/basic/src/commerce/usecases/checkout/v1/checkout_contract.py +0 -0
  52. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/examples/basic/src/commerce/usecases/checkout/v1/checkout_usecase.py +0 -0
  53. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/examples/basic/src/commerce/usecases/place_order/__init__.py +0 -0
  54. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/examples/basic/src/commerce/usecases/place_order/v1/__init__.py +0 -0
  55. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/examples/basic/src/commerce/usecases/place_order/v1/place_order_contract.py +0 -0
  56. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/examples/basic/src/commerce/usecases/place_order/v1/place_order_usecase.py +0 -0
  57. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/examples/basic/src/composition.py +0 -0
  58. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/examples/basic/tests/commerce/usecases/check_availability/v1/test_check_availability.py +0 -0
  59. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/examples/basic/tests/commerce/usecases/checkout/v1/test_checkout.py +0 -0
  60. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/examples/basic/tests/commerce/usecases/place_order/v1/test_place_order.py +0 -0
  61. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/examples/basic/tests/conftest.py +0 -0
  62. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/examples/basic/usecaseapi.ucase.yaml +0 -0
  63. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/schema/usecaseapi.manifest.v1.schema.yaml +0 -0
  64. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/scripts/verify_distribution.py +0 -0
  65. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/scripts/write_coverage_pr_comment.py +0 -0
  66. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/scripts/write_coverage_summary.py +0 -0
  67. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/src/usecaseapi/__init__.py +0 -0
  68. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/src/usecaseapi/api.py +0 -0
  69. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/src/usecaseapi/cli.py +0 -0
  70. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/src/usecaseapi/contracts.py +0 -0
  71. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/src/usecaseapi/errors.py +0 -0
  72. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/src/usecaseapi/manifest.py +0 -0
  73. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/src/usecaseapi/model.py +0 -0
  74. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/src/usecaseapi/py.typed +0 -0
  75. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/src/usecaseapi/scaffold.py +0 -0
  76. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/tests/test_call.py +0 -0
  77. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/tests/test_coverage_pr_comment.py +0 -0
  78. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/tests/test_full_service_validation.py +0 -0
  79. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/tests/test_manifest.py +0 -0
  80. {usecaseapi-1.1.0 → usecaseapi-1.1.2}/tests/test_snapshot_docs_scaffold.py +0 -0
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: usecaseapi
3
- Version: 1.1.0
4
- Summary: FastAPI-style contracts for Python application use cases.
3
+ Version: 1.1.2
4
+ Summary: Code-first, OpenAPI-inspired contracts for same-process Python 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
7
7
  Project-URL: Repository, https://github.com/Wisteria30/usecaseapi
@@ -42,7 +42,7 @@ Description-Content-Type: text/markdown
42
42
  </p>
43
43
 
44
44
  <p align="center">
45
- <em>FastAPI-style contracts for same-process Python application use cases.</em>
45
+ <em>Code-first, OpenAPI-inspired contracts for same-process Python use cases.</em>
46
46
  </p>
47
47
 
48
48
  <p align="center">
@@ -5,7 +5,7 @@
5
5
  </p>
6
6
 
7
7
  <p align="center">
8
- <em>FastAPI-style contracts for same-process Python application use cases.</em>
8
+ <em>Code-first, OpenAPI-inspired contracts for same-process Python use cases.</em>
9
9
  </p>
10
10
 
11
11
  <p align="center">
@@ -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, and publishes to
38
- PyPI. Pushing a matching `v*` tag or running the workflow manually also publishes
39
- the current package version.
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 also supports pushed tags
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
 
@@ -4,8 +4,8 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "usecaseapi"
7
- version = "1.1.0"
8
- description = "FastAPI-style contracts for Python application use cases."
7
+ version = "1.1.2"
8
+ description = "Code-first, OpenAPI-inspired contracts for same-process Python use cases."
9
9
  readme = "README.md"
10
10
  license = "MIT"
11
11
  license-files = ["LICENSE"]
@@ -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