Skip to content

Commit b3875a1

Browse files
committed
Merge remote-tracking branch 'origin/main' into fix/build-no-progress-timeout
Signed-off-by: Tinson Lai <tinsonl@nvidia.com> # Conflicts: # crates/openshell-bootstrap/src/build.rs
2 parents a19bda8 + 2e0afea commit b3875a1

81 files changed

Lines changed: 6706 additions & 869 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/deb-package.yml

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
name: Debian Package
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
deb-version:
7+
required: true
8+
type: string
9+
checkout-ref:
10+
required: true
11+
type: string
12+
13+
permissions:
14+
contents: read
15+
packages: read
16+
17+
defaults:
18+
run:
19+
shell: bash
20+
21+
jobs:
22+
build-deb-linux:
23+
name: Build Debian Package (Linux ${{ matrix.arch }})
24+
strategy:
25+
matrix:
26+
include:
27+
- arch: amd64
28+
runner: build-amd64
29+
deb_arch: amd64
30+
cli_target: x86_64-unknown-linux-musl
31+
gnu_target: x86_64-unknown-linux-gnu
32+
- arch: arm64
33+
runner: build-arm64
34+
deb_arch: arm64
35+
cli_target: aarch64-unknown-linux-musl
36+
gnu_target: aarch64-unknown-linux-gnu
37+
runs-on: ${{ matrix.runner }}
38+
timeout-minutes: 20
39+
container:
40+
image: ghcr.io/nvidia/openshell/ci:latest
41+
credentials:
42+
username: ${{ github.actor }}
43+
password: ${{ secrets.GITHUB_TOKEN }}
44+
steps:
45+
- uses: actions/checkout@v6
46+
with:
47+
ref: ${{ inputs['checkout-ref'] }}
48+
49+
- name: Download CLI artifact
50+
uses: actions/download-artifact@v4
51+
with:
52+
name: cli-linux-${{ matrix.arch }}
53+
path: package-input/
54+
55+
- name: Download gateway artifact
56+
uses: actions/download-artifact@v4
57+
with:
58+
name: gateway-binary-linux-${{ matrix.arch }}
59+
path: package-input/
60+
61+
- name: Download VM driver artifact
62+
uses: actions/download-artifact@v4
63+
with:
64+
name: driver-vm-linux-${{ matrix.arch }}
65+
path: package-input/
66+
67+
- name: Extract package inputs
68+
run: |
69+
set -euo pipefail
70+
mkdir -p package-binaries
71+
tar -xzf "package-input/openshell-${{ matrix.cli_target }}.tar.gz" -C package-binaries
72+
tar -xzf "package-input/openshell-gateway-${{ matrix.gnu_target }}.tar.gz" -C package-binaries
73+
tar -xzf "package-input/openshell-driver-vm-${{ matrix.gnu_target }}.tar.gz" -C package-binaries
74+
ls -lah package-binaries
75+
76+
- name: Build Debian package
77+
run: |
78+
set -euo pipefail
79+
OPENSHELL_CLI_BINARY="${PWD}/package-binaries/openshell" \
80+
OPENSHELL_GATEWAY_BINARY="${PWD}/package-binaries/openshell-gateway" \
81+
OPENSHELL_DRIVER_VM_BINARY="${PWD}/package-binaries/openshell-driver-vm" \
82+
OPENSHELL_DEB_VERSION="${{ inputs['deb-version'] }}" \
83+
OPENSHELL_DEB_ARCH="${{ matrix.deb_arch }}" \
84+
OPENSHELL_OUTPUT_DIR=artifacts \
85+
tasks/scripts/package-deb.sh
86+
87+
- name: Upload Debian package artifact
88+
uses: actions/upload-artifact@v4
89+
with:
90+
name: deb-linux-${{ matrix.arch }}
91+
path: artifacts/*.deb
92+
retention-days: 5
Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
name: Driver VM Linux
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
cargo-version:
7+
required: true
8+
type: string
9+
image-tag:
10+
required: true
11+
type: string
12+
checkout-ref:
13+
required: true
14+
type: string
15+
16+
permissions:
17+
contents: read
18+
packages: read
19+
20+
defaults:
21+
run:
22+
shell: bash
23+
24+
jobs:
25+
download-kernel-runtime:
26+
name: Download Kernel Runtime
27+
runs-on: build-amd64
28+
timeout-minutes: 10
29+
container:
30+
image: ghcr.io/nvidia/openshell/ci:latest
31+
credentials:
32+
username: ${{ github.actor }}
33+
password: ${{ secrets.GITHUB_TOKEN }}
34+
steps:
35+
- uses: actions/checkout@v4
36+
with:
37+
ref: ${{ inputs['checkout-ref'] }}
38+
39+
- name: Download Linux runtime tarballs
40+
env:
41+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
42+
run: |
43+
set -euo pipefail
44+
mkdir -p runtime-artifacts
45+
46+
for platform in linux-aarch64 linux-x86_64; do
47+
asset="vm-runtime-${platform}.tar.zst"
48+
echo "Downloading ${asset}..."
49+
asset_url=$(curl -fsSL \
50+
-H "Accept: application/vnd.github+json" \
51+
-H "Authorization: Bearer ${GH_TOKEN}" \
52+
"https://api.github.com/repos/${GITHUB_REPOSITORY}/releases/tags/vm-dev" \
53+
| jq -r --arg asset "$asset" '.assets[] | select(.name == $asset) | .browser_download_url' \
54+
| head -n1)
55+
if [ -z "$asset_url" ]; then
56+
echo "::error::No ${asset} asset found on vm-dev release"
57+
exit 1
58+
fi
59+
curl -fL -o "runtime-artifacts/${asset}" "$asset_url"
60+
done
61+
62+
ls -lah runtime-artifacts/
63+
64+
- name: Verify downloads
65+
run: |
66+
set -euo pipefail
67+
for platform in linux-aarch64 linux-x86_64; do
68+
test -f "runtime-artifacts/vm-runtime-${platform}.tar.zst"
69+
done
70+
71+
- name: Upload runtime artifacts
72+
uses: actions/upload-artifact@v4
73+
with:
74+
name: driver-vm-kernel-runtime-tarballs
75+
path: runtime-artifacts/vm-runtime-*.tar.zst
76+
retention-days: 1
77+
78+
build-driver-vm-linux:
79+
name: Build Driver VM (Linux ${{ matrix.arch }})
80+
needs: [download-kernel-runtime]
81+
strategy:
82+
matrix:
83+
include:
84+
- arch: arm64
85+
runner: build-arm64
86+
target: aarch64-unknown-linux-gnu
87+
platform: linux-aarch64
88+
guest_arch: aarch64
89+
- arch: amd64
90+
runner: build-amd64
91+
target: x86_64-unknown-linux-gnu
92+
platform: linux-x86_64
93+
guest_arch: x86_64
94+
runs-on: ${{ matrix.runner }}
95+
timeout-minutes: 30
96+
container:
97+
image: ghcr.io/nvidia/openshell/ci:latest
98+
credentials:
99+
username: ${{ github.actor }}
100+
password: ${{ secrets.GITHUB_TOKEN }}
101+
options: --privileged
102+
env:
103+
MISE_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
104+
SCCACHE_MEMCACHED_ENDPOINT: ${{ vars.SCCACHE_MEMCACHED_ENDPOINT }}
105+
OPENSHELL_IMAGE_TAG: ${{ inputs['image-tag'] }}
106+
steps:
107+
- uses: actions/checkout@v4
108+
with:
109+
ref: ${{ inputs['checkout-ref'] }}
110+
fetch-depth: 0
111+
112+
- name: Mark workspace safe for git
113+
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
114+
115+
- name: Fetch tags
116+
run: git fetch --tags --force
117+
118+
- name: Install tools
119+
run: mise install --locked
120+
121+
- name: Cache Rust target and registry
122+
uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2
123+
with:
124+
shared-key: driver-vm-linux-${{ matrix.arch }}
125+
cache-directories: .cache/sccache
126+
cache-targets: "true"
127+
128+
- name: Install zstd
129+
run: apt-get update && apt-get install -y --no-install-recommends zstd && rm -rf /var/lib/apt/lists/*
130+
131+
- name: Download kernel runtime tarball
132+
uses: actions/download-artifact@v4
133+
with:
134+
name: driver-vm-kernel-runtime-tarballs
135+
path: runtime-download/
136+
137+
- name: Stage compressed runtime for embedding
138+
run: |
139+
set -euo pipefail
140+
COMPRESSED_DIR="${PWD}/target/vm-runtime-compressed"
141+
mkdir -p "$COMPRESSED_DIR"
142+
143+
EXTRACT_DIR=$(mktemp -d)
144+
zstd -d "runtime-download/vm-runtime-${{ matrix.platform }}.tar.zst" --stdout \
145+
| tar -xf - -C "$EXTRACT_DIR"
146+
147+
echo "Extracted runtime files:"
148+
ls -lah "$EXTRACT_DIR"
149+
150+
for file in "$EXTRACT_DIR"/*; do
151+
[ -f "$file" ] || continue
152+
name=$(basename "$file")
153+
[ "$name" = "provenance.json" ] && continue
154+
zstd -19 -f -q -T0 -o "${COMPRESSED_DIR}/${name}.zst" "$file"
155+
done
156+
157+
echo "Staged compressed runtime artifacts:"
158+
ls -lah "$COMPRESSED_DIR"
159+
160+
- name: Build bundled supervisor
161+
run: |
162+
set -euo pipefail
163+
OPENSHELL_VM_RUNTIME_COMPRESSED_DIR="${PWD}/target/vm-runtime-compressed" \
164+
tasks/scripts/vm/build-supervisor-bundle.sh --arch "${{ matrix.guest_arch }}"
165+
166+
- name: Verify embedded driver inputs
167+
run: |
168+
set -euo pipefail
169+
for file in libkrun.so.zst libkrunfw.so.5.zst gvproxy.zst openshell-sandbox.zst; do
170+
test -s "target/vm-runtime-compressed/${file}"
171+
done
172+
173+
- name: Scope workspace to driver-vm crates
174+
run: |
175+
set -euo pipefail
176+
sed -i 's|members = \["crates/\*"\]|members = ["crates/openshell-driver-vm", "crates/openshell-core"]|' Cargo.toml
177+
178+
- name: Patch workspace version
179+
if: ${{ inputs['cargo-version'] != '' }}
180+
run: |
181+
set -euo pipefail
182+
sed -i -E '/^\[workspace\.package\]/,/^\[/{s/^version[[:space:]]*=[[:space:]]*".*"/version = "'"${{ inputs['cargo-version'] }}"'"/}' Cargo.toml
183+
184+
- name: Build openshell-driver-vm
185+
run: |
186+
set -euo pipefail
187+
OPENSHELL_VM_RUNTIME_COMPRESSED_DIR="${PWD}/target/vm-runtime-compressed" \
188+
mise x -- cargo build --release -p openshell-driver-vm
189+
190+
- name: sccache stats
191+
if: always()
192+
run: mise x -- sccache --show-stats
193+
194+
- name: Package binary
195+
run: |
196+
set -euo pipefail
197+
mkdir -p artifacts
198+
tar -czf "artifacts/openshell-driver-vm-${{ matrix.target }}.tar.gz" \
199+
-C target/release openshell-driver-vm
200+
201+
- name: Upload artifact
202+
uses: actions/upload-artifact@v4
203+
with:
204+
name: driver-vm-linux-${{ matrix.arch }}
205+
path: artifacts/*.tar.gz
206+
retention-days: 5

.github/workflows/issue-triage.yml

Lines changed: 35 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,40 +8,50 @@ permissions:
88
issues: write
99

1010
jobs:
11-
check-agent-diagnostic:
11+
label-non-maintainer-issues:
1212
runs-on: ubuntu-latest
13-
# Only run on bug reports (title starts with "bug:")
14-
if: startsWith(github.event.issue.title, 'bug:')
13+
if: github.repository_owner == 'NVIDIA'
1514
steps:
16-
- name: Check for agent diagnostic section
15+
- name: Check contributor permissions
16+
id: contributor
1717
uses: actions/github-script@v7
1818
with:
19+
result-encoding: string
1920
script: |
20-
const body = context.payload.issue.body || '';
21-
22-
// Check if the Agent Diagnostic section has substantive content.
23-
// GitHub issue forms render textarea labels as h3 headings, but
24-
// issues created through gh or API clients often use h2 headings.
25-
const diagnosticMatch = body.match(
26-
/^#{2,4}\s+Agent Diagnostic[s]?\s*\n([\s\S]*?)(?=\n#{2,4}\s+|$)/im
27-
);
28-
29-
const diagnosticText = diagnosticMatch?.[1].trim() || '';
30-
const hasSubstantiveDiagnostic = diagnosticText.length > 0
31-
&& !diagnosticText.toLowerCase().startsWith('example:')
32-
&& !['n/a', 'none', 'no', 'not applicable'].includes(diagnosticText.toLowerCase());
33-
34-
if (hasSubstantiveDiagnostic) {
35-
console.log('Agent diagnostic section found with content. Passing.');
36-
return;
21+
const author = context.payload.issue.user.login;
22+
const maintainerPermissions = ['admin', 'maintain', 'write'];
23+
24+
try {
25+
const { data } = await github.rest.repos.getCollaboratorPermissionLevel({
26+
owner: context.repo.owner,
27+
repo: context.repo.repo,
28+
username: author,
29+
});
30+
31+
if (maintainerPermissions.includes(data.permission)) {
32+
console.log(`${author} has maintainer permissions: ${data.permission}.`);
33+
return 'false';
34+
}
35+
36+
console.log(`${author} is not a maintainer; permission is ${data.permission}.`);
37+
return 'true';
38+
} catch (e) {
39+
if (e.status === 404) {
40+
console.log(`${author} is not a repository collaborator; labeling for triage.`);
41+
return 'true';
42+
}
43+
44+
throw e;
3745
}
3846
39-
console.log('Agent diagnostic section missing or placeholder. Flagging.');
40-
41-
// Add state:triage-needed label
47+
- name: Add triage label
48+
if: steps.contributor.outputs.result == 'true'
49+
uses: actions/github-script@v7
50+
with:
51+
script: |
4252
await github.rest.issues.addLabels({
4353
owner: context.repo.owner,
4454
repo: context.repo.repo,
4555
issue_number: context.issue.number,
46-
labels: ['state:triage-needed']
56+
labels: ['state:triage-needed'],
4757
});

0 commit comments

Comments
 (0)