Optimize compilation of switch statements for untagged variants #5208
Workflow file for this run
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: CI | |
on: | |
push: | |
branches: [master, 11.0_release] | |
# See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#filter-pattern-cheat-sheet | |
tags: | |
- "v[0-9]+.[0-9]+.[0-9]+" | |
- "v[0-9]+.[0-9]+.[0-9]+-*" | |
pull_request: | |
branches: [master, 11.0_release] | |
concurrency: | |
group: ci-${{ github.ref }}-1 | |
# Cancel previous builds for pull requests only. | |
cancel-in-progress: ${{ github.event_name == 'pull_request' }} | |
env: | |
OCAMLRUNPARAM: b | |
jobs: | |
build-rewatch: | |
strategy: | |
fail-fast: false | |
matrix: | |
include: | |
- os: macos-13 # x64 | |
rust-target: x86_64-apple-darwin | |
- os: macos-14 # ARM | |
rust-target: aarch64-apple-darwin | |
- os: ubuntu-latest # x64 | |
rust-target: x86_64-unknown-linux-musl | |
- os: buildjet-2vcpu-ubuntu-2204-arm # ARM | |
rust-target: aarch64-unknown-linux-musl | |
- os: windows-latest | |
rust-target: x86_64-pc-windows-gnu | |
runs-on: ${{matrix.os}} | |
env: | |
RUST_BACKTRACE: "1" | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Restore build cache | |
id: build-cache | |
uses: actions/cache@v4 | |
with: | |
path: rewatch/target | |
key: rewatch-build-v2-${{ matrix.rust-target }}-${{ hashFiles('rewatch/src/**', 'rewatch/Cargo.lock') }} | |
- name: Install musl gcc | |
if: steps.build-cache.outputs.cache-hit != 'true' && runner.os == 'Linux' | |
run: sudo apt-get install -y --no-install-recommends musl-tools | |
- name: Install rust toolchain | |
if: steps.build-cache.outputs.cache-hit != 'true' | |
uses: dtolnay/rust-toolchain@master | |
with: | |
toolchain: stable | |
targets: ${{matrix.rust-target}} | |
- name: Build rewatch | |
if: steps.build-cache.outputs.cache-hit != 'true' | |
run: cargo build --manifest-path rewatch/Cargo.toml --target ${{matrix.rust-target}} --release | |
- name: Copy rewatch exe to platform bin dir | |
run: | | |
cp rewatch/target/${{matrix.rust-target}}/release/rewatch${{ runner.os == 'Windows' && '.exe' || '' }} rewatch | |
node ./scripts/copyExes.js -rewatch | |
- name: Get artifact dir name | |
run: node .github/workflows/get_artifact_dir_name.js | |
- name: "Upload artifact: rewatch binary" | |
uses: actions/upload-artifact@v4 | |
with: | |
name: rewatch-${{env.artifact_dir_name}} | |
path: ${{ env.artifact_dir_name }} | |
build-compiler: | |
strategy: | |
fail-fast: false | |
matrix: | |
include: | |
- os: ubuntu-latest # x64 | |
ocaml_compiler: ocaml-variants.5.2.0+options,ocaml-option-static | |
upload_binaries: true | |
upload_libs: true | |
# Build the playground compiler and run the benchmarks on the fastest runner | |
build_playground: true | |
benchmarks: true | |
- os: buildjet-2vcpu-ubuntu-2204-arm # ARM | |
ocaml_compiler: ocaml-variants.5.2.0+options,ocaml-option-static | |
upload_binaries: true | |
- os: macos-13 # x64 | |
ocaml_compiler: 5.2.0 | |
upload_binaries: true | |
- os: macos-14 # ARM | |
ocaml_compiler: 5.2.0 | |
upload_binaries: true | |
- os: windows-latest | |
ocaml_compiler: 5.2.0 | |
upload_binaries: true | |
# Verify that the compiler still builds with older OCaml versions | |
- os: ubuntu-latest | |
ocaml_compiler: ocaml-variants.5.0.0+options,ocaml-option-static | |
- os: ubuntu-latest | |
ocaml_compiler: ocaml-variants.4.14.2+options,ocaml-option-static | |
- os: ubuntu-latest | |
ocaml_compiler: ocaml-variants.4.13.0+options,ocaml-option-static | |
runs-on: ${{matrix.os}} | |
env: | |
# setup-ocaml opam version cannot be configured | |
# we do track its version mannually | |
OPAM_VERSION: 2.2.0 | |
DUNE_PROFILE: release | |
steps: | |
- name: "Windows: Set git to use LF" | |
if: runner.os == 'Windows' | |
run: | | |
git config --global core.autocrlf false | |
git config --global core.eol lf | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Use Node.js | |
uses: actions/setup-node@v4 | |
with: | |
node-version: 18 | |
- name: Get artifact dir name | |
run: node .github/workflows/get_artifact_dir_name.js | |
- name: Install dependencies (Linux) | |
if: runner.os == 'Linux' | |
uses: awalsh128/[email protected] | |
with: | |
# See https://github.com/ocaml/setup-ocaml/blob/b2105f9/packages/setup-ocaml/src/unix.ts#L9 | |
packages: bubblewrap darcs g++-multilib gcc-multilib mercurial musl-tools rsync | |
version: v2 | |
# matrix.ocaml_compiler may contain commas | |
- name: Get OPAM cache key | |
shell: bash | |
run: echo "opam_cache_key=opam-env-v4-${{ matrix.os }}-${{ matrix.ocaml_compiler }}-${{ hashFiles('dune-project') }}" | sed 's/,/-/g' >> $GITHUB_ENV | |
- name: Restore OPAM environment | |
id: cache-opam-env | |
uses: actions/cache/restore@v4 | |
with: | |
path: | | |
${{ runner.tool_cache }}/opam | |
~/.opam | |
_opam | |
.opam-path | |
D:\cygwin | |
D:\.opam | |
key: ${{ env.opam_cache_key }} | |
- name: Use OCaml ${{matrix.ocaml_compiler}} | |
uses: ocaml/[email protected] | |
if: steps.cache-opam-env.outputs.cache-hit != 'true' | |
with: | |
ocaml-compiler: ${{matrix.ocaml_compiler}} | |
opam-pin: false | |
- name: Get OPAM executable path | |
if: steps.cache-opam-env.outputs.cache-hit != 'true' | |
uses: actions/github-script@v7 | |
with: | |
script: | | |
const opamPath = await io.which('opam', true); | |
console.log('opam executable found: %s', opamPath); | |
const fs = require('fs/promises'); | |
await fs.writeFile('.opam-path', opamPath, 'utf-8'); | |
console.log('stored path to .opam-path'); | |
- name: Install OPAM dependencies | |
if: steps.cache-opam-env.outputs.cache-hit != 'true' | |
run: opam install . --deps-only --with-test | |
- name: Cache OPAM environment | |
if: steps.cache-opam-env.outputs.cache-hit != 'true' | |
uses: actions/cache/save@v4 | |
with: | |
path: | | |
${{ runner.tool_cache }}/opam | |
~/.opam | |
_opam | |
.opam-path | |
D:\cygwin | |
D:\.opam | |
key: ${{ env.opam_cache_key }} | |
- name: Use cached OPAM environment | |
if: steps.cache-opam-env.outputs.cache-hit == 'true' | |
run: | | |
# https://github.com/ocaml/setup-ocaml/blob/b2105f9/packages/setup-ocaml/src/installer.ts#L33 | |
echo "OPAMVERBOSE=$RUNNER_DEBUG" >> "$GITHUB_ENV" | |
echo "OPAMCOLOR=always" >> "$GITHUB_ENV" | |
echo "OPAMCONFIRMLEVEL=unsafe-yes" >> "$GITHUB_ENV" | |
echo "OPAMERRLOGLEN=0" >> "$GITHUB_ENV" | |
echo "OPAMPRECISETRACKING=1" >> "$GITHUB_ENV" | |
echo "OPAMYES=1" >> "$GITHUB_ENV" | |
if [[ "$RUNNER_OS" != "Windows" ]]; then | |
echo "OPAMROOT=$HOME/.opam" >> "$GITHUB_ENV" | |
else | |
echo "OPAMROOT=D:\\.opam" >> "$GITHUB_ENV" | |
fi | |
OPAM_PATH="$(cat .opam-path)" | |
chmod +x "$OPAM_PATH" | |
dirname "$OPAM_PATH" >> "$GITHUB_PATH" | |
if [[ "$RUNNER_OS" == "Windows" ]]; then | |
fsutil behavior query SymlinkEvaluation | |
fsutil behavior set symlinkEvaluation R2L:1 R2R:1 | |
fsutil behavior query SymlinkEvaluation | |
CYGWIN="winsymlinks:native" | |
CYGWIN_ROOT="D:\\cygwin" | |
CYGWIN_ROOT_BIN="D:\\cygwin\\bin" | |
CYGWIN_ROOT_WRAPPERBIN="D:\\cygwin\\wrapperbin" | |
echo "HOME=$USERPROFILE" >> "$GITHUB_ENV" | |
echo "MSYS=winsymlinks:native" >> "$GITHUB_ENV" | |
echo "CYGWIN=$CYGWIN" >> "$GITHUB_ENV" | |
echo "CYGWIN_ROOT=$CYGWIN_ROOT" >> "$GITHUB_ENV" | |
echo "CYGWIN_ROOT_BIN=$CYGWIN_ROOT_BIN" >> "$GITHUB_ENV" | |
echo "CYGWIN_ROOT_WRAPPERBIN=$CYGWIN_ROOT_WRAPPERBIN" >> "$GITHUB_ENV" | |
echo "$CYGWIN_ROOT_WRAPPERBIN" >> "$GITHUB_PATH" | |
fi | |
shell: bash | |
# see https://github.com/ocaml/setup-ocaml/issues/815 | |
- name: "Windows: set SHELLOPTS=igncr" | |
if: runner.os == 'Windows' | |
run: echo "SHELLOPTS=igncr" >>"$GITHUB_ENV" | |
- name: Build compiler | |
if: runner.os != 'Linux' | |
run: opam exec -- dune build --display quiet --profile release | |
- name: Build compiler (Linux static) | |
if: runner.os == 'Linux' | |
run: opam exec -- dune build --display quiet --profile static | |
- name: Install npm packages | |
run: npm ci --ignore-scripts | |
- name: Copy compiler exes to platform bin dir | |
run: node ./scripts/copyExes.js -compiler | |
- name: Restore ninja build cache | |
id: ninja-build-cache | |
uses: actions/cache@v4 | |
with: | |
path: ${{ env.artifact_dir_name }}/ninja.exe | |
key: ninja-build-v1-${{ matrix.os }}-${{ hashFiles('ninja/src/**') }} | |
- name: Setup Python for ninja build | |
if: steps.ninja-build-cache.outputs.cache-hit != 'true' | |
uses: actions/setup-python@v5 | |
with: | |
python-version: '3.10' | |
- name: Setup MSVC for ninja build (Windows) | |
if: steps.ninja-build-cache.outputs.cache-hit != 'true' && runner.os == 'Windows' | |
uses: TheMrMilchmann/setup-msvc-dev@v3 | |
with: | |
arch: x64 | |
- name: Build ninja | |
if: steps.ninja-build-cache.outputs.cache-hit != 'true' && runner.os != 'Linux' | |
run: node scripts/buildNinjaBinary.js | |
- name: Build ninja (Linux static) | |
if: steps.ninja-build-cache.outputs.cache-hit != 'true' && runner.os == 'Linux' | |
env: | |
LDFLAGS: -static | |
run: node scripts/buildNinjaBinary.js | |
- name: Copy ninja exe to platform bin dir | |
if: steps.ninja-build-cache.outputs.cache-hit != 'true' | |
run: node ./scripts/copyExes.js -ninja | |
- name: "Syntax: Run roundtrip tests" | |
if: ${{ runner.os != 'Windows' }} | |
run: opam exec -- make test-syntax-roundtrip | |
- name: "Syntax: Run tests (Windows)" | |
if: ${{ runner.os == 'Windows' }} | |
run: opam exec -- make test-syntax | |
- name: Build runtime/stdlib | |
run: ./scripts/buildRuntime.sh | |
shell: bash | |
- name: Check for changes in lib folder | |
run: git diff --exit-code lib/js lib/es6 | |
- name: Version Check | |
run: ./scripts/prebuilt.js | |
- name: Run tests | |
run: node scripts/test.js -all | |
- name: Check for diffs in tests folder | |
run: git diff --ignore-cr-at-eol --exit-code tests | |
- name: Run gentype tests | |
if: runner.os != 'Windows' | |
run: make -C tests/gentype_tests/typescript-react-example clean test | |
- name: Run syntax benchmarks | |
if: matrix.benchmarks | |
run: ./_build/install/default/bin/syntax_benchmarks | tee tests/benchmark-output.json | |
- name: Restore previous benchmark data | |
if: matrix.benchmarks | |
uses: actions/cache/restore@v4 | |
with: | |
path: ./tests/benchmark-cache | |
key: syntax-benchmark-v1 | |
- name: Create new benchmark data and comment on alert | |
# Do not run for PRs created from other repos as those won't be able to write to the pull request | |
if: ${{ matrix.benchmarks && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.event.repository.full_name) }} | |
uses: benchmark-action/github-action-benchmark@v1 | |
with: | |
name: Syntax Benchmarks | |
tool: customSmallerIsBetter | |
output-file-path: tests/benchmark-output.json | |
external-data-json-path: ./tests/benchmark-cache/benchmark-data.json | |
github-token: ${{ secrets.GITHUB_TOKEN }} | |
alert-threshold: "105%" | |
comment-always: false | |
comment-on-alert: true | |
- name: Save benchmark data as new baseline | |
if: matrix.benchmarks && github.ref == 'refs/heads/master' | |
uses: actions/cache/save@v4 | |
with: | |
path: ./tests/benchmark-cache | |
key: syntax-benchmark-v1 | |
- name: Build playground compiler | |
if: matrix.build_playground | |
run: | | |
opam exec -- node packages/playground-bundling/scripts/generate_cmijs.js | |
opam exec -- dune build --profile browser | |
cp ./_build/default/compiler/jsoo/jsoo_playground_main.bc.js playground/compiler.js | |
- name: Test playground compiler | |
if: matrix.build_playground | |
run: node playground/playground_test.js | |
- name: Upload playground compiler to CDN | |
if: ${{ matrix.build_playground && startsWith(github.ref, 'refs/tags/v') }} | |
env: | |
KEYCDN_USER: ${{ secrets.KEYCDN_USER }} | |
KEYCDN_PASSWORD: ${{ secrets.KEYCDN_PASSWORD }} | |
run: bash playground/upload_bundle.sh | |
- name: "Upload artifacts: binaries" | |
if: matrix.upload_binaries | |
uses: actions/upload-artifact@v4 | |
with: | |
name: binaries-${{ env.artifact_dir_name }} | |
path: ${{ env.artifact_dir_name }} | |
- name: "Upload artifacts: lib/ocaml" | |
if: matrix.upload_libs | |
uses: actions/upload-artifact@v4 | |
with: | |
name: lib-ocaml | |
path: lib/ocaml | |
package: | |
needs: | |
- build-compiler | |
- build-rewatch | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Use Node.js | |
uses: actions/setup-node@v4 | |
with: | |
node-version: 18 | |
- name: NPM install | |
run: npm ci --ignore-scripts | |
- name: Download artifacts | |
uses: actions/download-artifact@v4 | |
with: | |
pattern: "@(binaries-*|rewatch-*|lib-ocaml)" | |
- name: Move artifacts | |
run: ./scripts/moveArtifacts.sh | |
- name: npm pack (rescript) + check artifact list | |
run: node ./scripts/npmPack.js | |
- name: Copy JS files to stdlib package | |
run: mkdir -p packages/std/lib && cp -R lib/es6 lib/js packages/std/lib | |
- name: npm pack (@rescript/std) | |
run: npm pack | |
working-directory: packages/std | |
- name: Prepare package upload | |
# For pull requests, pass the correct commit SHA explicitly as GITHUB_SHA points to the wrong commit. | |
run: node .github/workflows/prepare_package_upload.js ${{ github.event.pull_request.head.sha }} | |
- name: "Upload artifact: npm packages" | |
uses: actions/upload-artifact@v4 | |
with: | |
name: npm-packages | |
path: | | |
rescript-${{ env.rescript_version }}.tgz | |
rescript-std-${{ env.rescript_version }}.tgz | |
outputs: | |
rescript_version: ${{ env.rescript_version }} | |
installationTest: | |
needs: package | |
strategy: | |
fail-fast: false | |
matrix: | |
os: [ | |
macos-13, # x64 | |
macos-14, # ARM | |
ubuntu-latest, | |
buildjet-2vcpu-ubuntu-2204-arm, | |
windows-latest, | |
] | |
runs-on: ${{matrix.os}} | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Use Node.js | |
uses: actions/setup-node@v4 | |
with: | |
node-version: 18 | |
- name: Download artifacts | |
uses: actions/download-artifact@v4 | |
with: | |
name: npm-packages | |
path: packages/test | |
- name: Install ReScript package | |
run: | | |
npm i --ignore-scripts --no-audit \ | |
rescript-${{ needs.package.outputs.rescript_version }}.tgz | |
shell: bash | |
working-directory: packages/test | |
- name: Test installation | |
run: npx rescript -h && npx rescript build && cat src/Test.bs.js | |
shell: bash | |
working-directory: packages/test | |
publish: | |
needs: [package, installationTest] | |
if: startsWith(github.ref, 'refs/tags/v') | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Use Node.js | |
uses: actions/setup-node@v4 | |
with: | |
node-version: 18 | |
registry-url: https://registry.npmjs.org # Needed to make auth work for publishing | |
- name: Download artifacts | |
uses: actions/download-artifact@v4 | |
with: | |
name: npm-packages | |
- name: Publish packages on npm with tag "ci" | |
env: | |
NODE_AUTH_TOKEN: ${{ secrets.NPM_ACCESS_TOKEN }} | |
run: | | |
npm publish rescript-${{ needs.package.outputs.rescript_version }}.tgz --tag ci | |
npm publish rescript-std-${{ needs.package.outputs.rescript_version }}.tgz --tag ci | |
- name: Update Website Playground | |
env: | |
NEXT_REVALIDATE_SECRET_TOKEN: ${{ secrets.NEXT_REVALIDATE_SECRET_TOKEN }} | |
run: ./playground/website_update_playground.sh | |
shell: bash |