Skip to content
Closed
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
146 changes: 144 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,61 @@ jobs:
pnpm test packages/compiler/test/cc-driver.test.ts
--testNamePattern "host-native clang static build"

llvm_artifacts_linux_x64:
name: test (Linux x64 LLVM artifacts, no clang)
runs-on: ubuntu-24.04
timeout-minutes: 25
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 11.1.3
- uses: actions/setup-node@v4
with:
node-version-file: .node-version
cache: pnpm
- name: Install pinned LLVM development distribution
run: |
sudo apt-get update
sudo apt-get install --yes libzstd-dev
curl -fL --retry 3 -o "$RUNNER_TEMP/llvm.tar.xz" https://github.com/llvm/llvm-project/releases/download/llvmorg-22.1.8/LLVM-22.1.8-Linux-X64.tar.xz
tar -xJf "$RUNNER_TEMP/llvm.tar.xz" -C "$RUNNER_TEMP"
mv "$RUNNER_TEMP/LLVM-22.1.8-Linux-X64" "$RUNNER_TEMP/llvm-22.1.8"
echo "LLVM_DIR=$RUNNER_TEMP/llvm-22.1.8/lib/cmake/llvm" >> "$GITHUB_ENV"
echo "$RUNNER_TEMP/llvm-22.1.8/bin" >> "$GITHUB_PATH"
- run: pnpm install --frozen-lockfile
- run: pnpm --filter @scriptc/llvm-linux-x64-gnu build:native
- run: CC=clang AR=llvm-ar pnpm --filter @scriptc/runtime-linux-x64-gnu build:native
- uses: vercel-labs/setup-zig@v1
with:
version: 0.16.0
- run: pnpm --filter @scriptc/runtime-wasm32-wasi build:native
- run: pnpm build
- name: Linux helper object format and no-clang output contract
run: |
PATH="$RUNNER_TEMP/traps:$PATH"
mkdir -p "$RUNNER_TEMP/traps"
for tool in clang cc gcc ar ld; do printf '#!/bin/sh\nexit 97\n' > "$RUNNER_TEMP/traps/$tool"; chmod +x "$RUNNER_TEMP/traps/$tool"; done
node packages/cli/dist/main.js build tests/corpus/001-hello.ts --emit=obj -o "$RUNNER_TEMP/hello.o"
file "$RUNNER_TEMP/hello.o" | grep 'ELF 64-bit LSB relocatable, x86-64'
- name: Linux helper/runtime-pack executable differential smoke
env:
SCRIPTC_NO_CACHE: "1"
SCRIPTC_LEGACY_C_PIPELINE: "0"
run: |
node packages/cli/dist/main.js build tests/corpus/001-hello.ts -o "$RUNNER_TEMP/hello"
test "$("$RUNNER_TEMP/hello")" = 'hello world'
- name: WASI helper object/runtime-pack smoke
run: pnpm test packages/cli/test/wasi-runtime-pack.test.ts

llvm_artifacts_macos_arm64:
name: test (macOS arm64 LLVM artifacts, no clang, ${{ matrix.shard }}/3)
runs-on: macos-15
timeout-minutes: 20
# Shard 1 additionally runs package/install and link-parity contracts
# before its LLVM differential slice. The slice itself can take ~10
# minutes on a cold hosted runner, so 20 minutes cancels an otherwise
# healthy job before the differential completes.
timeout-minutes: 35
strategy:
fail-fast: false
matrix:
Expand Down Expand Up @@ -191,6 +242,38 @@ jobs:
"$RUNNER_TEMP/installed-link.json" "$RUNNER_TEMP/installed-program"
test "$("$RUNNER_TEMP/installed-program")" = 'hello world'

