scalar-sdk 0.3.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 (140) hide show
  1. scalar_sdk-0.3.2/.claude/skills/scalar-api-python-sdk/SKILL.md +70 -0
  2. scalar_sdk-0.3.2/.github/workflows/release-please.yml +93 -0
  3. scalar_sdk-0.3.2/.github/workflows/release-title-edit.yml +117 -0
  4. scalar_sdk-0.3.2/.github/workflows/sdk-ci.yml +16 -0
  5. scalar_sdk-0.3.2/.github/workflows/sdk-release.yml +34 -0
  6. scalar_sdk-0.3.2/.gitignore +10 -0
  7. scalar_sdk-0.3.2/.release-please-manifest.json +3 -0
  8. scalar_sdk-0.3.2/CHANGELOG.md +351 -0
  9. scalar_sdk-0.3.2/LICENSE +201 -0
  10. scalar_sdk-0.3.2/PKG-INFO +170 -0
  11. scalar_sdk-0.3.2/README.md +152 -0
  12. scalar_sdk-0.3.2/SECURITY.md +3 -0
  13. scalar_sdk-0.3.2/SKILL.md +70 -0
  14. scalar_sdk-0.3.2/VERSIONING.md +86 -0
  15. scalar_sdk-0.3.2/api.md +807 -0
  16. scalar_sdk-0.3.2/openapi.augmented.json +6687 -0
  17. scalar_sdk-0.3.2/pyproject.toml +28 -0
  18. scalar_sdk-0.3.2/release-please-config.json +46 -0
  19. scalar_sdk-0.3.2/scalar-sdk.manifest.json +9831 -0
  20. scalar_sdk-0.3.2/src/__init__.py +88 -0
  21. scalar_sdk-0.3.2/src/_base_client.py +2232 -0
  22. scalar_sdk-0.3.2/src/_client.py +794 -0
  23. scalar_sdk-0.3.2/src/_compat.py +226 -0
  24. scalar_sdk-0.3.2/src/_constants.py +14 -0
  25. scalar_sdk-0.3.2/src/_event_handler.py +85 -0
  26. scalar_sdk-0.3.2/src/_exceptions.py +126 -0
  27. scalar_sdk-0.3.2/src/_files.py +173 -0
  28. scalar_sdk-0.3.2/src/_models.py +962 -0
  29. scalar_sdk-0.3.2/src/_qs.py +149 -0
  30. scalar_sdk-0.3.2/src/_resource.py +43 -0
  31. scalar_sdk-0.3.2/src/_response.py +842 -0
  32. scalar_sdk-0.3.2/src/_send_queue.py +90 -0
  33. scalar_sdk-0.3.2/src/_streaming.py +395 -0
  34. scalar_sdk-0.3.2/src/_types.py +274 -0
  35. scalar_sdk-0.3.2/src/_utils/__init__.py +64 -0
  36. scalar_sdk-0.3.2/src/_utils/_compat.py +45 -0
  37. scalar_sdk-0.3.2/src/_utils/_datetime_parse.py +136 -0
  38. scalar_sdk-0.3.2/src/_utils/_json.py +35 -0
  39. scalar_sdk-0.3.2/src/_utils/_logs.py +25 -0
  40. scalar_sdk-0.3.2/src/_utils/_path.py +127 -0
  41. scalar_sdk-0.3.2/src/_utils/_proxy.py +65 -0
  42. scalar_sdk-0.3.2/src/_utils/_reflection.py +42 -0
  43. scalar_sdk-0.3.2/src/_utils/_resources_proxy.py +24 -0
  44. scalar_sdk-0.3.2/src/_utils/_streams.py +12 -0
  45. scalar_sdk-0.3.2/src/_utils/_sync.py +58 -0
  46. scalar_sdk-0.3.2/src/_utils/_transform.py +457 -0
  47. scalar_sdk-0.3.2/src/_utils/_typing.py +156 -0
  48. scalar_sdk-0.3.2/src/_utils/_utils.py +433 -0
  49. scalar_sdk-0.3.2/src/_version.py +4 -0
  50. scalar_sdk-0.3.2/src/py.typed +0 -0
  51. scalar_sdk-0.3.2/src/resources/__init__.py +131 -0
  52. scalar_sdk-0.3.2/src/resources/authentication.py +240 -0
  53. scalar_sdk-0.3.2/src/resources/login_portals.py +555 -0
  54. scalar_sdk-0.3.2/src/resources/namespaces.py +143 -0
  55. scalar_sdk-0.3.2/src/resources/registry.py +1463 -0
  56. scalar_sdk-0.3.2/src/resources/rules.py +869 -0
  57. scalar_sdk-0.3.2/src/resources/scalar_docs.py +368 -0
  58. scalar_sdk-0.3.2/src/resources/schemas/__init__.py +47 -0
  59. scalar_sdk-0.3.2/src/resources/schemas/access_group.py +297 -0
  60. scalar_sdk-0.3.2/src/resources/schemas/schemas.py +597 -0
  61. scalar_sdk-0.3.2/src/resources/schemas/version.py +417 -0
  62. scalar_sdk-0.3.2/src/resources/teams.py +143 -0
  63. scalar_sdk-0.3.2/src/resources/themes.py +667 -0
  64. scalar_sdk-0.3.2/src/types/__init__.py +70 -0
  65. scalar_sdk-0.3.2/src/types/authentication_exchange_personal_token_params.py +14 -0
  66. scalar_sdk-0.3.2/src/types/authentication_exchange_personal_token_response.py +14 -0
  67. scalar_sdk-0.3.2/src/types/authentication_list_current_user_response.py +38 -0
  68. scalar_sdk-0.3.2/src/types/login_portal_create_params.py +21 -0
  69. scalar_sdk-0.3.2/src/types/login_portal_create_response.py +10 -0
  70. scalar_sdk-0.3.2/src/types/login_portal_delete_response.py +7 -0
  71. scalar_sdk-0.3.2/src/types/login_portal_email.py +32 -0
  72. scalar_sdk-0.3.2/src/types/login_portal_email_param.py +34 -0
  73. scalar_sdk-0.3.2/src/types/login_portal_list_response.py +22 -0
  74. scalar_sdk-0.3.2/src/types/login_portal_page.py +38 -0
  75. scalar_sdk-0.3.2/src/types/login_portal_page_param.py +40 -0
  76. scalar_sdk-0.3.2/src/types/login_portal_retrieve_response.py +23 -0
  77. scalar_sdk-0.3.2/src/types/login_portal_update_params.py +12 -0
  78. scalar_sdk-0.3.2/src/types/login_portal_update_response.py +7 -0
  79. scalar_sdk-0.3.2/src/types/namespace_list_response.py +8 -0
  80. scalar_sdk-0.3.2/src/types/registry_create_api_document_access_group_params.py +18 -0
  81. scalar_sdk-0.3.2/src/types/registry_create_api_document_access_group_response.py +7 -0
  82. scalar_sdk-0.3.2/src/types/registry_create_api_document_params.py +28 -0
  83. scalar_sdk-0.3.2/src/types/registry_create_api_document_response.py +24 -0
  84. scalar_sdk-0.3.2/src/types/registry_create_api_document_version_params.py +24 -0
  85. scalar_sdk-0.3.2/src/types/registry_create_api_document_version_response.py +45 -0
  86. scalar_sdk-0.3.2/src/types/registry_delete_api_document_access_group_params.py +18 -0
  87. scalar_sdk-0.3.2/src/types/registry_delete_api_document_access_group_response.py +7 -0
  88. scalar_sdk-0.3.2/src/types/registry_delete_api_document_response.py +7 -0
  89. scalar_sdk-0.3.2/src/types/registry_delete_api_document_version_response.py +7 -0
  90. scalar_sdk-0.3.2/src/types/registry_list_all_api_documents_response.py +69 -0
  91. scalar_sdk-0.3.2/src/types/registry_list_api_document_version_metadata_response.py +45 -0
  92. scalar_sdk-0.3.2/src/types/registry_list_api_documents_response.py +69 -0
  93. scalar_sdk-0.3.2/src/types/registry_retrieve_api_document_version_response.py +7 -0
  94. scalar_sdk-0.3.2/src/types/registry_update_api_document_params.py +22 -0
  95. scalar_sdk-0.3.2/src/types/registry_update_api_document_response.py +7 -0
  96. scalar_sdk-0.3.2/src/types/registry_update_api_document_version_params.py +20 -0
  97. scalar_sdk-0.3.2/src/types/registry_update_api_document_version_response.py +18 -0
  98. scalar_sdk-0.3.2/src/types/rule_create_ruleset_access_group_params.py +18 -0
  99. scalar_sdk-0.3.2/src/types/rule_create_ruleset_access_group_response.py +7 -0
  100. scalar_sdk-0.3.2/src/types/rule_create_ruleset_params.py +22 -0
  101. scalar_sdk-0.3.2/src/types/rule_create_ruleset_response.py +10 -0
  102. scalar_sdk-0.3.2/src/types/rule_delete_ruleset_access_group_params.py +18 -0
  103. scalar_sdk-0.3.2/src/types/rule_delete_ruleset_access_group_response.py +7 -0
  104. scalar_sdk-0.3.2/src/types/rule_delete_ruleset_response.py +7 -0
  105. scalar_sdk-0.3.2/src/types/rule_list_rulesets_response.py +30 -0
  106. scalar_sdk-0.3.2/src/types/rule_retrieve_ruleset_document_response.py +7 -0
  107. scalar_sdk-0.3.2/src/types/rule_update_ruleset_params.py +24 -0
  108. scalar_sdk-0.3.2/src/types/rule_update_ruleset_response.py +7 -0
  109. scalar_sdk-0.3.2/src/types/scalar_doc_create_guide_params.py +25 -0
  110. scalar_sdk-0.3.2/src/types/scalar_doc_create_guide_response.py +14 -0
  111. scalar_sdk-0.3.2/src/types/scalar_doc_list_guides_response.py +82 -0
  112. scalar_sdk-0.3.2/src/types/scalar_doc_publish_guide_response.py +14 -0
  113. scalar_sdk-0.3.2/src/types/schema_create_params.py +26 -0
  114. scalar_sdk-0.3.2/src/types/schema_create_response.py +10 -0
  115. scalar_sdk-0.3.2/src/types/schema_delete_response.py +7 -0
  116. scalar_sdk-0.3.2/src/types/schema_list_response.py +45 -0
  117. scalar_sdk-0.3.2/src/types/schema_update_params.py +20 -0
  118. scalar_sdk-0.3.2/src/types/schema_update_response.py +7 -0
  119. scalar_sdk-0.3.2/src/types/schemas/__init__.py +12 -0
  120. scalar_sdk-0.3.2/src/types/schemas/access_group_create_schema_params.py +18 -0
  121. scalar_sdk-0.3.2/src/types/schemas/access_group_create_schema_response.py +7 -0
  122. scalar_sdk-0.3.2/src/types/schemas/access_group_delete_schema_params.py +18 -0
  123. scalar_sdk-0.3.2/src/types/schemas/access_group_delete_schema_response.py +7 -0
  124. scalar_sdk-0.3.2/src/types/schemas/version_create_schema_params.py +18 -0
  125. scalar_sdk-0.3.2/src/types/schemas/version_create_schema_response.py +10 -0
  126. scalar_sdk-0.3.2/src/types/schemas/version_delete_schema_response.py +7 -0
  127. scalar_sdk-0.3.2/src/types/schemas/version_retrieve_schema_response.py +7 -0
  128. scalar_sdk-0.3.2/src/types/slug.py +7 -0
  129. scalar_sdk-0.3.2/src/types/team_list_response.py +28 -0
  130. scalar_sdk-0.3.2/src/types/theme_create_params.py +18 -0
  131. scalar_sdk-0.3.2/src/types/theme_create_response.py +10 -0
  132. scalar_sdk-0.3.2/src/types/theme_delete_response.py +7 -0
  133. scalar_sdk-0.3.2/src/types/theme_list_response.py +24 -0
  134. scalar_sdk-0.3.2/src/types/theme_replace_document_params.py +12 -0
  135. scalar_sdk-0.3.2/src/types/theme_replace_document_response.py +7 -0
  136. scalar_sdk-0.3.2/src/types/theme_retrieve_response.py +7 -0
  137. scalar_sdk-0.3.2/src/types/theme_update_params.py +14 -0
  138. scalar_sdk-0.3.2/src/types/theme_update_response.py +7 -0
  139. scalar_sdk-0.3.2/src/types/version.py +7 -0
  140. scalar_sdk-0.3.2/tests/smoke-test.py +719 -0
