Skip to content

Commit 8e73cd6

Browse files
committed
test(snap): smoke PR artifacts before release
Signed-off-by: Evan Lezar <elezar@nvidia.com>
1 parent 736893e commit 8e73cd6

8 files changed

Lines changed: 335 additions & 178 deletions

File tree

.agents/skills/test-release-canary/SKILL.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ validation lives in the `TypeScript SDK` branch check, including a publish
2929
dry-run. The tagged release workflow publishes the package to GitHub Packages;
3030
verify that job directly when diagnosing SDK publication failures.
3131

32+
The PR-only `test:snap` label runs the same gateway lifecycle smoke test in
33+
`Branch E2E Checks`, but packages a Snap from that workflow's amd64 prebuilt
34+
binary artifacts. It does not require or publish a Release Dev artifact.
35+
3236
## Trigger paths
3337

3438
The workflow has two triggers:
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
name: Snap gateway smoke test
5+
description: Install a local OpenShell Snap with Docker and verify gateway readiness.
6+
7+
inputs:
8+
snap-path:
9+
description: Path to the locally built Snap artifact.
10+
required: true
11+
telemetry-enabled:
12+
description: Value supplied to the gateway service environment.
13+
required: false
14+
default: "false"
15+
16+
runs:
17+
using: composite
18+
steps:
19+
- name: Install snapd
20+
shell: bash
21+
run: |
22+
set -euo pipefail
23+
sudo apt-get update
24+
sudo apt-get install -y snapd
25+
sudo systemctl enable --now snapd.socket
26+
sudo systemctl start snapd
27+
sudo snap wait system seed.loaded
28+
29+
- name: Install Docker snap
30+
shell: bash
31+
run: sudo snap install docker
32+
33+
- name: Install, connect, and verify gateway
34+
shell: bash
35+
env:
36+
SNAP_PATH: ${{ inputs.snap-path }}
37+
TELEMETRY_ENABLED: ${{ inputs.telemetry-enabled }}
38+
run: |
39+
set -Eeuo pipefail
40+
41+
collect_diagnostics() {
42+
set +e
43+
sudo snap services openshell
44+
sudo snap connections openshell
45+
sudo snap changes
46+
sudo systemctl status snap.openshell.gateway.service --no-pager
47+
sudo journalctl -b -u snap.openshell.gateway.service --no-pager -n 300
48+
sudo journalctl -b -u snapd.service --no-pager -n 300
49+
sudo snap logs openshell.gateway -n=300
50+
sudo ss -ltnp '( sport = :17670 )'
51+
}
52+
trap collect_diagnostics ERR
53+
54+
snap_path=$(compgen -G "$SNAP_PATH" | head -n 1 || true)
55+
test -n "$snap_path"
56+
sudo systemctl set-environment "OPENSHELL_TELEMETRY_ENABLED=${TELEMETRY_ENABLED}"
57+
sudo snap install "$snap_path" --dangerous
58+
sudo snap connect openshell:docker docker:docker-daemon
59+
sudo snap connect openshell:log-observe
60+
sudo snap connect openshell:system-observe
61+
62+
openshell --version
63+
sudo snap services openshell
64+
openshell gateway add http://127.0.0.1:17670 --local --name snap-docker
65+
openshell gateway select snap-docker
66+
for _ in $(seq 1 30); do
67+
if openshell status; then
68+
exit 0
69+
fi
70+
sleep 1
71+
done
72+
echo "Gateway did not become ready within 30 seconds" >&2
73+
exit 1

