Skip to content

Support SIGUSR1, SIGUSR2, and SIGWINCH #300

Support SIGUSR1, SIGUSR2, and SIGWINCH

Support SIGUSR1, SIGUSR2, and SIGWINCH #300

Workflow file for this run

name: Release
on:
workflow_dispatch:
inputs:
release_version:
description: "Release version, for example 0.21.0 or 0.21.0-rc1"
required: true
type: string
pull_request:
# Do not add permissions here! Configure them at the job level!
permissions: {}
concurrency:
group: ${{ github.event_name == 'workflow_dispatch' && format('release-{0}', github.repository) || format('release-validate-{0}-{1}', github.repository, github.ref) }}
cancel-in-progress: ${{ github.event_name != 'workflow_dispatch' }}
jobs:
rust-version:
name: read Rust version
runs-on: ubuntu-24.04
outputs:
version: ${{ steps.read.outputs.version }}
steps:
- uses: actions/checkout@v7
- id: read
run: |
version=$(sed -n 's/^channel = "\(.*\)".*/\1/p' rust-toolchain.toml)
echo "version=$version" >> "$GITHUB_OUTPUT"
release-info:
name: Validate release request
runs-on: ubuntu-24.04
outputs:
release_version: ${{ steps.validate.outputs.release_version }}
docs_version: ${{ steps.validate.outputs.docs_version }}
steps:
- name: Checkout
uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Validate release request
id: validate
uses: roc-lang/release-package/actions/validate-release@af2f0cd8662874b825ff3917f4286e793ba18c55
with:
release_version: ${{ github.event_name == 'workflow_dispatch' && inputs.release_version || '' }}
dry_run: ${{ github.event_name != 'workflow_dispatch' }}
github_token: ${{ github.token }}
- name: Validate release branch
if: github.event_name == 'workflow_dispatch'
env:
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
RELEASE_VERSION: ${{ steps.validate.outputs.release_version }}
run: |
python3 scripts/check_release_branch.py \
--version "$RELEASE_VERSION" \
--ref-type "$GITHUB_REF_TYPE" \
--ref-name "$GITHUB_REF_NAME" \
--default-branch "$DEFAULT_BRANCH"
build-windows-host:
name: Build Windows x64 host
needs: [rust-version, release-info]
runs-on: windows-2025
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Install Zig
uses: mlugg/setup-zig@8d6198c65fb0feaa111df26e6b467fea8345e46f
with:
version: 0.17.0
- name: Install Rust
shell: bash
run: |
rustup toolchain install "${{ needs.rust-version.outputs.version }}" --profile minimal --target x86_64-pc-windows-msvc --component rust-docs,llvm-tools-preview
rustup default "${{ needs.rust-version.outputs.version }}"
- name: Prepare Cargo package version
if: github.event_name == 'workflow_dispatch'
shell: bash
env:
RELEASE_VERSION: ${{ needs.release-info.outputs.release_version }}
run: python scripts/check_release_version.py "$RELEASE_VERSION" --update
- name: Build Windows host
shell: pwsh
run: python scripts/build.py
- name: Verify Windows runtime ABI and redistribution evidence
shell: pwsh
run: python -m unittest scripts/test_windows_runtime.py
- name: Upload Windows host
uses: actions/upload-artifact@v7
with:
name: windows-x64-host
path: platform/targets/x64win/
if-no-files-found: error
retention-days: 7
build:
name: Build release bundle
needs: [rust-version, release-info, build-windows-host]
# macOS cross-compiles the Apple and Linux musl hosts. Windows is built
# natively above because the Rust dependencies require the Windows SDK.
runs-on: macos-15
outputs:
release_version: ${{ needs.release-info.outputs.release_version }}
docs_version: ${{ needs.release-info.outputs.docs_version }}
test_matrix: ${{ steps.bundles.outputs.test_matrix }}
steps:
- name: Checkout
uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Install Roc
uses: roc-lang/setup-roc@cbe782d6f165b89c87d99f50a59ac4f5f73b4427 # ratchet:roc-lang/setup-roc@v0.3.0
with:
version: nightly-new-compiler
nightly-tag: nightly-2026-11-06-34f137a
- name: Install Zig
uses: mlugg/setup-zig@8d6198c65fb0feaa111df26e6b467fea8345e46f
with:
version: 0.17.0
- name: Install Rust with cross-compilation targets
run: |
rustup toolchain install "${{ needs.rust-version.outputs.version }}" --profile minimal --component llvm-tools-preview \
--target x86_64-apple-darwin --target aarch64-apple-darwin \
--target x86_64-unknown-linux-musl --target aarch64-unknown-linux-musl
rustup default "${{ needs.rust-version.outputs.version }}"
- name: Download Windows host
uses: actions/download-artifact@v8
with:
name: windows-x64-host
path: platform/targets/x64win
- name: Prepare Cargo package version
if: github.event_name == 'workflow_dispatch'
env:
RELEASE_VERSION: ${{ needs.release-info.outputs.release_version }}
run: python3 scripts/check_release_version.py "$RELEASE_VERSION" --update
- name: Build platform for all targets
run: ./scripts/build.py --all
- name: Validate package
env:
NO_BUILD: "1"
run: ./scripts/test.py
- name: Resolve previous release
if: github.event_name == 'workflow_dispatch'
id: previous
uses: roc-lang/release-package/actions/resolve-previous-release@af2f0cd8662874b825ff3917f4286e793ba18c55
with:
github_token: ${{ github.token }}
# roc bump cannot extract a public API that mentions an unexposed type, and
# 0.25.0's Sqlite row decoders take Host.SqliteStmt. Keep warning until the
# predecessor is a release without such a type, and bound the check so a
# compiler hang cannot block release.
- name: Check version bump
env:
RELEASE_VERSION: ${{ needs.release-info.outputs.release_version }}
DRY_RUN: ${{ github.event_name != 'workflow_dispatch' }}
PREVIOUS_URL: ${{ steps.previous.outputs.previous_url }}
run: |
python3 scripts/check_version_bump.py \
--version "$RELEASE_VERSION" \
--dry-run "$DRY_RUN" \
--mode warn \
--previous-url "$PREVIOUS_URL" \
--timeout-seconds 120
- name: Check third-party notices are current
run: python3 scripts/third_party_notices.py --check
- name: Bundle platform
run: ./scripts/bundle.py --output-dir dist
- name: Prepare release bundle metadata
id: bundles
uses: roc-lang/release-package/actions/prepare-bundles@af2f0cd8662874b825ff3917f4286e793ba18c55
with:
bundle_glob: dist/*.tar.zst
test_os_json: '["macos-15","macos-15-intel","ubuntu-22.04","windows-2025"]'
- name: Upload release bundles
uses: actions/upload-artifact@v7
with:
name: release-bundles
path: .release/bundles/*
if-no-files-found: error
retention-days: 7
- name: Upload release metadata
uses: actions/upload-artifact@v7
with:
name: release-metadata
path: |
.release/bump-output.txt
.release/previous-url.txt
.release/release-bundles.json
.release/test-matrix.json
if-no-files-found: error
retention-days: 7
test-bundles:
name: Test ${{ matrix.bundle_name }} bundle (${{ matrix.os }})
needs: [rust-version, build]
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include: ${{ fromJson(needs.build.outputs.test_matrix) }}
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Install Roc
uses: roc-lang/setup-roc@cbe782d6f165b89c87d99f50a59ac4f5f73b4427 # ratchet:roc-lang/setup-roc@v0.3.0
with:
version: nightly-new-compiler
nightly-tag: nightly-2026-11-06-34f137a
- name: Install Rust
shell: bash
run: |
rustup toolchain install "${{ needs.rust-version.outputs.version }}" --profile minimal
rustup default "${{ needs.rust-version.outputs.version }}"
- name: Download release bundles
uses: actions/download-artifact@v8
with:
name: release-bundles
path: .release/test-bundles
- name: Test release bundle (Unix)
if: matrix.os != 'windows-2025'
uses: roc-lang/release-package/actions/test-bundle@af2f0cd8662874b825ff3917f4286e793ba18c55
with:
test_bundle_command: ./scripts/test.py --bundle-path
bundle_path: .release/test-bundles/${{ matrix.artifact_file }}
bundle_name: ${{ matrix.bundle_name }}
release_version: ${{ needs.build.outputs.release_version }}
- name: Test release bundle (Windows)
if: matrix.os == 'windows-2025'
uses: roc-lang/release-package/actions/test-bundle@af2f0cd8662874b825ff3917f4286e793ba18c55
with:
test_bundle_command: python scripts/test.py --bundle-path
bundle_path: .release/test-bundles/${{ matrix.artifact_file }}
bundle_name: ${{ matrix.bundle_name }}
release_version: ${{ needs.build.outputs.release_version }}
build-docs:
name: Build docs archive
needs: build
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Install Roc
uses: roc-lang/setup-roc@cbe782d6f165b89c87d99f50a59ac4f5f73b4427 # ratchet:roc-lang/setup-roc@v0.3.0
with:
version: nightly-new-compiler
nightly-tag: nightly-2026-11-06-34f137a
- name: Create docs staging tree
run: mkdir -p docs-site
- name: Snapshot docs staging tree
uses: roc-lang/release-package/actions/docs-snapshot@af2f0cd8662874b825ff3917f4286e793ba18c55
with:
docs_root: docs-site
- name: Generate docs archive
env:
DOCS_URL_ROOT: /basic-cli/${{ needs.build.outputs.docs_version }}
DOCS_VERSION: ${{ needs.build.outputs.docs_version }}
run: |
set -euo pipefail
ROC_DOCS_URL_ROOT="$DOCS_URL_ROOT" roc docs --output="docs-site/$DOCS_VERSION" platform/main.roc
- name: Validate versioned docs
uses: roc-lang/release-package/actions/docs-validate@af2f0cd8662874b825ff3917f4286e793ba18c55
with:
docs_root: docs-site
docs_version: ${{ needs.build.outputs.docs_version }}
- name: Archive versioned docs
env:
DOCS_VERSION: ${{ needs.build.outputs.docs_version }}
run: tar -czf docs.tar.gz -C docs-site "$DOCS_VERSION"
- name: Upload docs archive
uses: actions/upload-artifact@v7
with:
name: platform-docs
path: docs.tar.gz
if-no-files-found: error
retention-days: 7
publish-release:
name: Publish GitHub release
needs:
- rust-version
- build
- build-docs
- test-bundles
if: github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
outputs:
release_source_commit: ${{ steps.release-source.outputs.commit_sha || github.sha }}
steps:
- name: Checkout
uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Install Rust
run: |
rustup toolchain install "${{ needs.rust-version.outputs.version }}" --profile minimal
rustup default "${{ needs.rust-version.outputs.version }}"
- name: Prepare Cargo package version
env:
RELEASE_VERSION: ${{ needs.build.outputs.release_version }}
run: python3 scripts/check_release_version.py "$RELEASE_VERSION" --update
- name: Open release source follow-up PR
if: github.ref_name == github.event.repository.default_branch
id: release-source
uses: roc-lang/release-package/actions/create-followup-pr@af2f0cd8662874b825ff3917f4286e793ba18c55
with:
release_version: ${{ needs.build.outputs.release_version }}
paths: |
Cargo.toml
Cargo.lock
branch_prefix: release-followup
base_branch: ${{ github.event.repository.default_branch }}
commit_message: Update sources for ${{ needs.build.outputs.release_version }}
pr_title: Update sources for ${{ needs.build.outputs.release_version }}
pr_body: |
Release follow-up for ${{ needs.build.outputs.release_version }}.
Updates the Cargo package version to match the published platform release.
The published example URLs will be added after the release is available.
github_token: ${{ github.token }}
- name: Download release bundles
uses: actions/download-artifact@v8
with:
name: release-bundles
path: .release/bundles
- name: Download release metadata
uses: actions/download-artifact@v8
with:
name: release-metadata
path: .release
- name: Download docs archive
uses: actions/download-artifact@v8
with:
name: platform-docs
- name: Select release notes
id: release-notes
env:
RELEASE_VERSION: ${{ needs.build.outputs.release_version }}
run: |
if [[ -f "docs/releases/${RELEASE_VERSION}.md" ]]; then
echo "custom=true" >> "$GITHUB_OUTPUT"
else
echo "custom=false" >> "$GITHUB_OUTPUT"
fi
- name: Use repository release notes
if: steps.release-notes.outputs.custom == 'true'
uses: roc-lang/release-package/actions/make-release-notes@af2f0cd8662874b825ff3917f4286e793ba18c55
with:
release_version: ${{ needs.build.outputs.release_version }}
release_notes_command: >-
python3 scripts/render_release_notes.py
"docs/releases/${RELEASE_VERSION}.md" "$RELEASE_NOTES_PATH"
--repo "$GITHUB_REPOSITORY"
--version "$RELEASE_VERSION"
--bundles "$RELEASE_BUNDLES_PATH"
- name: Generate release notes
if: steps.release-notes.outputs.custom != 'true'
uses: roc-lang/release-package/actions/make-release-notes@af2f0cd8662874b825ff3917f4286e793ba18c55
with:
release_version: ${{ needs.build.outputs.release_version }}
target: ${{ steps.release-source.outputs.commit_sha || github.sha }}
docs_url: ${{ github.ref_name == github.event.repository.default_branch && format('https://{0}.github.io/{1}/{2}/', github.repository_owner, github.event.repository.name, needs.build.outputs.docs_version) || '' }}
github_token: ${{ github.token }}
- name: Publish release
uses: roc-lang/release-package/actions/publish-release@af2f0cd8662874b825ff3917f4286e793ba18c55
with:
release_version: ${{ needs.build.outputs.release_version }}
target: ${{ steps.release-source.outputs.commit_sha || github.sha }}
additional_assets: docs.tar.gz
github_token: ${{ github.token }}
publish-docs:
name: Publish versioned docs and update examples
needs:
- build
- publish-release
if: github.event_name == 'workflow_dispatch' && github.ref_name == github.event.repository.default_branch
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Checkout
uses: actions/checkout@v7
with:
ref: ${{ needs.publish-release.outputs.release_source_commit }}
fetch-depth: 0
- name: Install Roc
uses: roc-lang/setup-roc@cbe782d6f165b89c87d99f50a59ac4f5f73b4427 # ratchet:roc-lang/setup-roc@v0.3.0
with:
version: nightly-new-compiler
nightly-tag: nightly-2026-11-06-34f137a
- name: Download release metadata
uses: actions/download-artifact@v8
with:
name: release-metadata
path: .release
- name: Derive release bundle URL and update examples and Nix pins
env:
RELEASE_VERSION: ${{ needs.build.outputs.release_version }}
run: |
bundle_url="$(python3 - <<'PY'
import json
import os
from pathlib import Path
bundles = json.loads(Path(".release/release-bundles.json").read_text(encoding="utf-8"))
if len(bundles) != 1:
raise SystemExit(f"expected exactly one release bundle, found {len(bundles)}")
artifact_file = bundles[0]["artifact_file"]
print(
f"https://github.com/{os.environ['GITHUB_REPOSITORY']}/releases/"
f"download/{os.environ['RELEASE_VERSION']}/{artifact_file}"
)
PY
)"
./scripts/update_app_platform_urls.py \
--platform-url "$bundle_url" \
examples
python3 scripts/update_nix_release.py \
--version "$RELEASE_VERSION" \
--url "$bundle_url"
- name: Validate updated examples
run: |
for example in examples/*.roc; do
roc check "$example" --no-cache
roc test "$example" --no-cache
done
- name: Restore published versioned docs
env:
GH_TOKEN: ${{ github.token }}
run: ./scripts/restore_release_docs.sh www
- name: Snapshot existing docs
uses: roc-lang/release-package/actions/docs-snapshot@af2f0cd8662874b825ff3917f4286e793ba18c55
with:
docs_root: www
- name: Generate release docs
env:
DOCS_URL_ROOT: /basic-cli/${{ needs.build.outputs.docs_version }}
DOCS_VERSION: ${{ needs.build.outputs.docs_version }}
run: |
rm -rf "www/$DOCS_VERSION"
ROC_DOCS_URL_ROOT="$DOCS_URL_ROOT" roc docs \
--output="www/$DOCS_VERSION" \
platform/main.roc
- name: Update docs index
uses: roc-lang/release-package/actions/docs-index@af2f0cd8662874b825ff3917f4286e793ba18c55
with:
docs_root: www
docs_version: ${{ needs.build.outputs.docs_version }}
- name: Validate docs
uses: roc-lang/release-package/actions/docs-validate@af2f0cd8662874b825ff3917f4286e793ba18c55
with:
docs_root: www
docs_version: ${{ needs.build.outputs.docs_version }}
- name: Create Pages tree
run: |
mkdir -p temp_docs
cp -R www/. temp_docs/
# Keep /main live without committing a generated main snapshot.
ROC_DOCS_URL_ROOT=/basic-cli/main roc docs \
--output=temp_docs/main \
platform/main.roc
- name: Fix legacy generated URLs
run: |
find temp_docs -type f \( -name "*.html" -o -name "*.js" \) \
-exec sed -i 's|/packages/basic-cli/|/basic-cli/|g' {} +
- name: Setup Pages
uses: actions/configure-pages@v6
- name: Upload Pages artifact
uses: actions/upload-pages-artifact@v5
with:
path: temp_docs
- name: Deploy Pages
id: deployment
uses: actions/deploy-pages@v5
# Runs last on purpose. This step only opens a PR for humans to merge
# later, so nothing above depends on it, and keeping it after the deploy
# means a failure here can never skip the Pages steps the way it did on
# 0.21.0. It reads the same working tree either way: the examples were
# already rewritten near the top of this job, and `git checkout -B` only
# moves a branch pointer at HEAD.
- name: Open release follow-up PR
uses: roc-lang/release-package/actions/create-followup-pr@af2f0cd8662874b825ff3917f4286e793ba18c55
with:
release_version: ${{ needs.build.outputs.release_version }}
paths: |
Cargo.toml
Cargo.lock
examples
nix/release.json
branch_prefix: release-followup
base_branch: ${{ github.event.repository.default_branch }}
commit_message: Update sources for ${{ needs.build.outputs.release_version }}
pr_title: Update sources for ${{ needs.build.outputs.release_version }}
pr_body: |
Release follow-up for ${{ needs.build.outputs.release_version }}.
Updates the Cargo package version, checked-in examples, and Nix
release pins to match the published platform release.
github_token: ${{ github.token }}