Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .agents/skills/test-release-canary/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ validation lives in the `TypeScript SDK` branch check, including a publish
dry-run. The tagged release workflow publishes the package to GitHub Packages;
verify that job directly when diagnosing SDK publication failures.

Release Dev also publishes an attested `openshell-release-manifest.json` for standalone core runtime archives and container images. The canary does not download or verify that manifest and continues to consume the rolling dev packages, chart and image tags. A passing canary proves only the install and runtime paths it exercises; it does not prove manifest attestation or digest selection. For manifest failures, inspect the producing Release Dev run's image identity, assembly and attestation steps with `watch-github-actions`.

## Trigger paths

The workflow has two triggers:
Expand Down
2 changes: 2 additions & 0 deletions .agents/skills/watch-github-actions/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ not substitute the current `main` tip or the event's older PR base SHA. Merge
groups and manual runs use their explicit baseline. Findings are reported by
`Reject new high or critical findings`; distinguish those from scanner failures.

For core runtime release identity failures, inspect `Record immutable image identity` and `Verify SBOM attestation` in the Build Images jobs, then `Download producing image identities`, `Assemble immutable core runtime manifest` and `Attest core runtime manifest` in Release Dev. Build Images is shared by Branch E2E, Release Dev and Release Tag; only Release Dev assembles and publishes `openshell-release-manifest.json`. Compare the `core-image-identity-*` artifacts' source SHA and workflow run ID with the failing release job. A downstream retry can reuse completed image jobs from the same source and run; identities from a different run are rejected. Assembly also checks archive checksums and matches staged image executable hashes to the corresponding archives, so inspect the failed component and platform before rerunning jobs. Assembly and attestation finish before development release assets are replaced or image tags are promoted; successful canary installation does not verify the manifest.

View logs for a specific run:

