Skip to content
Merged
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
76 changes: 76 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
name: Release

on:
release:
types:
- published

permissions:
contents: read
id-token: write

jobs:
npm:
name: npm
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v7
with:
fetch-depth: 0

- name: Set up Node.js
uses: actions/setup-node@v7
with:
node-version: 24.18.0
registry-url: https://registry.npmjs.org
package-manager-cache: false

- name: Install current npm CLI
run: npm install --global npm@12.0.2

- name: Install JavaScript development dependencies
run: npm ci

- name: Install stable Rust toolchain
run: rustup toolchain install stable --profile minimal --target wasm32-unknown-unknown

- name: Install WebAssembly binding generator
uses: taiki-e/install-action@e67fa11c4b9316fa714ddf0abed07a0c3143b95b
with:
tool: wasm-bindgen-cli@0.2.127
fallback: none

- name: Verify release version
run: |
package_version=$(node --print "require('./packages/engine/package.json').version")
workspace_version=$(node --print "require('./package.json').version")
test "$package_version" = "$workspace_version"
test "$GITHUB_REF_NAME" = "v$package_version"
git merge-base --is-ancestor "$GITHUB_SHA" origin/main

- name: Build browser WebAssembly package
run: npm run build:wasm

- name: Test browser package
run: npm test

- name: Check browser package types
run: npm run typecheck

- name: Verify browser package contents
run: npm run pack:check

- name: Check whether version is already published
id: package
run: |
package_version=$(node --print "require('./packages/engine/package.json').version")
if npm view "@stack-sh/engine@$package_version" version >/dev/null 2>&1; then
echo "published=true" >> "$GITHUB_OUTPUT"
else
echo "published=false" >> "$GITHUB_OUTPUT"
fi

- name: Publish package
if: steps.package.outputs.published != 'true'
run: npm publish --workspace @stack-sh/engine --access public
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ The renderer emits fixed-dimension standalone SVG with embedded catalog icons, l

The npm package exports synchronous `format`, `check`, and `render` functions after asynchronous module initialization. Each operation accepts `string | Uint8Array` and returns a specific typed result with camel-case metadata and portable diagnostics. Invalid UTF-8 remains a normal `STK1001` result. Unsupported JavaScript input types and internal operational failures throw at the adapter boundary. Shared fixtures compare complete native and WebAssembly results, including formatted source, diagnostics, SVG, and metadata. Artifact validation audits WebAssembly imports and package contents; browser consumers retain responsibility for loading the module and performing any DOM, filesystem, network, or clock work.

Public npm releases are produced from GitHub Releases after the repository checks pass. See [RELEASING.md](./RELEASING.md) for the first-release bootstrap and subsequent trusted-publishing flow.

## Architecture

- [`docs/decisions/0001-build-the-formatter-from-compiler-models.md`](./docs/decisions/0001-build-the-formatter-from-compiler-models.md)
Expand Down
36 changes: 36 additions & 0 deletions RELEASING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Releasing `@stack-sh/engine`

The package is public and is released from this public repository. Release artifacts must come from a merged `main` revision whose `baseline` and `Minimum supported Rust` checks have passed.

## First release

The npm package must exist before its trusted publisher can be configured. An authenticated maintainer with publish access to the `@stack-sh` scope performs the one-time bootstrap from a clean `main` checkout:

```sh
npm ci
rustup target add wasm32-unknown-unknown --toolchain stable
npm run build:wasm
npm test
npm run typecheck
npm run pack:check
npm publish --workspace @stack-sh/engine --access public
```

After `@stack-sh/engine` exists on npm, configure its trusted publisher with these exact values:

- Provider: GitHub Actions
- Organization: `stack-sh`
- Repository: `engine`
- Workflow filename: `release.yaml`
- Allowed action: `npm publish`

Then create the `v0.1.0` GitHub Release from the same merged revision. The release workflow recognizes that the package version already exists and completes without publishing it twice.

## Subsequent releases

1. Update the workspace and package versions in a pull request.
2. Run the complete repository checks and merge the pull request.
3. Create a GitHub Release whose tag is exactly `v<package version>` and targets the merged commit.
4. Verify that the release workflow publishes the package through npm trusted publishing.

The workflow rejects a tag that does not match the package version. It builds and validates the package again on the tagged revision, uses no long-lived npm token, and leaves npm provenance enabled.