llvm_artifacts_macos_x64:
name: test (macOS x64 LLVM artifacts, no clang)
runs-on: macos-15-intel
timeout-minutes: 20
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 11.1.3
- uses: actions/setup-node@v4
with:
node-version-file: .node-version
cache: pnpm
- run: brew install llvm@22
- run: pnpm install --frozen-lockfile
- run: LLVM_DIR=/usr/local/opt/llvm@22/lib/cmake/llvm pnpm --filter @scriptc/llvm-darwin-x64 build:native
- run: pnpm --filter @scriptc/runtime-darwin-x64 build:native
- run: pnpm build
- name: Intel Mach-O no-clang object contract
run: |
mkdir -p "$RUNNER_TEMP/traps"
for tool in clang cc gcc ar ld; do printf '#!/bin/sh\nexit 97\n' > "$RUNNER_TEMP/traps/$tool"; chmod +x "$RUNNER_TEMP/traps/$tool"; done
PATH="$RUNNER_TEMP/traps:$PATH" node packages/cli/dist/main.js build tests/corpus/001-hello.ts --emit=obj -o "$RUNNER_TEMP/hello.o"
file "$RUNNER_TEMP/hello.o" | grep 'Mach-O 64-bit object x86_64'
- name: Intel helper/runtime-pack executable smoke
env:
SCRIPTC_NO_CACHE: "1"
SCRIPTC_LEGACY_C_PIPELINE: "0"
run: |
node packages/cli/dist/main.js build tests/corpus/001-hello.ts -o "$RUNNER_TEMP/hello"
test "$($RUNNER_TEMP/hello)" = 'hello world'

# Exercises the supported Windows GNU target and the built CLI end to end:
# TS7 must open its synthetic project, ambient files must resolve across
# slash styles, and the default executable must use the .exe suffix.
Expand Down Expand Up @@ -262,17 +345,76 @@ jobs:
pnpm exec vitest run packages/compiler/test/cc-driver.test.ts
--testNamePattern "Windows CA roots honor"

llvm_artifacts_windows_x64:
name: test (Windows x64 MSVC LLVM artifacts)
# The official LLVM 22 Windows archives are MSVC-built and the helper
# selects CMake's VS 2022 generator. `windows-latest` can move to an
# image without that generator, so retain the hosted VS 2022 contract.
runs-on: windows-2022
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 11.1.3
- uses: actions/setup-node@v4
with:
node-version-file: .node-version
cache: pnpm
- name: Install pinned LLVM development distribution
shell: pwsh
run: |
# windows-2022 already provides CMake, Ninja, VS 2022, and 7-Zip.
# Use the complete archive because it supplies LLVM's exported CMake
# targets and static libraries. Windows tar.exe takes 25+ minutes to
# materialize it; two-stage 7-Zip extraction takes seconds.
$archive = "$env:RUNNER_TEMP\clang+llvm-22.1.8-x86_64-pc-windows-msvc.tar.xz"
$llvm = "$env:RUNNER_TEMP\llvm-22.1.8"
$expanded = "$env:RUNNER_TEMP\llvm-expanded"
$sevenZip = "$env:ProgramFiles\7-Zip\7z.exe"
if (-not (Test-Path $sevenZip)) {
choco install 7zip --no-progress -y
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
}
if (-not (Test-Path $sevenZip)) { throw "7-Zip is unavailable" }
curl.exe -fL --retry 3 -o $archive https://github.com/llvm/llvm-project/releases/download/llvmorg-22.1.8/clang%2Bllvm-22.1.8-x86_64-pc-windows-msvc.tar.xz
& $sevenZip x -y "-o$expanded" $archive
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
& $sevenZip x -y "-o$expanded" "$expanded\clang+llvm-22.1.8-x86_64-pc-windows-msvc.tar"
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
Move-Item "$expanded\clang+llvm-22.1.8-x86_64-pc-windows-msvc" $llvm
echo "LLVM_DIR=$llvm\lib\cmake\llvm" >> $env:GITHUB_ENV
echo "$llvm\bin" >> $env:GITHUB_PATH
- run: pnpm install --frozen-lockfile
- name: Build Windows helper
run: pnpm --filter @scriptc/llvm-win32-x64-msvc build:native
- uses: vercel-labs/setup-zig@v1
with:
version: 0.16.0
- name: Build Windows runtime pack
run: pnpm --filter @scriptc/runtime-win32-x64-msvc build:native
- run: pnpm build
- name: Windows COFF no-clang object contract
shell: pwsh
run: |
node packages/cli/dist/main.js build tests/corpus/001-hello.ts --emit=obj -o "$env:RUNNER_TEMP\hello.obj"
$bytes = [System.IO.File]::ReadAllBytes("$env:RUNNER_TEMP\hello.obj")
if ($bytes[0] -ne 0x64 -or $bytes[1] -ne 0x86) { throw "expected AMD64 COFF object" }

