Skip to content

Commit f91c492

Browse files
Changed to ORAS build
1 parent c99a3b1 commit f91c492

File tree

3 files changed

+281
-131
lines changed

3 files changed

+281
-131
lines changed

.github/workflows/nightly.yml

Lines changed: 128 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Nightly Release
1+
name: Nightly Release (ORAS)
22

33
on:
44
schedule:
@@ -9,7 +9,6 @@ env:
99
CARGO_TERM_COLOR: always
1010

1111
jobs:
12-
# 0) Move/force the "nightly" tag to main and delete the prior GH release.
1312
prepare-nightly-release:
1413
name: Prepare nightly tag + delete prior release
1514
runs-on: ubuntu-latest
@@ -34,118 +33,185 @@ jobs:
3433
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
3534
run: gh release delete nightly --yes || true
3635

37-
build-plugin:
38-
name: Build and sign nightly plugin
39-
environment: staging
36+
build-wasm:
37+
name: Build plugin.wasm
4038
needs: prepare-nightly-release
4139
runs-on: ubuntu-24.04
4240
permissions:
43-
contents: write
44-
packages: write
45-
id-token: write # needed for keyless signing
46-
41+
contents: read
42+
outputs:
43+
sha: ${{ steps.meta.outputs.sha }}
4744
steps:
4845
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
4946
with:
5047
ref: nightly
5148
fetch-depth: 0
5249
submodules: true
5350

54-
- name: Show git version
51+
- name: Set up TinyGo
52+
uses: acifani/setup-tinygo@db56321a62b9a67922bb9ac8f9d085e218807bb3 # v2.0.1
53+
with:
54+
tinygo-version: "0.40.1"
55+
56+
- name: Build wasm (auditable)
57+
run: GOOS=wasip1 GOARCH=wasm tinygo build -no-debug -panic=trap -scheduler=none -o plugin.wasm
58+
59+
- name: Ensure plugin.wasm exists
5560
shell: bash
5661
run: |
57-
git describe --tags --always --dirty=-modified || echo "No git version available"
62+
set -euo pipefail
63+
ls -lh ./plugin.wasm
64+
65+
- name: Record commit sha
66+
id: meta
67+
shell: bash
68+
run: |
69+
set -euo pipefail
70+
echo "sha=${GITHUB_SHA}" >> "$GITHUB_OUTPUT"
71+
72+
- name: Upload wasm artifact
73+
uses: actions/upload-artifact@v4
74+
with:
75+
name: plugin-wasm
76+
path: plugin.wasm
77+
if-no-files-found: error
78+
79+
publish-oras:
80+
name: Publish ORAS artifact + sign
81+
needs: build-wasm
82+
runs-on: ubuntu-24.04
83+
permissions:
84+
contents: read
85+
packages: write
86+
id-token: write # keyless signing
87+
outputs:
88+
nightly_ref: ${{ steps.meta.outputs.nightly_ref }}
89+
nightly_digest: ${{ steps.digest.outputs.nightly_digest }}
90+
steps:
91+
- name: Download wasm artifact
92+
uses: actions/download-artifact@v4
93+
with:
94+
name: plugin-wasm
95+
path: .
5896

59-
- name: Set up Docker Buildx
60-
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
97+
- name: Install ORAS
98+
uses: oras-project/setup-oras@v1
6199

62100
- name: Install cosign
63101
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
64102