@@ -0,0 +1,70 @@
1
+ ---
2
+ name: scalar-api-python-sdk
3
+ description: "Python SDK for Scalar API. Use when writing Python code that calls Scalar API with the scalar-sdk package: installing it, constructing and authenticating the client, and calling API operations."
4
+ ---
5
+
6
+ # Scalar API Python SDK
7
+
8
+ Generated Python client for Scalar API, published as `scalar-sdk`. Use the generated client instead of hand-writing HTTP requests.
9
+
10
+ ## Install
11
+
12
+ ```sh
13
+ pip install scalar-sdk
14
+ ```
15
+
16
+ ## Client setup and authentication
17
+
18
+ ```python
19
+ import os
20
+
21
+ from scalar_sdk import Scalar
22
+
23
+ client = Scalar(
24
+ bearer_auth=os.environ.get("BEARER_AUTH"),
25
+ )
26
+ ```
27
+
28
+ Provide credentials using the options below. Environment variables are read automatically when the target runtime supports them:
29
+
30
+ - `bearer_auth` (env: `BEARER_AUTH`) — Credential for the BearerAuth scheme.
31
+
32
+ ## Calling operations
33
+
34
+ ```python
35
+ import os
36
+
37
+ from scalar_sdk import Scalar
38
+
39
+ client = Scalar(
40
+ bearer_auth=os.environ.get("BEARER_AUTH"),
41
+ )
42
+
43
+ registry = client.registry.list_all_api_documents()
44
+ print(registry)
45
+ ```
46
+
47
+ Method names, parameter shapes, and response types are generated from the API description — do not guess them. Look up the exact call signature in [api.md](../../../api.md) before writing a call.
48
+
49
+ ## Error handling
50
+
51
+ Non-success responses throw generated API errors. Error objects expose status, headers, response body, and request metadata where the target runtime supports it.
52
+
53
+ ```python
54
+ from scalar_sdk import APIStatusError
55
+
56
+ try:
57
+ registry = client.registry.list_all_api_documents()
58
+ except APIStatusError as err:
59
+ print(err.status_code, err.message)
60
+ raise
61
+ ```
62
+
63
+ ## Requirements
64
+
65
+ - Python 3.8 or newer
66
+
67
+ ## Reference files
68
+
69
+ - [README.md](../../../README.md) — full feature tour: client options, request options, retries and timeouts, logging.
70
+ - [api.md](../../../api.md) — complete catalogue of every operation with request and response types.
@@ -0,0 +1,93 @@
1
+ name: Release Please
2
+
3
+ on:
4
+ # Fires when a human merges the platform-managed release PR into main
5
+ # (the PR's base, so its diff shows the full pending release). Regenerations and
6
+ # custom-code pushes only touch scalar-next and never run this workflow.
7
+ push:
8
+ branches:
9
+ - main
10
+ # Manual fallback only; nothing in the automated chain depends on dispatch.
11
+ workflow_dispatch:
12
+
13
+ permissions:
14
+ contents: write
15
+ # Required to update the merged release PR's autorelease labels after tagging.
16
+ pull-requests: write
17
+
18
+ jobs:
19
+ release-please:
20
+ runs-on: ubuntu-latest
21
+ outputs:
22
+ release_created: ${{ steps.release.outputs.release_created }}
23
+ # Consumed by the publish job's checkout: without this mapping the checkout ref would be
24
+ # empty and the publish would build the triggering branch head instead of the released
25
+ # tag's exact commit.
26
+ tag_name: ${{ steps.release.outputs.tag_name }}
27
+ steps:
28
+ - uses: googleapis/release-please-action@45996ed1f6d02564a971a2fa1b5860e934307cf7 # v5.0.0
29
+ id: release
30
+ with:
31
+ target-branch: main
32
+ config-file: release-please-config.json
33
+ manifest-file: .release-please-manifest.json
34
+ # Release PRs are opened and updated by the Scalar platform with its own
35
+ # credential (so their CI runs without manual approval); this workflow only
36
+ # cuts the tag + GitHub Release once a release PR is merged.
37
+ skip-github-pull-request: true
38
+ - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
39
+ if: ${{ steps.release.outputs.release_created == 'true' }}
40
+ with:
41
+ fetch-depth: 0
42
+ # Merging the release PR into main is itself the promotion, but the
43
+ # version bump and changelog must also land back on scalar-next, or the next
44
+ # release PR would propose this release again. A real merge (never a plain
45
+ # commit push) so a squash- or rebase-merged release PR syncs just as well; the
46
+ # non-conventional message keeps the sync commit out of future changelogs. Plain
47
+ # (non-force) push on purpose: losing a race against a concurrent regeneration
48
+ # push fails loudly here, and the platform's next sync re-converges.
49
+ - name: Sync release back to scalar-next
50
+ if: ${{ steps.release.outputs.release_created == 'true' }}
51
+ run: |
52
+ git config user.name "github-actions[bot]"
53
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
54
+ git fetch origin scalar-next
55
+ git checkout -B scalar-next origin/scalar-next
56
+ git merge --no-edit -m "Sync release ${{ steps.release.outputs.tag_name }} back to scalar-next" "${{ steps.release.outputs.sha }}"
57
+ git push origin scalar-next
58
+ publish:
59
+ needs: release-please
60
+ # `!cancelled()` keeps publishing even when the back-sync to the integration branch
61
+ # failed: a raced integration branch must not block the release from reaching its
62
+ # registry.
63
+ if: ${{ !cancelled() && needs.release-please.outputs.release_created == 'true' }}
64
+ runs-on: ubuntu-latest
65
+ # Job-level permissions replace the workflow's release-cutting grants with the publish
66
+ # floor. OIDC trusted publishing verifies this run's claims, which name this workflow
67
+ # file — register release-please.yml as the trusted publisher on the registry.
68
+ permissions:
69
+ contents: read
70
+ id-token: write
71
+ packages: write
72
+ env:
73
+ VERSIONING_POLICY: manual
74
+ steps:
75
+ # Publishing runs inline — a top-level job of this same run — rather than dispatching
76
+ # sdk-release.yml: workflow_dispatch resolves the target workflow on the repository's
77
+ # default branch only, so a dispatch would 404 whenever the release line is any other
78
+ # branch, while OIDC trusted publishing accepts this job because it stays top-level
79
+ # (never a reusable-workflow call). The release-please job cut the tag earlier in this
80
+ # run; checking it out publishes exactly the released commit, not the branch head that
81
+ # triggered the workflow.
82
+ - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
83
+ with:
84
+ ref: ${{ needs.release-please.outputs.tag_name }}
85
+ - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
86
+ with:
87
+ python-version: "3.11"
88
+ - run: python -m pip install --upgrade build
89
+ - run: python -m build
90
+ - name: Publish to PyPI
91
+ uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0
92
+ with:
93
+ skip-existing: true
@@ -0,0 +1,117 @@
1
+ name: Release PR Version
2
+
3
+ on:
4
+ # `edited` is not one of the default pull_request types, but it is the point of this
5
+ # workflow: retitling the release PR is how a maintainer picks an exact version. The
6
+ # other types keep the consistency check attached to the PR as it evolves.
7
+ pull_request:
8
+ types: [opened, reopened, edited, synchronize]
9
+
10
+ # Read-only by default; only the job that pushes the Release-As commit widens this.
11
+ permissions:
12
+ contents: read
13
+
14
+ jobs:
15
+ version-consistency:
16
+ # Also the check name the release PR's footer tells maintainers to wait for.
17
+ name: Release PR version
18
+ # Only the platform's release PR carries a version in its title; every other pull request
19
+ # skips this job, which GitHub reports as neutral. The release may be presented from
20
+ # scalar-next itself or from the release-please branch rendered off it, so both heads
21
+ # count as the release PR.
22
+ if: >-
23
+ ${{ github.event.pull_request.base.ref == 'main'
24
+ && (github.event.pull_request.head.ref == 'scalar-next'
25
+ || startsWith(github.event.pull_request.head.ref, 'release-please--branches--scalar-next--')) }}
26
+ runs-on: ubuntu-latest
27
+ steps:
28
+ - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
29
+ with:
30
+ # The version committed on the PR head is what merging would actually release.
31
+ ref: ${{ github.event.pull_request.head.sha }}
32
+ # Fails while the title version and the committed version disagree — the window between
33
+ # a maintainer's retitle and the platform re-rendering the PR from it. Without this a
34
+ # merge in that window would tag a release whose own files self-report the old version,
35
+ # and a title release-please cannot parse would silently cut no release at all.
36
+ - name: Compare the title version with the committed version
37
+ env:
38
+ # The title is human input, so it is bound through the environment (never
39
+ # interpolated into the script) and matched against a strict semver pattern
40
+ # before it is read.
41
+ PR_TITLE: ${{ github.event.pull_request.title }}
42
+ run: |
43
+ pattern='^release: ((0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-[0-9A-Za-z.-]+)?(\+[0-9A-Za-z.-]+)?)$'
44
+ if [[ ! "$PR_TITLE" =~ $pattern ]]; then
45
+ echo "::error::Release PR title must be \"release: X.Y.Z\" with a full semver version, got: $PR_TITLE"
46
+ exit 1
47
+ fi
48
+ title_version="${BASH_REMATCH[1]}"
49
+ manifest_version="$(jq -r '.["."]' .release-please-manifest.json)"
50
+ if [[ "$title_version" != "$manifest_version" ]]; then
51
+ echo "::error::Release PR title says $title_version but the pull request is versioned $manifest_version. Wait for the release PR to be re-rendered at $title_version before merging."
52
+ exit 1
53
+ fi
54
+ echo "Release PR title and committed version agree on $title_version."
55
+
56
+ apply-title-version:
57
+ name: Apply edited release version
58
+ # A human retitle of the open release PR is bridged into the canonical explicit-version
59
+ # mechanism (a Release-As commit on scalar-next, which the platform re-renders the
60
+ # release PR from). `changes.title` is only set when the title itself changed, and bot
61
+ # senders are ignored so the platform's own retitles cannot bounce back into another
62
+ # commit.
63
+ if: >-
64
+ ${{ github.event.action == 'edited'
65
+ && github.event.changes.title != null
66
+ && github.event.sender.type != 'Bot'
67
+ && github.event.pull_request.state == 'open'
68
+ && github.event.pull_request.base.ref == 'main'
69
+ && (github.event.pull_request.head.ref == 'scalar-next'
70
+ || startsWith(github.event.pull_request.head.ref, 'release-please--branches--scalar-next--')) }}
71
+ # One bridge run at a time per pull request, newest retitle wins. Two retitles in quick
72
+ # succession (a version typo corrected seconds later) would otherwise start two runs that
73
+ # both read the version committed on the PR head, both get past the no-op guard, and both
74
+ # push — and since each fetches scalar-next immediately before committing, the second
75
+ # push fast-forwards instead of failing. release-please honours the newest Release-As
76
+ # footer, so the release would land on whichever run happened to push last, not on the
77
+ # title the maintainer actually left behind.
78
+ concurrency:
79
+ group: release-title-edit-${{ github.event.pull_request.number }}
80
+ cancel-in-progress: true
81
+ runs-on: ubuntu-latest
82
+ permissions:
83
+ contents: write
84
+ steps:
85
+ - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
86
+ with:
87
+ # The PR head, so the version the pull request currently carries can be read before
88
+ # deciding whether anything needs to change.
89
+ ref: ${{ github.event.pull_request.head.sha }}
90
+ - name: Push a Release-As commit for the edited version
91
+ env:
92
+ PR_TITLE: ${{ github.event.pull_request.title }}
93
+ run: |
94
+ set -euo pipefail
95
+ pattern='^release: ((0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-[0-9A-Za-z.-]+)?(\+[0-9A-Za-z.-]+)?)$'
96
+ if [[ ! "$PR_TITLE" =~ $pattern ]]; then
97
+ echo "::error::Release PR title must be \"release: X.Y.Z\" with a full semver version, got: $PR_TITLE"
98
+ exit 1
99
+ fi
100
+ # Only ever a validated semver from here on, so it is safe in a commit message.
101
+ version="${BASH_REMATCH[1]}"
102
+ manifest_version="$(jq -r '.["."]' .release-please-manifest.json)"
103
+ # The re-rendered PR is retitled to the version it now carries; stopping here keeps
104
+ # that from producing an endless chain of Release-As commits.
105
+ if [[ "$version" == "$manifest_version" ]]; then
106
+ echo "This release PR already carries $version; nothing to do."
107
+ exit 0
108
+ fi
109
+ git config user.name "github-actions[bot]"
110
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
111
+ git fetch origin scalar-next
112
+ git checkout -B scalar-next origin/scalar-next
113
+ git commit --allow-empty -m "chore: release $version" -m "Release-As: $version"
114
+ # Plain (non-force) push: losing a race against a regeneration push fails loudly
115
+ # rather than discarding it, and the retitle can simply be repeated.
116
+ git push origin scalar-next
117
+ echo "Pushed Release-As: $version to scalar-next. The release PR will be re-rendered at that version."
@@ -0,0 +1,16 @@
1
+ name: Python SDK CI
2
+
3
+ on:
4
+ push:
5
+ pull_request:
6
+
7
+ jobs:
8
+ verify:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
12
+ - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
13
+ with:
14
+ python-version: "3.11"
15
+ - run: python -m pip install --upgrade build
16
+ - run: python -m build
@@ -0,0 +1,34 @@
1
+ name: Python SDK Release
2
+
3
+ on:
4
+ # Manual re-publish only: the automated publish for each release runs as the `publish` job
5
+ # inside release-please.yml, in the same run that cuts the tag (dispatching a workflow here
6
+ # instead would resolve it on the repository's default branch only, which breaks releasing
7
+ # from any other release line). Dispatch this workflow at an existing release tag to re-run
8
+ # a failed or skipped publish. A dispatched run is top-level, so OIDC trusted-publisher
9
+ # claims name this file; register it as an additional trusted publisher only when manual
10
+ # re-publishes are used. Never add a workflow_call trigger here — registries reject
11
+ # publishes from called (reusable) workflows.
12
+ workflow_dispatch:
13
+
14
+ permissions:
15
+ contents: read
16
+ id-token: write
17
+ packages: write
18
+
19
+ jobs:
20
+ release:
21
+ runs-on: ubuntu-latest
22
+ env:
23
+ VERSIONING_POLICY: manual
24
+ steps:
25
+ - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
26
+ - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
27
+ with:
28
+ python-version: "3.11"
29
+ - run: python -m pip install --upgrade build
30
+ - run: python -m build
31
+ - name: Publish to PyPI
32
+ uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0
33
+ with:
34
+ skip-existing: true
@@ -0,0 +1,10 @@
1
+ # Generated by Scalar SDK Generator.
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ .venv/
6
+ dist/
7
+ build/
8
+ .mypy_cache/
9
+ .pytest_cache/
10
+ .ruff_cache/
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.3.2"
3
+ }