# Aggregate gate with the pre-matrix job's name, so anything keyed on the
# single "test" check (branch protection, badges) keeps resolving. Fails
# unless every matrix shard and both platform integration jobs succeeded.
test:
needs: [tests, linux_host_clang, llvm_artifacts_macos_arm64, windows_cli]
needs: [tests, linux_host_clang, llvm_artifacts_linux_x64, llvm_artifacts_macos_arm64, llvm_artifacts_macos_x64, windows_cli, llvm_artifacts_windows_x64]
if: always()
runs-on: ubuntu-latest
steps:
- name: All lanes green
run: |
test "${{ needs.tests.result }}" = success
test "${{ needs.linux_host_clang.result }}" = success
test "${{ needs.llvm_artifacts_linux_x64.result }}" = success
test "${{ needs.llvm_artifacts_macos_arm64.result }}" = success
test "${{ needs.llvm_artifacts_macos_x64.result }}" = success
test "${{ needs.windows_cli.result }}" = success
test "${{ needs.llvm_artifacts_windows_x64.result }}" = success
157 changes: 147 additions & 10 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,133 @@ jobs:
fi
echo "version=$LOCAL_VERSION" >> "$GITHUB_OUTPUT"

build-native-packages:
name: Build native package (${{ matrix.platform }})
needs: check-release
if: needs.check-release.outputs.should_release == 'true'
strategy:
fail-fast: false
matrix:
include:
- platform: darwin-arm64
runner: macos-15
helper: llvm-darwin-arm64
runtime: runtime-darwin-arm64
- platform: darwin-x64
runner: macos-15-intel
helper: llvm-darwin-x64
runtime: runtime-darwin-x64
- platform: linux-x64
runner: ubuntu-24.04
helper: llvm-linux-x64-gnu
runtime: runtime-linux-x64-gnu
llvm_asset: LLVM-22.1.8-Linux-X64
- platform: linux-arm64
runner: ubuntu-24.04-arm
helper: llvm-linux-arm64-gnu
runtime: runtime-linux-arm64-gnu
llvm_asset: LLVM-22.1.8-Linux-ARM64
- platform: windows-x64
runner: windows-2022
helper: llvm-win32-x64-msvc
runtime: runtime-win32-x64-msvc
use_zig: true
- platform: linux-x64-musl
runner: ubuntu-24.04
helper: llvm-linux-x64-musl
runtime: runtime-linux-x64-musl
llvm_asset: LLVM-22.1.8-Linux-X64
use_zig: true
- platform: linux-arm64-musl
runner: ubuntu-24.04-arm
helper: llvm-linux-arm64-musl
runtime: runtime-linux-arm64-musl
llvm_asset: LLVM-22.1.8-Linux-ARM64
use_zig: true
- platform: wasm32-wasi
runner: ubuntu-24.04
helper: llvm-linux-x64-gnu
runtime: runtime-wasm32-wasi
llvm_asset: LLVM-22.1.8-Linux-X64
use_zig: true
runs-on: ${{ matrix.runner }}
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 11.1.3
- uses: actions/setup-node@v4
with:
node-version: "24"
cache: pnpm
- name: Install toolchain (macOS)
if: startsWith(matrix.platform, 'darwin')
run: brew install llvm@22
- name: Install pinned LLVM development distribution (Linux)
if: startsWith(matrix.platform, 'linux') || matrix.platform == 'wasm32-wasi'
run: |
sudo apt-get update
sudo apt-get install --yes libzstd-dev
curl -fL --retry 3 -o "$RUNNER_TEMP/llvm.tar.xz" "https://github.com/llvm/llvm-project/releases/download/llvmorg-22.1.8/${{ matrix.llvm_asset }}.tar.xz"
tar -xJf "$RUNNER_TEMP/llvm.tar.xz" -C "$RUNNER_TEMP"
mv "$RUNNER_TEMP/${{ matrix.llvm_asset }}" "$RUNNER_TEMP/llvm-22.1.8"
echo "LLVM_DIR=$RUNNER_TEMP/llvm-22.1.8/lib/cmake/llvm" >> "$GITHUB_ENV"
echo "$RUNNER_TEMP/llvm-22.1.8/bin" >> "$GITHUB_PATH"
- uses: vercel-labs/setup-zig@v1
if: matrix.use_zig == true
with:
version: 0.16.0
- name: Install pinned LLVM development distribution (Windows)
if: matrix.platform == 'windows-x64'
shell: pwsh
run: |
# The complete archive supplies LLVM's exported CMake targets and
# static libraries. windows-2022 includes CMake, Ninja, VS 2022,
# and 7-Zip; unlike tar.exe, 7-Zip expands this archive quickly.
$archive = "$env:RUNNER_TEMP\clang+llvm-22.1.8-x86_64-pc-windows-msvc.tar.xz"
$llvm = "$env:RUNNER_TEMP\llvm-22.1.8"
$expanded = "$env:RUNNER_TEMP\llvm-expanded"
$sevenZip = "$env:ProgramFiles\7-Zip\7z.exe"
if (-not (Test-Path $sevenZip)) {
choco install 7zip --no-progress -y
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
}
if (-not (Test-Path $sevenZip)) { throw "7-Zip is unavailable" }
curl.exe -fL --retry 3 -o $archive https://github.com/llvm/llvm-project/releases/download/llvmorg-22.1.8/clang%2Bllvm-22.1.8-x86_64-pc-windows-msvc.tar.xz
& $sevenZip x -y "-o$expanded" $archive
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
& $sevenZip x -y "-o$expanded" "$expanded\clang+llvm-22.1.8-x86_64-pc-windows-msvc.tar"
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
Move-Item "$expanded\clang+llvm-22.1.8-x86_64-pc-windows-msvc" $llvm
echo "LLVM_DIR=$llvm\lib\cmake\llvm" >> $env:GITHUB_ENV
echo "$llvm\bin" >> $env:GITHUB_PATH
- run: pnpm install --frozen-lockfile
- name: Build native packages (POSIX)
if: matrix.platform != 'windows-x64'
run: |
pnpm --filter @scriptc/${{ matrix.helper }} build:native
if [ "${{ matrix.use_zig }}" = true ]; then
CC=zig AR=zig pnpm --filter @scriptc/${{ matrix.runtime }} build:native
else
CC=clang AR=llvm-ar pnpm --filter @scriptc/${{ matrix.runtime }} build:native
fi
- name: Build native packages (Windows)
if: matrix.platform == 'windows-x64'
run: |
pnpm --filter @scriptc/${{ matrix.helper }} build:native
pnpm --filter @scriptc/${{ matrix.runtime }} build:native
- uses: actions/upload-artifact@v4
with:
name: native-${{ matrix.platform }}
path: |
packages/${{ matrix.helper }}
packages/${{ matrix.runtime }}
retention-days: 1

