Skip to content

v0.3.0-rc-2026-02-09 #8

v0.3.0-rc-2026-02-09

v0.3.0-rc-2026-02-09 #8

Workflow file for this run

name: Publish
# This workflow publishes all WASI proposals to GitHub Container Registry
# when a release is created
on:
release:
types: [published]
workflow_dispatch:
inputs:
version:
description: 'Version to publish (without the v)'
required: true
type: string
wit_dir:
description: 'WIT directory to publish from (wit or wit-0.3.0-draft)'
required: true
type: choice
options:
- wit
- wit-0.3.0-draft
default: wit
jobs:
# Determine version and configuration
setup:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.version }}
wit_dir: ${{ steps.config.outputs.wit_dir }}
is_prerelease: ${{ steps.config.outputs.is_prerelease }}
proposals: ${{ steps.config.outputs.proposals }}
steps:
- name: Get version from release tag
id: version
run: |
if [ "${{ github.event_name }}" == "release" ]; then
# Extract version from tag (remove 'v' prefix)
VERSION="${{ github.event.release.tag_name }}"
VERSION="${VERSION#v}"
else
VERSION="${{ inputs.version }}"
fi
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "Publishing version: $VERSION"
- name: Determine configuration
id: config
run: |
VERSION="${{ steps.version.outputs.version }}"
# Determine configuration based on version:
# - RC versions always use wit-0.3.0-draft
# - Stable versions use wit (or workflow_dispatch input if provided)
if [[ "$VERSION" == *"-rc-"* ]]; then
IS_PRERELEASE="true"
WIT_DIR="wit-0.3.0-draft"
PROPOSALS="random clocks filesystem sockets cli http"
elif [ "${{ github.event_name }}" == "workflow_dispatch" ] && [ -n "${{ inputs.wit_dir }}" ]; then
IS_PRERELEASE="false"
WIT_DIR="${{ inputs.wit_dir }}"
PROPOSALS="io random clocks filesystem sockets cli http"
else
IS_PRERELEASE="false"
WIT_DIR="wit"
PROPOSALS="io random clocks filesystem sockets cli http"
fi
{
echo "is_prerelease=$IS_PRERELEASE"
echo "wit_dir=$WIT_DIR"
echo "proposals=$PROPOSALS"
} >> "$GITHUB_OUTPUT"
# Publish proposals sequentially in dependency order:
# 1. io, random (no WASI dependencies)
# 2. clocks (depends on io)
# 3. filesystem, sockets (depend on io, clocks)
# 4. cli (depends on io, clocks, filesystem, random, sockets)
# 5. http (depends on cli, clocks, io)
publish-io:
needs: setup
# Skip io for P3 prereleases (no wit-0.3.0-draft directory)
if: needs.setup.outputs.is_prerelease != 'true'
uses: ./.github/workflows/publish-proposal.yml
with:
proposal: io
description: "WASI I/O interfaces for streams and poll"
version: ${{ needs.setup.outputs.version }}
wit_dir: ${{ needs.setup.outputs.wit_dir }}
secrets: inherit
publish-random:
needs: setup
uses: ./.github/workflows/publish-proposal.yml
with:
proposal: random
description: "WASI random number generation interfaces"
version: ${{ needs.setup.outputs.version }}
wit_dir: ${{ needs.setup.outputs.wit_dir }}
secrets: inherit
publish-clocks:
needs: [setup, publish-io, publish-random]
# For prereleases, only wait on random (io is skipped)
if: always() && !failure() && !cancelled()
uses: ./.github/workflows/publish-proposal.yml
with:
proposal: clocks
description: "WASI clock interfaces for monotonic and system clocks"
version: ${{ needs.setup.outputs.version }}
wit_dir: ${{ needs.setup.outputs.wit_dir }}
secrets: inherit
publish-filesystem:
needs: [setup, publish-clocks]
if: always() && !failure() && !cancelled()
uses: ./.github/workflows/publish-proposal.yml
with:
proposal: filesystem
description: "WASI filesystem interfaces"
version: ${{ needs.setup.outputs.version }}
wit_dir: ${{ needs.setup.outputs.wit_dir }}
secrets: inherit
publish-sockets:
needs: [setup, publish-clocks]
if: always() && !failure() && !cancelled()
uses: ./.github/workflows/publish-proposal.yml
with:
proposal: sockets
description: "WASI socket interfaces for TCP and UDP"
version: ${{ needs.setup.outputs.version }}
wit_dir: ${{ needs.setup.outputs.wit_dir }}
secrets: inherit
publish-cli:
needs: [setup, publish-filesystem, publish-sockets]
if: always() && !failure() && !cancelled()
uses: ./.github/workflows/publish-proposal.yml
with:
proposal: cli
description: "WASI CLI interfaces for command-line programs"
version: ${{ needs.setup.outputs.version }}
wit_dir: ${{ needs.setup.outputs.wit_dir }}
secrets: inherit
publish-http:
needs: [setup, publish-cli]
if: always() && !failure() && !cancelled()
uses: ./.github/workflows/publish-proposal.yml
with:
proposal: http
description: "WASI HTTP interfaces for HTTP client and server"
version: ${{ needs.setup.outputs.version }}
wit_dir: ${{ needs.setup.outputs.wit_dir }}
secrets: inherit
# Validate all packages were published successfully
validate:
needs: [setup, publish-io, publish-random, publish-clocks, publish-filesystem, publish-sockets, publish-cli, publish-http]
if: always() && !failure() && !cancelled()
runs-on: ubuntu-latest
steps:
- name: Install oras
uses: oras-project/setup-oras@22ce207df3b08e061f537244349aac6ae1d214f6 # v1.2.4
- name: Validate published packages
run: |
VERSION="${{ needs.setup.outputs.version }}"
PROPOSALS="${{ needs.setup.outputs.proposals }}"
echo "Validating packages for version $VERSION..."
FAILED=""
for proposal in $PROPOSALS; do
echo "Checking ghcr.io/webassembly/wasi/$proposal:$VERSION..."
if oras manifest fetch "ghcr.io/webassembly/wasi/$proposal:$VERSION" > /dev/null 2>&1; then
echo " ✓ $proposal published successfully"
else
echo " ✗ $proposal NOT FOUND"
FAILED="$FAILED $proposal"
fi
done
if [ -n "$FAILED" ]; then
echo ""
echo "ERROR: Failed to validate packages:$FAILED"
exit 1
fi
echo ""
echo "✓ All packages validated successfully!"
# Create and upload wit.tar.gz artifact to the GitHub release
upload-wit-tarball:
needs: [setup, validate]
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Install cargo-binstall
uses: cargo-bins/cargo-binstall@ec80feb9e330418e014932e5982599255eff6dbb # v1.17.4
- name: Install wkg and wasm-tools
run: |
cargo binstall -y wkg@0.15.0
cargo binstall -y wasm-tools@1.244.0
- name: Create consolidated WIT directory
run: |
VERSION="${{ needs.setup.outputs.version }}"
WIT_DIR="${{ needs.setup.outputs.wit_dir }}"
PROPOSALS="${{ needs.setup.outputs.proposals }}"
TARBALL_DIR="wasi-wit-$VERSION"
mkdir -p "$TARBALL_DIR"
# Build each proposal to .wasm, then extract consolidated WIT
for proposal in $PROPOSALS; do
echo "Building $proposal..."
(cd "proposals/$proposal" && wkg wit build -o "$GITHUB_WORKSPACE/$proposal.wasm" --wit-dir "$WIT_DIR")
mkdir -p "$TARBALL_DIR/$proposal"
wasm-tools component wit "$proposal.wasm" --out-dir "$TARBALL_DIR/$proposal/"
rm "$proposal.wasm"
done
echo "Created $TARBALL_DIR with contents:"
find "$TARBALL_DIR" -type f | head -20
- name: Create tarball
run: |
VERSION="${{ needs.setup.outputs.version }}"
tar -czvf "wasi-wit-$VERSION.tar.gz" "wasi-wit-$VERSION"
echo "Created wasi-wit-$VERSION.tar.gz"
ls -lh "wasi-wit-$VERSION.tar.gz"
- name: Upload to GitHub Release
env:
GH_TOKEN: ${{ github.token }}
run: |
VERSION="${{ needs.setup.outputs.version }}"
gh release upload "v$VERSION" "wasi-wit-$VERSION.tar.gz" --clobber
# Create specification entry after all publishes complete
create-specification:
needs: [setup, validate]
runs-on: ubuntu-latest
if: needs.setup.outputs.is_prerelease == 'false'
permissions:
contents: write
pull-requests: write
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Create specification directory
run: |
VERSION="${{ needs.setup.outputs.version }}"
SPEC_DIR="specifications/wasi-$VERSION"
mkdir -p "$SPEC_DIR"
cat > "$SPEC_DIR/Overview.md" << EOF
# WASI Specification v${VERSION}
This is version ${VERSION} of the WASI specification, based on the [WebAssembly
Component Model][cm].
## Proposals
The [WebAssembly Interface Type (WIT)][wit] definitions for the proposals included in this
version of the specification are pushed to OCI based on the [Wasm OCI Artifact
layout][wasm-oci]:
- [wasi:io@${VERSION}](https://github.com/WebAssembly/WASI/pkgs/container/wasi%2Fio?tag=${VERSION})
- [wasi:random@${VERSION}](https://github.com/WebAssembly/WASI/pkgs/container/wasi%2Frandom?tag=${VERSION})
- [wasi:clocks@${VERSION}](https://github.com/WebAssembly/WASI/pkgs/container/wasi%2Fclocks?tag=${VERSION})
- [wasi:sockets@${VERSION}](https://github.com/WebAssembly/WASI/pkgs/container/wasi%2Fsockets?tag=${VERSION})
- [wasi:filesystem@${VERSION}](https://github.com/WebAssembly/WASI/pkgs/container/wasi%2Ffilesystem?tag=${VERSION})
- [wasi:cli@${VERSION}](https://github.com/WebAssembly/WASI/pkgs/container/wasi%2Fcli?tag=${VERSION})
- [wasi:http@${VERSION}](https://github.com/WebAssembly/WASI/pkgs/container/wasi%2Fhttp?tag=${VERSION})
[cm]: https://github.com/WebAssembly/component-model
[wit]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md
[wasm-oci]: https://tag-runtime.cncf.io/wgs/wasm/deliverables/wasm-oci-artifact
EOF
# Remove leading whitespace from heredoc
sed -i 's/^ //' "$SPEC_DIR/Overview.md"
- name: Create Pull Request for specification
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8.1.0
with:
commit-message: "Add specification for v${{ needs.setup.outputs.version }}"
branch: spec-v${{ needs.setup.outputs.version }}
title: "Add specification for WASI v${{ needs.setup.outputs.version }}"
body: |
This PR adds the specification entry for WASI v${{ needs.setup.outputs.version }}.
The following packages have been published to GHCR:
- `ghcr.io/webassembly/wasi/io:${{ needs.setup.outputs.version }}`
- `ghcr.io/webassembly/wasi/random:${{ needs.setup.outputs.version }}`
- `ghcr.io/webassembly/wasi/clocks:${{ needs.setup.outputs.version }}`
- `ghcr.io/webassembly/wasi/sockets:${{ needs.setup.outputs.version }}`
- `ghcr.io/webassembly/wasi/filesystem:${{ needs.setup.outputs.version }}`
- `ghcr.io/webassembly/wasi/cli:${{ needs.setup.outputs.version }}`
- `ghcr.io/webassembly/wasi/http:${{ needs.setup.outputs.version }}`
base: main
delete-branch: true