Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .agents/skills/release-captain/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,7 @@ git worktree remove --force "$wt"
```

4. **Watch and verify.** Check that `Select Qualified Prerelease` names the
approved candidate, the GitHub Release has assets, no job failed, and the
wheel reached PyPI:
approved candidate, the GitHub Release has assets and no job failed:

```shell
gh run watch <run-id> --exit-status
Expand Down
19 changes: 4 additions & 15 deletions .agents/skills/release-openshell/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ Release creates `vX.Y.Z` at that exact commit, then rebuilds and publishes all
stable artifacts without rerunning qualification. Embedded versions change, so
stable artifacts are not byte-identical to the qualified prerelease. An existing
stable tag may be retried only if it already points to the selected commit. A retry
publishes only missing artifacts; published images, charts, release assets, npm,
and PyPI versions are kept, while the snap is uploaded again.
publishes only missing artifacts; published images, charts, release assets, and
npm versions are kept, while the snap is uploaded again.
Stable images are saved as OCI archives during the build and pushed under the
stable version tags during publication. Their SBOMs are verified before updating
`latest`; the qualified prerelease's commit-SHA image tags remain unchanged.
Expand Down Expand Up @@ -84,17 +84,6 @@ immutable version and advance latest only for a newer version.

Watch the stable release run and report its result.

## PyPI publishing
## Python SDK

Stable releases publish the Python wheel to PyPI from `wheel-publish.yml`, which the `publish-pypi` job in `release-publish.yml` calls after the GitHub Release is created. The workflow downloads the wheel from the stable GitHub Release, not a run's build artifact, and checks the stable tag's source commit and the wheel's release checksum. It uses Trusted Publishing with the `pypi` GitHub environment. PyPI matches the workflow file that contains the publishing job, so configure the `openshell` PyPI project's GitHub publisher with owner `NVIDIA`, repository `OpenShell`, workflow `wheel-publish.yml`, and environment `pypi`. No PyPI API token or GitLab trigger credentials are required.

The environment must allow the branch used to dispatch Release or `wheel-publish.yml`. For a support release, explicitly allow its support branch before dispatching. Required reviewers, if configured, must approve the PyPI job. An existing wheel on PyPI is skipped; PyPI does not allow replacing a published wheel.

If a stable release did not reach PyPI, publish the wheel without rerunning Release:

```shell
gh workflow run wheel-publish.yml -R NVIDIA/OpenShell --ref main \
-f release-tag=vX.Y.Z -f source-sha=<tag commit> -f python-version=X.Y.Z
```