```bash
Expand Down
45 changes: 42 additions & 3 deletions .github/actions/build-docker-image/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ inputs:
runs:
using: composite
steps:
- name: Set up release identity tooling
uses: astral-sh/setup-uv@ae62891fec2bb8e7d6c99fc78c9fec3a63790f8d # v10.0.0
with:
version: "0.10.12"
enable-cache: false

- uses: ./.github/actions/setup-buildx
with:
buildkitd-config: /etc/buildkit/buildkitd.toml
Expand Down Expand Up @@ -56,6 +62,8 @@ runs:
install -Dm0755 artifact/arm64/${BINARY} deploy/docker/.build/prebuilt-binaries/arm64/${BINARY}

- name: Build ${{ inputs.component }} image
# Keep both exporters' manifest options identical: Buildx reports one
# image digest, which must also identify the pushed registry object.
shell: bash
env:
COMPONENT: ${{ inputs.component }}
Expand All @@ -72,15 +80,46 @@ runs:
--cache-to type=gha,mode=max,scope=${COMPONENT} \
--provenance=mode=min \
--attest type=sbom \
--metadata-file artifacts/images/${COMPONENT}-build-metadata.json \
--output type=image,push=true,oci-mediatypes=true,oci-artifact=true \
--output type=oci,dest=artifacts/images/${COMPONENT}.tar \
--output type=oci,dest=artifacts/images/${COMPONENT}.tar,oci-mediatypes=true,oci-artifact=true \
.

- name: Record immutable image identity
shell: bash
env:
COMPONENT: ${{ inputs.component }}
run: |
set -euo pipefail
metadata="artifacts/images/${COMPONENT}-build-metadata.json"
digest=$(uv run --no-project --offline --no-python-downloads --python python3 python tasks/scripts/release.py image-build-digest --metadata-file "$metadata")
docker buildx imagetools inspect "ghcr.io/nvidia/openshell/${COMPONENT}@${digest}" --raw > "artifacts/images/${COMPONENT}-index.json"
uv run --no-project --offline --no-python-downloads --python python3 python tasks/scripts/release.py record-image-identity \
--component "$COMPONENT" \
--source-sha "$(git rev-parse HEAD)" \
--run-id "$GITHUB_RUN_ID" \
--run-attempt "$GITHUB_RUN_ATTEMPT" \
--metadata-file "$metadata" \
--index-file "artifacts/images/${COMPONENT}-index.json" \
--binary-dir artifact \
--output "image-identities/${COMPONENT}.json"

- name: Verify SBOM attestation
shell: bash
env:
IMAGE_REF: ghcr.io/nvidia/openshell/${{ inputs.component }}:${{ inputs.image-tag }}
run: tasks/scripts/verify-image-sbom.sh "${IMAGE_REF}" --require-cargo
COMPONENT: ${{ inputs.component }}
run: |
set -euo pipefail
digest=$(uv run --no-project --offline --no-python-downloads --python python3 python tasks/scripts/release.py image-build-digest --metadata-file "artifacts/images/${COMPONENT}-build-metadata.json")
tasks/scripts/verify-image-sbom.sh "ghcr.io/nvidia/openshell/${COMPONENT}@${digest}" --require-cargo

- name: Upload ${{ inputs.component }} identity
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: core-image-identity-${{ inputs.component }}
path: image-identities/${{ inputs.component }}.json
retention-days: 5
if-no-files-found: error

- name: Upload ${{ inputs.component }} image
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
Expand Down
35 changes: 35 additions & 0 deletions .github/workflows/release-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ jobs:
needs:
- compute-versions
- package-binaries
- build-images
- build-python-wheel
- conformance-integration
- feature-specific-integration
Expand All @@ -282,6 +283,19 @@ jobs:
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Download producing image identities
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: core-image-identity-*
path: image-identities/
merge-multiple: true

- name: Set up release identity tooling
uses: astral-sh/setup-uv@ae62891fec2bb8e7d6c99fc78c9fec3a63790f8d # v10.0.0
with:
version: "0.10.12"
enable-cache: false

- name: Download all CLI artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
Expand Down Expand Up @@ -424,6 +438,25 @@ jobs:
openshell-supervisor-aarch64-unknown-linux-gnu.tar.gz > openshell-supervisor-checksums-sha256.txt
cat openshell-supervisor-checksums-sha256.txt

- name: Assemble immutable core runtime manifest
env:
CARGO_VERSION: ${{ needs.compute-versions.outputs.cargo_version }}
run: |
set -euo pipefail
uv run --no-project --offline --no-python-downloads --python python3 python tasks/scripts/release.py generate-release-manifest \
--source-sha "$GITHUB_SHA" \
--run-id "$GITHUB_RUN_ID" \
--run-attempt "$GITHUB_RUN_ATTEMPT" \
--cargo-version "$CARGO_VERSION" \
--release-dir release \
--image-dir image-identities \
--output release/openshell-release-manifest.json

- name: Attest core runtime manifest
uses: actions/attest@508db95dd578ae2727ebd6217d5ba78e4fbda05d # v4.2.1
with:
subject-path: release/openshell-release-manifest.json

- name: Generate Homebrew formula
run: |
set -euo pipefail
Expand Down Expand Up @@ -473,6 +506,7 @@ jobs:
name.endsWith('.whl') ||
name.endsWith('.deb') ||
name.endsWith('.rpm') ||
name === 'openshell-release-manifest.json' ||
name.endsWith('.snap')
)
);
Expand Down Expand Up @@ -543,6 +577,7 @@ jobs:
release/openshell-sandbox-checksums-sha256.txt
release/openshell-supervisor-checksums-sha256.txt
release/openshell-prover-checksums-sha256.txt
release/openshell-release-manifest.json

release-helm:
name: Release Helm Chart (OCI, dev)
Expand Down
2 changes: 2 additions & 0 deletions architecture/build.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ generated by BuildKit's default Syft scanner. The registry exporter uses OCI
media types and `oci-artifact=true`, so each attestation identifies its subject.
GHCR exposes these through the image index because it has no referrers API.

The image-producing action also records the exact OCI index and Linux platform digests, source commit, workflow run and staged executable hashes. Release Dev joins those records with checksum-verified standalone core archives and checks that each image's staged executable matches the archive for the same component and platform. It assembles and attests a versioned `openshell-release-manifest.json` only after the complete core matrix validates, before replacing development release assets or promoting image tags, then publishes the manifest alongside the archives. A downstream retry may reuse completed image jobs from the same source and workflow run; another run's identities are rejected. The manifest describes artifact association, not tested protocol compatibility or live deployment health. Release Tag publication remains a separate release path.

Attestations require a registry-backed image index. Local builds therefore keep
`--provenance=false`, and Podman builds carry neither attestation.
`tasks/scripts/verify-image-sbom.sh` verifies the merged multi-arch tag and runs
Expand Down
2 changes: 2 additions & 0 deletions docs/about/installation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ The script detects your operating system and installs the OpenShell CLI, standal

You can also download release artifacts directly from the [OpenShell GitHub Releases](https://github.com/NVIDIA/OpenShell/releases) page.

Development builds publish `openshell-release-manifest.json` with an artifact attestation. Its `schema_version: 1` and `inventory_scope: "core-runtime"` describe the standalone CLI, gateway, sandbox and supervisor archives, and gateway/sandbox/supervisor container images. The manifest records the full source commit, Cargo version, workflow run, archive targets and SHA256 checksums, and image index and platform digests. Native installer packages, VM-driver bundles, the prover and SDKs are outside this inventory. Retain the manifest, verify downloaded archive bytes against its checksums, and use image references in the form `<repository>@<index_digest>` or the selected platform digest. The development download location can move; a checksum mismatch requires obtaining the matching build instead of silently adopting the new bytes. These identities describe one build and do not establish runtime qualification or upgrade compatibility.

### Install a prerelease

Prerelease packages are retained as GitHub Actions artifacts for 90 days and require an authenticated [GitHub CLI](https://cli.github.com/) session. The `pre` alias installs the latest prerelease:
Expand Down
Loading
Loading