Skip to content

Commit 52097f2

Browse files
authored
ci(release): run package release canaries (#1256)
1 parent 8ab5ee8 commit 52097f2

2 files changed

Lines changed: 99 additions & 290 deletions

File tree

.github/workflows/release-canary.yml

Lines changed: 23 additions & 269 deletions
Original file line numberDiff line numberDiff line change
@@ -2,293 +2,47 @@ name: Release Canary
22

33
on:
44
workflow_dispatch:
5-
inputs:
6-
tag:
7-
description: "Release tag to test (e.g. dev, v1.2.3)"
8-
required: true
9-
type: string
105
workflow_run:
11-
workflows: ["Release Dev", "Release Tag"]
6+
workflows: ["Release Dev"]
127
types: [completed]
138

149
permissions:
1510
contents: read
16-
packages: read
1711

1812
defaults:
1913
run:
2014
shell: bash
2115

2216
jobs:
23-
# ---------------------------------------------------------------------------
24-
# Verify the default install path (no OPENSHELL_VERSION) resolves to latest
25-
# ---------------------------------------------------------------------------
26-
install-default:
27-
name: Install default (${{ matrix.arch }})
28-
if: >-
29-
github.event.workflow_run.conclusion == 'success'
30-
&& github.event.workflow_run.name == 'Release Tag'
31-
strategy:
32-
fail-fast: false
33-
matrix:
34-
include:
35-
- arch: amd64
36-
runner: linux-amd64-cpu8
37-
- arch: arm64
38-
runner: linux-arm64-cpu8
39-
runs-on: ${{ matrix.runner }}
40-
timeout-minutes: 10
41-
container:
42-
image: ghcr.io/nvidia/openshell/ci:latest
43-
credentials:
44-
username: ${{ github.actor }}
45-
password: ${{ secrets.GITHUB_TOKEN }}
46-
steps:
47-
- name: Install CLI (default / latest)
48-
run: |
49-
set -euo pipefail
50-
curl -LsSf https://raw.githubusercontent.com/NVIDIA/OpenShell/main/install.sh | sh
51-
52-
- name: Verify CLI installation
53-
run: |
54-
set -euo pipefail
55-
command -v openshell
56-
ACTUAL="$(openshell --version)"
57-
echo "Installed: $ACTUAL"
58-
# This job only runs after Release Tag, so the triggering tag
59-
# should match the latest release the default installer resolves to.
60-
TAG="${{ github.event.workflow_run.head_branch }}"
61-
if [[ "$TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
62-
EXPECTED="${TAG#v}"
63-
if [[ "$ACTUAL" != *"$EXPECTED"* ]]; then
64-
echo "::error::Version mismatch: expected '$EXPECTED' in '$ACTUAL'"
65-
exit 1
66-
fi
67-
echo "Version check passed: found $EXPECTED in output"
68-
fi
69-
70-
install-dev:
71-
name: Install Debian package (${{ matrix.arch }})
17+
macos:
18+
name: macOS Homebrew
7219
if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }}
73-
strategy:
74-
fail-fast: false
75-
matrix:
76-
include:
77-
- arch: amd64
78-
runner: linux-amd64-cpu8
79-
- arch: arm64
80-
runner: linux-arm64-cpu8
81-
runs-on: ${{ matrix.runner }}
82-
timeout-minutes: 10
83-
container:
84-
image: ghcr.io/nvidia/openshell/ci:latest
85-
credentials:
86-
username: ${{ github.actor }}
87-
password: ${{ secrets.GITHUB_TOKEN }}
20+
runs-on: macos-latest-xlarge
21+
timeout-minutes: 20
8822
steps:
89-
- name: Determine release tag
90-
id: release
23+
- name: Install dev and check status
9124
run: |
92-
set -euo pipefail
93-
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
94-
echo "tag=${{ inputs.tag }}" >> "$GITHUB_OUTPUT"
95-
else
96-
WORKFLOW_NAME="${{ github.event.workflow_run.name }}"
97-
if [ "$WORKFLOW_NAME" = "Release Dev" ]; then
98-
echo "tag=dev" >> "$GITHUB_OUTPUT"
99-
elif [ "$WORKFLOW_NAME" = "Release Tag" ]; then
100-
TAG="${{ github.event.workflow_run.head_branch }}"
101-
if [ -z "$TAG" ]; then
102-
echo "::error::Could not determine release tag from workflow_run"
103-
exit 1
104-
fi
105-
echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
106-
else
107-
echo "::error::Unexpected triggering workflow: ${WORKFLOW_NAME}"
108-
exit 1
109-
fi
110-
fi
25+
curl -LsSf https://raw.githubusercontent.com/NVIDIA/OpenShell/${{ github.event.workflow_run.head_sha || github.sha }}/install-dev.sh | sh
26+
openshell status
11127
112-
- name: Install Debian package
113-
run: |
114-
set -euo pipefail
115-
curl -LsSf https://raw.githubusercontent.com/NVIDIA/OpenShell/main/install-dev.sh \
116-
| OPENSHELL_VERSION=${{ steps.release.outputs.tag }} sh
117-
118-
- name: Verify gateway and VM driver versions
119-
run: |
120-
set -euo pipefail
121-
command -v openshell-gateway
122-
test -x /usr/libexec/openshell/openshell-driver-vm
123-
124-
GATEWAY_ACTUAL="$(openshell-gateway --version)"
125-
DRIVER_ACTUAL="$(/usr/libexec/openshell/openshell-driver-vm --version)"
126-
echo "Gateway: ${GATEWAY_ACTUAL}"
127-
echo "Driver: ${DRIVER_ACTUAL}"
128-
129-
TAG="${{ steps.release.outputs.tag }}"
130-
if [[ "$TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
131-
EXPECTED="${TAG#v}"
132-
for actual in "$GATEWAY_ACTUAL" "$DRIVER_ACTUAL"; do
133-
if [[ "$actual" != *"$EXPECTED"* ]]; then
134-
echo "::error::Version mismatch: expected '$EXPECTED' in '$actual'"
135-
exit 1
136-
fi
137-
done
138-
echo "Version check passed: found $EXPECTED in both binaries"
139-
else
140-
echo "Non-release tag ($TAG), skipping version check"
141-
fi
142-
143-
canary:
144-
name: Canary package gateway (${{ matrix.arch }})
28+
ubuntu:
29+
name: Ubuntu Docker
14530
if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }}
146-
strategy:
147-
fail-fast: false
148-
matrix:
149-
include:
150-
- arch: amd64
151-
runner: linux-amd64-cpu8
152-
- arch: arm64
153-
runner: linux-arm64-cpu8
154-
runs-on: ${{ matrix.runner }}
155-
timeout-minutes: 30
156-
env:
157-
OPENSHELL_REGISTRY_TOKEN: ${{ secrets.GITHUB_TOKEN }}
158-
OPENSHELL_CANARY_PORT: "17670"
31+
runs-on: ubuntu-latest
32+
timeout-minutes: 20
15933
steps:
160-
- uses: actions/checkout@v6
161-
162-
- name: Determine release tag
163-
id: release
34+
- name: Ensure Docker
16435
run: |
165-
set -euo pipefail
166-
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
167-
echo "tag=${{ inputs.tag }}" >> "$GITHUB_OUTPUT"
168-
else
169-
WORKFLOW_NAME="${{ github.event.workflow_run.name }}"
170-
if [ "$WORKFLOW_NAME" = "Release Dev" ]; then
171-
echo "tag=dev" >> "$GITHUB_OUTPUT"
172-
elif [ "$WORKFLOW_NAME" = "Release Tag" ]; then
173-
TAG="${{ github.event.workflow_run.head_branch }}"
174-
if [ -z "$TAG" ]; then
175-
echo "::error::Could not determine release tag from workflow_run"
176-
exit 1
177-
fi
178-
echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
179-
else
180-
echo "::error::Unexpected triggering workflow: ${WORKFLOW_NAME}"
181-
exit 1
182-
fi
36+
if ! command -v docker >/dev/null 2>&1; then
37+
sudo apt-get update
38+
sudo apt-get install -y docker.io
18339
fi
40+
sudo systemctl start docker || sudo service docker start
41+
mkdir -p "${HOME}/.config/openshell"
42+
printf 'OPENSHELL_DRIVERS=docker\n' > "${HOME}/.config/openshell/gateway.env"
43+
docker info
18444
185-
- name: Install Debian package
45+
- name: Install dev and check status
18646
run: |
187-
set -euo pipefail
188-
curl -LsSf https://raw.githubusercontent.com/NVIDIA/OpenShell/main/install-dev.sh \
189-
| OPENSHELL_VERSION=${{ steps.release.outputs.tag }} sh
190-
191-
- name: Verify package binaries
192-
run: |
193-
set -euo pipefail
194-
command -v openshell
195-
command -v openshell-gateway
196-
test -x /usr/libexec/openshell/openshell-driver-vm
197-
198-
CLI_ACTUAL="$(openshell --version)"
199-
GATEWAY_ACTUAL="$(openshell-gateway --version)"
200-
DRIVER_ACTUAL="$(/usr/libexec/openshell/openshell-driver-vm --version)"
201-
echo "CLI: ${CLI_ACTUAL}"
202-
echo "Gateway: ${GATEWAY_ACTUAL}"
203-
echo "Driver: ${DRIVER_ACTUAL}"
204-
205-
TAG="${{ steps.release.outputs.tag }}"
206-
if [[ "$TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
207-
EXPECTED="${TAG#v}"
208-
for actual in "$CLI_ACTUAL" "$GATEWAY_ACTUAL" "$DRIVER_ACTUAL"; do
209-
if [[ "$actual" != *"$EXPECTED"* ]]; then
210-
echo "::error::Version mismatch: expected '$EXPECTED' in '$actual'"
211-
exit 1
212-
fi
213-
done
214-
echo "Version check passed: found $EXPECTED in package binaries"
215-
else
216-
echo "Non-release tag ($TAG), skipping version check"
217-
fi
218-
219-
- name: Start packaged gateway
220-
run: |
221-
set -euo pipefail
222-
223-
# The CLI no longer owns gateway lifecycle. In CI we start the
224-
# gateway binary installed by the Debian package directly, using the
225-
# Docker driver so this canary can launch a real sandbox.
226-
systemctl --user stop openshell-gateway >/dev/null 2>&1 || true
227-
228-
STATE_DIR="$(mktemp -d)"
229-
LOG="${STATE_DIR}/openshell-gateway.log"
230-
echo "GATEWAY_LOG=${LOG}" >> "$GITHUB_ENV"
231-
echo "GATEWAY_STATE_DIR=${STATE_DIR}" >> "$GITHUB_ENV"
232-
233-
OPENSHELL_BIND_ADDRESS=0.0.0.0 \
234-
OPENSHELL_SERVER_PORT="${OPENSHELL_CANARY_PORT}" \
235-
OPENSHELL_DISABLE_TLS=true \
236-
OPENSHELL_DISABLE_GATEWAY_AUTH=true \
237-
OPENSHELL_DRIVERS=docker \
238-
OPENSHELL_DB_URL="sqlite:${STATE_DIR}/openshell.db?mode=rwc" \
239-
OPENSHELL_GRPC_ENDPOINT="http://host.openshell.internal:${OPENSHELL_CANARY_PORT}" \
240-
OPENSHELL_SSH_GATEWAY_HOST=127.0.0.1 \
241-
OPENSHELL_SSH_GATEWAY_PORT="${OPENSHELL_CANARY_PORT}" \
242-
OPENSHELL_SANDBOX_NAMESPACE="canary-${{ matrix.arch }}-${{ github.run_id }}" \
243-
nohup openshell-gateway >"${LOG}" 2>&1 &
244-
PID=$!
245-
echo "GATEWAY_PID=${PID}" >> "$GITHUB_ENV"
246-
247-
for _ in $(seq 1 60); do
248-
if curl -fsS "http://127.0.0.1:${OPENSHELL_CANARY_PORT}/healthz" >/dev/null; then
249-
break
250-
fi
251-
if ! kill -0 "$PID" 2>/dev/null; then
252-
echo "::error::openshell-gateway exited before becoming healthy"
253-
cat "$LOG"
254-
exit 1
255-
fi
256-
sleep 1
257-
done
258-
259-
curl -fsS "http://127.0.0.1:${OPENSHELL_CANARY_PORT}/healthz"
260-
openshell gateway remove local >/dev/null 2>&1 || true
261-
openshell gateway add "http://127.0.0.1:${OPENSHELL_CANARY_PORT}" --local --name local
262-
263-
- name: Run canary test
264-
run: |
265-
set -euo pipefail
266-
267-
echo "Creating sandbox and running 'echo hello world'..."
268-
OUTPUT=$(openshell sandbox create --no-keep --no-tty -- echo "hello world" 2>&1) || {
269-
EXIT_CODE=$?
270-
echo "::error::openshell sandbox create failed with exit code ${EXIT_CODE}"
271-
echo "$OUTPUT"
272-
exit $EXIT_CODE
273-
}
274-
275-
echo "$OUTPUT"
276-
277-
if echo "$OUTPUT" | grep -q "hello world"; then
278-
echo "Canary test passed: 'hello world' found in output"
279-
else
280-
echo "::error::Canary test failed: 'hello world' not found in output"
281-
exit 1
282-
fi
283-
284-
- name: Stop packaged gateway
285-
if: always()
286-
run: |
287-
set -euo pipefail
288-
if [ -n "${GATEWAY_PID:-}" ]; then
289-
kill "$GATEWAY_PID" >/dev/null 2>&1 || true
290-
fi
291-
if [ "${{ job.status }}" != "success" ] && [ -n "${GATEWAY_LOG:-}" ] && [ -f "$GATEWAY_LOG" ]; then
292-
echo "Gateway log:"
293-
cat "$GATEWAY_LOG"
294-
fi
47+
curl -LsSf https://raw.githubusercontent.com/NVIDIA/OpenShell/${{ github.event.workflow_run.head_sha || github.sha }}/install-dev.sh | sh
48+
openshell status

0 commit comments

Comments
 (0)