.github/workflows/branch-e2e.yml

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ jobs:
2727
run_gpu_e2e: ${{ steps.labels.outputs.run_gpu_e2e }}
2828
run_kubernetes_ha_e2e: ${{ steps.labels.outputs.run_kubernetes_ha_e2e }}
2929
run_kubernetes_credential_drivers_e2e: ${{ steps.labels.outputs.run_kubernetes_credential_drivers_e2e }}
30+
run_snap_smoke: ${{ steps.labels.outputs.run_snap_smoke }}
3031
run_any_e2e: ${{ steps.labels.outputs.run_any_e2e }}
3132
steps:
3233
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
@@ -46,6 +47,7 @@ jobs:
4647
run_gpu_e2e="$(jq -r 'index("test:e2e-gpu") != null' <<< "$LABELS_JSON")"
4748
run_kubernetes_ha_e2e="$(jq -r 'index("test:e2e-kubernetes") != null' <<< "$LABELS_JSON")"
4849
run_kubernetes_credential_drivers_e2e="$(jq -r 'index("test:e2e-kubernetes") != null' <<< "$LABELS_JSON")"
50+
run_snap_smoke="$(jq -r 'index("test:snap") != null' <<< "$LABELS_JSON")"
4951
;;
5052
merge_group)
5153
# Merge groups have no PR labels. When GPU E2E is required as documented
@@ -55,15 +57,17 @@ jobs:
5557
run_gpu_e2e=true
5658
run_kubernetes_ha_e2e=false
5759
run_kubernetes_credential_drivers_e2e=false
60+
run_snap_smoke=true
5861
;;
5962
*)
6063
run_core_e2e=true
6164
run_gpu_e2e=true
6265
run_kubernetes_ha_e2e=true
6366
run_kubernetes_credential_drivers_e2e=true
67+
run_snap_smoke=true
6468
;;
6569
esac
66-
if [ "$run_core_e2e" = "true" ] || [ "$run_gpu_e2e" = "true" ] || [ "$run_kubernetes_ha_e2e" = "true" ] || [ "$run_kubernetes_credential_drivers_e2e" = "true" ]; then
70+
if [ "$run_core_e2e" = "true" ] || [ "$run_gpu_e2e" = "true" ] || [ "$run_kubernetes_ha_e2e" = "true" ] || [ "$run_kubernetes_credential_drivers_e2e" = "true" ] || [ "$run_snap_smoke" = "true" ]; then
6771
run_any_e2e=true
6872
else
6973
run_any_e2e=false
@@ -73,6 +77,7 @@ jobs:
7377
echo "run_gpu_e2e=$run_gpu_e2e"
7478
echo "run_kubernetes_ha_e2e=$run_kubernetes_ha_e2e"
7579
echo "run_kubernetes_credential_drivers_e2e=$run_kubernetes_credential_drivers_e2e"
80+
echo "run_snap_smoke=$run_snap_smoke"
7681
echo "run_any_e2e=$run_any_e2e"
7782
} >> "$GITHUB_OUTPUT"
7883
@@ -86,6 +91,7 @@ jobs:
8691
with:
8792
component: gateway
8893
image-tag: ${{ github.sha }}
94+
platform: ${{ (needs.pr_metadata.outputs.run_core_e2e == 'true' || needs.pr_metadata.outputs.run_gpu_e2e == 'true' || needs.pr_metadata.outputs.run_kubernetes_ha_e2e == 'true' || needs.pr_metadata.outputs.run_kubernetes_credential_drivers_e2e == 'true') && 'linux/amd64,linux/arm64' || 'linux/amd64' }}
8995

9096
build-supervisor:
9197
needs: [pr_metadata]
@@ -97,6 +103,7 @@ jobs:
97103
with:
98104
component: supervisor
99105
image-tag: ${{ github.sha }}
106+
platform: ${{ (needs.pr_metadata.outputs.run_core_e2e == 'true' || needs.pr_metadata.outputs.run_gpu_e2e == 'true' || needs.pr_metadata.outputs.run_kubernetes_ha_e2e == 'true' || needs.pr_metadata.outputs.run_kubernetes_credential_drivers_e2e == 'true') && 'linux/amd64,linux/arm64' || 'linux/amd64' }}
100107

