mirror of
https://github.com/NVIDIA/OpenShell.git
synced 2026-10-31 07:44:57 +08:00
ci(release): allow release publishers to be dispatched individually (#4987)
* ci(release): allow release publishers to be dispatched individually
Move the TypeScript SDK and wheel publishers into reusable workflows and add
workflow_dispatch to them and to snap-publish.yml, following sync-docs.yml.
Release still calls each one. A maintainer can now publish one missing
component for an existing release without rebuilding or rerunning Release.
The snap publisher can upload artifacts from an earlier run, and a manual
latest/stable upload requires a release tag so it still rechecks the newest
stable release.
Signed-off-by: Matthew Grossman <mgrossman@nvidia.com>
* ci(release): allow the Go SDK tag to be dispatched individually
Signed-off-by: Matthew Grossman <mgrossman@nvidia.com>
* ci(release): verify dispatched snap and wheel inputs match the release
A dispatched snap upload checks that its artifacts were built for the
release tag. A wheel publish first confirms the tag points to the given
commit and that each wheel is attached to that release at the given
version. artifact-run-id is declared on workflow_call so callers do not
rely on an undeclared input.
Signed-off-by: Matthew Grossman <mgrossman@nvidia.com>
* ci(release): verify the provenance of dispatched snap artifacts
A manual snap upload now requires artifact-run-id to be this repository's
publishing workflow for the channel, and stable snaps must match the GitHub
Release asset digests. A skipped stable upload now reports a notice.
Signed-off-by: Matthew Grossman <mgrossman@nvidia.com>
* Revert "ci(release): verify the provenance of dispatched snap artifacts"
This reverts commit 8bcf1e1e73.
Signed-off-by: Matthew Grossman <mgrossman@nvidia.com>
---------
Signed-off-by: Matthew Grossman <mgrossman@nvidia.com>
This commit is contained in:
@@ -265,12 +265,15 @@ jobs:
|
||||
publish-snap:
|
||||
name: Publish snap
|
||||
needs: build-snap
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
uses: ./.github/workflows/snap-publish.yml
|
||||
with:
|
||||
upload-channel: latest/edge
|
||||
github-environment: latest/edge
|
||||
secrets:
|
||||
publish-credentials: ${{ secrets.SNAPCRAFT_STORE_CREDENTIALS }}
|
||||
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_STORE_CREDENTIALS }}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Create / update the dev GitHub Release with CLI, gateway, driver, and wheels
|
||||
|
||||
@@ -509,161 +509,70 @@ jobs:
|
||||
name: Publish Snap
|
||||
needs: release
|
||||
if: ${{ !inputs.is-prerelease && inputs.make-latest }}
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
uses: ./.github/workflows/snap-publish.yml
|
||||
with:
|
||||
upload-channel: latest/stable
|
||||
github-environment: latest/stable
|
||||
release-tag: ${{ inputs.release-tag }}
|
||||
secrets:
|
||||
publish-credentials: ${{ secrets.SNAPCRAFT_STORE_CREDENTIALS }}
|
||||
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_STORE_CREDENTIALS }}
|
||||
|
||||
publish-prerelease-snap:
|
||||
name: Publish Prerelease Snap
|
||||
needs: release
|
||||
if: inputs.is-prerelease
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
uses: ./.github/workflows/snap-publish.yml
|
||||
with:
|
||||
upload-channel: latest/beta
|
||||
release-tag: ${{ inputs.release-tag }}
|
||||
github-environment: latest/beta
|
||||
secrets:
|
||||
publish-credentials: ${{ secrets.SNAPCRAFT_STORE_CREDENTIALS }}
|
||||
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_STORE_CREDENTIALS }}
|
||||
|
||||
publish-sdk-typescript:
|
||||
name: Publish TypeScript SDK
|
||||
needs: release
|
||||
if: ${{ !inputs.is-prerelease }}
|
||||
runs-on: linux-amd64-cpu8
|
||||
timeout-minutes: 15
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
defaults:
|
||||
run:
|
||||
shell: nix shell --inputs-from . nixpkgs#nodejs_24 -c bash -euo pipefail {0}
|
||||
steps:
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
ref: ${{ inputs.source-sha }}
|
||||
uses: ./.github/workflows/sdk-typescript-publish.yml
|
||||
with:
|
||||
release-tag: ${{ inputs.release-tag }}
|
||||
source-ref: ${{ inputs.source-sha }}
|
||||
npm-version: ${{ inputs.npm-version }}
|
||||
make-latest: ${{ inputs.make-latest }}
|
||||
|
||||
- uses: ./.github/actions/setup-nix
|
||||
|
||||
- name: Install TypeScript dependencies
|
||||
working-directory: ./sdk/typescript
|
||||
run: npm ci
|
||||
|
||||
- name: Configure npm auth for GitHub Packages
|
||||
working-directory: ./sdk/typescript
|
||||
run: |
|
||||
{
|
||||
echo "@nvidia:registry=https://npm.pkg.github.com"
|
||||
# Keep the token reference literal for npm to expand at publish time.
|
||||
# shellcheck disable=SC2016
|
||||
echo '//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}'
|
||||
} > .npmrc
|
||||
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
if: inputs.make-latest
|
||||
with:
|
||||
persist-credentials: false
|
||||
ref: ${{ github.workflow_sha }}
|
||||
path: release-workflow
|
||||
sparse-checkout: .github/actions/check-latest-release
|
||||
|
||||
- name: Check current latest release
|
||||
id: latest
|
||||
if: inputs.make-latest
|
||||
uses: ./release-workflow/.github/actions/check-latest-release
|
||||
with:
|
||||
release-tag: ${{ inputs.release-tag }}
|
||||
|
||||
- name: Publish
|
||||
working-directory: ./sdk/typescript
|
||||
env:
|
||||
OPENSHELL_NPM_VERSION: ${{ inputs.npm-version }}
|
||||
MAKE_LATEST: ${{ steps.latest.outputs.make-latest }}
|
||||
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
npm pkg set version="${OPENSHELL_NPM_VERSION}"
|
||||
dist_tag=latest
|
||||
if [[ "${MAKE_LATEST}" != "true" ]]; then
|
||||
dist_tag="release-${OPENSHELL_NPM_VERSION%.*}"
|
||||
fi
|
||||
npm publish --tag "${dist_tag}"
|
||||
|
||||
# Go resolves submodule versions from directory-prefixed tags, so the SDK at
|
||||
# sdk/go needs its own sdk/go/vX.Y.Z tag to show up as a release on pkg.go.dev.
|
||||
tag-sdk-go:
|
||||
name: Tag Go SDK
|
||||
needs: release
|
||||
if: ${{ !inputs.is-prerelease }}
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
permissions:
|
||||
contents: write
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
VERSION: ${{ inputs.semver }}
|
||||
SOURCE_SHA: ${{ inputs.source-sha }}
|
||||
steps:
|
||||
- name: Create Go SDK tag
|
||||
run: |
|
||||
set -euo pipefail
|
||||
tag="sdk/go/v${VERSION}"
|
||||
# Lightweight tag, so the ref points at the commit directly.
|
||||
if ! existing=$(gh api "repos/${GITHUB_REPOSITORY}/git/ref/tags/${tag}" --jq .object.sha 2>/dev/null); then
|
||||
gh api "repos/${GITHUB_REPOSITORY}/git/refs" -f ref="refs/tags/${tag}" -f sha="${SOURCE_SHA}"
|
||||
elif [[ "${existing}" != "${SOURCE_SHA}" ]]; then
|
||||
echo "${tag} already exists at ${existing}, expected ${SOURCE_SHA}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# pkg.go.dev picks up versions the Go module proxy has fetched.
|
||||
- name: Request version from Go module proxy
|
||||
continue-on-error: true
|
||||
run: curl --fail --silent --show-error --max-time 60 "https://proxy.golang.org/github.com/!n!v!i!d!i!a/!open!shell/sdk/go/@v/v${VERSION}.info"
|
||||
uses: ./.github/workflows/sdk-go-tag.yml
|
||||
with:
|
||||
version: ${{ inputs.semver }}
|
||||
source-sha: ${{ inputs.source-sha }}
|
||||
|
||||
trigger-wheel-publish:
|
||||
name: Trigger Wheel Publish
|
||||
needs: release
|
||||
if: ${{ !inputs.is-prerelease }}
|
||||
runs-on: [self-hosted, nv]
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- name: Trigger GitLab CI
|
||||
env:
|
||||
GITLAB_CI_TRIGGER_TOKEN: ${{ secrets.GITLAB_CI_TRIGGER_TOKEN }}
|
||||
GITLAB_CI_TRIGGER_URL: ${{ secrets.GITLAB_CI_TRIGGER_URL }}
|
||||
COMMIT_SHA: ${{ inputs.source-sha }}
|
||||
RELEASE_VERSION: ${{ inputs.python-version }}
|
||||
RELEASE_TAG: ${{ env.RELEASE_TAG }}
|
||||
WHEEL_FILENAMES: ${{ needs.release.outputs.wheel_filenames }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
if [ -z "${WHEEL_FILENAMES}" ]; then
|
||||
echo "No wheel filenames provided by build job" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
response=$(curl -X POST \
|
||||
--fail \
|
||||
--silent \
|
||||
--show-error \
|
||||
-F "token=${GITLAB_CI_TRIGGER_TOKEN}" \
|
||||
-F "ref=main" \
|
||||
-F "variables[PIPELINE_ACTION]=publish_wheels" \
|
||||
-F "variables[GITHUB_REPOSITORY]=${GITHUB_REPOSITORY}" \
|
||||
-F "variables[COMMIT_SHA]=${COMMIT_SHA}" \
|
||||
-F "variables[RELEASE_TAG]=${RELEASE_TAG}" \
|
||||
-F "variables[RELEASE_VERSION]=${RELEASE_VERSION}" \
|
||||
-F "variables[RELEASE_KIND]=stable" \
|
||||
-F "variables[WHEEL_FILENAMES]=${WHEEL_FILENAMES}" \
|
||||
"${GITLAB_CI_TRIGGER_URL}")
|
||||
pipeline_id=$(printf '%s' "$response" | sed -n 's/.*"id":\([0-9][0-9]*\).*/\1/p')
|
||||
pipeline_status=$(printf '%s' "$response" | sed -n 's/.*"status":"\([^"]*\)".*/\1/p')
|
||||
echo "Triggered GitLab pipeline ${pipeline_id:-unknown} with status=${pipeline_status:-unknown}"
|
||||
uses: ./.github/workflows/wheel-publish.yml
|
||||
with:
|
||||
release-tag: ${{ inputs.release-tag }}
|
||||
source-sha: ${{ inputs.source-sha }}
|
||||
python-version: ${{ inputs.python-version }}
|
||||
wheel-filenames: ${{ needs.release.outputs.wheel_filenames }}
|
||||
secrets:
|
||||
GITLAB_CI_TRIGGER_TOKEN: ${{ secrets.GITLAB_CI_TRIGGER_TOKEN }}
|
||||
GITLAB_CI_TRIGGER_URL: ${{ secrets.GITLAB_CI_TRIGGER_URL }}
|
||||
|
||||
publish-fern-docs:
|
||||
name: Sync and Publish Fern Docs
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# Go resolves submodule versions from directory-prefixed tags, so the SDK at
|
||||
# sdk/go needs its own sdk/go/vX.Y.Z tag to show up as a release on pkg.go.dev.
|
||||
name: Tag Go SDK
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
version:
|
||||
required: true
|
||||
type: string
|
||||
source-sha:
|
||||
required: true
|
||||
type: string
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: Release version without the v prefix, e.g. 0.1.6
|
||||
required: true
|
||||
type: string
|
||||
source-sha:
|
||||
description: Commit the stable tag points to
|
||||
required: true
|
||||
type: string
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
tag:
|
||||
name: Tag Go SDK
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
VERSION: ${{ inputs.version }}
|
||||
SOURCE_SHA: ${{ inputs.source-sha }}
|
||||
steps:
|
||||
- name: Create Go SDK tag
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
tag="sdk/go/v${VERSION}"
|
||||
# Lightweight tag, so the ref points at the commit directly.
|
||||
if ! existing=$(gh api "repos/${GITHUB_REPOSITORY}/git/ref/tags/${tag}" --jq .object.sha 2>/dev/null); then
|
||||
gh api "repos/${GITHUB_REPOSITORY}/git/refs" -f ref="refs/tags/${tag}" -f sha="${SOURCE_SHA}"
|
||||
elif [[ "${existing}" != "${SOURCE_SHA}" ]]; then
|
||||
echo "${tag} already exists at ${existing}, expected ${SOURCE_SHA}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# pkg.go.dev picks up versions the Go module proxy has fetched.
|
||||
- name: Request version from Go module proxy
|
||||
continue-on-error: true
|
||||
shell: bash
|
||||
run: curl --fail --silent --show-error --max-time 60 "https://proxy.golang.org/github.com/!n!v!i!d!i!a/!open!shell/sdk/go/@v/v${VERSION}.info"
|
||||
@@ -0,0 +1,102 @@
|
||||
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: Publish TypeScript SDK
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
release-tag:
|
||||
required: true
|
||||
type: string
|
||||
source-ref:
|
||||
description: Commit to build the package from
|
||||
required: true
|
||||
type: string
|
||||
npm-version:
|
||||
required: true
|
||||
type: string
|
||||
make-latest:
|
||||
description: Whether this release may update the npm latest dist-tag
|
||||
required: false
|
||||
default: false
|
||||
type: boolean
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
release-tag:
|
||||
description: Stable tag to publish, e.g. v0.1.6
|
||||
required: true
|
||||
type: string
|
||||
npm-version:
|
||||
description: npm package version, e.g. 0.1.6
|
||||
required: true
|
||||
type: string
|
||||
make-latest:
|
||||
description: Update the latest dist-tag if this is still the newest stable release
|
||||
required: false
|
||||
default: true
|
||||
type: boolean
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
name: Publish TypeScript SDK
|
||||
runs-on: linux-amd64-cpu8
|
||||
timeout-minutes: 15
|
||||
defaults:
|
||||
run:
|
||||
shell: nix shell --inputs-from . nixpkgs#nodejs_24 -c bash -euo pipefail {0}
|
||||
steps:
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
ref: ${{ inputs.source-ref || inputs.release-tag }}
|
||||
|
||||
- uses: ./.github/actions/setup-nix
|
||||
|
||||
- name: Install TypeScript dependencies
|
||||
working-directory: ./sdk/typescript
|
||||
run: npm ci
|
||||
|
||||
- name: Configure npm auth for GitHub Packages
|
||||
working-directory: ./sdk/typescript
|
||||
run: |
|
||||
{
|
||||
echo "@nvidia:registry=https://npm.pkg.github.com"
|
||||
# Keep the token reference literal for npm to expand at publish time.
|
||||
# shellcheck disable=SC2016
|
||||
echo '//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}'
|
||||
} > .npmrc
|
||||
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
if: inputs.make-latest
|
||||
with:
|
||||
persist-credentials: false
|
||||
ref: ${{ github.workflow_sha }}
|
||||
path: release-workflow
|
||||
sparse-checkout: .github/actions/check-latest-release
|
||||
|
||||
- name: Check current latest release
|
||||
id: latest
|
||||
if: inputs.make-latest
|
||||
uses: ./release-workflow/.github/actions/check-latest-release
|
||||
with:
|
||||
release-tag: ${{ inputs.release-tag }}
|
||||
|
||||
- name: Publish
|
||||
working-directory: ./sdk/typescript
|
||||
env:
|
||||
OPENSHELL_NPM_VERSION: ${{ inputs.npm-version }}
|
||||
MAKE_LATEST: ${{ steps.latest.outputs.make-latest }}
|
||||
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
npm pkg set version="${OPENSHELL_NPM_VERSION}"
|
||||
dist_tag=latest
|
||||
if [[ "${MAKE_LATEST}" != "true" ]]; then
|
||||
dist_tag="release-${OPENSHELL_NPM_VERSION%.*}"
|
||||
fi
|
||||
npm publish --tag "${dist_tag}"
|
||||
@@ -17,11 +17,36 @@ on:
|
||||
required: false
|
||||
type: string
|
||||
default: ""
|
||||
artifact-run-id:
|
||||
description: Run whose snap-linux-* artifacts are uploaded; defaults to the current run
|
||||
required: false
|
||||
type: string
|
||||
default: ""
|
||||
secrets:
|
||||
publish-credentials:
|
||||
SNAPCRAFT_STORE_CREDENTIALS:
|
||||
required: true
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
upload-channel:
|
||||
description: Snap Store channel, also used as the GitHub environment
|
||||
required: true
|
||||
type: choice
|
||||
options:
|
||||
- latest/stable
|
||||
- latest/beta
|
||||
- latest/edge
|
||||
release-tag:
|
||||
description: Stable tag to recheck before updating the stable channel; required for latest/stable
|
||||
required: false
|
||||
type: string
|
||||
default: ""
|
||||
artifact-run-id:
|
||||
description: Run whose snap-linux-* artifacts are uploaded
|
||||
required: true
|
||||
type: string
|
||||
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
|
||||
defaults:
|
||||
@@ -40,7 +65,7 @@ jobs:
|
||||
runner: linux-arm64-cpu8
|
||||
runs-on: ${{ matrix.runner }}
|
||||
timeout-minutes: 10
|
||||
environment: ${{ inputs.github-environment }}
|
||||
environment: ${{ inputs.github-environment || inputs.upload-channel }}
|
||||
concurrency:
|
||||
group: snap-publish-${{ inputs.upload-channel }}-${{ matrix.arch }}
|
||||
cancel-in-progress: false
|
||||
@@ -58,6 +83,8 @@ jobs:
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
with:
|
||||
name: snap-linux-${{ matrix.arch }}
|
||||
run-id: ${{ inputs.artifact-run-id || github.run_id }}
|
||||
github-token: ${{ inputs.artifact-run-id && github.token || '' }}
|
||||
|
||||
- name: Install snapcraft
|
||||
run: |
|
||||
@@ -79,10 +106,15 @@ jobs:
|
||||
- name: Upload snap to Snap Store
|
||||
if: ${{ inputs.release-tag == '' || steps.latest.outputs.make-latest == 'true' }}
|
||||
env:
|
||||
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.publish-credentials }}
|
||||
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_STORE_CREDENTIALS }}
|
||||
INPUTS_UPLOAD_CHANNEL: ${{ inputs.upload-channel }}
|
||||
INPUTS_RELEASE_TAG: ${{ inputs.release-tag }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
if [[ "${INPUTS_UPLOAD_CHANNEL}" == latest/stable && -z "${INPUTS_RELEASE_TAG}" ]]; then
|
||||
echo "latest/stable uploads require release-tag" >&2
|
||||
exit 1
|
||||
fi
|
||||
shopt -s nullglob
|
||||
snaps=(*.snap)
|
||||
if [[ "${#snaps[@]}" -ne 1 ]]; then
|
||||
@@ -92,6 +124,11 @@ jobs:
|
||||
snap_file="${snaps[0]}"
|
||||
snap_name="${snap_file%.snap}"
|
||||
snap_name="${snap_name%%_*}"
|
||||
# Artifacts can come from another run, so confirm they were built for this tag.
|
||||
if [[ -n "${INPUTS_RELEASE_TAG}" && "${snap_file}" != "${snap_name}_${INPUTS_RELEASE_TAG#v}_"* ]]; then
|
||||
echo "${snap_file} was not built for ${INPUTS_RELEASE_TAG}" >&2
|
||||
exit 1
|
||||
fi
|
||||
component_args=()
|
||||
for comp in "${snap_name}"+*.comp; do
|
||||
component_file="${comp##*/}"
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: Publish Wheels
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
release-tag:
|
||||
required: true
|
||||
type: string
|
||||
source-sha:
|
||||
required: true
|
||||
type: string
|
||||
python-version:
|
||||
required: true
|
||||
type: string
|
||||
wheel-filenames:
|
||||
required: true
|
||||
type: string
|
||||
secrets:
|
||||
GITLAB_CI_TRIGGER_TOKEN:
|
||||
required: false
|
||||
GITLAB_CI_TRIGGER_URL:
|
||||
required: false
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
release-tag:
|
||||
description: Stable tag whose GitHub Release holds the wheels, e.g. v0.1.6
|
||||
required: true
|
||||
type: string
|
||||
source-sha:
|
||||
description: Commit the tag points to
|
||||
required: true
|
||||
type: string
|
||||
python-version:
|
||||
description: Python package version, e.g. 0.1.6
|
||||
required: true
|
||||
type: string
|
||||
wheel-filenames:
|
||||
description: Wheel filenames attached to the GitHub Release
|
||||
required: true
|
||||
type: string
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
# Dispatch inputs are free-form, so confirm they describe a published release.
|
||||
verify:
|
||||
name: Verify Release Inputs
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- name: Check tag, commit and wheels
|
||||
shell: bash
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
COMMIT_SHA: ${{ inputs.source-sha }}
|
||||
RELEASE_VERSION: ${{ inputs.python-version }}
|
||||
RELEASE_TAG: ${{ inputs.release-tag }}
|
||||
WHEEL_FILENAMES: ${{ inputs.wheel-filenames }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
tag_sha=$(gh api "repos/${GITHUB_REPOSITORY}/commits/${RELEASE_TAG}" --jq .sha)
|
||||
if [[ "${tag_sha}" != "${COMMIT_SHA}" ]]; then
|
||||
echo "${RELEASE_TAG} points to ${tag_sha}, not ${COMMIT_SHA}" >&2
|
||||
exit 1
|
||||
fi
|
||||
assets=$(gh release view "${RELEASE_TAG}" -R "${GITHUB_REPOSITORY}" --json assets --jq '.assets[].name')
|
||||
for wheel in ${WHEEL_FILENAMES//,/ }; do
|
||||
if ! grep -qxF "${wheel}" <<<"${assets}"; then
|
||||
echo "${wheel} is not attached to the ${RELEASE_TAG} release" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ "${wheel}" != *"-${RELEASE_VERSION}-"* ]]; then
|
||||
echo "${wheel} is not version ${RELEASE_VERSION}" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
trigger:
|
||||
name: Trigger Wheel Publish
|
||||
needs: verify
|
||||
runs-on: [self-hosted, nv]
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- name: Trigger GitLab CI
|
||||
shell: bash
|
||||
env:
|
||||
GITLAB_CI_TRIGGER_TOKEN: ${{ secrets.GITLAB_CI_TRIGGER_TOKEN }}
|
||||
GITLAB_CI_TRIGGER_URL: ${{ secrets.GITLAB_CI_TRIGGER_URL }}
|
||||
COMMIT_SHA: ${{ inputs.source-sha }}
|
||||
RELEASE_VERSION: ${{ inputs.python-version }}
|
||||
RELEASE_TAG: ${{ inputs.release-tag }}
|
||||
WHEEL_FILENAMES: ${{ inputs.wheel-filenames }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
if [ -z "${WHEEL_FILENAMES}" ]; then
|
||||
echo "No wheel filenames provided by build job" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
response=$(curl -X POST \
|
||||
--fail \
|
||||
--silent \
|
||||
--show-error \
|
||||
-F "token=${GITLAB_CI_TRIGGER_TOKEN}" \
|
||||
-F "ref=main" \
|
||||
-F "variables[PIPELINE_ACTION]=publish_wheels" \
|
||||
-F "variables[GITHUB_REPOSITORY]=${GITHUB_REPOSITORY}" \
|
||||
-F "variables[COMMIT_SHA]=${COMMIT_SHA}" \
|
||||
-F "variables[RELEASE_TAG]=${RELEASE_TAG}" \
|
||||
-F "variables[RELEASE_VERSION]=${RELEASE_VERSION}" \
|
||||
-F "variables[RELEASE_KIND]=stable" \
|
||||
-F "variables[WHEEL_FILENAMES]=${WHEEL_FILENAMES}" \
|
||||
"${GITLAB_CI_TRIGGER_URL}")
|
||||
pipeline_id=$(printf '%s' "$response" | sed -n 's/.*"id":\([0-9][0-9]*\).*/\1/p')
|
||||
pipeline_status=$(printf '%s' "$response" | sed -n 's/.*"status":"\([^"]*\)".*/\1/p')
|
||||
echo "Triggered GitLab pipeline ${pipeline_id:-unknown} with status=${pipeline_status:-unknown}"
|
||||
@@ -718,7 +718,10 @@ These workflows run after merge to publish dev/tagged artifacts and verify them.
|
||||
| `.github/workflows/release-notes.yml` | Shared prompt-driven release notes generation through Inference Hub, used by prerelease previews, notes-only previews, and stable publication when no preview is reused. |
|
||||
| `.github/workflows/release-qualification.yml` | Reusable qualification suites and result aggregation. Runs security scans, conformance and feature integration, Docker and VM E2E, protobuf compatibility, and advisory compatibility review. |
|
||||
| `.github/workflows/snap-package.yml` | Builds snap and component artifacts for Release Dev, Release, and Pre-release without Store credentials or publication. |
|
||||
| `.github/workflows/snap-publish.yml` | Uploads existing snap and component artifacts directly to a Store channel without rebuilding. Release Dev uses `latest/edge`, Pre-release uses `latest/beta`, and Release uses `latest/stable` for the stable rebuild. Uploads queue per channel and architecture, so tagged beta and stable jobs recheck repository tags after earlier publication finishes and before updating their floating channels. |
|
||||
| `.github/workflows/snap-publish.yml` | Uploads existing snap and component artifacts directly to a Store channel without rebuilding. Release Dev uses `latest/edge`, Pre-release uses `latest/beta`, and Release uses `latest/stable` for the stable rebuild. Uploads queue per channel and architecture, so tagged beta and stable jobs recheck repository tags after earlier publication finishes and before updating their floating channels. Manual dispatch uploads the `snap-linux-*` artifacts from `artifact-run-id`. |
|
||||
| `.github/workflows/sdk-typescript-publish.yml` | Publishes the TypeScript SDK to GitHub Packages. Called by stable Release; manual dispatch publishes a given tag and npm version. |
|
||||
| `.github/workflows/sdk-go-tag.yml` | Creates the `sdk/go/vX.Y.Z` tag and asks the Go module proxy to fetch it. Called by stable Release; manual dispatch tags a given version and commit. |
|
||||
| `.github/workflows/wheel-publish.yml` | Triggers the GitLab pipeline that publishes wheels from a GitHub Release to PyPI. Called by stable Release; manual dispatch republishes a given tag. |
|
||||
| `.github/workflows/release-canary.yml` | Smoke-tests published dev artifacts in the `macos`, `ubuntu-deb`, `ubuntu-snap-system-docker`, `fedora`, and `kubernetes` (kind + Helm) jobs. Each job reaches its gateway and creates, exercises, and deletes a sandbox. The `ubuntu-snap-system-docker` job verifies a compatible system Docker lifecycle, while `ubuntu-snap-docker-preflight` tests fail-fast behavior when Docker is absent or supplied by the Docker snap. The positive snap lane also runs a local policy containment check with the packaged prover. It runs automatically after `Release Dev` succeeds and supports manual dispatch (`gh workflow run release-canary.yml --ref <branch>`). See the `test-release-canary` skill for the playbook and local kind reproduction. |
|
||||
|
||||
## Required status contexts
|
||||
|
||||
Reference in New Issue
Block a user