Skip to content

Use a socket to communicate with the jit runtime process #7930

Use a socket to communicate with the jit runtime process

Use a socket to communicate with the jit runtime process #7930

Workflow file for this run

name: CI
defaults:
run:
shell: bash
on:
# Build on every pull request (and new PR commit)
pull_request:
# Build on new pushes to trunk (E.g. Merge commits)
# Without the branch filter, each commit on a branch with a PR is triggered twice.
# See: https://github.community/t/how-to-trigger-an-action-on-push-or-pull-request-but-not-both/16662
push:
branches:
- trunk
tags:
- release/*
workflow_dispatch:
env:
ormolu_version: "0.5.2.0"
racket_version: "8.7"
ucm_local_bin: "ucm-local-bin"
jit_version: "@unison/internal/releases/0.0.14"
jit_src_scheme: "unison-jit-src/scheme-libs/racket"
jit_dist: "unison-jit-dist"
jit_generator_os: ubuntu-20.04
runtime_tests_version: "@unison/runtime-tests/main"
runtime_tests_codebase: "~/.cache/unisonlanguage/runtime-tests.unison"
# locations of some files that will indicate whether we need to re-run certain steps
transcript_test_results: "transcript-test-results"
interpreter_test_results: "interpreter-test-results"
jit_test_results: "jit-test-results"
jobs:
ormolu:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v4
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@v41
with:
# globs copied from default settings for run-ormolu
files: |
**/*.hs
**/*.hs-boot
separator: "\n"
- uses: haskell-actions/run-ormolu@v15
with:
version: ${{ env.ormolu_version }}
mode: inplace
pattern: ${{ steps.changed-files.outputs.all_changed_files }}
- name: apply formatting changes
uses: stefanzweifel/git-auto-commit-action@v5
# Only try to commit formatting changes if we're running within the repo containing the PR,
# and not on a protected branch.
# The job doesn't have permission to push back to contributor forks on contributor PRs.
if: |
always()
&& !github.ref_protected
&& github.event.pull_request.base.repo.full_name == github.event.pull_request.head.repo.full_name
with:
commit_message: automatically run ormolu
build-ucm:
name: build ucm
runs-on: ${{ matrix.os }}
strategy:
# Run each build to completion, regardless of if any have failed
fail-fast: false
matrix:
os:
# While iterating on this file, you can disable one or more of these to speed things up
- ubuntu-20.04
- macOS-12
- windows-2019
# - windows-2022
steps:
- uses: actions/checkout@v4
- name: tweak environment
id: tweak-environment
run: |
ucm_local_bin="${RUNNER_TEMP//\\//}/${ucm_local_bin}"
echo "ucm_local_bin=$ucm_local_bin" >> $GITHUB_ENV
if [[ ${{runner.os}} = "Windows" ]]; then
echo "ucm=$ucm_local_bin/unison.exe" >> $GITHUB_ENV
echo "transcripts=$ucm_local_bin/transcripts.exe" >> $GITHUB_ENV
else
echo "ucm=$ucm_local_bin/unison" >> $GITHUB_ENV
echo "transcripts=$ucm_local_bin/transcripts" >> $GITHUB_ENV
fi
- name: cache ucm binaries
id: cache-ucm-binaries
uses: actions/cache@v4
with:
path: ${{env.ucm_local_bin}}
key: ucm-${{ matrix.os }}-${{ hashFiles('**/stack.yaml', '**/package.yaml', '**/*.hs')}}
- name: restore stack caches
if: steps.cache-ucm-binaries.outputs.cache-hit != 'true'
id: restore-stack-caches
uses: unisonweb/actions/stack/cache/restore@main
with:
cache-prefix: ci
- name: install stack
if: steps.cache-ucm-binaries.outputs.cache-hit != 'true'
uses: unisonweb/actions/stack/install@main
# Build deps, then build local code. Splitting it into two steps just allows us to see how much time each step
# takes.
- name: build dependencies
if: steps.cache-ucm-binaries.outputs.cache-hit != 'true'
# Run up to 5 times in a row before giving up.
# It's very unlikely that our build-dependencies step will fail on most builds,
# so if it fails its almost certainly due to a race condition on the Windows
# file-system API that stack runs into. Since any successful packages are
# cached within a single build, it should get further along on each re-start
# and should hopefully finish!
run: |
stack --version
tries=1
if [[ ${{matrix.os}} = "windows-"* ]]; then
tries=5
fi
for (( i = 0; i < $tries; i++ )); do
stack build --fast --only-dependencies --test --bench && break;
done
- name: build
if: steps.cache-ucm-binaries.outputs.cache-hit != 'true'
run: |
stack build \
--fast \
--test \
--no-run-tests \
--local-bin-path ${{env.ucm_local_bin}} \
--copy-bins
# The unison-cli test requires a git user.
- name: set git user info
if: steps.cache-ucm-binaries.outputs.cache-hit != 'true'
run: |
git config --global user.name "GitHub Actions"
git config --global user.email "actions@github.com"
# Run each test suite (tests and transcripts)
- name: unison-cli test
if: steps.cache-ucm-binaries.outputs.cache-hit != 'true'
run: stack build --fast --test unison-cli
- name: unison-core tests
if: steps.cache-ucm-binaries.outputs.cache-hit != 'true'
run: stack build --fast --test unison-core
- name: unison-parser-typechecker tests
if: steps.cache-ucm-binaries.outputs.cache-hit != 'true'
run: stack build --fast --test unison-parser-typechecker
- name: unison-sqlite tests
if: steps.cache-ucm-binaries.outputs.cache-hit != 'true'
run: stack build --fast --test unison-sqlite
- name: unison-syntax tests
if: steps.cache-ucm-binaries.outputs.cache-hit != 'true'
run: stack build --fast --test unison-syntax
- name: unison-util-bytes tests
if: steps.cache-ucm-binaries.outputs.cache-hit != 'true'
run: stack build --fast --test unison-util-bytes
- name: unison-util-cache tests
if: steps.cache-ucm-binaries.outputs.cache-hit != 'true'
run: stack build --fast --test unison-util-cache
- name: unison-util-relation tests
if: steps.cache-ucm-binaries.outputs.cache-hit != 'true'
run: stack build --fast --test unison-util-relation
- name: cli-integration-tests
if: steps.cache-ucm-binaries.outputs.cache-hit != 'true'
run: stack exec cli-integration-tests
- name: verify stack ghci startup
if: runner.os == 'macOS' && steps.cache-ucm-binaries.outputs.cache-hit != 'true'
run: echo | stack ghci
- name: save ucm artifact
uses: actions/upload-artifact@v4
with:
name: unison-${{ matrix.os }}
path: ${{ env.ucm }}
if-no-files-found: error
- name: save stack caches
if: |
!cancelled()
&& steps.restore-stack-caches.outputs.cache-hit != 'true'
&& steps.cache-ucm-binaries.outputs.cache-hit != 'true'
uses: unisonweb/actions/stack/cache/save@main
with:
cache-prefix: ci
transcripts:
name: run transcripts
needs: build-ucm
runs-on: ${{ matrix.os }}
strategy:
# Run each build to completion, regardless of if any have failed
fail-fast: false
matrix:
os:
# While iterating on this file, you can disable one or more of these to speed things up
- ubuntu-20.04
- macOS-12
- windows-2019
# - windows-2022
steps:
- uses: actions/checkout@v4
- name: tweak environment
run: |
transcript_test_results="${RUNNER_TEMP//\\//}/${transcript_test_results}"
echo "transcript_test_results=$transcript_test_results" >> $GITHUB_ENV
ucm_local_bin="${RUNNER_TEMP//\\//}/${ucm_local_bin}"
echo "ucm_local_bin=$ucm_local_bin" >> $GITHUB_ENV
if [[ ${{runner.os}} = "Windows" ]]; then
echo "ucm=$ucm_local_bin/unison.exe" >> $GITHUB_ENV
echo "transcripts=$ucm_local_bin/transcripts.exe" >> $GITHUB_ENV
else
echo "ucm=$ucm_local_bin/unison" >> $GITHUB_ENV
echo "transcripts=$ucm_local_bin/transcripts" >> $GITHUB_ENV
fi
- name: cache transcript test results
id: cache-transcript-test-results
uses: actions/cache@v4
with:
path: ${{env.transcript_test_results}}
key: transcripts-results-${{ matrix.os }}-${{ hashFiles('**/stack.yaml', '**/package.yaml', '**/*.hs')}}-${{ hashFiles('**/unison-src/**/*.md') }}
- name: restore binaries
uses: actions/cache/restore@v4
if: steps.cache-transcript-test-results.outputs.cache-hit != 'true'
with:
path: ${{env.ucm_local_bin}}
key: ucm-${{ matrix.os }}-${{ hashFiles('**/stack.yaml', '**/package.yaml', '**/*.hs')}}
fail-on-cache-miss: true
# One of the transcripts fails if the user's git name hasn't been set.
## (Which transcript? -AI)
- name: set git user info
run: |
git config --global user.name "GitHub Actions"
git config --global user.email "actions@github.com"
- name: round-trip-tests
if: steps.cache-transcript-test-results.outputs.cache-hit != 'true'
run: |
${{env.ucm}} transcript unison-src/transcripts-round-trip/main.md
${{env.ucm}} transcript unison-src/transcripts-manual/rewrites.md
# Fail if any transcripts cause git diffs.
git diff --ignore-cr-at-eol --exit-code \
unison-src/transcripts-round-trip/main.output.md \
unison-src/transcripts-manual/rewrites.output.md
- name: transcripts
if: steps.cache-transcript-test-results.outputs.cache-hit != 'true'
run: |
${{env.transcripts}}
# Fail if any transcripts cause git diffs.
git diff --ignore-cr-at-eol --exit-code unison-src/transcripts
- name: mark transcripts as passing
if: steps.cache-transcript-test-results.outputs.cache-hit != 'true'
run: |
echo "passing=true" >> "${{env.transcript_test_results}}"
interpreter-tests:
name: run interpreter tests
needs: build-ucm
runs-on: ${{ matrix.os }}
strategy:
# Run each build to completion, regardless of if any have failed
fail-fast: false
matrix:
os:
# While iterating on this file, you can disable one or more of these to speed things up
- ubuntu-20.04
- macOS-12
# - windows-2019
# - windows-2022
steps:
- uses: actions/checkout@v4
- name: tweak environment
run: |
interpreter_test_results="${RUNNER_TEMP//\\//}/${interpreter_test_results}"
echo "interpreter_test_results=$interpreter_test_results" >> $GITHUB_ENV
ucm_local_bin="${RUNNER_TEMP//\\//}/${ucm_local_bin}"
echo "ucm_local_bin=$ucm_local_bin" >> $GITHUB_ENV
if [[ ${{runner.os}} = "Windows" ]]; then
echo "ucm=$ucm_local_bin/unison.exe" >> $GITHUB_ENV
echo "transcripts=$ucm_local_bin/transcripts.exe" >> $GITHUB_ENV
else
echo "ucm=$ucm_local_bin/unison" >> $GITHUB_ENV
echo "transcripts=$ucm_local_bin/transcripts" >> $GITHUB_ENV
fi
- name: look up hash for runtime tests
run: echo "runtime_tests_causalhash=$(scripts/get-share-hash.sh ${{env.runtime_tests_version}})" >> $GITHUB_ENV
- name: cache interpreter test results
id: cache-interpreter-test-results
uses: actions/cache@v4
with:
path: ${{env.interpreter_test_results}}
key: interpreter-test-results-${{ matrix.os }}-${{ hashFiles('**/stack.yaml', '**/package.yaml', '**/*.hs')}}-${{ hashFiles('**/interpreter-tests.tpl.md') }}-${{env.runtime_tests_causalhash}}
- name: cache testing codebase
id: cache-testing-codebase
if: steps.cache-interpreter-test-results.outputs.cache-hit != 'true'
uses: actions/cache@v4
with:
path: ${{ env.runtime_tests_codebase }}
key: runtime-tests-codebase-${{env.runtime_tests_causalhash}}
restore-keys: runtime-tests-codebase-
- name: restore binaries
uses: actions/cache/restore@v4
if: steps.cache-interpreter-test-results.outputs.cache-hit != 'true'
with:
path: ${{env.ucm_local_bin}}
key: ucm-${{ matrix.os }}-${{ hashFiles('**/stack.yaml', '**/package.yaml', '**/*.hs')}}
fail-on-cache-miss: true
- name: interpreter tests
# this one should be re-run if the ucm binaries have changed or unison-src/ has changed
if: steps.cache-interpreter-test-results.outputs.cache-hit != 'true'
run: |
envsubst '${runtime_tests_version}' \
< unison-src/builtin-tests/interpreter-tests.tpl.md \
> unison-src/builtin-tests/interpreter-tests.md
${{ env.ucm }} transcript.fork -C ${{ env.runtime_tests_codebase }} unison-src/builtin-tests/interpreter-tests.md
cat unison-src/builtin-tests/interpreter-tests.output.md
git diff --exit-code unison-src/builtin-tests/interpreter-tests.output.md
- name: mark interpreter tests as passing
if: steps.cache-interpreter-test-results.outputs.cache-hit != 'true'
run: |
echo "passing=true" >> "${{env.interpreter_test_results}}"
generate-jit-source:
if: always() && needs.build-ucm.result == 'success'
name: generate jit source
needs: build-ucm
runs-on: ubuntu-20.04
steps:
- name: set up environment
run: |
echo "jit_src_scheme=${{ runner.temp }}/${{ env.jit_src_scheme }}" >> $GITHUB_ENV
echo "ucm=${{ runner.temp }}/unison" >> $GITHUB_ENV
- uses: actions/cache@v4
name: cache jit source
with:
path: ${{ env.jit_src_scheme }}
key: jit_src_scheme-racket_${{env.racket_version}}.jit_${{env.jit_version}}-${{hashFiles('**/scheme-libs/**')}}
- name: check source exists
id: jit_src_exists
if: steps.cache-jit-source.outputs.cache-hit != 'true'
run: |
files=(data-info boot-generated simple-wrappers builtin-generated compound-wrappers)
all_exist=true
for file in "${files[@]}"; do
if [[ ! -f "${{ env.jit_src_scheme }}/unison/$file.ss" ]]; then
echo "$file does not exist."
all_exist=false
# Uncomment the next line if you want to stop checking after the first missing file
# break
fi
done
if $all_exist; then
echo "files_exists=true" >> $GITHUB_OUTPUT
else
echo "files_exists=false" >> $GITHUB_OUTPUT
fi
- name: create transcript
if: steps.jit_src_exists.outputs.files_exists == 'false'
uses: DamianReeves/write-file-action@v1.3
with:
path: ${{ runner.temp }}/setup-jit.md
write-mode: overwrite
contents: |
```ucm
.> project.create-empty jit-setup
jit-setup/main> pull ${{ env.jit_version }} lib.jit
```
```unison
go = generateSchemeBoot "${{ env.jit_src_scheme }}"
```
```ucm
jit-setup/main> run go
```
- name: download ucm artifact
if: steps.jit_src_exists.outputs.files_exists == 'false'
uses: actions/download-artifact@v4
with:
name: unison-${{ env.jit_generator_os }}
path: ${{ runner.temp }}
- name: set ucm permissions
if: steps.jit_src_exists.outputs.files_exists == 'false'
run: chmod +x ${{ env.ucm }}
- name: download scheme-libs
if: steps.jit_src_exists.outputs.files_exists == 'false'
uses: actions/checkout@v4
- name: generate source
if: steps.jit_src_exists.outputs.files_exists == 'false'
run: |
mkdir -p ${{ env.jit_src_scheme }}
cp -R scheme-libs/racket/* ${{ env.jit_src_scheme }}
${{ env.ucm }} transcript ${{ runner.temp }}/setup-jit.md
- name: save jit source
if: always()
uses: actions/upload-artifact@v4
with:
name: jit-source
path: ${{ env.jit_src_scheme }}/**
if-no-files-found: error
build-jit-binary:
if: always() && needs.generate-jit-source.result == 'success'
name: build jit binary
needs: generate-jit-source
runs-on: ${{ matrix.os }}
strategy:
# Run each build to completion, regardless of if any have failed
fail-fast: false
matrix:
os:
# While iterating on this file, you can disable one or more of these to speed things up
- ubuntu-20.04
- macOS-12
- windows-2019
steps:
- name: set up environment
id: checks
run: |
jit_src_scheme="${{ runner.temp }}/${{ env.jit_src_scheme }}" # scheme source
jit_exe="${jit_src_scheme}/unison-runtime" # initially built jit
jit_dist="${{ runner.temp }}/${{ env.jit_dist }}" # jit binary with libraries destination
jit_dist_exe="${jit_dist}/bin/unison-runtime" # jit binary itself
ucm="${{ runner.temp }}/unison"
if [[ ${{runner.os}} = "Windows" ]]; then
jit_src_scheme="${jit_src_scheme//\\//}"
jit_dist="${jit_dist//\\//}"
jit_exe="${jit_exe//\\//}.exe"
jit_dist_exe="${jit_dist//\\//}/unison-runtime.exe"
ucm="${ucm//\\//}.exe"
fi
echo "jit_src_scheme=$jit_src_scheme" >> $GITHUB_ENV
echo "jit_exe=$jit_exe" >> $GITHUB_ENV
echo "jit_dist=$jit_dist" >> $GITHUB_ENV
echo "jit_dist_exe=$jit_dist_exe" >> $GITHUB_ENV
echo "ucm=$ucm" >> $GITHUB_ENV
- uses: actions/checkout@v4
with:
sparse-checkout: |
scripts/get-share-hash.sh
scheme-libs
unison-src/builtin-tests/jit-tests.tpl.md
unison-src/transcripts-using-base/serialized-cases/case-00.v4.ser
- name: cache/restore jit binaries
id: cache-jit-binaries
uses: actions/cache/restore@v4
with:
path: ${{ env.jit_dist }}
key: jit_dist-${{ matrix.os }}.racket_${{ env.racket_version }}.jit_${{ env.jit_version }}-${{hashFiles('**/scheme-libs/**')}}
- name: Cache Racket dependencies
if: steps.cache-jit-binaries.outputs.cache-hit != 'true'
uses: actions/cache@v4
with:
path: |
~/.cache/racket
~/.local/share/racket
key: ${{ matrix.os }}-racket-${{env.racket_version}}
- uses: Bogdanp/setup-racket@v1.11
if: steps.cache-jit-binaries.outputs.cache-hit != 'true'
with:
architecture: x64
distribution: full
variant: CS
version: ${{env.racket_version}}
- name: look up hash for runtime tests
run: |
echo "runtime_tests_causalhash=$(scripts/get-share-hash.sh ${{env.runtime_tests_version}})" >> $GITHUB_ENV
- name: cache jit test results
id: cache-jit-test-results
uses: actions/cache@v4
with:
path: ${{env.jit_test_results}}
key: jit-test-results.${{ matrix.os }}.racket_${{ env.racket_version }}.jit_${{ env.jit_version }}-${{hashFiles('**/scheme-libs/**')}}.tests_${{env.runtime_tests_causalhash}}
- name: install libb2 (linux)
uses: awalsh128/cache-apt-pkgs-action@latest
if: |
runner.os == 'Linux'
&& steps.cache-jit-test-results.outputs.cache-hit != 'true'
# read this if a package isn't installing correctly
# https://github.com/awalsh128/cache-apt-pkgs-action#caveats
with:
packages: libb2-dev
version: 1.0 # cache key version afaik
- name: install libb2 (macos)
if: |
runner.os == 'macOS'
&& steps.cache-jit-test-results.outputs.cache-hit != 'true'
run: brew install libb2
- name: download jit source
if: steps.cache-jit-binaries.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4
with:
name: jit-source
path: ${{ env.jit_src_scheme }}
- name: build jit binary
if: steps.cache-jit-binaries.outputs.cache-hit != 'true'
shell: bash
run: |
cp -R scheme-libs/racket/* "$jit_src_scheme"
raco pkg install --auto --skip-installed "$jit_src_scheme"/unison
raco exe --embed-dlls "$jit_src_scheme"/unison-runtime.rkt
raco distribute "$jit_dist" "$jit_exe"
- name: cache/save jit binaries
if: steps.cache-jit-binaries.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
with:
path: ${{ env.jit_dist }}
key: jit_dist-${{ matrix.os }}.racket_${{ env.racket_version }}.jit_${{ env.jit_version }}-${{hashFiles('**/scheme-libs/**')}}
- name: save jit binary
uses: actions/upload-artifact@v4
with:
name: jit-binary-${{ matrix.os }}
path: ${{ env.jit_dist }}/**
- name: cache testing codebase
id: cache-testing-codebase
if: steps.cache-jit-test-results.outputs.cache-hit != 'true'
uses: actions/cache@v4
with:
path: ${{ env.runtime_tests_codebase }}
key: runtime-tests-codebase-${{ matrix.os }}-${{env.runtime_tests_causalhash}}
restore-keys: runtime-tests-codebase-${{ matrix.os }}-
- name: download ucm
if: steps.cache-jit-test-results.outputs.cache-hit != 'true'
uses: actions/download-artifact@v4
with:
name: unison-${{ matrix.os }}
path: ${{ runner.temp }}
- name: set ucm permissions
if: steps.cache-jit-test-results.outputs.cache-hit != 'true'
run: chmod +x ${{ env.ucm }}
- name: jit integration test ${{ matrix.os }}
if: runner.os != 'Windows' && steps.cache-jit-test-results.outputs.cache-hit != 'true'
run: |
envsubst '${runtime_tests_version}' \
< unison-src/builtin-tests/jit-tests.tpl.md \
> unison-src/builtin-tests/jit-tests.md
${{ env.ucm }} transcript.fork --runtime-path ${{ env.jit_dist_exe }} -C ${{env.runtime_tests_codebase}} unison-src/builtin-tests/jit-tests.md
cat unison-src/builtin-tests/jit-tests.output.md
git diff --exit-code unison-src/builtin-tests/jit-tests.output.md
- name: mark jit tests as passing
if: runner.os != 'Windows' && steps.cache-jit-test-results.outputs.cache-hit != 'true'
run: |
echo "passing=true" >> "${{env.jit_test_results}}"
# - name: Setup tmate session
# uses: mxschmitt/action-tmate@v3
# if: ${{ failure() }}
# timeout-minutes: 15