publish:
name: Publish to npm
needs: check-release
needs: [check-release, build-native-packages]
if: needs.check-release.outputs.should_release == 'true'
runs-on: macos-15
timeout-minutes: 15
Expand All @@ -63,6 +187,13 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4

- name: Download native packages
uses: actions/download-artifact@v4
with:
pattern: native-*
path: native-artifacts
merge-multiple: true

- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
Expand All @@ -74,14 +205,10 @@ jobs:
node-version: "24"
registry-url: "https://registry.npmjs.org"

- name: Install pinned LLVM
run: brew install llvm@22

# 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 five packages —
# @scriptc/runtime, @scriptc/runtime-darwin-arm64,
# @scriptc/llvm-darwin-arm64, @scriptc/compiler, and scriptc — must each be
# secret exists anywhere in this repo. The runtime, every shipped
# platform runtime/helper package, compiler, and CLI must each be
# configured on npmjs.com with a GitHub Actions trusted publisher
# pointing at repository vercel-labs/scriptc, workflow release.yml,
# environment Release. A package missing that configuration fails
Expand All @@ -91,14 +218,13 @@ jobs:
- name: Install and build
run: |
pnpm install --frozen-lockfile
pnpm --filter @scriptc/llvm-darwin-arm64 build:native
pnpm --filter @scriptc/runtime-darwin-arm64 build:native
cp -R native-artifacts/. packages/
pnpm -r build

