openapi-client-codegen 0.1.12__tar.gz → 0.1.14__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.
- openapi_client_codegen-0.1.14/.github/workflows/ci-cd.yml +98 -0
- {openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/AGENTS.md +2 -2
- {openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/PKG-INFO +1 -1
- {openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/pyproject.toml +4 -3
- openapi_client_codegen-0.1.14/release-devkit.yaml +8 -0
- {openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/src/openapi_client_codegen/cli.py +15 -1
- {openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/tests/test_cli.py +36 -0
- {openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/uv.lock +57 -3
- openapi_client_codegen-0.1.12/.github/workflows/ci.yml +0 -26
- openapi_client_codegen-0.1.12/.github/workflows/release.yml +0 -31
- openapi_client_codegen-0.1.12/release-devkit.json +0 -10
- {openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/.gitattributes +0 -0
- {openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/.gitignore +0 -0
- {openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/.python-version +0 -0
- {openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/CLAUDE.md +0 -0
- {openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/LICENSE +0 -0
- {openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/NOTICE +0 -0
- {openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/README.md +0 -0
- {openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/ruff.base.toml +0 -0
- {openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/ruff.toml +0 -0
- {openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/src/openapi_client_codegen/__init__.py +0 -0
- {openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/src/openapi_client_codegen/_data/configs/csharp.json +0 -0
- {openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/src/openapi_client_codegen/_data/configs/python.json +0 -0
- {openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/src/openapi_client_codegen/_data/openapi-generator-ignore +0 -0
- {openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/src/openapi_client_codegen/_data/templates-patches/csharp/0001-csharp-remove-errant-comma.patch +0 -0
- {openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/src/openapi_client_codegen/_data/templates-patches/csharp/0002-csharp-models-required-only-constructors.patch +0 -0
- {openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/src/openapi_client_codegen/_data/templates-patches/csharp/0003-csharp-httpclient-use-defaultT.patch +0 -0
- {openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/src/openapi_client_codegen/_data/templates-patches/csharp/0004-csharp-support-hybrid-multipart-payloads.patch +0 -0
- {openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/src/openapi_client_codegen/_data/templates-patches/csharp/0006-csharp-streaming-download-response.patch +0 -0
- {openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/src/openapi_client_codegen/_data/templates-patches/csharp/0007-csharp-model-default-initializers.patch +0 -0
- {openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/src/openapi_client_codegen/_data/templates-patches/csharp/0008-csharp-redirect-documentation-file.patch +0 -0
- {openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/src/openapi_client_codegen/client.py +0 -0
- {openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/src/openapi_client_codegen/downgrade.py +0 -0
- {openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/src/openapi_client_codegen/orchestrator.py +0 -0
- {openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/src/openapi_client_codegen/py.typed +0 -0
- {openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/src/openapi_client_codegen/resources.py +0 -0
- {openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/src/openapi_client_codegen/templates.py +0 -0
- {openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/src/openapi_client_codegen/unity.py +0 -0
- {openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/tests/test_config.py +0 -0
- {openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/tests/test_downgrade.py +0 -0
- {openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/tests/test_orchestrate.py +0 -0
- {openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/tests/test_unity.py +0 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
name: CI/CD
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
push:
|
|
6
|
+
branches: [main, dev]
|
|
7
|
+
pull_request:
|
|
8
|
+
branches: [dev]
|
|
9
|
+
|
|
10
|
+
# Cancel superseded runs on the same branch, except main — where publish-stable
|
|
11
|
+
# must never die mid-release (overlapping release merges queue instead).
|
|
12
|
+
concurrency:
|
|
13
|
+
group: ci-${{ github.ref }}
|
|
14
|
+
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
|
|
15
|
+
|
|
16
|
+
permissions:
|
|
17
|
+
contents: read
|
|
18
|
+
|
|
19
|
+
env:
|
|
20
|
+
RELEASE_DEVKIT_VERSION: 0.1.25
|
|
21
|
+
|
|
22
|
+
jobs:
|
|
23
|
+
check:
|
|
24
|
+
if: github.ref != 'refs/heads/main'
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v5
|
|
28
|
+
with:
|
|
29
|
+
fetch-depth: 0
|
|
30
|
+
fetch-tags: true
|
|
31
|
+
persist-credentials: false
|
|
32
|
+
- uses: astral-sh/setup-uv@v7
|
|
33
|
+
with:
|
|
34
|
+
enable-cache: true
|
|
35
|
+
- run: uv run preflight-python
|
|
36
|
+
- shell: bash
|
|
37
|
+
run: uvx --from release-devkit==${{ env.RELEASE_DEVKIT_VERSION }} publish-stable --dry-run
|
|
38
|
+
|
|
39
|
+
ensure-release-pr:
|
|
40
|
+
if: github.event_name == 'push' && github.ref == 'refs/heads/dev'
|
|
41
|
+
runs-on: ubuntu-latest
|
|
42
|
+
permissions:
|
|
43
|
+
contents: write
|
|
44
|
+
pull-requests: write
|
|
45
|
+
env:
|
|
46
|
+
GH_TOKEN: ${{ github.token }}
|
|
47
|
+
steps:
|
|
48
|
+
- uses: actions/checkout@v5
|
|
49
|
+
with:
|
|
50
|
+
fetch-depth: 0
|
|
51
|
+
fetch-tags: true
|
|
52
|
+
persist-credentials: false
|
|
53
|
+
- uses: astral-sh/setup-uv@v7
|
|
54
|
+
- shell: bash
|
|
55
|
+
run: uvx --from release-devkit==${{ env.RELEASE_DEVKIT_VERSION }} ensure-release-pr
|
|
56
|
+
|
|
57
|
+
publish-stable:
|
|
58
|
+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
59
|
+
runs-on: ubuntu-latest
|
|
60
|
+
environment: release
|
|
61
|
+
permissions:
|
|
62
|
+
contents: write
|
|
63
|
+
id-token: write
|
|
64
|
+
env:
|
|
65
|
+
GH_TOKEN: ${{ github.token }}
|
|
66
|
+
steps:
|
|
67
|
+
- uses: actions/checkout@v5
|
|
68
|
+
with:
|
|
69
|
+
ref: main
|
|
70
|
+
fetch-depth: 0
|
|
71
|
+
fetch-tags: true
|
|
72
|
+
- uses: astral-sh/setup-uv@v7
|
|
73
|
+
- shell: bash
|
|
74
|
+
run: uvx --from release-devkit==${{ env.RELEASE_DEVKIT_VERSION }} publish-stable
|
|
75
|
+
env:
|
|
76
|
+
NPM_CONFIG_LOGLEVEL: verbose
|
|
77
|
+
|
|
78
|
+
publish-dev:
|
|
79
|
+
if: github.event_name == 'push' && github.ref == 'refs/heads/dev'
|
|
80
|
+
needs: [check]
|
|
81
|
+
runs-on: ubuntu-latest
|
|
82
|
+
environment: release
|
|
83
|
+
permissions:
|
|
84
|
+
contents: read
|
|
85
|
+
id-token: write
|
|
86
|
+
env:
|
|
87
|
+
GH_TOKEN: ${{ github.token }}
|
|
88
|
+
steps:
|
|
89
|
+
- uses: actions/checkout@v5
|
|
90
|
+
with:
|
|
91
|
+
fetch-depth: 0
|
|
92
|
+
fetch-tags: true
|
|
93
|
+
persist-credentials: false
|
|
94
|
+
- uses: astral-sh/setup-uv@v7
|
|
95
|
+
- shell: bash
|
|
96
|
+
run: uvx --from release-devkit==${{ env.RELEASE_DEVKIT_VERSION }} publish-dev
|
|
97
|
+
env:
|
|
98
|
+
NPM_CONFIG_LOGLEVEL: verbose
|
|
@@ -8,7 +8,7 @@ The package is `openapi_client_codegen` (src-layout under `src/openapi_client_co
|
|
|
8
8
|
|
|
9
9
|
## Release flow
|
|
10
10
|
|
|
11
|
-
Publishing rides `
|
|
11
|
+
Publishing rides `ci-cd.yml`, which combines CI and release: `check` runs `preflight-python` from the python-devkit dev dependency then `publish-stable --dry-run` as its trailing step, and the publish jobs (`publish-stable`, `publish-dev`, `ensure-release-pr`) run release-devkit's verbs as inlined `uvx --from release-devkit==${{ env.RELEASE_DEVKIT_VERSION }}` steps, version-pinned in the workflow `env:` (see release-devkit's `AGENTS.md`), never a project dependency (openapi-client-codegen sits inside release-devkit's transitive dependency graph; a project-level edge is a resolver cycle). The dev channel (`publish-dev` on `dev` push, an in-run job gated on `check`) ships immutable `-dev.<run-id>` prereleases; `ensure-release-pr` maintains the standing `dev` → `main` release-PR gate; `publish-stable` runs on `main` push under OIDC trusted publishing (publisher bound to `ci-cd.yml`, `release` environment). The committed `pyproject.toml` version is permanently the `0.0.0.dev0` sentinel; the `openapi-client-codegen-v*` tags are the version ledger (declared `major_minor` line in `release-devkit.yaml`, patch-auto within the line). API-breaking changes ship with a manually bumped `major_minor` — patch-auto assumes additive changes.
|
|
12
12
|
|
|
13
13
|
## Public API
|
|
14
14
|
|
|
@@ -20,7 +20,7 @@ The package init is empty (RUF067 strict mode — the canonical ruff config bans
|
|
|
20
20
|
| `ProjectsConfig` | The pydantic schema of a consumer's client-generation config (`extra="forbid"`): required `projects`, `root_name`, `generated_root`, `spec_command`, `requires`; optional `spec_env`, `npm_scope`, `license_spdx`, `repository_url`. `requires` is a PEP 440 specifier; `load_config` self-checks the installed version and refuses outside range; the `0.0.0.dev0` sentinel bypasses the *check*, not the field's presence (omission is a validation error; "no constraint" is explicit `requires: ">=0.0"`). The single source of identity — the CLI validates the `--config` file into it and consumes it; nothing overrides it per invocation. |
|
|
21
21
|
| `load_config(path)` | Parse the consumer's root YAML config into a `ProjectsConfig` (strictyaml, scalars as strings) and enforce the required `requires` version self-check. |
|
|
22
22
|
| `SpecProducer(command, env=None)` | Callable class wrapping any command that prints the spec to stdout, run with the project directory as cwd and an optional per-call env overlay; the CLI command builds it from the config's `spec_command` / `spec_env`, and programmatic consumers construct it directly. |
|
|
23
|
-
| `app` | The single-command CLI (invoked directly, no subcommand) behind the `openapi-client-codegen` console script and consumer `[project.scripts]` aliases (e.g. placeframe's `generate-clients`). It validates the `--config` YAML against the `ProjectsConfig` pydantic model (via `load_config`) (`extra="forbid"`: unknown keys rejected — a `ValidationError` propagates) and then runs the whole orchestration itself: per mapping entry (`projects` maps project paths to generator lists), produce the spec via `SpecProducer`, downgrade it, write `<project>/openapi.json` unless byte-identical to the committed spec (`no_cache` forces through), and `generate_client` per listed generator into `<generated_root>/<generator>/<names.base>`. The flags are invocation-scoped only (filters, `--no-cache`, `--root`; project paths resolve against `root`). Commands run shell-less (shlex-split, operators rejected), so env gating is the structured `spec_env`, never a `VAR=…` prefix. |
|
|
23
|
+
| `app` | The single-command CLI (invoked directly, no subcommand) behind the `openapi-client-codegen` console script and consumer `[project.scripts]` aliases (e.g. placeframe's `generate-clients`). It validates the `--config` YAML against the `ProjectsConfig` pydantic model (via `load_config`) (`extra="forbid"`: unknown keys rejected — a `ValidationError` propagates) and then runs the whole orchestration itself: per mapping entry (`projects` maps project paths to generator lists), produce the spec via `SpecProducer`, downgrade it, write `<project>/openapi.json` unless byte-identical to the committed spec (`no_cache` forces through), and `generate_client` per listed generator into `<generated_root>/<generator>/<names.base>`. The flags are invocation-scoped only (filters, `--no-cache`, `--check`, `--root`; project paths resolve against `root`). `--check` forces an unconditional regen and fails if any spec or generated client differs from the committed tree — the staleness gate consumers run in CI; the checked paths are fully derived from `ProjectsConfig` (every `<project>/openapi.json` plus `generated_root`), no per-consumer path args. Commands run shell-less (shlex-split, operators rejected), so env gating is the structured `spec_env`, never a `VAR=…` prefix. |
|
|
24
24
|
| `regenerate_templates(target_dir, extra_patches_dir=None)` | Author the C# templates into `target_dir/csharp` and apply the shipped (then optional extra) patches. |
|
|
25
25
|
| `generate_client(spec, generator, output_dir, names, templates_dir=None, extra_references=None, npm_scope=None, license_spdx=None, repository_url=None)` | Run the generator for one `(spec, generator)` and sync the result into `output_dir`. `templates_dir` is required for `csharp`. For csharp, `npm_scope` composes the UPM identity `{scope}.{base-minus-dashes}` (e.g. `org.outernet.placeframe.apiclient`); unset falls back to the legacy `org.nuget.{camel-lower}` identity. `license_spdx` / `repository_url` populate the manifest's `license` / `repository` fields when given. |
|
|
26
26
|
| `write_unity_package_metadata(package_dir, package_name, extra_references=None, npm_name=None, license_spdx=None, repository_url=None)` | Write `package.json` / `.asmdef` / `csc.rsp` / `Directory.Build.props`. Called by `generate_client` for csharp. |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: openapi-client-codegen
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.14
|
|
4
4
|
Summary: OpenAPI client-generation wrapper: Litestar spec dump, 3.1->3.0 downgrade, patched openapi-generator templates, Unity package metadata
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
License-File: NOTICE
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "openapi-client-codegen"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.14"
|
|
4
4
|
description = "OpenAPI client-generation wrapper: Litestar spec dump, 3.1->3.0 downgrade, patched openapi-generator templates, Unity package metadata"
|
|
5
5
|
requires-python = ">=3.13"
|
|
6
6
|
dependencies = [
|
|
@@ -16,6 +16,7 @@ dev = [
|
|
|
16
16
|
"basedpyright>=1.39.10",
|
|
17
17
|
"ruff>=0.14.11",
|
|
18
18
|
"pytest>=8.0.0",
|
|
19
|
+
"python-devkit>=0.1.0",
|
|
19
20
|
"pyyaml>=6.0.3",
|
|
20
21
|
"types-pyyaml>=6.0.12.20260906",
|
|
21
22
|
"types-strictyaml>=1.7.3.3",
|
|
@@ -31,8 +32,8 @@ openapi-client-codegen = "openapi_client_codegen.cli:app"
|
|
|
31
32
|
[tool.hatch.build.targets.wheel]
|
|
32
33
|
packages = ["src/openapi_client_codegen"]
|
|
33
34
|
include = [
|
|
34
|
-
"src/
|
|
35
|
-
"src/
|
|
35
|
+
"src/openapi_client_codegen/py.typed",
|
|
36
|
+
"src/openapi_client_codegen/_data/**",
|
|
36
37
|
]
|
|
37
38
|
|
|
38
39
|
[tool.uv.sources]
|
{openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/src/openapi_client_codegen/cli.py
RENAMED
|
@@ -3,6 +3,7 @@ from pathlib import Path
|
|
|
3
3
|
from tempfile import TemporaryDirectory
|
|
4
4
|
from typing import Annotated
|
|
5
5
|
|
|
6
|
+
from bashrun.bash import bash, bash_output
|
|
6
7
|
from typer import Option, Typer
|
|
7
8
|
|
|
8
9
|
from .client import generate_client
|
|
@@ -23,11 +24,16 @@ def generate_projects_command(
|
|
|
23
24
|
no_cache: Annotated[
|
|
24
25
|
bool, Option("--no-cache", help="Regenerate even when the committed spec is unchanged")
|
|
25
26
|
] = False,
|
|
27
|
+
check: Annotated[
|
|
28
|
+
bool,
|
|
29
|
+
Option("--check", help="Regenerate, then fail if any spec or generated client differs from the committed tree"),
|
|
30
|
+
] = False,
|
|
26
31
|
root: Annotated[Path, Option(help="Repository root the project paths resolve against")] = Path(),
|
|
27
32
|
) -> None:
|
|
28
33
|
settings = load_config(config)
|
|
29
34
|
root = root.resolve()
|
|
30
35
|
dump_spec = SpecProducer(settings.spec_command, env=settings.spec_env)
|
|
36
|
+
regenerate = no_cache or check
|
|
31
37
|
|
|
32
38
|
with TemporaryDirectory() as templates_directory_string:
|
|
33
39
|
templates_directory = Path(templates_directory_string)
|
|
@@ -49,7 +55,7 @@ def generate_projects_command(
|
|
|
49
55
|
if spec_path.exists():
|
|
50
56
|
old_spec = spec_path.read_text(encoding="utf-8")
|
|
51
57
|
|
|
52
|
-
if openapi_spec == old_spec and not
|
|
58
|
+
if openapi_spec == old_spec and not regenerate:
|
|
53
59
|
print("OpenAPI spec unchanged, skipping client generation")
|
|
54
60
|
continue
|
|
55
61
|
|
|
@@ -78,3 +84,11 @@ def generate_projects_command(
|
|
|
78
84
|
license_spdx=settings.license_spdx,
|
|
79
85
|
repository_url=settings.repository_url,
|
|
80
86
|
)
|
|
87
|
+
|
|
88
|
+
if check:
|
|
89
|
+
pathspec = " ".join(f"{name}/openapi.json" for name in settings.projects) + f" {settings.generated_root}"
|
|
90
|
+
if bash_output(f"git status --porcelain -- {pathspec}", cwd=root).strip():
|
|
91
|
+
bash(f"git diff -- {pathspec}", cwd=root)
|
|
92
|
+
raise SystemExit(
|
|
93
|
+
"Generated OpenAPI specs/clients are stale; re-run this command without --check and commit the result."
|
|
94
|
+
)
|
|
@@ -27,6 +27,8 @@ FULL_SETTINGS: dict[str, object] = {
|
|
|
27
27
|
class Recorder:
|
|
28
28
|
def __init__(self) -> None:
|
|
29
29
|
self.generated: list[tuple[str, Path]] = []
|
|
30
|
+
self.git_commands: list[str] = []
|
|
31
|
+
self.git_dirty = False
|
|
30
32
|
|
|
31
33
|
def fake_bash_output(self, command: str, *, cwd: Path | None = None, env: dict[str, str] | None = None) -> str:
|
|
32
34
|
return json.dumps({"openapi": "3.1.0", "info": {"title": "demo", "version": "0.0.0"}, "paths": {}})
|
|
@@ -48,6 +50,13 @@ class Recorder:
|
|
|
48
50
|
) -> None:
|
|
49
51
|
self.generated.append((generator, output_dir))
|
|
50
52
|
|
|
53
|
+
def fake_git_status(self, command: str, *, cwd: Path | None = None, env: dict[str, str] | None = None) -> str:
|
|
54
|
+
self.git_commands.append(command)
|
|
55
|
+
return "M packages/generated/dummy\n" if self.git_dirty else ""
|
|
56
|
+
|
|
57
|
+
def fake_git_diff(self, command: str, *, cwd: Path | None = None, env: dict[str, str] | None = None) -> None:
|
|
58
|
+
self.git_commands.append(command)
|
|
59
|
+
|
|
51
60
|
|
|
52
61
|
@pytest.fixture
|
|
53
62
|
def recorder(monkeypatch: pytest.MonkeyPatch) -> Recorder:
|
|
@@ -55,6 +64,8 @@ def recorder(monkeypatch: pytest.MonkeyPatch) -> Recorder:
|
|
|
55
64
|
monkeypatch.setattr(orchestrator, "bash_output", recorder.fake_bash_output)
|
|
56
65
|
monkeypatch.setattr(cli, "regenerate_templates", recorder.fake_regenerate_templates)
|
|
57
66
|
monkeypatch.setattr(cli, "generate_client", recorder.fake_generate_client)
|
|
67
|
+
monkeypatch.setattr(cli, "bash_output", recorder.fake_git_status)
|
|
68
|
+
monkeypatch.setattr(cli, "bash", recorder.fake_git_diff)
|
|
58
69
|
return recorder
|
|
59
70
|
|
|
60
71
|
|
|
@@ -107,3 +118,28 @@ def test_missing_required_field_fails(tmp_path: Path, recorder: Recorder) -> Non
|
|
|
107
118
|
assert result.exit_code != 0
|
|
108
119
|
assert "spec_command" in str(result.exception)
|
|
109
120
|
assert recorder.generated == []
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def test_check_forces_regen_and_passes_when_clean(tmp_path: Path, recorder: Recorder) -> None:
|
|
124
|
+
config = write_config(tmp_path, FULL_SETTINGS)
|
|
125
|
+
(tmp_path / "docker" / "api").mkdir(parents=True)
|
|
126
|
+
|
|
127
|
+
result = runner.invoke(app, ["--config", str(config), "--root", str(tmp_path), "--check"])
|
|
128
|
+
|
|
129
|
+
assert result.exit_code == 0
|
|
130
|
+
assert [generator for generator, _ in recorder.generated] == ["python", "csharp"]
|
|
131
|
+
assert recorder.git_commands == ["git status --porcelain -- docker/api/openapi.json packages/generated"]
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def test_check_fails_when_tree_stale(tmp_path: Path, recorder: Recorder) -> None:
|
|
135
|
+
config = write_config(tmp_path, FULL_SETTINGS)
|
|
136
|
+
(tmp_path / "docker" / "api").mkdir(parents=True)
|
|
137
|
+
recorder.git_dirty = True
|
|
138
|
+
|
|
139
|
+
result = runner.invoke(app, ["--config", str(config), "--root", str(tmp_path), "--check"])
|
|
140
|
+
|
|
141
|
+
assert result.exit_code != 0
|
|
142
|
+
assert recorder.git_commands == [
|
|
143
|
+
"git status --porcelain -- docker/api/openapi.json packages/generated",
|
|
144
|
+
"git diff -- docker/api/openapi.json packages/generated",
|
|
145
|
+
]
|
|
@@ -34,11 +34,25 @@ wheels = [
|
|
|
34
34
|
|
|
35
35
|
[[package]]
|
|
36
36
|
name = "bashrun"
|
|
37
|
-
version = "0.1.
|
|
37
|
+
version = "0.1.12"
|
|
38
38
|
source = { registry = "https://pypi.org/simple" }
|
|
39
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
39
|
+
sdist = { url = "https://files.pythonhosted.org/packages/19/2c/742acb113293e712d82c5cfce35a30f344385a7d9852d5844b0bcff4f12f/bashrun-0.1.12.tar.gz", hash = "sha256:d5fd926ec1cb1df6e218a98fe8ad737c24b72bcf740bdfbe2ecf4c77894878a0", size = 32364, upload-time = "2026-09-30T04:02:19.854Z" }
|
|
40
40
|
wheels = [
|
|
41
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
41
|
+
{ url = "https://files.pythonhosted.org/packages/f6/1d/4de203dbe4d711b39f7b440bd141b429864e2a3539faa9b6531eab456195/bashrun-0.1.12-py3-none-any.whl", hash = "sha256:9a188b90eb25249d24556dcdaccfa09ca3efe741406a1c71c7e3cecd170f41b0", size = 7511, upload-time = "2026-09-30T04:02:18.991Z" },
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
[[package]]
|
|
45
|
+
name = "ci-devkit"
|
|
46
|
+
version = "0.1.14"
|
|
47
|
+
source = { registry = "https://pypi.org/simple" }
|
|
48
|
+
dependencies = [
|
|
49
|
+
{ name = "bashrun" },
|
|
50
|
+
{ name = "pydantic" },
|
|
51
|
+
{ name = "pydantic-settings" },
|
|
52
|
+
]
|
|
53
|
+
sdist = { url = "https://files.pythonhosted.org/packages/22/25/dc42c65e6147eb64477eae4f410b26d630f03f46c3d3bdcdab374df28081/ci_devkit-0.1.14.tar.gz", hash = "sha256:f8b45fa995bba626edda29c191883224173155a39137da5a1bc67f09ad28d337", size = 51204, upload-time = "2026-09-30T04:06:27.581Z" }
|
|
54
|
+
wheels = [
|
|
55
|
+
{ url = "https://files.pythonhosted.org/packages/4f/08/56cafd065e2d00ad90d450867282d79469bc4c7c9eefa1dc11dcf84e0c96/ci_devkit-0.1.14-py3-none-any.whl", hash = "sha256:64b74d797a040d8d57735eda30dbb59844d0de9c64e53dd24e9769d10bc34e18", size = 25689, upload-time = "2026-09-30T04:06:26.522Z" },
|
|
42
56
|
]
|
|
43
57
|
|
|
44
58
|
[[package]]
|
|
@@ -112,6 +126,7 @@ dependencies = [
|
|
|
112
126
|
dev = [
|
|
113
127
|
{ name = "basedpyright" },
|
|
114
128
|
{ name = "pytest" },
|
|
129
|
+
{ name = "python-devkit" },
|
|
115
130
|
{ name = "pyyaml" },
|
|
116
131
|
{ name = "ruff" },
|
|
117
132
|
{ name = "types-pyyaml" },
|
|
@@ -131,6 +146,7 @@ requires-dist = [
|
|
|
131
146
|
dev = [
|
|
132
147
|
{ name = "basedpyright", specifier = ">=1.39.10" },
|
|
133
148
|
{ name = "pytest", specifier = ">=8.0.0" },
|
|
149
|
+
{ name = "python-devkit", specifier = ">=0.1.0" },
|
|
134
150
|
{ name = "pyyaml", specifier = ">=6.0.3" },
|
|
135
151
|
{ name = "ruff", specifier = ">=0.14.11" },
|
|
136
152
|
{ name = "types-pyyaml", specifier = ">=6.0.12.20260906" },
|
|
@@ -226,6 +242,20 @@ wheels = [
|
|
|
226
242
|
{ url = "https://files.pythonhosted.org/packages/63/19/67830dda664e6bdf9285ee2e40f355d0d7d6b92aa0c42e8d217bb8d33d36/pydantic_core-2.46.5-cp314-cp314t-win_arm64.whl", hash = "sha256:acf8a67ba51f4ca9ddbd0e6b3000a65ac51ab734661778b3e7ba64d99a710f2f", size = 1989276, upload-time = "2026-08-28T10:00:16.984Z" },
|
|
227
243
|
]
|
|
228
244
|
|
|
245
|
+
[[package]]
|
|
246
|
+
name = "pydantic-settings"
|
|
247
|
+
version = "2.15.0"
|
|
248
|
+
source = { registry = "https://pypi.org/simple" }
|
|
249
|
+
dependencies = [
|
|
250
|
+
{ name = "pydantic" },
|
|
251
|
+
{ name = "python-dotenv" },
|
|
252
|
+
{ name = "typing-inspection" },
|
|
253
|
+
]
|
|
254
|
+
sdist = { url = "https://files.pythonhosted.org/packages/68/ca/31c57507b13119d7d3cfa1576dad2911a4861e3be07b579395f4e9d393f9/pydantic_settings-2.15.0.tar.gz", hash = "sha256:694b793e84f766ba76a90ebdefc01d0a9a045dab0382bee70393da93712ad117", size = 261253, upload-time = "2026-08-07T09:24:57.419Z" }
|
|
255
|
+
wheels = [
|
|
256
|
+
{ url = "https://files.pythonhosted.org/packages/30/a4/2bffa9f8e804325a09867f0e9d30795c80ea9f8d62560bd1b6ad6220eb2f/pydantic_settings-2.15.0-py3-none-any.whl", hash = "sha256:0ba092c291c94baceb5eff768aa0d56400a457585bc0175925a5a5510303da42", size = 69413, upload-time = "2026-08-07T09:24:55.839Z" },
|
|
257
|
+
]
|
|
258
|
+
|
|
229
259
|
[[package]]
|
|
230
260
|
name = "pygments"
|
|
231
261
|
version = "2.20.0"
|
|
@@ -263,6 +293,30 @@ wheels = [
|
|
|
263
293
|
{ url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" },
|
|
264
294
|
]
|
|
265
295
|
|
|
296
|
+
[[package]]
|
|
297
|
+
name = "python-devkit"
|
|
298
|
+
version = "0.1.15"
|
|
299
|
+
source = { registry = "https://pypi.org/simple" }
|
|
300
|
+
dependencies = [
|
|
301
|
+
{ name = "bashrun" },
|
|
302
|
+
{ name = "ci-devkit" },
|
|
303
|
+
{ name = "pydantic" },
|
|
304
|
+
{ name = "typer" },
|
|
305
|
+
]
|
|
306
|
+
sdist = { url = "https://files.pythonhosted.org/packages/82/53/c3b37f69c35475b09cdf1c18deb193238d7ab5143ee6bc97e5c22c48fe87/python_devkit-0.1.15.tar.gz", hash = "sha256:ac1ef0f2a4622e9c97763f4e353005c41164e2d6d4b130cdb709e811947f253d", size = 34651, upload-time = "2026-09-30T04:12:18.88Z" }
|
|
307
|
+
wheels = [
|
|
308
|
+
{ url = "https://files.pythonhosted.org/packages/b6/81/da4f76cbfccb5a4d5a58a9f51d3e2b7d40f6dc9edd931d7891b2789adeae/python_devkit-0.1.15-py3-none-any.whl", hash = "sha256:0c13684cc780e3ba9b3e25feed61065b355e8fc7436bee043e7c6adf71fa40e7", size = 14537, upload-time = "2026-09-30T04:12:17.918Z" },
|
|
309
|
+
]
|
|
310
|
+
|
|
311
|
+
[[package]]
|
|
312
|
+
name = "python-dotenv"
|
|
313
|
+
version = "1.2.3"
|
|
314
|
+
source = { registry = "https://pypi.org/simple" }
|
|
315
|
+
sdist = { url = "https://files.pythonhosted.org/packages/6a/53/ed9d74092561d4b01a2ef1349d52cdbc135e526c245f366b089cfca6de49/python_dotenv-1.2.3.tar.gz", hash = "sha256:a20a594dabeaa385725aa239d5244871c143ecb356add8a20fcf23773a6c3a35", size = 58945, upload-time = "2026-08-16T16:54:54.067Z" }
|
|
316
|
+
wheels = [
|
|
317
|
+
{ url = "https://files.pythonhosted.org/packages/0d/17/c5c6b53ddc18f297992099b3d9ec16c855c0ccc83263a21fe4d1c625ec6c/python_dotenv-1.2.3-py3-none-any.whl", hash = "sha256:904552145e8bfed22162c09dab1c2b9b54fefa7b23ba780f4f26ca0316b0f0d9", size = 22780, upload-time = "2026-08-16T16:54:52.473Z" },
|
|
318
|
+
]
|
|
319
|
+
|
|
266
320
|
[[package]]
|
|
267
321
|
name = "pyyaml"
|
|
268
322
|
version = "6.0.3"
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
name: CI
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches: [main]
|
|
6
|
-
pull_request:
|
|
7
|
-
branches: [main]
|
|
8
|
-
|
|
9
|
-
concurrency:
|
|
10
|
-
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
|
11
|
-
cancel-in-progress: true
|
|
12
|
-
|
|
13
|
-
jobs:
|
|
14
|
-
check:
|
|
15
|
-
runs-on: ubuntu-latest
|
|
16
|
-
permissions:
|
|
17
|
-
contents: read
|
|
18
|
-
steps:
|
|
19
|
-
- uses: actions/checkout@v5
|
|
20
|
-
|
|
21
|
-
- uses: astral-sh/setup-uv@v7
|
|
22
|
-
with:
|
|
23
|
-
enable-cache: true
|
|
24
|
-
|
|
25
|
-
- name: Preflight
|
|
26
|
-
run: uvx --from python-devkit==0.1.5 preflight-python
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
name: Release
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
workflow_run:
|
|
5
|
-
workflows: [CI]
|
|
6
|
-
types: [completed]
|
|
7
|
-
branches: [main]
|
|
8
|
-
|
|
9
|
-
concurrency:
|
|
10
|
-
group: release
|
|
11
|
-
cancel-in-progress: false
|
|
12
|
-
|
|
13
|
-
jobs:
|
|
14
|
-
publish:
|
|
15
|
-
if: github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'push' && github.event.workflow_run.head_branch == 'main'
|
|
16
|
-
runs-on: ubuntu-latest
|
|
17
|
-
permissions:
|
|
18
|
-
contents: write
|
|
19
|
-
id-token: write
|
|
20
|
-
steps:
|
|
21
|
-
- uses: actions/checkout@v5
|
|
22
|
-
with:
|
|
23
|
-
ref: ${{ github.event.workflow_run.head_sha }}
|
|
24
|
-
|
|
25
|
-
# Workaround: fetch-tags is broken with shallow clones
|
|
26
|
-
- run: git fetch --tags origin
|
|
27
|
-
|
|
28
|
-
- uses: astral-sh/setup-uv@v7
|
|
29
|
-
|
|
30
|
-
- name: Publish
|
|
31
|
-
run: uvx --from release-devkit==0.1.18 publish-stable --config release-devkit.json
|
|
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
|
{openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/src/openapi_client_codegen/client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/src/openapi_client_codegen/py.typed
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openapi_client_codegen-0.1.12 → openapi_client_codegen-0.1.14}/src/openapi_client_codegen/unity.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|