원클릭으로
build-and-release
Use when changing Azure Pipelines, reproducing CI locally, or validating PySafeguard version stamping and publishing.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Use when changing Azure Pipelines, reproducing CI locally, or validating PySafeguard version stamping and publishing.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Use when working on PySafeguard module internals, adding new auth strategies, extending the client, working with the event system (SignalR), or understanding internal patterns like PKCE, HiddenString, or async lazy imports.
Use when running tests, writing tests, investigating test failures, or setting up a test environment against a live Safeguard appliance. Covers pytest configuration, pytest-asyncio, integration test setup, environment variables, and the preflight fixture.
Use when making Safeguard API calls via SafeguardClient, working with HTTP methods, streaming, error handling, A2A credential retrieval, or managing token lifecycle. Covers method signatures, parameter conventions, and common patterns.
Use when setting up or troubleshooting Safeguard A2A certificate registrations, API keys, credential retrieval, brokering, or A2A-backed event listeners.
| name | build-and-release |
| description | Use when changing Azure Pipelines, reproducing CI locally, or validating PySafeguard version stamping and publishing. |
Use this skill when you need to change azure-pipelines.yml, debug why a build or release ran, reproduce the pipeline locally, or understand how PySafeguard versions are stamped and published.
| File | Role |
|---|---|
azure-pipelines.yml | Top-level pipeline definition: triggers, job conditions, GitHub release, and PyPI publish steps |
pipeline-templates/global-variables.yml | Computes isTagBuild from Build.SourceBranch |
pipeline-templates/build-steps.yml | Shared install/lint/test/build/twine-check steps used by both jobs |
versionnumber.ps1 | Converts the base semantic version into the build/package version and release tag |
pyproject.toml | Poetry metadata, base semantic version, package name, dependencies, and pytest config |
The pipeline is intentionally narrow:
main and release-*v*main and release-***/*.mdLICENSEdocs/.github/CODEOWNERSThere are no explicit Azure DevOps stages; the pipeline uses two jobs with mutually exclusive conditions:
PRValidation
Build.Reason == PullRequestubuntu-latestpipeline-templates/build-steps.ymltwine checkBuildAndPublish
Both jobs run the same steps from pipeline-templates/build-steps.yml:
3.12 with UsePythonVersion@0pip and wheelpoetry install --all-extrasversionnumber.ps1poetry run ruff check src/poetry run ruff format --check src/poetry run mypy src/poetry run python -m pytest tests/ -m "not integration" --tb=short -qpoetry buildtwine check dist/*dist/* into the artifact staging directorydropThe artifact publishing steps are guarded with succeededOrFailed(), so failed builds still expose dist/* when those files exist.
BuildAndPublish adds two publishing paths after the shared build:
GitHub release via GitHubRelease@1
PangaeaBuild-GitHubOneIdentity/PySafeguard$(Build.ArtifactStagingDirectory)/dist/*commitBased, compared to lastFullReleaseisPreRelease is true for non-tag buildsPyPI publish via Twine
Build.SourceBranch starts with refs/tags/TwineAuthenticate@1, then uploads dist/*The base semantic version lives in pyproject.toml under [project].version.
versionnumber.ps1 reads it with:
poetry version --short
That means the checked-in value is the release baseline, not necessarily the exact artifact version produced in CI.
Tag builds are release builds.
isTagBuild comes from startsWith(Build.SourceBranch, 'refs/tags/')versionnumber.ps1 validates the tag with ^v\d+\.\d+\.\d+v removed
v8.1.0 -> 8.1.0ReleaseTag is the original tag nameThe regex only validates the v<major>.<minor>.<patch> prefix, so tags with an allowed suffix after that prefix still pass.
Branch builds become development packages.
PackageVersion = <semantic-version>.dev<BuildId % 65534>8.0.2 and build id 70001 becomes 8.0.2.dev4467ReleaseTag = dev/v<PackageVersion>The modulo keeps the dev suffix inside the range accepted by Python packaging tools.
poetry version <PackageVersion>versionnumber.ps1 locally, expect pyproject.toml to change until you reset itv* tag, not by editing files in the build outputRun these from the repo root:
pip install poetry
poetry install --all-extras
poetry run ruff check src/
poetry run ruff format --check src/
poetry run mypy src/
poetry run python -m pytest tests/ -m "not integration" --tb=short -q
poetry build
pip install twine
twine check dist/*
3.12 locally when reproducing CI because the pipeline pins that interpreterpoetry install --all-extras is important because the repo's checks depend on dev tools and optional extras being availableUse PowerShell from the repo root:
pwsh .\versionnumber.ps1 -BuildId 12345 -TagName v8.0.2 -IsTagBuild $true
pwsh .\versionnumber.ps1 -BuildId 12345 -TagName main -IsTagBuild $false
After a dry run, revert pyproject.toml unless you intentionally changed the base semantic version.
| Target | When it runs | What is published |
|---|---|---|
Azure Pipeline artifact drop | Every build, even on failure when artifacts exist | dist/* |
| GitHub Releases | Every non-PR build | dist/* plus generated changelog |
| PyPI | Tagged builds only | dist/* via Twine |
dev/v<PackageVersion>There is currently no package signing step in the pipeline.
If signing is added later, update this skill and AGENTS.md in the same change.
PangaeaBuild-GitHub - required by GitHubRelease@1pypiOneIdentity - required by TwineAuthenticate@1$(PYPIRC_PATH) - generated by Twine authentication and consumed by twine uploadBuild.SourceBranchBuild.SourceBranchNameBuild.SourceVersionBuild.BuildId.pypirc, PyPI tokens, GitHub tokens, or exported service-connection credentialspyproject.tomlpyproject.toml only when intentionally changing the SDK version linemain or release-* to verify dev build behaviorvX.Y.Z tag to trigger the real PyPI publish pathazure-pipelines.ymlpipeline-templates/build-steps.ymlpipeline-templates/global-variables.ymlversionnumber.ps1AGENTS.md