diff --git a/.github/workflows/release-canary.yml b/.github/workflows/release-canary.yml index 9c209d0c9..49937847b 100644 --- a/.github/workflows/release-canary.yml +++ b/.github/workflows/release-canary.yml @@ -72,6 +72,47 @@ jobs: curl -LsSf https://raw.githubusercontent.com/NVIDIA/OpenShell/${{ github.event.workflow_run.head_sha || github.sha }}/install.sh | sh openshell status + ubuntu-snap: + name: Ubuntu Snap + if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }} + runs-on: ubuntu-24.04 + timeout-minutes: 20 + steps: + - name: Install snapd + run: | + sudo apt-get update + sudo apt-get install -y snapd + sudo systemctl start snapd + + - name: Install Docker snap + run: | + sudo snap install docker + + - name: Download snap from release + run: | + set -euo pipefail + SNAP_NAME=$(curl -sL "https://api.github.com/repos/NVIDIA/OpenShell/releases/tags/dev" | jq -r '.assets[].name' | grep -E 'openshell_.*amd64\.snap$' | head -1) + if [ -z "$SNAP_NAME" ]; then + echo "Could not find snap asset in dev release" + exit 1 + fi + curl -LsSf "https://github.com/NVIDIA/OpenShell/releases/download/dev/$SNAP_NAME" -o openshell.snap + + - name: Install snap (dangerous — from release, not store) + run: | + sudo snap install ./openshell.snap --dangerous + + - name: Connect interfaces + run: | + sudo snap connect openshell:docker docker:docker-daemon + sudo snap connect openshell:log-observe + sudo snap connect openshell:system-observe + sudo snap connect openshell:ssh-keys + + - name: Check status + run: | + openshell status + kubernetes: name: Kubernetes Helm (kind) if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }} diff --git a/.github/workflows/release-dev.yml b/.github/workflows/release-dev.yml index 5c8eac435..921295503 100644 --- a/.github/workflows/release-dev.yml +++ b/.github/workflows/release-dev.yml @@ -647,6 +647,17 @@ jobs: checkout-ref: ${{ github.sha }} secrets: inherit + build-snap: + name: Build Snap + needs: [compute-versions] + 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-cli-linux, build-gateway-binary-linux] @@ -697,7 +708,7 @@ jobs: # --------------------------------------------------------------------------- release-dev: name: Release Dev - needs: [compute-versions, build-cli-linux, build-cli-macos, build-gateway-binary-linux, build-gateway-binary-macos, build-supervisor-binary-linux, build-python-wheels-linux, build-python-wheel-macos, build-driver-vm-linux, build-driver-vm-macos, build-deb, build-rpm, smoke-linux-dev-artifacts] + needs: [compute-versions, build-cli-linux, build-cli-macos, build-gateway-binary-linux, build-gateway-binary-macos, build-supervisor-binary-linux, build-python-wheels-linux, build-python-wheel-macos, build-driver-vm-linux, build-driver-vm-macos, build-deb, build-rpm, build-snap, smoke-linux-dev-artifacts] runs-on: linux-amd64-cpu8 timeout-minutes: 10 permissions: @@ -759,6 +770,13 @@ jobs: 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 @@ -914,6 +932,7 @@ jobs: 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 diff --git a/.github/workflows/release-tag.yml b/.github/workflows/release-tag.yml index fc0f47480..de6a5b6f4 100644 --- a/.github/workflows/release-tag.yml +++ b/.github/workflows/release-tag.yml @@ -683,6 +683,17 @@ jobs: checkout-ref: ${{ inputs.tag || github.ref }} secrets: inherit + build-snap: + name: Build Snap + needs: [compute-versions] + uses: ./.github/workflows/snap-package.yml + with: + checkout-ref: ${{ inputs.tag || github.ref }} + upload-channel: latest/stable + github-environment: latest/stable + secrets: + publish-credentials: ${{ secrets.SNAPCRAFT_STORE_CREDENTIALS }} + build-rpm: name: Build RPM Packages needs: [compute-versions, build-cli-linux, build-gateway-binary-linux] @@ -807,7 +818,7 @@ jobs: # --------------------------------------------------------------------------- release: name: Release - needs: [compute-versions, build-cli-linux, build-cli-macos, build-gateway-binary-linux, build-gateway-binary-macos, build-supervisor-binary-linux, build-python-wheels-linux, build-python-wheel-macos, tag-ghcr-release, build-driver-vm-linux, build-driver-vm-macos, build-deb, build-rpm, smoke-linux-release-artifacts] + needs: [compute-versions, build-cli-linux, build-cli-macos, build-gateway-binary-linux, build-gateway-binary-macos, build-supervisor-binary-linux, build-python-wheels-linux, build-python-wheel-macos, tag-ghcr-release, build-driver-vm-linux, build-driver-vm-macos, build-deb, build-rpm, build-snap, smoke-linux-release-artifacts] runs-on: linux-amd64-cpu8 timeout-minutes: 10 permissions: @@ -871,6 +882,13 @@ jobs: 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: Capture wheel filenames id: wheel_filenames run: | @@ -966,6 +984,7 @@ jobs: release/openshell-aarch64-apple-darwin.tar.gz release/openshell_*.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 diff --git a/.github/workflows/snap-package.yml b/.github/workflows/snap-package.yml new file mode 100644 index 000000000..b67579847 --- /dev/null +++ b/.github/workflows/snap-package.yml @@ -0,0 +1,122 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +name: Snap Package + +on: + workflow_call: + inputs: + checkout-ref: + required: true + type: string + upload-channel: + required: true + type: string + description: "Snap Store channel to upload to (e.g., latest/edge, latest/candidate, latest/stable)" + github-environment: + required: true + type: string + description: "GitHub deployment environment for approval gates (e.g., latest/edge, latest/stable)" + +permissions: + contents: read + +defaults: + run: + shell: bash + +jobs: + build-snap: + name: Build Snap (Linux ${{ matrix.arch }}) + strategy: + matrix: + include: + - arch: amd64 + runner: linux-amd64-cpu8 + - arch: arm64 + runner: linux-arm64-cpu8 + runs-on: ${{ matrix.runner }} + timeout-minutes: 60 + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + ref: ${{ inputs.checkout-ref }} + fetch-depth: 0 + + - name: Install snapd + run: | + set -euo pipefail + if ! command -v snapd >/dev/null 2>&1; then + sudo apt-get update + sudo apt-get install -y snapd + fi + sudo systemctl start snapd + sudo systemctl enable snapd + + - name: Install LXD + run: | + set -euo pipefail + sudo snap install lxd + sudo usermod -aG lxd $USER + sudo lxd init --auto + + - name: Install core24 + run: | + set -euo pipefail + sudo snap install core24 + + - name: Install snapcraft + run: | + set -euo pipefail + sudo snap install snapcraft --classic + + - name: Build snap + run: | + set -euo pipefail + snapcraft pack -v + + - name: Capture snap filename + id: capture + run: | + set -euo pipefail + SNAP_FILE=$(ls -1 *.snap 2>/dev/null | head -1) + if [ -z "$SNAP_FILE" ]; then + echo "ERROR: No .snap file found after snapcraft pack" + exit 1 + fi + echo "snap-file=${SNAP_FILE}" >> $GITHUB_OUTPUT + echo "Built snap: ${SNAP_FILE}" + + - name: Upload snap artifact (${{ matrix.arch }}) + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + with: + name: snap-linux-${{ matrix.arch }} + path: | + ${{ steps.capture.outputs.snap-file }} + *.comp + retention-days: 5 + + - name: Upload snap to Snap Store + environment: + name: ${{ inputs.github-environment }} + env: + SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_STORE_CREDENTIALS }} + run: | + set -euo pipefail + SNAP_FILE="${{ steps.capture.outputs.snap-file }}" + SNAP_NAME="${SNAP_FILE%.snap}" + SNAP_NAME="${SNAP_NAME%%_*}" + + COMPONENT_ARGS=() + shopt -s nullglob + for comp in "${SNAP_NAME}"+*.comp; do + echo "Adding component: $comp" + COMPONENT_ARGS+=(--component "$comp") + done + + echo "Uploading $SNAP_FILE to ${{ inputs.upload-channel }}" + if [ ${#COMPONENT_ARGS[@]} -gt 0 ]; then + snapcraft upload --release "${{ inputs.upload-channel }}" "$SNAP_FILE" "${COMPONENT_ARGS[@]}" + else + snapcraft upload --release "${{ inputs.upload-channel }}" "$SNAP_FILE" + fi diff --git a/snapcraft.yaml b/snapcraft.yaml index 6257ca851..f17dd8a58 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -12,8 +12,7 @@ description: | LLM inference routing. base: core24 -# TODO: this prevents publishing a snap to latest/stable. -grade: devel +grade: stable confinement: strict license: Apache-2.0 website: https://docs.nvidia.com/openshell/latest/index.html