chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
name: CEF Runtime
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
cef_version:
|
||||
description: "CEF version to package"
|
||||
required: true
|
||||
default: "144.0.6+g5f7e671+chromium-144.0.7559.59"
|
||||
source:
|
||||
description: "Build from official archive or CEF source"
|
||||
required: true
|
||||
type: choice
|
||||
default: "official"
|
||||
options:
|
||||
- official
|
||||
- source
|
||||
cef_branch:
|
||||
description: "Optional CEF branch for source builds"
|
||||
required: false
|
||||
default: ""
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build ${{ matrix.platform }}
|
||||
runs-on: ${{ matrix.runner }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- platform: macosarm64
|
||||
runner: macos-14
|
||||
- platform: macosx64
|
||||
runner: macos-15
|
||||
- platform: linux64
|
||||
runner: ubuntu-latest
|
||||
- platform: linuxarm64
|
||||
runner: ubuntu-24.04-arm
|
||||
- platform: windows64
|
||||
runner: windows-2022
|
||||
# windowsarm64 disabled: Zig 0.16.0 aarch64-windows binary is broken
|
||||
# https://codeberg.org/ziglang/zig/issues/31865
|
||||
# - platform: windowsarm64
|
||||
# runner: windows-11-arm
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: mlugg/setup-zig@v2
|
||||
with:
|
||||
version: 0.16.0
|
||||
|
||||
- name: Download official CEF
|
||||
if: ${{ inputs.source == 'official' }}
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
version="${{ inputs.cef_version }}"
|
||||
platform="${{ matrix.platform }}"
|
||||
archive="cef_binary_${version}_${platform}.tar.bz2"
|
||||
base="https://cef-builds.spotifycdn.com"
|
||||
mkdir -p zig-out/cef-download
|
||||
curl --fail --location --output "zig-out/cef-download/${archive}" "${base}/${archive}"
|
||||
curl --fail --location --output "zig-out/cef-download/${archive}.sha256" "${base}/${archive}.sha256"
|
||||
expected="$(tr -d '[:space:]' < "zig-out/cef-download/${archive}.sha256")"
|
||||
if command -v sha256sum &>/dev/null; then
|
||||
actual="$(sha256sum "zig-out/cef-download/${archive}" | awk '{print $1}')"
|
||||
elif command -v shasum &>/dev/null; then
|
||||
actual="$(shasum -a 256 "zig-out/cef-download/${archive}" | awk '{print $1}')"
|
||||
else
|
||||
echo "::error::No SHA-256 hashing utility found"; exit 1
|
||||
fi
|
||||
test "$expected" = "$actual"
|
||||
tar -xjf "zig-out/cef-download/${archive}" -C zig-out/cef-download
|
||||
echo "CEF_ROOT=zig-out/cef-download/${archive%.tar.bz2}" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Build CEF wrapper
|
||||
if: ${{ inputs.source == 'official' }}
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
cmake_args=(-S "$CEF_ROOT" -B "$CEF_ROOT/build/libcef_dll_wrapper")
|
||||
case "${{ matrix.platform }}" in
|
||||
*arm64) cmake_args+=(-DPROJECT_ARCH=arm64) ;;
|
||||
macosx64) cmake_args+=(-DCMAKE_OSX_ARCHITECTURES=x86_64 -DPROJECT_ARCH=x86_64) ;;
|
||||
esac
|
||||
cmake "${cmake_args[@]}"
|
||||
cmake --build "$CEF_ROOT/build/libcef_dll_wrapper" --target libcef_dll_wrapper --config Release
|
||||
mkdir -p "$CEF_ROOT/libcef_dll_wrapper"
|
||||
case "${{ matrix.platform }}" in
|
||||
windows*) wrapper="libcef_dll_wrapper.lib" ;;
|
||||
*) wrapper="libcef_dll_wrapper.a" ;;
|
||||
esac
|
||||
find "$CEF_ROOT/build/libcef_dll_wrapper" -name "$wrapper" -print -quit | xargs -I{} cp "{}" "$CEF_ROOT/libcef_dll_wrapper/$wrapper"
|
||||
|
||||
- name: Prepare native-sdk runtime archive
|
||||
if: ${{ inputs.source == 'official' }}
|
||||
shell: bash
|
||||
run: |
|
||||
zig build
|
||||
cli="zig-out/bin/native"
|
||||
if [[ "${{ runner.os }}" == "Windows" ]]; then cli="zig-out/bin/native.exe"; fi
|
||||
"$cli" cef prepare-release --dir "$CEF_ROOT" --output zig-out/cef --version "${{ inputs.cef_version }}"
|
||||
|
||||
- name: Build CEF from source and prepare runtime
|
||||
if: ${{ inputs.source == 'source' }}
|
||||
shell: bash
|
||||
run: |
|
||||
zig build
|
||||
chmod +x tools/cef/build-from-source.sh
|
||||
args=(
|
||||
tools/cef/build-from-source.sh
|
||||
--platform "${{ matrix.platform }}"
|
||||
--version "${{ inputs.cef_version }}"
|
||||
--output zig-out/cef
|
||||
--native-sdk-bin zig-out/bin/native
|
||||
)
|
||||
if [ -n "${{ inputs.cef_branch }}" ]; then
|
||||
args+=(--cef-branch "${{ inputs.cef_branch }}")
|
||||
fi
|
||||
"${args[@]}"
|
||||
|
||||
- name: Publish release asset
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
tag_name: cef-${{ inputs.cef_version }}
|
||||
name: CEF ${{ inputs.cef_version }}
|
||||
files: |
|
||||
zig-out/cef/native-sdk-cef-${{ inputs.cef_version }}-${{ matrix.platform }}.tar.gz
|
||||
zig-out/cef/native-sdk-cef-${{ inputs.cef_version }}-${{ matrix.platform }}.tar.gz.sha256
|
||||
@@ -0,0 +1,335 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
zig:
|
||||
name: Zig Core
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: mlugg/setup-zig@v2
|
||||
with:
|
||||
version: 0.16.0
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
# The TypeScript core suites transpile at build/test time; without
|
||||
# node they skip silently, so CI must provide it.
|
||||
- run: npm ci --prefix packages/core
|
||||
- run: zig build test
|
||||
- run: zig build validate
|
||||
|
||||
macos-webview:
|
||||
name: macOS WebView
|
||||
runs-on: macos-14
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: mlugg/setup-zig@v2
|
||||
with:
|
||||
version: 0.16.0
|
||||
- run: zig build test-webview-system-link
|
||||
- run: zig build test-webview-smoke
|
||||
# Signed-package seal pin: an ad-hoc signed package must pass
|
||||
# codesign --verify --strict (macOS runners are the only tier with
|
||||
# codesign; the step skips loudly anywhere else).
|
||||
- run: zig build test-package-signing
|
||||
# Shared macos-14 runners are far noisier than a dev box (the second
|
||||
# CI run measured a 576 ms automation-ready against the 500 ms local
|
||||
# ceiling), so widen the smoke budgets here instead of weakening the
|
||||
# local defaults. NATIVE_SDK_SMOKE_BUDGET_MS raises the first-frame latency
|
||||
# budget and the automation-ready ceiling together; every correctness
|
||||
# assertion in the smokes stays strict.
|
||||
- run: zig build test-gpu-dashboard-smoke
|
||||
env:
|
||||
NATIVE_SDK_SMOKE_BUDGET_MS: "1500"
|
||||
- run: zig build test-gpu-components-smoke
|
||||
env:
|
||||
NATIVE_SDK_SMOKE_BUDGET_MS: "1500"
|
||||
|
||||
macos-gpu-perf:
|
||||
name: macOS GPU Perf
|
||||
runs-on: macos-14
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: mlugg/setup-zig@v2
|
||||
with:
|
||||
version: 0.16.0
|
||||
# Percentile perf check: 5 cold launches asserting p90
|
||||
# first-frame latency under NATIVE_SDK_PERF_BUDGET_MS, then 5 steady-state
|
||||
# widget clicks asserting p90 input latency under NATIVE_SDK_PERF_INPUT_BUDGET_MS.
|
||||
# Its own job so a shared-runner slowdown is visible in isolation and
|
||||
# never blocks the correctness smokes.
|
||||
# Shared macos-14 runners are far noisier than a dev box (first CI run
|
||||
# measured a 581 ms cold-start outlier against the 300 ms default), so
|
||||
# widen the budgets here instead of weakening the local defaults: this
|
||||
# job exists to catch step-function regressions, not runner noise.
|
||||
- run: zig build test-gpu-dashboard-perf
|
||||
env:
|
||||
NATIVE_SDK_PERF_BUDGET_MS: "1500"
|
||||
NATIVE_SDK_PERF_INPUT_BUDGET_MS: "500"
|
||||
|
||||
linux-webkitgtk:
|
||||
name: Linux WebKitGTK
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: mlugg/setup-zig@v2
|
||||
with:
|
||||
version: 0.16.0
|
||||
- name: Install WebKitGTK dependencies
|
||||
run: sudo apt-get update && sudo apt-get install -y libgtk-4-dev libwebkitgtk-6.0-dev
|
||||
- run: zig build test-webview-system-link -Dplatform=linux
|
||||
# Declare-to-use, proven on real Linux executables WITH the
|
||||
# WebKitGTK dev package installed — the seam, not the environment:
|
||||
# the native-only ui-inbox binary must carry no libwebkitgtk
|
||||
# DT_NEEDED entry and no webkit_/jsc_ dynamic symbol even though
|
||||
# the headers were right there, while the webview example must
|
||||
# keep them. (The environment half — building native-only on a
|
||||
# runner with no WebKitGTK dev package at all — is the
|
||||
# linux-canvas-smoke job.)
|
||||
- run: zig build test-linux-web-layer-audit
|
||||
|
||||
windows-webview:
|
||||
name: Windows WebView
|
||||
runs-on: windows-2022
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: mlugg/setup-zig@v2
|
||||
with:
|
||||
version: 0.16.0
|
||||
# Builds the WebView example with the system engine, compiling the
|
||||
# full embedded-WebView host against the vendored WebView2 SDK
|
||||
# header (third_party/webview2). The host refuses to fall back to
|
||||
# the stubbed layer, so a regression — a missing header, a broken
|
||||
# include path, or a conformance error in the embedded layer — is a
|
||||
# compile failure here, not a silent WebViewNotFound at runtime.
|
||||
- run: zig build test-webview-system-link -Dplatform=windows
|
||||
|
||||
cef-platform-tooling:
|
||||
name: CEF Platform Tooling
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: mlugg/setup-zig@v2
|
||||
with:
|
||||
version: 0.16.0
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
# The TypeScript core suites transpile at build/test time; without
|
||||
# node they skip silently, so CI must provide it.
|
||||
- run: npm ci --prefix packages/core
|
||||
- run: zig build test-tooling
|
||||
|
||||
npm-package:
|
||||
name: npm Package
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 24
|
||||
- run: npm --prefix packages/native-sdk run version:check
|
||||
- run: npm --prefix packages/native-sdk run scripts:check
|
||||
|
||||
native-examples:
|
||||
name: Native Examples
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: mlugg/setup-zig@v2
|
||||
with:
|
||||
version: 0.16.0
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
# The TypeScript examples transpile at build time; the transpiler
|
||||
# needs its installed dependency.
|
||||
- run: npm ci --prefix packages/core
|
||||
- name: Install GTK dependencies
|
||||
run: sudo apt-get update && sudo apt-get install -y libgtk-4-dev libwebkitgtk-6.0-dev
|
||||
- run: zig build test-examples-native
|
||||
# Declare-to-use, proven on real Windows executables: the
|
||||
# canvas-only ui-inbox cross-compiles without the embedded WebView
|
||||
# layer (no WebView2Loader.dll reference, no loader installed) and
|
||||
# the webview example keeps it.
|
||||
- run: zig build test-windows-web-layer-audit
|
||||
|
||||
linux-canvas-smoke:
|
||||
name: Linux Canvas Smoke
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: mlugg/setup-zig@v2
|
||||
with:
|
||||
version: 0.16.0
|
||||
# Deliberately NO libwebkitgtk-6.0-dev: ui-inbox declares no web
|
||||
# use, so its host compiles with the WebKitGTK stub seam and this
|
||||
# job doubles as the native-only Linux LINK test — the build can
|
||||
# only succeed if nothing in a native-only app needs the WebKitGTK
|
||||
# headers or pkg-config entry. (The seam under webkit-PRESENT
|
||||
# conditions is the linux-webkitgtk job's ELF cross-audit.)
|
||||
- name: Install GTK and Xvfb
|
||||
run: sudo apt-get update && sudo apt-get install -y libgtk-4-dev xvfb
|
||||
# Drives the gpu_surface software path under Xvfb: snapshot ready,
|
||||
# gpu_backend=software, gpu_nonblank=true, automation widget-click,
|
||||
# a rendered screenshot, an ELF audit that the built binary carries
|
||||
# no WebKitGTK reference, and ZERO WebKit helper processes (canvas
|
||||
# apps never boot WebKit). A11y env, the widened cold-start
|
||||
# readiness budget (shared runners stall ~27 s before the first
|
||||
# runtime event), and failure forensics (dump snapshot + app log)
|
||||
# all live in the script.
|
||||
- name: Build and drive ui-inbox headless
|
||||
run: .github/scripts/linux-canvas-smoke.sh
|
||||
|
||||
windows-canvas-smoke:
|
||||
name: Windows Canvas Smoke (Wine)
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: mlugg/setup-zig@v2
|
||||
with:
|
||||
version: 0.16.0
|
||||
- name: Install Wine, Xvfb, and xdotool
|
||||
run: sudo apt-get update && sudo apt-get install -y wine xvfb xdotool
|
||||
# Cross-compiles ui-inbox for x86_64-windows-gnu and drives the
|
||||
# gpu_surface software path (child HWND + WM_TIMER + SetDIBitsToDevice)
|
||||
# under Wine: snapshot ready, gpu_backend=software, gpu_nonblank=true,
|
||||
# automation widget-click, and real XTEST pointer/keyboard input.
|
||||
# Wineprefix init happens inline in the script (measured 21s from
|
||||
# scratch in an ubuntu-24.04 container, so no cache step).
|
||||
- name: Build and drive ui-inbox.exe under Wine
|
||||
run: .github/scripts/windows-canvas-smoke.sh
|
||||
|
||||
windows-effects-smoke:
|
||||
name: Windows Effects Smoke (Wine)
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: mlugg/setup-zig@v2
|
||||
with:
|
||||
version: 0.16.0
|
||||
- name: Install Wine and Xvfb
|
||||
run: sudo apt-get update && sudo apt-get install -y wine xvfb
|
||||
# Cross-compiles examples/effects-probe for x86_64-windows-gnu and
|
||||
# proves the effect system's live Windows path under Wine: fx.spawn
|
||||
# launches cmd.exe, streamed lines land in the model, the worker's
|
||||
# PostMessageW wake shows up as effects_wake events in the trace
|
||||
# log (frame ticks also drain, so the log is the wake's evidence),
|
||||
# and fx.cancel terminates the child with the line count frozen.
|
||||
- name: Build and drive effects-probe.exe under Wine
|
||||
run: .github/scripts/windows-effects-smoke.sh
|
||||
|
||||
frontend-examples:
|
||||
name: Frontend Examples
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: mlugg/setup-zig@v2
|
||||
with:
|
||||
version: 0.16.0
|
||||
- run: zig build test-examples-frontends
|
||||
|
||||
mobile-examples:
|
||||
name: Mobile Examples
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: mlugg/setup-zig@v2
|
||||
with:
|
||||
version: 0.16.0
|
||||
- run: zig build test-examples-mobile
|
||||
|
||||
scaffold:
|
||||
name: Generated App Scaffolds
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: mlugg/setup-zig@v2
|
||||
with:
|
||||
version: 0.16.0
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
# The default scaffold is a TypeScript core: its build runs the
|
||||
# @native-sdk/core transpiler from this checkout's own install.
|
||||
- run: npm ci --prefix packages/core
|
||||
- run: zig build
|
||||
- name: Scaffold and test the zero-config native app
|
||||
run: |
|
||||
set -euo pipefail
|
||||
app=".zig-cache/scaffold-native-slim"
|
||||
rm -rf "$app"
|
||||
./zig-out/bin/native init "$app"
|
||||
# Slim scaffold: no build files — the CLI's generated graph drives it.
|
||||
test ! -f "$app/build.zig"
|
||||
test ! -f "$app/build.zig.zon"
|
||||
# The editor surface landed: package.json + tsconfig.json + the
|
||||
# materialized @native-sdk/core copy stock tsc resolves.
|
||||
test -f "$app/package.json"
|
||||
test -f "$app/tsconfig.json"
|
||||
test -f "$app/node_modules/@native-sdk/core/sdk/core.ts"
|
||||
# ...and none of it is build truth: every verb works without it.
|
||||
rm -rf "$app/node_modules"
|
||||
./zig-out/bin/native test "$app" -Dplatform=null
|
||||
./zig-out/bin/native check "$app"
|
||||
# check self-healed the editor copy back into place.
|
||||
test -f "$app/node_modules/@native-sdk/core/sdk/core.ts"
|
||||
./zig-out/bin/native eject "$app"
|
||||
(cd "$app" && zig build test -Dplatform=null)
|
||||
- name: Scaffold and test frontend templates
|
||||
run: |
|
||||
set -euo pipefail
|
||||
for frontend in native next vite react svelte vue; do
|
||||
app=".zig-cache/scaffold-${frontend}"
|
||||
rm -rf "$app"
|
||||
./zig-out/bin/native init "$app" --frontend "$frontend" --full
|
||||
(cd "$app" && zig build test -Dplatform=null && ../../zig-out/bin/native validate app.zon)
|
||||
# Every scaffold ships a CI workflow; parse it as real YAML.
|
||||
test -s "$app/.github/workflows/ci.yml"
|
||||
python3 -c 'import sys, yaml; yaml.safe_load(open(sys.argv[1]))' "$app/.github/workflows/ci.yml"
|
||||
done
|
||||
|
||||
evals-typecheck:
|
||||
name: Evals Typecheck
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
- uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 10.23.0
|
||||
package_json_file: evals/package.json
|
||||
- run: pnpm install --frozen-lockfile
|
||||
working-directory: evals
|
||||
- run: pnpm typecheck
|
||||
working-directory: evals
|
||||
|
||||
docs:
|
||||
name: Docs
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
- uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 10.23.0
|
||||
package_json_file: docs/package.json
|
||||
- run: pnpm install --frozen-lockfile
|
||||
working-directory: docs
|
||||
- run: pnpm check
|
||||
working-directory: docs
|
||||
@@ -0,0 +1,255 @@
|
||||
name: Release
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency: ${{ github.workflow }}-${{ github.ref }}
|
||||
|
||||
jobs:
|
||||
check-release:
|
||||
name: Check for new version
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
permissions:
|
||||
contents: read
|
||||
outputs:
|
||||
should_release: ${{ steps.check.outputs.should_release }}
|
||||
needs_github_release: ${{ steps.check.outputs.needs_github_release }}
|
||||
version: ${{ steps.check.outputs.version }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "24"
|
||||
registry-url: "https://registry.npmjs.org"
|
||||
|
||||
- name: Compare package.json version to npm and check GitHub release
|
||||
id: check
|
||||
run: |
|
||||
LOCAL_VERSION=$(node -p "require('./packages/native-sdk/package.json').version")
|
||||
echo "Local version: $LOCAL_VERSION"
|
||||
|
||||
NPM_VERSION=$(npm view @native-sdk/cli version 2>/dev/null || echo "0.0.0")
|
||||
echo "npm version: $NPM_VERSION"
|
||||
|
||||
if [ "$LOCAL_VERSION" != "$NPM_VERSION" ]; then
|
||||
echo "Version changed: $NPM_VERSION -> $LOCAL_VERSION"
|
||||
echo "should_release=true" >> "$GITHUB_OUTPUT"
|
||||
echo "needs_github_release=true" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "Version unchanged on npm, skipping publish"
|
||||
echo "should_release=false" >> "$GITHUB_OUTPUT"
|
||||
|
||||
TAG="v$LOCAL_VERSION"
|
||||
EXISTING_ASSETS=$(gh release view "$TAG" --json assets --jq '.assets[].name' 2>/dev/null || true)
|
||||
missing=0
|
||||
for asset in \
|
||||
CHECKSUMS.txt \
|
||||
native-sdk-darwin-arm64 \
|
||||
native-sdk-darwin-x64 \
|
||||
native-sdk-linux-arm64 \
|
||||
native-sdk-linux-x64 \
|
||||
native-sdk-linux-musl-arm64 \
|
||||
native-sdk-linux-musl-x64 \
|
||||
native-sdk-win32-arm64.exe \
|
||||
native-sdk-win32-x64.exe
|
||||
do
|
||||
if ! printf '%s\n' "$EXISTING_ASSETS" | grep -Fx "$asset" >/dev/null; then
|
||||
echo "Missing release asset: $asset"
|
||||
missing=1
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$missing" -eq 0 ]; then
|
||||
echo "GitHub release $TAG exists with native assets"
|
||||
echo "needs_github_release=false" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "GitHub release $TAG is missing native assets, will create/update it"
|
||||
echo "needs_github_release=true" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "version=$LOCAL_VERSION" >> "$GITHUB_OUTPUT"
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
github-release:
|
||||
name: Create GitHub Release
|
||||
needs: check-release
|
||||
if: needs.check-release.outputs.needs_github_release == 'true'
|
||||
runs-on: macos-14
|
||||
timeout-minutes: 10
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Zig
|
||||
uses: mlugg/setup-zig@v2
|
||||
with:
|
||||
version: 0.16.0
|
||||
|
||||
- name: Extract changelog entry
|
||||
run: |
|
||||
VERSION="${{ needs.check-release.outputs.version }}"
|
||||
awk '/<!-- release:start -->/{found=1; next} /<!-- release:end -->/{exit} found{print}' CHANGELOG.md > /tmp/release-notes.md
|
||||
|
||||
LINES=$(wc -l < /tmp/release-notes.md | tr -d ' ')
|
||||
if [ "$LINES" -lt 2 ]; then
|
||||
echo "Error: No release notes found between <!-- release:start --> and <!-- release:end --> markers in CHANGELOG.md"
|
||||
exit 1
|
||||
fi
|
||||
echo "Extracted release notes for $VERSION ($LINES lines)"
|
||||
|
||||
- name: Build native release assets (all platforms)
|
||||
run: |
|
||||
# Cross-compiles the CLI for all eight platforms and writes the
|
||||
# flat release assets + CHECKSUMS.txt into zig-out/release/.
|
||||
bash packages/native-sdk/scripts/build-binaries.sh
|
||||
|
||||
- name: Create GitHub Release
|
||||
run: |
|
||||
VERSION="${{ needs.check-release.outputs.version }}"
|
||||
TAG="v$VERSION"
|
||||
|
||||
if gh release view "$TAG" &>/dev/null; then
|
||||
echo "Release $TAG already exists, updating assets"
|
||||
else
|
||||
echo "Creating release $TAG..."
|
||||
gh release create "$TAG" \
|
||||
--title "$TAG" \
|
||||
--notes-file /tmp/release-notes.md
|
||||
fi
|
||||
|
||||
gh release upload "$TAG" \
|
||||
zig-out/release/native-sdk-* \
|
||||
zig-out/release/CHECKSUMS.txt \
|
||||
--clobber
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
publish:
|
||||
name: Publish CLI to npm
|
||||
needs: [check-release, github-release]
|
||||
if: >-
|
||||
always()
|
||||
&& needs.check-release.outputs.should_release == 'true'
|
||||
&& (needs.github-release.result == 'success' || needs.github-release.result == 'skipped')
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
environment: Release
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "24"
|
||||
registry-url: "https://registry.npmjs.org"
|
||||
|
||||
# Publishing uses npm trusted publishing (OIDC): the job's id-token
|
||||
# permission lets npm mint short-lived credentials, so no npm token
|
||||
# secret exists anywhere in this repo. All nine packages —
|
||||
# @native-sdk/cli plus the eight @native-sdk/cli-* platform packages
|
||||
# under packages/native-sdk/npm/ — must each be configured on
|
||||
# npmjs.com with a GitHub Actions trusted publisher pointing at
|
||||
# repository vercel-labs/native, workflow release.yml,
|
||||
# environment Release. If a package is missing that configuration,
|
||||
# npm publish fails loudly with an OIDC authentication error before
|
||||
# anything is uploaded for that package. Trusted publishing requires
|
||||
# npm >= 11.5.1, satisfied by the npm bundled with Node 24.
|
||||
# @native-sdk/core (packages/core) joins that publish set the moment
|
||||
# its "private" flag drops (see the publish step below) — its
|
||||
# npmjs.com trusted-publisher configuration must exist BEFORE that
|
||||
# flip lands.
|
||||
|
||||
- name: Check version sync
|
||||
run: npm --prefix packages/native-sdk run version:check
|
||||
|
||||
- name: Check package scripts
|
||||
run: npm --prefix packages/native-sdk run scripts:check
|
||||
|
||||
- name: Download release binaries
|
||||
run: |
|
||||
VERSION="${{ needs.check-release.outputs.version }}"
|
||||
mkdir -p /tmp/native-sdk-release
|
||||
gh release download "v$VERSION" \
|
||||
--pattern 'native-sdk-*' \
|
||||
--pattern 'CHECKSUMS.txt' \
|
||||
--dir /tmp/native-sdk-release
|
||||
(cd /tmp/native-sdk-release && sha256sum -c CHECKSUMS.txt)
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Stage binaries into the platform packages
|
||||
run: |
|
||||
# Release-asset name -> npm platform package (same table as
|
||||
# packages/native-sdk/scripts/build-binaries.sh).
|
||||
stage() {
|
||||
asset="$1"; key="$2"; ext="$3"
|
||||
mkdir -p "packages/native-sdk/npm/$key/bin"
|
||||
cp "/tmp/native-sdk-release/$asset" "packages/native-sdk/npm/$key/bin/native$ext"
|
||||
chmod 755 "packages/native-sdk/npm/$key/bin/native$ext"
|
||||
}
|
||||
stage native-sdk-darwin-arm64 darwin-arm64 ""
|
||||
stage native-sdk-darwin-x64 darwin-x64 ""
|
||||
stage native-sdk-linux-arm64 linux-arm64-gnu ""
|
||||
stage native-sdk-linux-x64 linux-x64-gnu ""
|
||||
stage native-sdk-linux-musl-arm64 linux-arm64-musl ""
|
||||
stage native-sdk-linux-musl-x64 linux-x64-musl ""
|
||||
stage native-sdk-win32-arm64.exe win32-arm64 ".exe"
|
||||
stage native-sdk-win32-x64.exe win32-x64 ".exe"
|
||||
|
||||
- name: Publish to npm
|
||||
run: |
|
||||
VERSION="${{ needs.check-release.outputs.version }}"
|
||||
|
||||
# Platform packages first, so the main package's
|
||||
# optionalDependencies pins are resolvable the moment it lands.
|
||||
# Re-runs skip anything already on the registry at this version.
|
||||
publish_dir() {
|
||||
dir="$1"
|
||||
name=$(node -p "require('./$dir/package.json').name")
|
||||
if npm view "$name@$VERSION" version >/dev/null 2>&1; then
|
||||
echo "$name@$VERSION already published, skipping"
|
||||
return 0
|
||||
fi
|
||||
(cd "$dir" && npm publish --provenance --access public)
|
||||
}
|
||||
|
||||
for dir in packages/native-sdk/npm/*/; do
|
||||
publish_dir "${dir%/}"
|
||||
done
|
||||
|
||||
# @native-sdk/core (packages/core) rides the same version and
|
||||
# release gate as the CLI (sync-version.js stamps it; the
|
||||
# version check above refuses a half-bumped tree).
|
||||
#
|
||||
# ============================ LOUD FLIP REQUIREMENT ==========
|
||||
# packages/core/package.json keeps "private": true until the
|
||||
# 0.5.0 cut BY DESIGN, and that field IS the publish switch:
|
||||
# while private, the guard below skips the package (npm would
|
||||
# refuse to publish it anyway); the 0.5.0 change that drops
|
||||
# "private" makes this same step start publishing it with no
|
||||
# workflow edit. Before dropping the flag, configure the
|
||||
# @native-sdk/core trusted publisher on npmjs.com (see the note
|
||||
# above) or the first public release fails here.
|
||||
# =============================================================
|
||||
if [ "$(node -p "require('./packages/core/package.json').private === true")" = "true" ]; then
|
||||
echo "@native-sdk/core is private (pre-0.5.0): skipping publish by design"
|
||||
else
|
||||
publish_dir packages/core
|
||||
fi
|
||||
|
||||
publish_dir packages/native-sdk
|
||||
Reference in New Issue
Block a user