Skip to content

crux-mir

crux-mir #2308

name: crux-mir
on:
push:
tags: ["crux-v?[0-9]+.[0-9]+(.[0-9]+)?"]
branches: [master, "release-**"]
pull_request:
schedule:
- cron: "0 10 * * *" # 10am UTC -> 2/3am PST
workflow_dispatch:
env:
# The CACHE_VERSION can be updated to force the use of a new cache if
# the current cache contents become corrupted/invalid. This can
# sometimes happen when (for example) the OS version is changed but
# older .so files are cached, which can have various effects
# (e.g. cabal complains it can't find a valid version of the "happy"
# tool).
#
# This also periodically happens on MacOS builds due to a tar bug
# (symptom: "No suitable image found ... unknown file type, first
# eight bytes: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00")
CACHE_VERSION: 4
# If you update this, make sure to also update RUST_TOOLCHAIN in
# .github/Dockerfile-crux-mir
RUST_TOOLCHAIN: "nightly-2023-01-23"
jobs:
config:
runs-on: ubuntu-22.04
outputs:
name: ${{ steps.config.outputs.name }}
crux-mir-version: ${{ steps.config.outputs.crux-mir-version }}
event-tag: ${{ steps.config.outputs.tag }}
event-schedule: ${{ steps.config.outputs.schedule }}
publish: ${{ steps.config.outputs.publish }}
release: ${{ steps.config.outputs.release }}
retention-days: ${{ steps.config.outputs.retention-days }}
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: config
id: config
env:
EVENT_TAG: ${{ startsWith(github.event.ref, 'refs/tags/') }}
EVENT_SCHEDULE: ${{ github.event_name == 'schedule' }}
EVENT_DISPATCH: ${{ github.event_name == 'workflow_dispatch' }}
RELEASE: ${{ startsWith(github.event.ref, 'refs/heads/release-crux-') }}
run: |
set -x
.github/ci.sh output name crux-mir-$(.github/ci.sh crux_mir_ver)
.github/ci.sh output crux-mir-version $(.github/ci.sh crux_mir_ver)
.github/ci.sh output tag $EVENT_TAG
.github/ci.sh output schedule $EVENT_SCHEDULE
.github/ci.sh output publish $({ $EVENT_TAG || $EVENT_SCHEDULE; } && echo true || echo false)
.github/ci.sh output release $([[ "refs/heads/release-crux-$(.github/ci.sh crux_mir_ver)" == "${{ github.event.ref }}" ]] && echo true || echo false)
.github/ci.sh output retention-days $($RELEASE && echo 90 || echo 5)
build:
runs-on: ${{ matrix.os }}
needs: [config]
strategy:
fail-fast: false
matrix:
os: [ubuntu-22.04]
cabal: ["3.10.3.0"]
ghc: ["9.4.8", "9.6.5", "9.8.2"]
include:
- os: ubuntu-20.04
cabal: 3.10.3.0
ghc: 9.4.8
- os: macos-14
cabal: 3.10.3.0
ghc: 9.4.8
# We want Windows soon, but it doesn't need to be now
name: crux-mir - GHC v${{ matrix.ghc }} - ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
with:
submodules: true
- uses: haskell-actions/setup@v2
id: setup-haskell
with:
ghc-version: ${{ matrix.ghc }}
cabal-version: ${{ matrix.cabal }}
- name: Post-GHC installation fixups on Windows
shell: bash
if: runner.os == 'Windows'
run: |
# A workaround for https://github.com/Mistuke/CabalChoco/issues/5
cabal user-config update -a "extra-include-dirs: \"\""
cabal user-config update -a "extra-lib-dirs: \"\""
- name: Install Nix
if: runner.os == 'Linux'
uses: cachix/install-nix-action@v16
with:
nix_path: nixpkgs=channel:21.11
install_url: https://releases.nixos.org/nix/nix-2.10.3/install
extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
- name: Install latest Rust nightly
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ env.RUST_TOOLCHAIN }}
override: true
components: rustc-dev
- uses: actions/cache/restore@v4
name: Restore cabal store cache
with:
path: |
${{ steps.setup-haskell.outputs.cabal-store }}
dist-newstyle
key: ${{ env.CACHE_VERSION }}-cabal-${{ matrix.os }}-${{ matrix.ghc }}-${{ hashFiles(format('cabal.GHC-{0}.config', matrix.ghc)) }}-${{ github.sha }}
restore-keys: |
${{ env.CACHE_VERSION }}-cabal-${{ matrix.os }}-${{ matrix.ghc }}-${{ hashFiles(format('cabal.GHC-{0}.config', matrix.ghc)) }}-
- shell: bash
run: .github/ci.sh install_system_deps
env:
SOLVER_PKG_VERSION: "snapshot-20240212"
BUILD_TARGET_OS: ${{ matrix.os }}
BUILD_TARGET_ARCH: ${{ runner.arch }}
- name: Setup Environment Vars
if: runner.os == 'Linux'
run: |
GHC=haskell.compiler.ghc$(echo ${{ matrix.ghc }} | sed -e s,\\.,,g)
case ${{ matrix.ghc }} in
9.4.8) GHC_NIXPKGS=github:nixos/nixpkgs/nixos-24.05 ;;
9.6.5) GHC_NIXPKGS=github:nixos/nixpkgs/nixos-24.05 ;;
9.8.2) GHC_NIXPKGS=github:nixos/nixpkgs/nixos-24.05 ;;
*) GHC_NIXPKGS=github:nixos/nixpkgs/21.11 ;;
esac
echo NS="nix shell ${GHC_NIXPKGS}#cabal-install ${GHC_NIXPKGS}#${GHC} nixpkgs#gmp nixpkgs#zlib nixpkgs#zlib.dev" >> $GITHUB_ENV
- name: Package's Cabal/GHC compatibility
shell: bash
if: runner.os == 'Linux'
# Using setup will use the cabal library installed with GHC
# instead of the cabal library of the Cabal-install tool to
# verify the cabal file is compatible with the associated
# GHC cabal library version. Cannot run configure or build,
# because dependencies aren't present, but a clean is
# sufficient to cause parsing/validation of the cabal file.
run: |
defsetup() { echo import Distribution.Simple; echo main = defaultMain; }
setup_src() { if [ ! -f Setup.hs ] ; then defsetup > DefSetup.hs; fi; ls *Setup.hs; }
setup_bin() { echo setup.${{ matrix.ghc }}; }
with_ghc() { $NS -c ${@}; }
(cd crux-mir; with_ghc ghc -o $(setup_bin) $(setup_src) && ./$(setup_bin) clean)
- shell: bash
run: cd dependencies/mir-json && cargo install --locked --force
- shell: bash
run: .github/ci.sh configure
- name: Generate source distributions
shell: bash
run: cabal sdist crucible-syntax crucible-concurrency crucible-mir crux-mir
- shell: bash
run: .github/ci.sh build exe:crux-mir
- shell: bash
name: Haddock
run: cabal v2-haddock crucible-syntax crucible-concurrency crux-mir
- shell: bash
run: cd crux-mir && bash ./translate_libs.sh
- shell: bash
run: .github/ci.sh test crux-mir
- name: Create binary artifact
shell: bash
run: |
NAME="crux-mir-${{ needs.config.outputs.crux-mir-version }}-${{ matrix.os }}-${{ runner.arch }}"
echo "NAME=$NAME" >> $GITHUB_ENV
.github/ci.sh bundle_crux_mir_files
if: github.repository == 'GaloisInc/crucible'
env:
OS_TAG: ${{ matrix.os }}
ARCH_TAG: ${{ runner.arch }}
VERSION: ${{ needs.config.outputs.crux-mir-version }}
- name: Sign binary artifact
# The SIGNING_PASSPHRASE and SIGNING_KEY secrets are only available on
# jobs run from the main repo, and as a result, they won't work when
# run from a fork. Signing binaries isn't essential to the rest of the
# workflow, so it is safe to skip this step on forks.
if: github.event.pull_request.head.repo.fork == false
shell: bash
env:
SIGNING_PASSPHRASE: ${{ secrets.SIGNING_PASSPHRASE }}
SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
run: |
.github/ci.sh sign "${NAME}.tar.gz"
- uses: actions/upload-artifact@v4
if: github.repository == 'GaloisInc/crucible'
with:
path: crux-mir-*.tar.gz*
name: crux-mir-${{ matrix.os }}-${{ matrix.ghc }}
- uses: actions/cache/save@v4
name: Save cabal store cache
if: always()
with:
path: |
${{ steps.setup-haskell.outputs.cabal-store }}
dist-newstyle
key: ${{ env.CACHE_VERSION }}-cabal-${{ matrix.os }}-${{ matrix.ghc }}-${{ hashFiles(format('cabal.GHC-{0}.config', matrix.ghc)) }}-${{ github.sha }}
build-push-image:
runs-on: ubuntu-22.04
needs: [config]
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || needs.config.outputs.release == 'true'
strategy:
fail-fast: false
matrix:
include:
- file: .github/Dockerfile-crux-mir
image: ghcr.io/galoisinc/crux-mir
cache: ghcr.io/galoisinc/cache-crux-mir
steps:
- uses: actions/checkout@v2
with:
submodules: true
- name: Clear up some disk space
run: |
# The crux-mir Docker image is rather large (~1GB compressed), and
# the mere act of building the image requires just over 14 GB of disk
# space, which the maximum provided by a GitHub Action CI runner. To
# clear up some extra space, we delete ~10GB worth of pre-installed
# GitHub Actions tools, none of which we make use of.
sudo rm -rf /usr/share/dotnet
sudo rm -rf /opt/ghc
sudo rm -rf "/usr/local/share/boost"
sudo rm -rf "$AGENT_TOOLSDIRECTORY" # Python installations
- uses: rlespinasse/[email protected]
- id: common-tag
run: |
echo "::set-output name=common-tag::$GITHUB_REF_SLUG"
echo "COMMON_TAG=$GITHUB_REF_SLUG" >> $GITHUB_ENV
- uses: docker/setup-buildx-action@v1
- uses: crazy-max/ghaction-docker-meta@v1
name: Labels
id: labels
with:
images: ${{ matrix.image }}
- uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/build-push-action@v2
with:
context: .
tags: ${{ matrix.image }}:${{ steps.common-tag.outputs.common-tag }}
labels: ${{ steps.labels.outputs.labels }}
load: true
push: false
file: ${{ matrix.file }}
build-args: ${{ matrix.build-args }}
cache-from: |
type=registry,ref=${{ matrix.cache }}:${{ steps.prefix.outputs.prefix }}master
type=registry,ref=${{ matrix.cache }}:${{ steps.common-tag.outputs.common-tag }}
- name: Cache image build
uses: docker/build-push-action@v2
continue-on-error: true # Tolerate cache upload failures - this should be handled better
with:
context: .
file: ${{ matrix.file }}
build-args: ${{ matrix.build-args }}
cache-to: type=registry,ref=${{ matrix.cache }}:${{ steps.common-tag.outputs.common-tag }},mode=max
- if: needs.config.outputs.event-schedule == 'true'
name: ${{ matrix.image }}:nightly
run: |
docker tag ${{ matrix.image }}:$COMMON_TAG ${{ matrix.image }}:nightly
docker push ${{ matrix.image }}:nightly
- if: needs.config.outputs.release == 'true'
name: ${{ matrix.image }}:${{ needs.config.outputs.crux-mir-version }}
run: |
docker tag ${{ matrix.image }}:$COMMON_TAG ${{ matrix.image }}:${{ needs.config.outputs.crux-mir-version }}
docker push ${{ matrix.image }}:${{ needs.config.outputs.crux-mir-version }}
docker tag ${{ matrix.image }}:$COMMON_TAG ${{ matrix.image }}:latest
docker push ${{ matrix.image }}:latest