The OIDC release workflow (.github/workflows/release.yml) was written as part of #5 but cannot be landed via normal git push — the configured PAT lacks workflow scope, and per the universal CLAUDE.md we do not widen the PAT, use --admin, or swap credentials. It must land via the GitHub Contents API using the in-process classic-PAT pattern (AssemblyZero ADR-0216), OR via a web-UI PR.
This must be on main before the first OIDC tag-push publish (part of #1). It does not block reserving the name if the first release is uploaded manually with twine instead.
File to land: .github/workflows/release.yml
name: Release to PyPI
on:
push:
tags:
- "v*.*.*"
permissions:
id-token: write
contents: read
jobs:
release:
runs-on: ubuntu-latest
environment: pypi
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.10"
- name: Install Poetry
run: pipx install poetry
- name: Build distributions
run: poetry build
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
Landing options
- classic-PAT Contents API (sanctioned): a focused script using
with classic_pat_session() PUTs the file to a branch + opens a PR; the operator runs it. Reference: AssemblyZero/tools/fleet_delete_pr_sentinel.py.
- web-UI PR: create the file through github.com (web commits are not subject to the PAT workflow-scope rule), then merge.
The OIDC release workflow (
.github/workflows/release.yml) was written as part of #5 but cannot be landed via normalgit push— the configured PAT lacksworkflowscope, and per the universal CLAUDE.md we do not widen the PAT, use--admin, or swap credentials. It must land via the GitHub Contents API using the in-process classic-PAT pattern (AssemblyZero ADR-0216), OR via a web-UI PR.This must be on
mainbefore the first OIDC tag-push publish (part of #1). It does not block reserving the name if the first release is uploaded manually with twine instead.File to land:
.github/workflows/release.ymlLanding options
with classic_pat_session()PUTs the file to a branch + opens a PR; the operator runs it. Reference:AssemblyZero/tools/fleet_delete_pr_sentinel.py.