- name: Check version sync
run: |
VERSION="${{ needs.check-release.outputs.version }}"
for pkg in packages/runtime packages/runtime-darwin-arm64 packages/llvm-darwin-arm64 packages/compiler packages/cli; do
for pkg in packages/runtime packages/runtime-darwin-arm64 packages/llvm-darwin-arm64 packages/runtime-linux-x64-gnu packages/llvm-linux-x64-gnu packages/runtime-linux-arm64-gnu packages/llvm-linux-arm64-gnu packages/runtime-linux-x64-musl packages/llvm-linux-x64-musl packages/runtime-linux-arm64-musl packages/llvm-linux-arm64-musl packages/runtime-wasm32-wasi packages/runtime-win32-x64-msvc packages/llvm-win32-x64-msvc packages/compiler packages/cli; do
V=$(node -p "require('./$pkg/package.json').version")
if [ "$V" != "$VERSION" ]; then
echo "Version mismatch: $pkg is $V, expected $VERSION"
Expand Down Expand Up @@ -152,6 +278,17 @@ jobs:
publish_dir packages/runtime
publish_dir packages/runtime-darwin-arm64
publish_dir packages/llvm-darwin-arm64 "$HELPER_TARBALL"
publish_dir packages/runtime-linux-x64-gnu
publish_dir packages/llvm-linux-x64-gnu
publish_dir packages/runtime-linux-arm64-gnu
publish_dir packages/llvm-linux-arm64-gnu
publish_dir packages/runtime-linux-x64-musl
publish_dir packages/llvm-linux-x64-musl
publish_dir packages/runtime-linux-arm64-musl
publish_dir packages/llvm-linux-arm64-musl
publish_dir packages/runtime-wasm32-wasi
publish_dir packages/runtime-win32-x64-msvc
publish_dir packages/llvm-win32-x64-msvc
publish_dir packages/compiler
publish_dir packages/cli
env:
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ dist/
/packages/runtime-darwin-arm64/artifacts/
/packages/runtime-darwin-arm64/runtime-pack.json
/packages/runtime-darwin-arm64/.runtime-pack-*
/packages/llvm-*/bin/
/packages/runtime-*/artifacts/
/packages/runtime-*/runtime-pack.json
/packages/runtime-*/.runtime-pack-*
!tests/fixtures/fetch/node_modules/eventsource-parser/dist/
!tests/fixtures/npm/node_modules/*/dist/
!tests/fixtures/npm/workspace/*/dist/
Expand Down
Loading
Loading