Skip to content

chore(license): align repository compliance text (#3467) #1255

chore(license): align repository compliance text (#3467)

chore(license): align repository compliance text (#3467) #1255

Workflow file for this run

name: Release Dev
on:
push:
branches: [main]
workflow_dispatch:
permissions:
contents: read
packages: read
defaults:
run:
shell: bash
jobs:
# ---------------------------------------------------------------------------
# Compute all versions once at the start to avoid git-describe race conditions
# ---------------------------------------------------------------------------
compute-versions:
name: Compute Versions
runs-on: linux-amd64-cpu8
timeout-minutes: 5
container:
image: ghcr.io/nvidia/openshell/ci:latest
credentials:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
outputs:
python_version: ${{ steps.v.outputs.python }}
docs_version: ${{ steps.v.outputs.docs_version }}
cargo_version: ${{ steps.v.outputs.cargo }}
deb_version: ${{ steps.v.outputs.deb }}
rpm_version: ${{ steps.v.outputs.rpm_version }}
rpm_release: ${{ steps.v.outputs.rpm_release }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- name: Mark workspace safe for git
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Fetch tags
run: git fetch --tags --force
- name: Compute all versions
id: v
run: |
set -euo pipefail
python_version=$(uv run python tasks/scripts/release.py get-version --dev --python)
{
echo "python=${python_version}"
echo "docs_version=${python_version%%+*}"
echo "cargo=$(uv run python tasks/scripts/release.py get-version --dev --cargo)"
echo "deb=$(uv run python tasks/scripts/release.py get-version --dev --deb)"
echo "rpm_version=$(uv run python tasks/scripts/release.py get-version --dev --rpm-version)"
echo "rpm_release=$(uv run python tasks/scripts/release.py get-version --dev --rpm-release)"
} >> "$GITHUB_OUTPUT"
build-binaries:
needs: compute-versions
permissions:
contents: read
uses: ./.github/workflows/build-binaries.yml
with:
cargo-version: ${{ needs.compute-versions.outputs.cargo_version }}
supervisor-image-tag: dev
checkout-ref: ${{ github.sha }}
secrets:
CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }}
build-vm-driver:
needs: [compute-versions, build-binaries]
permissions:
contents: read
uses: ./.github/workflows/build-vm-driver.yml
with:
cargo-version: ${{ needs.compute-versions.outputs.cargo_version }}
supervisor-image-tag: dev
checkout-ref: ${{ github.sha }}
secrets:
CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }}
package-binaries:
needs: [build-binaries, build-vm-driver]
permissions:
actions: read
contents: read
uses: ./.github/workflows/package-release-binaries.yml
with:
checkout-ref: ${{ github.sha }}
build-images:
needs: build-binaries
permissions:
contents: read
packages: write
uses: ./.github/workflows/build-images.yml
with:
checkout-ref: ${{ github.sha }}
prepare-integration:
needs: [build-binaries, build-images]
permissions:
actions: read
contents: read
packages: read
uses: ./.github/workflows/prepare-integration-inputs.yml
conformance-integration:
needs: prepare-integration
permissions:
actions: read
contents: read
packages: read
uses: ./.github/workflows/integration-runner.yml
with:
category: conformance
source-sha: ${{ needs.prepare-integration.outputs.source_sha }}
integration-inputs-artifact-id: ${{ needs.prepare-integration.outputs.integration_inputs_artifact_id }}
feature-specific-integration:
needs: prepare-integration
permissions:
actions: read
contents: read
packages: read
uses: ./.github/workflows/integration-runner.yml
with:
category: feature-specific
source-sha: ${{ needs.prepare-integration.outputs.source_sha }}
integration-inputs-artifact-id: ${{ needs.prepare-integration.outputs.integration_inputs_artifact_id }}
test-matrix: >-
[
{"environment":"fedora-podman-rootful","installer":"binaries","testsuite":"provider-refresh"},
{"environment":"fedora-podman-rootless","installer":"binaries","testsuite":"provider-refresh"}
]
docker-e2e:
needs: [build-binaries, build-images]
permissions:
actions: read
contents: read
packages: read
uses: ./.github/workflows/e2e-docker-test.yml
with:
image-tag: ${{ github.sha }}
checkout-ref: ${{ github.sha }}
runner: linux-arm64-cpu8
conformance-artifact-prefix: openshell-conformance
vm-e2e:
needs: [build-binaries, build-vm-driver]
permissions:
actions: read
contents: read
packages: read
uses: ./.github/workflows/e2e-vm-test.yml
with:
checkout-ref: ${{ github.sha }}
conformance-artifact-prefix: openshell-conformance
tag-ghcr-dev:
name: Tag GHCR Images as Dev
needs: [build-images, release-dev]
runs-on: linux-amd64-cpu8
timeout-minutes: 10
permissions:
packages: write
steps:
- name: Log in to GHCR
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u "${GITHUB_ACTOR}" --password-stdin
- name: Tag images as dev
run: |
set -euo pipefail
REGISTRY="ghcr.io/nvidia/openshell"
for component in gateway sandbox supervisor; do
echo "Tagging ${REGISTRY}/${component}:${{ github.sha }} as dev..."
docker buildx imagetools create \
--prefer-index=false \
-t "${REGISTRY}/${component}:dev" \
"${REGISTRY}/${component}:${{ github.sha }}"
done
build-python-wheel:
name: Build Python Wheel
needs: [compute-versions]
runs-on: linux-amd64-cpu8
timeout-minutes: 20
container:
image: ghcr.io/nvidia/openshell/ci:latest
credentials:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
env:
MISE_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
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: ${{ github.sha }}
- name: Mark workspace safe for git
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Sync Python dependencies
run: uv sync
- name: Build Python wheel
run: |
set -euo pipefail
mise run python:build
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]
uses: ./.github/workflows/deb-package.yml
with:
deb-version: ${{ needs.compute-versions.outputs.deb_version }}
checkout-ref: ${{ github.sha }}
build-snap:
name: Build Snap
needs: [compute-versions, build-binaries]
uses: ./.github/workflows/snap-package.yml
with:
checkout-ref: ${{ github.sha }}
upload-channel: latest/edge
github-environment: latest/edge
secrets:
publish-credentials: ${{ secrets.SNAPCRAFT_STORE_CREDENTIALS }}
build-rpm:
name: Build RPM Packages
needs: [compute-versions, build-binaries]
uses: ./.github/workflows/rpm-package.yml
with:
checkout-ref: ${{ github.sha }}
rpm-version: ${{ needs.compute-versions.outputs.rpm_version }}
rpm-release: ${{ needs.compute-versions.outputs.rpm_release }}
cargo-version: ${{ needs.compute-versions.outputs.cargo_version }}
# ---------------------------------------------------------------------------
# Create / update the dev GitHub Release with CLI, gateway, driver, and wheels
# ---------------------------------------------------------------------------
release-dev:
name: Release Dev
needs:
- compute-versions
- package-binaries
- build-python-wheel
- conformance-integration
- feature-specific-integration
- docker-e2e
- vm-e2e
- build-deb
- build-rpm
- build-snap
runs-on: linux-amd64-cpu8
timeout-minutes: 10
permissions:
contents: write
id-token: write
attestations: write
artifact-metadata: write
outputs:
wheel_filenames: ${{ steps.wheel_filenames.outputs.wheel_filenames }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Download all CLI artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: cli-*
path: release/
merge-multiple: true
- name: Download gateway binary artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: gateway-binary-*
path: release/
merge-multiple: true
- name: Download supervisor binary artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: supervisor-binary-*
path: release/
merge-multiple: true
- name: Download sandbox binary artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: sandbox-binary-*
path: release/
merge-multiple: true
- name: Download VM driver artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: driver-vm-*
path: release/
merge-multiple: true
- name: Download prover binary artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: prover-binary-*
path: release/
merge-multiple: true
- name: Download prover checksums
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
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:
pattern: deb-linux-*
path: release/
merge-multiple: true
- name: Download RPM package artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: rpm-linux-*
path: release/
merge-multiple: true
- name: Download snap artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: snap-linux-*
path: release/
merge-multiple: true
- name: Normalize dev package filenames
run: |
set -euo pipefail
shopt -s nullglob
move_one() {
local dest="$1"
shift
local matches=("$@")
if [ "${#matches[@]}" -ne 1 ]; then
echo "expected exactly one source for ${dest}, found ${#matches[@]}: ${matches[*]-}" >&2
exit 1
fi
mv "${matches[0]}" "release/${dest}"
}
move_one openshell-dev-amd64.deb release/openshell_*_amd64.deb
move_one openshell-dev-arm64.deb release/openshell_*_arm64.deb
move_one openshell-dev-x86_64.rpm release/openshell-[0-9]*.x86_64.rpm
move_one openshell-dev-aarch64.rpm release/openshell-[0-9]*.aarch64.rpm
move_one openshell-gateway-dev-x86_64.rpm release/openshell-gateway-[0-9]*.x86_64.rpm
move_one openshell-gateway-dev-aarch64.rpm release/openshell-gateway-[0-9]*.aarch64.rpm
ls -la release/
- name: Capture wheel filenames
id: wheel_filenames
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
wheel_filename=$(basename "${wheels[0]}")
echo "wheel_filenames=${wheel_filename}" >> "$GITHUB_OUTPUT"
- name: Generate checksums
run: |
set -euo pipefail
cd release
sha256sum -- \
openshell-x86_64-unknown-linux-musl.tar.gz \
openshell-aarch64-unknown-linux-musl.tar.gz \
openshell-aarch64-apple-darwin.tar.gz \
openshell-driver-vm-x86_64-unknown-linux-gnu.tar.gz \
openshell-driver-vm-aarch64-unknown-linux-gnu.tar.gz \
openshell-driver-vm-aarch64-apple-darwin.tar.gz \
*.deb \
openshell-*.rpm \
*.whl > openshell-checksums-sha256.txt
cat openshell-checksums-sha256.txt
sha256sum -- \
openshell-gateway-x86_64-unknown-linux-gnu.tar.gz \
openshell-gateway-aarch64-unknown-linux-gnu.tar.gz \
openshell-gateway-aarch64-apple-darwin.tar.gz > openshell-gateway-checksums-sha256.txt
cat openshell-gateway-checksums-sha256.txt
sha256sum -- \
openshell-sandbox-x86_64-unknown-linux-musl.tar.gz \
openshell-sandbox-aarch64-unknown-linux-musl.tar.gz > openshell-sandbox-checksums-sha256.txt
cat openshell-sandbox-checksums-sha256.txt
sha256sum -- \
openshell-supervisor-x86_64-unknown-linux-gnu.tar.gz \
openshell-supervisor-aarch64-unknown-linux-gnu.tar.gz > openshell-supervisor-checksums-sha256.txt
cat openshell-supervisor-checksums-sha256.txt
- name: Generate Homebrew formula
run: |
set -euo pipefail
python3 tasks/scripts/release.py generate-homebrew-formula \
--release-tag dev \
--release-dir release \
--output release/openshell.rb
cat release/openshell.rb
- name: Attest VM driver artifacts
uses: actions/attest@508db95dd578ae2727ebd6217d5ba78e4fbda05d # v4.2.1
with:
subject-path: |
release/openshell-driver-vm-x86_64-unknown-linux-gnu.tar.gz
release/openshell-driver-vm-aarch64-unknown-linux-gnu.tar.gz
release/openshell-driver-vm-aarch64-apple-darwin.tar.gz
- name: Prune managed assets from dev release
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
with:
script: |
const [owner, repo] = process.env.GITHUB_REPOSITORY.split('/');
// Fetch the dev release
let release;
try {
release = await github.rest.repos.getReleaseByTag({ owner, repo, tag: 'dev' });
} catch (err) {
if (err.status === 404) {
core.info('No existing dev release found; skipping managed asset pruning.');
return;
}
throw err;
}
const assets = release.data.assets;
core.info(`=== Current dev release assets (${assets.length} total) ===`);
for (const a of assets) {
core.info(` ${String(a.id).padStart(12)} ${a.name}`);
}
const managed = (name) => (
name.startsWith('openshell') &&
(
name.endsWith('.tar.gz') ||
name.endsWith('.txt') ||
name.endsWith('.whl') ||
name.endsWith('.deb') ||
name.endsWith('.rpm') ||
name.endsWith('.snap')
)
);
let deleted = 0, skipped = 0;
for (const asset of assets) {
if (managed(asset.name)) {
core.info(`Deleting managed dev asset: ${asset.name} (id=${asset.id})`);
await github.rest.repos.deleteReleaseAsset({ owner, repo, asset_id: asset.id });
deleted++;
} else {
core.info(`Skipping unmanaged asset: ${asset.name}`);
skipped++;
}
}
core.info(`Summary: deleted=${deleted}, skipped=${skipped}`);
- name: Move dev tag
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git tag -fa dev -m "Latest Dev" "${GITHUB_SHA}"
git push --force origin dev
- name: Create / update GitHub Release
uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2
with:
name: OpenShell Development Build
prerelease: true
tag_name: dev
target_commitish: ${{ github.sha }}
body: |
This build is automatically published on every commit to main that passes CI.
> **NOTE**: This is a development build, not a tagged release, and may be unstable.
### Quick install
```
curl -LsSf https://raw.githubusercontent.com/NVIDIA/OpenShell/main/install.sh | OPENSHELL_VERSION=dev sh
```
files: |
release/openshell-x86_64-unknown-linux-musl.tar.gz
release/openshell-aarch64-unknown-linux-musl.tar.gz
release/openshell-aarch64-apple-darwin.tar.gz
release/openshell-dev-amd64.deb
release/openshell-dev-arm64.deb
release/openshell-*.rpm
release/*.snap
release/openshell-gateway-x86_64-unknown-linux-gnu.tar.gz
release/openshell-gateway-aarch64-unknown-linux-gnu.tar.gz
release/openshell-gateway-aarch64-apple-darwin.tar.gz
release/openshell-sandbox-x86_64-unknown-linux-musl.tar.gz
release/openshell-sandbox-aarch64-unknown-linux-musl.tar.gz
release/openshell-supervisor-x86_64-unknown-linux-gnu.tar.gz
release/openshell-supervisor-aarch64-unknown-linux-gnu.tar.gz
release/openshell-driver-vm-x86_64-unknown-linux-gnu.tar.gz
release/openshell-driver-vm-aarch64-unknown-linux-gnu.tar.gz
release/openshell-driver-vm-aarch64-apple-darwin.tar.gz
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
release/openshell-sandbox-checksums-sha256.txt
release/openshell-supervisor-checksums-sha256.txt
release/openshell-prover-checksums-sha256.txt
release-helm:
name: Release Helm Chart (OCI, dev)
needs: [release-dev, tag-ghcr-dev]
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
packages: write
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: ./.github/actions/release-helm-oci
with:
chart-version: 0.0.0-dev
app-version: dev
release-kind: dev
pin-sha: ${{ github.sha }}
publish-fern-docs:
name: Sync and Publish Fern Docs
needs: [compute-versions, release-dev, release-helm, trigger-wheel-publish]
permissions:
contents: write
uses: ./.github/workflows/sync-docs.yml
with:
operation: sync
channel: dev
source_ref: ${{ github.sha }}
release_version: ${{ needs.compute-versions.outputs.docs_version }}
display_name: Dev
availability: beta
publish: true
secrets:
FERN_TOKEN: ${{ secrets.FERN_TOKEN }}
trigger-wheel-publish:
name: Trigger Wheel Publish
needs: [compute-versions, release-dev]
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 }}
RELEASE_VERSION: ${{ needs.compute-versions.outputs.python_version }}
WHEEL_FILENAMES: ${{ needs.release-dev.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]=${GITHUB_SHA}" \
-F "variables[RELEASE_TAG]=dev" \
-F "variables[RELEASE_VERSION]=${RELEASE_VERSION}" \
-F "variables[RELEASE_KIND]=dev" \
-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}"