Development and prerelease wheels remain GitHub Release assets and do not publish to PyPI.
Core no longer builds or publishes the Python SDK for releases. Stable and prerelease GitHub Releases carry no wheel, and nothing in core publishes to PyPI. `openshell` `0.1.7` is the last core-built wheel. From `0.1.8` on, [ai-openshell/sdk-python](https://github.com/ai-openshell/sdk-python) publishes `openshell` on the same day as each stable core release, once its update PR for the core tag merges. The rolling `dev` release still attaches a development wheel until the SDK sources leave core (NVIDIA/OpenShell#5287).
39 changes: 39 additions & 0 deletions .github/workflows/branch-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,9 @@ jobs:
- name: Test
run: mise run test:python

- name: Test Python scripts
run: mise run test:python-scripts

- name: Test local gateway configuration helpers
run: |
bash tasks/scripts/test-gateway-pull-policy.sh
Expand Down Expand Up @@ -638,6 +641,42 @@ jobs:
echo "$changed"
exit 1

python-sdk-freeze:
# The Python SDK moved to ai-openshell/sdk-python (#5287), which imported it
# at v0.1.7. Its files stay only until core removes them, so PRs must not
# add or change them. Deleting files is allowed (the removal PR). The paths
# are the ones the import moved: all of python/ plus the two SDK build
# scripts. The shared root pyproject.toml and uv.lock stay editable.
# Merge queue runs skip this job; the PR already passed it on its mirror.
name: Python SDK Freeze
needs: pr_metadata
if: needs.pr_metadata.outputs.should_run == 'true' && github.event_name == 'push'
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false

- name: Reject changes to the Python SDK
env:
BASE_SHA: ${{ needs.pr_metadata.outputs.base_sha }}
run: |
set -euo pipefail
changed=$(git diff --name-only --diff-filter=d "${BASE_SHA}...HEAD" -- \
python \
tasks/scripts/generate_python_proto.py \
tasks/scripts/verify-python-wheel.py)
if [ -z "$changed" ]; then
echo "No added or changed Python SDK files."
exit 0
fi
echo "::error title=Python SDK moved::The Python SDK moved to https://github.com/ai-openshell/sdk-python. Drop the Python SDK changes from this PR and open SDK changes there. Regenerated bindings are not needed here; sdk-python regenerates them from core releases."
echo "Changed Python SDK files:"
echo "$changed"
exit 1

markdown:
name: Markdown
needs: pr_metadata
Expand Down
45 changes: 0 additions & 45 deletions .github/workflows/release-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ on:
required: true
type: boolean
outputs:
python_version:
description: Python package version
value: ${{ jobs.compute-versions.outputs.python_version }}
npm_version:
description: TypeScript package version
value: ${{ jobs.compute-versions.outputs.npm_version }}
Expand Down Expand Up @@ -56,7 +53,6 @@ jobs:
run:
shell: nix develop -c bash -euo pipefail {0}
outputs:
python_version: ${{ steps.v.outputs.python }}
cargo_version: ${{ steps.v.outputs.cargo }}
npm_version: ${{ steps.v.outputs.npm }}
deb_version: ${{ steps.v.outputs.deb }}
Expand Down Expand Up @@ -106,7 +102,6 @@ jobs:
fi
{
echo "is_prerelease=${is_prerelease}"
echo "python=$(uv run --no-project python tasks/scripts/release.py get-version --python)"
echo "cargo=$(uv run --no-project python tasks/scripts/release.py get-version --cargo)"
echo "npm=$(uv run --no-project python tasks/scripts/release.py get-version --npm)"
echo "deb=$(uv run --no-project python tasks/scripts/release.py get-version --deb)"
Expand Down Expand Up @@ -160,46 +155,6 @@ jobs:
push-images: ${{ inputs.is-prerelease }}
checkout-ref: ${{ needs.compute-versions.outputs.source_sha }}

build-python-wheel:
name: Build Python Wheel
needs: [compute-versions]
runs-on: linux-amd64-cpu8
timeout-minutes: 20
defaults:
run:
shell: nix develop -c bash -euo pipefail {0}
env:
SETUPTOOLS_SCM_PRETEND_VERSION_FOR_OPENSHELL: ${{ needs.compute-versions.outputs.python_version }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
ref: ${{ needs.compute-versions.outputs.source_sha }}

- uses: ./.github/actions/setup-nix
with:
prepare-shell: "true"

- name: Sync Python dependencies
run: uv sync --frozen

- name: Build Python wheel
run: |
set -euo pipefail
uv run --frozen python tasks/scripts/generate_python_proto.py
uv build --wheel --out-dir target/wheels
uv run --no-project python tasks/scripts/verify-python-wheel.py target/wheels \
--expected-version "${SETUPTOOLS_SCM_PRETEND_VERSION_FOR_OPENSHELL}"
ls -la target/wheels/*.whl

- name: Upload wheel artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: python-wheel
path: target/wheels/*.whl
retention-days: 5

build-deb:
name: Build Debian Packages
needs: [compute-versions, build-binaries, build-vm-driver]
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/release-prerelease.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
concurrency:
group: release-prerelease-tags
cancel-in-progress: false
queue: max

Check failure on line 30 in .github/workflows/release-prerelease.yml

View workflow job for this annotation

GitHub Actions / Actionlint (informational)

unexpected key "queue" for "concurrency" section. expected one of "cancel-in-progress", "group"
outputs:
tag: ${{ steps.tag.outputs.tag }}
source-sha: ${{ steps.tag.outputs.source_sha }}
Expand Down Expand Up @@ -124,7 +124,6 @@
release-tag: ${{ needs.resolve.outputs.tag }}
source-sha: ${{ needs.build.outputs.source_sha }}
semver: ${{ needs.build.outputs.semver }}
python-version: ${{ needs.build.outputs.python_version }}
npm-version: ${{ needs.build.outputs.npm_version }}
is-prerelease: true
secrets:
Expand Down
41 changes: 2 additions & 39 deletions .github/workflows/release-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,6 @@ on:
description: Release version without the v prefix
required: true
type: string
python-version:
description: Python package version
required: true
type: string
npm-version:
description: TypeScript package version
required: true
Expand Down Expand Up @@ -116,12 +112,6 @@ jobs:
name: prover-checksums
path: release/

- name: Download wheel artifact
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: python-wheel
path: release/

- name: Download Debian package artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
Expand All @@ -143,16 +133,6 @@ jobs:
path: release/
merge-multiple: true

- name: Verify wheel count
run: |
set -euo pipefail
shopt -s nullglob
wheels=(release/*.whl)
if [ "${#wheels[@]}" -ne 1 ]; then
echo "expected exactly one Python wheel, found ${#wheels[@]}" >&2
exit 1
fi

- name: Generate checksums
run: |
set -euo pipefail
Expand All @@ -165,8 +145,7 @@ jobs:
openshell-driver-vm-aarch64-unknown-linux-gnu.tar.gz \
openshell-driver-vm-aarch64-apple-darwin.tar.gz \
openshell_*.deb \
openshell-*.rpm \
*.whl > openshell-checksums-sha256.txt
openshell-*.rpm > openshell-checksums-sha256.txt
cat openshell-checksums-sha256.txt
sha256sum -- \
openshell-gateway-x86_64-unknown-linux-gnu.tar.gz \
Expand Down Expand Up @@ -199,7 +178,6 @@ jobs:
release/*.tar.gz
release/*.deb
release/*.rpm
release/*.whl

- name: Upload assembled release assets
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
Expand Down Expand Up @@ -428,7 +406,6 @@ jobs:
release/openshell-prover-x86_64-unknown-linux-musl.tar.gz
release/openshell-prover-aarch64-unknown-linux-musl.tar.gz
release/openshell-prover-aarch64-apple-darwin.tar.gz
release/*.whl
release/openshell.rb
release/openshell-checksums-sha256.txt
release/openshell-gateway-checksums-sha256.txt
Expand Down Expand Up @@ -522,19 +499,6 @@ jobs:
buf push proto --label "${RELEASE_TAG}" \
--source-control-url "${SOURCE_CONTROL_URL}"

publish-pypi:
name: Publish Python Wheel
needs: release
if: ${{ !inputs.is-prerelease }}
permissions:
contents: read
id-token: write
uses: ./.github/workflows/wheel-publish.yml
with:
release-tag: ${{ inputs.release-tag }}
source-sha: ${{ inputs.source-sha }}
python-version: ${{ inputs.python-version }}

publish-snap:
name: Publish Snap
needs: release
Expand Down Expand Up @@ -600,7 +564,6 @@ jobs:
- tag-ghcr-release
- release-helm
- release
- publish-pypi
- publish-snap
- publish-prerelease-snap
- publish-sdk-typescript
Expand All @@ -620,7 +583,7 @@ jobs:
if [[ "${IS_PRERELEASE}" == "true" ]]; then
expected+=(publish-prerelease-snap)
else
expected+=(publish-pypi publish-sdk-typescript tag-sdk-go)
expected+=(publish-sdk-typescript tag-sdk-go)
if [[ "${MAKE_LATEST}" == "true" ]]; then
expected+=(publish-snap)
fi
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
concurrency:
group: ${{ inputs.notes-only && format('release-notes-preview-{0}', github.ref) || 'release-stable' }}
cancel-in-progress: false
queue: max

Check failure on line 25 in .github/workflows/release.yml

View workflow job for this annotation

GitHub Actions / Actionlint (informational)

unexpected key "queue" for "concurrency" section. expected one of "cancel-in-progress", "group"

jobs:
preview-notes:
Expand Down Expand Up @@ -153,7 +153,6 @@
release-tag: ${{ needs.promote.outputs.tag }}
source-sha: ${{ needs.build.outputs.source_sha }}
semver: ${{ needs.build.outputs.semver }}
python-version: ${{ needs.build.outputs.python_version }}
npm-version: ${{ needs.build.outputs.npm_version }}
is-prerelease: false
make-latest: ${{ needs.promote.outputs.make-latest == 'true' }}
Expand Down
92 changes: 0 additions & 92 deletions .github/workflows/wheel-publish.yml

This file was deleted.

Loading
Loading