mirror of
https://github.com/NVIDIA/OpenShell.git
synced 2026-10-17 05:31:16 +08:00
197 lines
7.0 KiB
YAML
197 lines
7.0 KiB
YAML
name: Release Canary
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
tag:
|
|
description: "Release tag to test (e.g. dev, v1.2.3)"
|
|
required: true
|
|
type: string
|
|
workflow_run:
|
|
workflows: ["Release Dev", "Release Tag"]
|
|
types: [completed]
|
|
|
|
permissions:
|
|
contents: read
|
|
packages: read
|
|
|
|
defaults:
|
|
run:
|
|
shell: bash
|
|
|
|
jobs:
|
|
# ---------------------------------------------------------------------------
|
|
# Verify the default install path (no OPENSHELL_VERSION) resolves to latest
|
|
# ---------------------------------------------------------------------------
|
|
install-default:
|
|
name: Install default (${{ matrix.arch }})
|
|
if: >-
|
|
github.event.workflow_run.conclusion == 'success'
|
|
&& github.event.workflow_run.name == 'Release Tag'
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- arch: amd64
|
|
runner: build-amd64
|
|
- arch: arm64
|
|
runner: build-arm64
|
|
runs-on: ${{ matrix.runner }}
|
|
timeout-minutes: 10
|
|
container:
|
|
image: ghcr.io/nvidia/openshell/ci:latest
|
|
credentials:
|
|
username: ${{ github.actor }}
|
|
password: ${{ secrets.GITHUB_TOKEN }}
|
|
steps:
|
|
- name: Install CLI (default / latest)
|
|
run: |
|
|
set -euo pipefail
|
|
curl -LsSf https://raw.githubusercontent.com/NVIDIA/OpenShell/main/install.sh | sh
|
|
|
|
- name: Verify CLI installation
|
|
run: |
|
|
set -euo pipefail
|
|
command -v openshell
|
|
ACTUAL="$(openshell --version)"
|
|
echo "Installed: $ACTUAL"
|
|
# This job only runs after Release Tag, so the triggering tag
|
|
# should match the latest release the default installer resolves to.
|
|
TAG="${{ github.event.workflow_run.head_branch }}"
|
|
if [[ "$TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
EXPECTED="${TAG#v}"
|
|
if [[ "$ACTUAL" != *"$EXPECTED"* ]]; then
|
|
echo "::error::Version mismatch: expected '$EXPECTED' in '$ACTUAL'"
|
|
exit 1
|
|
fi
|
|
echo "Version check passed: found $EXPECTED in output"
|
|
fi
|
|
|
|
canary:
|
|
name: Canary ${{ matrix.mode }} (${{ matrix.arch }})
|
|
if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
arch:
|
|
- amd64
|
|
- arm64
|
|
mode:
|
|
- auto-bootstrap
|
|
- two-step
|
|
include:
|
|
- arch: amd64
|
|
runner: build-amd64
|
|
target: x86_64-unknown-linux-musl
|
|
- arch: arm64
|
|
runner: build-arm64
|
|
target: aarch64-unknown-linux-musl
|
|
runs-on: ${{ matrix.runner }}
|
|
timeout-minutes: 30
|
|
container:
|
|
image: ghcr.io/nvidia/openshell/ci:latest
|
|
credentials:
|
|
username: ${{ github.actor }}
|
|
password: ${{ secrets.GITHUB_TOKEN }}
|
|
options: --privileged
|
|
volumes:
|
|
- /var/run/docker.sock:/var/run/docker.sock
|
|
env:
|
|
OPENSHELL_REGISTRY_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
# The CI container mounts the host Docker socket, so the gateway
|
|
# container is a sibling — not reachable at 127.0.0.1 from inside
|
|
# this container. OPENSHELL_GATEWAY_HOST tells the auto-bootstrap
|
|
# to advertise a reachable address instead.
|
|
OPENSHELL_GATEWAY_HOST: host.docker.internal
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Determine release tag
|
|
id: release
|
|
run: |
|
|
set -euo pipefail
|
|
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
|
echo "tag=${{ inputs.tag }}" >> "$GITHUB_OUTPUT"
|
|
else
|
|
WORKFLOW_NAME="${{ github.event.workflow_run.name }}"
|
|
if [ "$WORKFLOW_NAME" = "Release Dev" ]; then
|
|
echo "tag=dev" >> "$GITHUB_OUTPUT"
|
|
elif [ "$WORKFLOW_NAME" = "Release Tag" ]; then
|
|
TAG="${{ github.event.workflow_run.head_branch }}"
|
|
if [ -z "$TAG" ]; then
|
|
echo "::error::Could not determine release tag from workflow_run"
|
|
exit 1
|
|
fi
|
|
echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
|
|
else
|
|
echo "::error::Unexpected triggering workflow: ${WORKFLOW_NAME}"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
- name: Install CLI from published install script
|
|
run: |
|
|
set -euo pipefail
|
|
curl -LsSf https://raw.githubusercontent.com/NVIDIA/OpenShell/main/install.sh | OPENSHELL_VERSION=${{ steps.release.outputs.tag }} OPENSHELL_INSTALL_DIR=/usr/local/bin sh
|
|
|
|
- name: Verify CLI installation
|
|
run: |
|
|
set -euo pipefail
|
|
command -v openshell
|
|
ACTUAL="$(openshell --version)"
|
|
echo "Installed: $ACTUAL"
|
|
TAG="${{ steps.release.outputs.tag }}"
|
|
# For tagged releases (v1.2.3), verify the semver appears in the version string
|
|
if [[ "$TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
EXPECTED="${TAG#v}"
|
|
if [[ "$ACTUAL" != *"$EXPECTED"* ]]; then
|
|
echo "::error::Version mismatch: expected '$EXPECTED' in '$ACTUAL'"
|
|
exit 1
|
|
fi
|
|
echo "Version check passed: found $EXPECTED in output"
|
|
else
|
|
echo "Non-release tag ($TAG), skipping version check"
|
|
fi
|
|
|
|
- name: Resolve gateway host
|
|
run: |
|
|
# On Linux CI runners host.docker.internal is not set automatically
|
|
# (it's a Docker Desktop feature). Add it via the Docker bridge IP.
|
|
if ! getent hosts host.docker.internal >/dev/null 2>&1; then
|
|
BRIDGE_IP=$(docker network inspect bridge --format '{{(index .IPAM.Config 0).Gateway}}')
|
|
echo "Adding /etc/hosts entry: ${BRIDGE_IP} host.docker.internal"
|
|
echo "${BRIDGE_IP} host.docker.internal" >> /etc/hosts
|
|
fi
|
|
|
|
# Two-step mode: explicitly start the gateway before creating a sandbox.
|
|
# --gateway-host is required because the gateway container is a Docker
|
|
# sibling (not in the same network namespace). Without it the metadata
|
|
# stores 127.0.0.1 which is unreachable from this CI container.
|
|
- name: Start gateway
|
|
if: matrix.mode == 'two-step'
|
|
run: |
|
|
set -euo pipefail
|
|
echo "Starting gateway..."
|
|
openshell gateway start --gateway-host "$OPENSHELL_GATEWAY_HOST"
|
|
|
|
- name: Run canary test
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
echo "Creating sandbox and running 'echo hello world'..."
|
|
OUTPUT=$(openshell sandbox create --no-keep --no-tty -- echo "hello world" 2>&1) || {
|
|
EXIT_CODE=$?
|
|
echo "::error::openshell sandbox create failed with exit code ${EXIT_CODE}"
|
|
echo "$OUTPUT"
|
|
exit $EXIT_CODE
|
|
}
|
|
|
|
echo "$OUTPUT"
|
|
|
|
if echo "$OUTPUT" | grep -q "hello world"; then
|
|
echo "Canary test passed: 'hello world' found in output"
|
|
else
|
|
echo "::error::Canary test failed: 'hello world' not found in output"
|
|
exit 1
|
|
fi
|