65-
- name: Log in to GitHub Container Registry
66-
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
67-
with:
68-
registry: ghcr.io
69-
username: ${{ github.actor }}
70-
password: ${{ secrets.GITHUB_TOKEN }}
71-
72-
# Build WASM for both platforms at once
73-
# WASM is platform-independent, so buildx creates proper multi-arch manifest automatically
74-
- name: Build and push multi-arch plugin image
75-
id: build
76-
uses: docker/build-push-action@v6
77-
with:
78-
context: .
79-
push: true
80-
platforms: linux/amd64,linux/arm64
81-
provenance: false
82-
tags: |
83-
ghcr.io/${{ github.repository }}:nightly
84-
85-
- name: Get manifest digest for signing
103+
- name: ORAS login to GHCR
86104
shell: bash
87105
run: |
88106
set -euo pipefail
107+
echo "${{ secrets.GITHUB_TOKEN }}" | oras login ghcr.io -u "${{ github.actor }}" --password-stdin
89108
90-
IMAGE="ghcr.io/${{ github.repository }}"
109+
- name: Compute ORAS ref
110+
id: meta
111+
shell: bash
112+
run: |
113+
set -euo pipefail
114+
REF="ghcr.io/${{ github.repository }}:nightly"
115+
echo "nightly_ref=$REF" >> "$GITHUB_OUTPUT"
116+
117+
- name: Push ORAS artifact (plugin.wasm)
118+
shell: bash
119+
run: |
120+
set -euo pipefail
121+
REF="${{ steps.meta.outputs.nightly_ref }}"
91122
92-
# Get the manifest list digest for signing
93-
MANIFEST_DIGEST=$(docker buildx imagetools inspect "${IMAGE}:nightly" --format '{{json .Manifest}}' | jq -r '.digest')
94-
echo "IMAGE_DIGEST=${MANIFEST_DIGEST}" >> $GITHUB_ENV
123+
# Publish as an OCI artifact:
124+
# - artifact type: identifies "this is a hyper-mcp plugin artifact"
125+
# - layer: the wasm blob
126+
oras push "$REF" \
127+
--artifact-type application/vnd.hyper-mcp.plugin.v2 \
128+
./plugin.wasm:application/wasm
95129
96-
- name: Sign manifest list by digest
130+
- name: Resolve ORAS digest
131+
id: digest
97132
shell: bash
98133
run: |
99134
set -euo pipefail
135+
REF="${{ steps.meta.outputs.nightly_ref }}"
100136
101-
MANIFEST_DIGEST="${{ env.IMAGE_DIGEST }}"
102-
IMAGE="ghcr.io/${{ github.repository }}"
137+
# Get the descriptor JSON and extract the digest
138+
nightly_digest="$(
139+
oras manifest fetch "$REF" --descriptor \
140+
| python3 -c 'import json,sys; print(json.load(sys.stdin)["digest"])'
141+
)"
103142
104-
echo "Signing multi-arch manifest list ${IMAGE}@${MANIFEST_DIGEST}"
105-
cosign sign --yes "${IMAGE}@${MANIFEST_DIGEST}"
143+
if [[ ! "$nightly_digest" =~ ^sha256:[0-9a-f]{64}$ ]]; then
144+
echo "ERROR: Invalid digest: '$nightly_digest'" >&2
145+
exit 1
146+
fi
106147
107-
- name: Write release notes (with immutable digest)
108-
id: notes
148+
echo "nightly_digest=$nightly_digest" >> "$GITHUB_OUTPUT"
149+
echo "Resolved nightly digest: $nightly_digest"
150+
151+
- name: Sign ORAS artifact by digest
109152
shell: bash
110153
run: |
111154
set -euo pipefail
155+
IMAGE="ghcr.io/${{ github.repository }}"
156+
cosign sign --yes "${IMAGE}@${{ steps.digest.outputs.nightly_digest }}"
112157
158+
publish-nightly-release:
159+
name: Publish nightly GitHub Release
160+
needs: publish-oras
161+
runs-on: ubuntu-latest
162+
permissions:
163+
contents: write
164+
steps:
165+
- name: Download plugin.wasm artifact
166+
uses: actions/download-artifact@v4
167+
with:
168+
name: plugin-wasm
169+
path: .
170+
171+
- name: Create release notes
172+
shell: bash
173+
run: |
174+
set -euo pipefail
113175
IMAGE="ghcr.io/${{ github.repository }}"
114-
NIGHTLY_DIGEST="${{ env.IMAGE_DIGEST }}"
115-
SHA="${GITHUB_SHA}"
176+
REF="${{ needs.publish-oras.outputs.nightly_ref }}"
177+
DIGEST="${{ needs.publish-oras.outputs.nightly_digest }}"
116178
117179
cat > release-body.md <<EOF
118180
Nightly build from \`main\`.
119181
120-
Commit:
121-
- \`${SHA}\`
122-
123-
Container image (tag):
124-
- \`${IMAGE}:nightly\`
182+
OCI artifact (tag):
183+
- \`${REF}\`
125184
126185
✅ Immutable digest (recommended for pinning):
127-
- \`${IMAGE}@${NIGHTLY_DIGEST}\`
186+
- \`${IMAGE}@${DIGEST}\`
128187
129-
All container images are signed with Cosign. Verify the **immutable digest** with:
188+
Release asset:
189+
- \`plugin.wasm\`
190+
191+
Pull with ORAS:
192+
\`\`\`bash
193+
oras pull ${REF}
194+
\`\`\`
195+
196+
All artifacts are signed with Cosign. Verify the **immutable digest** with:
130197
131198
\`\`\`bash
132199
cosign verify \
133-
--certificate-identity "https://github.com/${{ github.repository }}/.github/workflows/nightly.yml@refs/heads/main" \
134-
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
135-
${IMAGE}@${NIGHTLY_DIGEST}
200+
--certificate-identity-regexp "https://github.com/${{ github.repository }}/.github/workflows/nightly.yml@refs/heads/main" \
201+
--certificate-oidc-issuer-regexp "https://token.actions.githubusercontent.com" \
202+
${IMAGE}@${DIGEST}
136203
\`\`\`
137204
EOF
138205
139-
echo "body_path=release-body.md" >> "$GITHUB_OUTPUT"
140-
141206
- name: Create new nightly release
142-
id: create_release
143207
uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0
144208
with:
145209
tag_name: nightly
146-
name: Nightly build
210+
name: Nightly build (ORAS)
147211
draft: false
148212
prerelease: true
149213
generate_release_notes: true
150214
preserve_order: true
151-
body_path: ${{ steps.notes.outputs.body_path }}
215+
body_path: release-body.md
216+
files: |
217+
plugin.wasm

0 commit comments

Comments
 (0)