101108
build-cli:
102109
needs: [pr_metadata]
@@ -107,7 +114,45 @@ jobs:
107114
uses: ./.github/workflows/docker-build.yml
108115
with:
109116
component: cli
110-
platform: linux/amd64,linux/arm64
117+
platform: ${{ (needs.pr_metadata.outputs.run_core_e2e == 'true' || needs.pr_metadata.outputs.run_gpu_e2e == 'true' || needs.pr_metadata.outputs.run_kubernetes_ha_e2e == 'true' || needs.pr_metadata.outputs.run_kubernetes_credential_drivers_e2e == 'true') && 'linux/amd64,linux/arm64' || 'linux/amd64' }}
118+
119+
build-snap:
120+
name: Build Snap
121+
needs: [pr_metadata, build-gateway, build-supervisor, build-cli]
122+
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_snap_smoke == 'true'
123+
permissions:
124+
actions: read
125+
contents: read
126+
packages: read
127+
uses: ./.github/workflows/snap-build.yml
128+
with:
129+
checkout-ref: ${{ github.sha }}
130+
artifact-layout: raw
131+
build-matrix: '{"include":[{"arch":"amd64","runner":"linux-amd64-cpu8"}]}'
132+
cli-artifact-prefix: rust-binary-cli
133+
gateway-artifact-prefix: rust-binary-gateway
134+
supervisor-artifact-prefix: rust-binary-supervisor
135+
136+
snap-smoke:
137+
name: Snap Smoke
138+
needs: [pr_metadata, build-snap]
139+
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_snap_smoke == 'true'
140+
runs-on: ubuntu-latest
141+
timeout-minutes: 20
142+
permissions:
143+
actions: read
144+
contents: read
145+
steps:
146+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
147+
- name: Download locally built Snap
148+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
149+
with:
150+
name: snap-linux-amd64
151+
path: release/
152+
- name: Install and verify local Snap
153+
uses: ./.github/actions/snap-gateway-smoke
154+
with:
155+
snap-path: ./release/*.snap
111156

112157
build-driver-vm-linux:
113158
needs: [pr_metadata]

.github/workflows/e2e-label-help.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ permissions: {}
1919
jobs:
2020
hint:
2121
name: Post next-step hint for E2E label
22-
if: github.event.label.name == 'test:e2e' || github.event.label.name == 'test:e2e-gpu' || github.event.label.name == 'test:e2e-kubernetes'
22+
if: github.event.label.name == 'test:e2e' || github.event.label.name == 'test:e2e-gpu' || github.event.label.name == 'test:e2e-kubernetes' || github.event.label.name == 'test:snap'
2323
runs-on: ubuntu-latest
2424
permissions:
2525
pull-requests: write
@@ -55,6 +55,11 @@ jobs:
5555
build_summary="gateway and supervisor images"
5656
status_summary="This is an optional proof-of-life suite; failures are visible in the workflow run but do not publish a required CI gate status."
5757
;;
58+
test:snap)
59+
suite_summary="Snap packaging and gateway lifecycle smoke test"
60+
build_summary="amd64 CLI, gateway, and supervisor binaries"
61+
status_summary="This is an optional proof-of-life suite; failures are visible in the workflow run but do not publish a required CI gate status."
62+
;;
5863
*) echo "Unrecognized label $LABEL_NAME"; exit 1 ;;
5964
esac
6065

.github/workflows/release-canary.yml

Lines changed: 9 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -163,19 +163,10 @@ jobs:
163163
runs-on: ubuntu-latest
164164
timeout-minutes: 20
165165
steps:
166-
- name: Install snapd
167-
run: |
168-
set -euo pipefail
169-
sudo apt-get update
170-
sudo apt-get install -y snapd
171-
sudo systemctl enable --now snapd.socket
172-
sudo systemctl start snapd
173-
sudo snap wait system seed.loaded
174-
175-
- name: Install Docker snap
176-
run: |
177-
set -euo pipefail
178-
sudo snap install docker
166+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
167+
with:
168+
ref: ${{ github.event.workflow_run.head_sha || github.sha }}
169+
fetch-depth: 1
179170

180171
- name: Download snap from release-dev artifacts
181172
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
@@ -186,48 +177,11 @@ jobs:
186177
path: release/
187178
merge-multiple: true
188179

189-
- name: Install snap (dangerous — from release, not store)
190-
run: |
191-
set -euo pipefail
192-
sudo systemctl set-environment \
193-
"OPENSHELL_TELEMETRY_ENABLED=${OPENSHELL_TELEMETRY_ENABLED}"
194-
sudo snap install ./release/*.snap --dangerous
195-
196-
- name: Connect interfaces
197-
run: |
198-
set -euo pipefail
199-
sudo snap connect openshell:docker docker:docker-daemon
200-
sudo snap connect openshell:log-observe
201-
sudo snap connect openshell:system-observe
202-
203-
- name: Register snap gateway and check status
204-
run: |
205-
set -euo pipefail
206-
openshell --version
207-
sudo snap services openshell
208-
openshell gateway add http://127.0.0.1:17670 --local --name snap-docker
209-
openshell gateway select snap-docker
210-
for _ in $(seq 1 30); do
211-
if openshell status; then
212-
exit 0
213-
fi
214-
sleep 1
215-
done
216-
echo "Gateway did not become ready within 30 seconds" >&2
217-
exit 1
218-
219-
- name: Collect Snap diagnostics
220-
if: failure()
221-
run: |
222-
set +e
223-
sudo snap services openshell
224-
sudo snap connections openshell
225-
sudo snap changes
226-
sudo systemctl status snap.openshell.gateway.service --no-pager
227-
sudo journalctl -b -u snap.openshell.gateway.service --no-pager -n 300
228-
sudo journalctl -b -u snapd.service --no-pager -n 300
229-
sudo snap logs openshell.gateway -n=300
230-
sudo ss -ltnp '( sport = :17670 )'
180+
- name: Install and verify local Snap
181+
uses: ./.github/actions/snap-gateway-smoke
182+
with:
183+
snap-path: ./release/*.snap
184+
telemetry-enabled: ${{ env.OPENSHELL_TELEMETRY_ENABLED }}
231185

232186
kubernetes:
233187
name: Kubernetes Helm (kind)

0 commit comments

Comments
 (0)