Haskell CI - NIGHTLY #15641
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: Haskell CI | |
# If it's a scheduled (for us: nightly) build, set the name of this run to a static value, so we can identify it easier. | |
# Otherwise, replicate the default run name: either the PR title if it exists, or the commit message otherwise. | |
run-name: | | |
${{github.event_name == 'schedule' && 'Haskell CI - NIGHTLY' | |
|| github.event.pull_request.title == '' && github.event.head_commit.message | |
|| github.event.pull_request.title}} | |
on: | |
push: | |
branches: [ "master", "release/**" ] | |
pull_request: | |
branches: [ "**" ] | |
schedule: | |
# "Nightly" builds: Every day at 06:00 UTC | |
- cron: '0 6 * * *' | |
# for running the workflow manually - useful for branches without PRs, for which jobs don't get ran automatically | |
workflow_dispatch: | |
inputs: | |
nightly: | |
description: Run with the same settings as a nightly build | |
type: boolean | |
default: false | |
# Cancel running workflows when a new workflow on the same PR or branch is started, | |
# but put scheduled workflows into their own group | |
concurrency: | |
group: ${{ | |
format('{0}-{1}{2}', | |
github.workflow, | |
github.event.pull_request.number || github.ref, | |
github.event_name == 'schedule' && '-scheduled' || '')}} | |
cancel-in-progress: true | |
jobs: | |
build: | |
strategy: | |
matrix: | |
ghc: ["8.10.7", "9.2.8", "9.6.6", "9.8.2", "9.10.1"] | |
os: [ubuntu-latest] | |
fail-fast: false | |
runs-on: ${{ matrix.os }} | |
env: | |
# Modify this value to "invalidate" the cabal cache. | |
CABAL_CACHE_VERSION: "2023-07-17" | |
# current ref from: 27.02.2022 | |
SECP256K1_REF: ac83be33d0956faf6b7f61a60ab524ef7d6a473a | |
SECP_CACHE_VERSION: "2022-12-30" | |
defaults: | |
run: | |
shell: bash | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Free up disk space | |
run: | | |
# Remove software and language runtimes we're not using | |
sudo rm -rf \ | |
"$AGENT_TOOLSDIRECTORY" \ | |
/opt/google/chrome \ | |
/opt/microsoft/msedge \ | |
/opt/microsoft/powershell \ | |
/opt/pipx \ | |
/usr/lib/mono \ | |
/usr/local/julia* \ | |
/usr/local/lib/android \ | |
/usr/local/lib/node_modules \ | |
/usr/local/share/chromium \ | |
/usr/local/share/powershell \ | |
/usr/share/dotnet \ | |
/usr/share/swift | |
df -h / | |
- name: Install system dependencies | |
uses: input-output-hk/actions/base@latest | |
with: | |
use-sodium-vrf: false # default is true | |
- name: Install Haskell | |
id: install-haskell | |
uses: input-output-hk/actions/haskell@latest | |
with: | |
ghc-version: ${{ matrix.ghc }} | |
cabal-version: 3.12.1.0 | |
- name: Configure to use libsodium | |
run: | | |
cat >> cabal.project <<EOF | |
package cardano-crypto-praos | |
flags: -external-libsodium-vrf | |
EOF | |
- name: Configure to limit the heap size for ghc 8 | |
if: startsWith(${{ matrix.ghc }}, 8) | |
run: | | |
cat >> cabal.project <<EOF | |
with-compiler: $PWD/scripts/ghc-limited | |
with-hc-pkg: ghc-pkg | |
EOF | |
echo "GHC_HEAP_LIMIT=12" >> $GITHUB_ENV | |
- name: Cabal update | |
run: cabal update | |
# We create a dependencies.txt file that can be used to index the cabal | |
# store cache. | |
# | |
# We do not use plan.json directly because adding a dependency to our | |
# Cabal files which was already present somewhere else would result in a | |
# diferent plan, even though the set of dependencies is the same. | |
- name: Record dependencies to be used as cache keys | |
id: record-deps | |
run: | | |
cabal build all --enable-tests --dry-run --minimize-conflict-set | |
cat dist-newstyle/cache/plan.json \ | |
| jq '.["install-plan"][].id' \ | |
| sort \ | |
| uniq \ | |
| tee dependencies.txt | |
- name: Restore cache | |
uses: actions/cache/restore@v4 | |
id: restore-cabal-cache | |
env: | |
cache-name: cache-cabal-build | |
with: | |
path: | | |
${{ steps.install-haskell.outputs.cabal-store }} | |
# A new cache is created upon a change to the cabal build plan, | |
# cabal.project (and/or cabal.project.local), or a bump to | |
# CABAL_CACHE_VERSION. | |
key: ${{ env.cache-name }}-${{ runner.os }}-${{ matrix.ghc }}-${{ env.CABAL_CACHE_VERSION }}-${{ hashFiles('dependencies.txt') }}-${{ hashFiles('cabal.project*') }} | |
# Restoring attempts are from current branch then master. The key above | |
# is by default already a restore-key. | |
restore-keys: | | |
${{ env.cache-name }}-${{ runner.os }}-${{ matrix.ghc }}-${{ env.CABAL_CACHE_VERSION }}-${{ hashFiles('dependencies.txt') }} | |
${{ env.cache-name }}-${{ runner.os }}-${{ matrix.ghc }}-${{ env.CABAL_CACHE_VERSION }}- | |
- name: Check workflow test matrix | |
run: cabal build all --dry-run && scripts/check-workflow-test-matrix.hs | |
- name: Build dependencies | |
id: build-dependencies | |
run: cabal build all --only-dependencies | |
# Save the cache of built dependencies early, so that it is available for | |
# the next GHA run if the Build step fails. | |
- name: Save cache | |
uses: actions/cache/save@v4 | |
id: save-cabal-cache | |
# Note: cache-hit will be set to true only when cache hit occurs for the | |
# exact key match. For a partial key match via restore-keys or a cache | |
# miss, it will be set to false. | |
if: steps.build-dependencies.outcome == 'success' && steps.restore-cabal-cache.outputs.cache-hit != 'true' | |
with: | |
path: ${{ steps.install-haskell.outputs.cabal-store }} | |
key: ${{ steps.restore-cabal-cache.outputs.cache-primary-key }} | |
- name: Build | |
run: cabal build all | |
# Pass working directory to test jobs | |
- name: Archive working directory | |
# pax format is needed to avoid unnecessary rebuilding, because the | |
# default format uses a one-second resolution for timestamps | |
run: tar --use-compress-program zstdmt --format posix --exclude-vcs -cf /var/tmp/state.tzst . && mv /var/tmp/state.tzst . | |
- name: Upload working directory archive | |
# upload-artifact is pinned to avoid a bug in download-artifact | |
# See https://github.com/actions/download-artifact/issues/328 | |
uses: actions/[email protected] | |
with: | |
name: state-${{ matrix.ghc }}-${{ matrix.os }} | |
path: state.tzst | |
overwrite: true | |
retention-days: 1 | |
test: | |
needs: build | |
strategy: | |
matrix: | |
package: | |
- byron-spec-chain | |
- byron-spec-ledger | |
- cardano-crypto-wrapper | |
- cardano-data | |
- cardano-ledger-allegra | |
- cardano-ledger-alonzo | |
- cardano-ledger-alonzo-test | |
- cardano-ledger-api | |
- cardano-ledger-babbage | |
- cardano-ledger-babbage-test | |
- cardano-ledger-binary | |
- cardano-ledger-byron | |
- cardano-ledger-conformance | |
- cardano-ledger-conway | |
- cardano-ledger-conway-test | |
- cardano-ledger-core | |
- cardano-ledger-mary | |
- cardano-ledger-shelley | |
- cardano-ledger-shelley-ma-test | |
- cardano-ledger-shelley-test | |
- cardano-ledger-test | |
- cardano-protocol-tpraos | |
- constrained-generators | |
- non-integral | |
- set-algebra | |
- small-steps | |
- vector-map | |
ghc: ["8.10.7", "9.2.8", "9.6.6", "9.8.2", "9.10.1"] | |
os: [ubuntu-latest] | |
fail-fast: false | |
runs-on: ${{ matrix.os }} | |
name: ${{ matrix.package }}-${{ matrix.ghc }}-${{ matrix.os }} | |
env: | |
# Modify this value to "invalidate" the cabal cache. | |
CABAL_CACHE_VERSION: "2023-07-17" | |
# current ref from: 27.02.2022 | |
SECP256K1_REF: ac83be33d0956faf6b7f61a60ab524ef7d6a473a | |
SECP_CACHE_VERSION: "2022-12-30" | |
defaults: | |
run: | |
shell: bash | |
steps: | |
- name: Free up disk space | |
run: | | |
# Remove software and language runtimes we're not using | |
sudo rm -rf \ | |
"$AGENT_TOOLSDIRECTORY" \ | |
/opt/google/chrome \ | |
/opt/microsoft/msedge \ | |
/opt/microsoft/powershell \ | |
/opt/pipx \ | |
/usr/lib/mono \ | |
/usr/local/julia* \ | |
/usr/local/lib/android \ | |
/usr/local/lib/node_modules \ | |
/usr/local/share/chromium \ | |
/usr/local/share/powershell \ | |
/usr/share/dotnet \ | |
/usr/share/swift | |
df -h / | |
- name: Install system dependencies | |
uses: input-output-hk/actions/base@latest | |
with: | |
use-sodium-vrf: false # default is true | |
- name: Install Haskell | |
id: install-haskell | |
uses: input-output-hk/actions/haskell@latest | |
with: | |
ghc-version: ${{ matrix.ghc }} | |
cabal-version: 3.12.1.0 | |
- name: Set up Ruby 2.7 | |
uses: ruby/setup-ruby@v1 | |
with: | |
ruby-version: 2.7 | |
- name: Install cbor-diag and cddl | |
run: | | |
gem install cddl -v 0.10.3 | |
gem install cbor-diag | |
- name: Download Mainnet Mirror | |
run: | | |
REF=a31ac75 | |
{ | |
curl -L https://github.com/input-output-hk/cardano-mainnet-mirror/tarball/$REF -o mainnet-mirror.tgz | |
tar -xzf mainnet-mirror.tgz | |
mv input-output-hk-cardano-mainnet-mirror-$REF/epochs . | |
} || | |
{ | |
git clone https://github.com/input-output-hk/cardano-mainnet-mirror | |
cd cardano-mainnet-mirror | |
git checkout $REF | |
mv epochs .. | |
cd .. | |
} | |
- name: Set NIGHTLY environment variable if the job was triggered by the scheduler | |
if: "${{ github.event_name == 'schedule' | |
|| contains(github.event.pull_request.title, 'nightly') | |
|| github.event_name == 'workflow_dispatch' && github.event.inputs.nightly }}" | |
run: | | |
echo "NIGHTLY=true" >> $GITHUB_ENV | |
# Retrieve working directory from build jobs | |
- name: Download working directory archive | |
uses: actions/download-artifact@v4 | |
with: | |
name: state-${{ matrix.ghc }}-${{ matrix.os }} | |
- name: Unarchive working directory | |
run: tar -xf state.tzst --use-compress-program unzstd && rm state.tzst | |
- name: Cabal update | |
run: cabal update | |
# A dependencies.txt file should have been created by the build job, so we | |
# check if it exists and is not empty. | |
- name: Check dependencies to be used as cache keys | |
id: check-deps | |
run: | | |
./scripts/file-not-null.sh dependencies.txt | |
- name: Restore cache | |
uses: actions/cache/restore@v4 | |
id: restore-cabal-cache | |
env: | |
cache-name: cache-cabal-build | |
with: | |
path: | | |
${{ steps.install-haskell.outputs.cabal-store }} | |
key: ${{ env.cache-name }}-${{ runner.os }}-${{ matrix.ghc }}-${{ env.CABAL_CACHE_VERSION }}-${{ hashFiles('dependencies.txt') }}-${{ hashFiles('cabal.project*') }} | |
# The cache with this specific key should have been created by the build | |
# job. If the cache is missing, something is terribly wrong! We fail the | |
# test job, or otherwise we would start rebuilding all the dependencies. | |
fail-on-cache-miss: true | |
- name: Run tests | |
run: | | |
export CARDANO_MAINNET_MIRROR="$(pwd)/epochs" | |
if [ -z "$NIGHTLY" ]; then | |
cabal test "${{ matrix.package }}" | |
else | |
TRIES=3 | |
scripts/cabal-test-with-retries.sh "${{ matrix.package }}" "$TRIES" | |
fi | |
complete: | |
name: Tests completed | |
runs-on: ubuntu-latest | |
needs: test | |
if: always() | |
steps: | |
- run: | | |
case ${{ needs.test.result }} in | |
success) | |
echo 'All tests completed successfully' | |
true;; | |
failure) | |
echo 'Some tests failed' | |
false;; | |
*) | |
echo 'Tests were ${{ needs.test.result }}' | |
false;; | |
esac | |
fourmolu: | |
runs-on: ubuntu-latest | |
defaults: | |
run: | |
shell: bash | |
strategy: | |
fail-fast: false | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Install fourmolu | |
run: | | |
FOURMOLU_VERSION="0.16.2.0" | |
mkdir -p "$HOME/.local/bin" | |
curl -sL "https://github.com/fourmolu/fourmolu/releases/download/v${FOURMOLU_VERSION}/fourmolu-${FOURMOLU_VERSION}-linux-x86_64" -o "$HOME/.local/bin/fourmolu" | |
chmod a+x "$HOME/.local/bin/fourmolu" | |
echo "$HOME/.local/bin" >> $GITHUB_PATH | |
- name: Run fourmolu | |
run: ./scripts/fourmolize.sh | |
cabal-format: | |
runs-on: ubuntu-latest | |
defaults: | |
run: | |
shell: bash | |
strategy: | |
fail-fast: false | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Format all cabal files | |
run: ./scripts/cabal-format.sh | |
gen-hie: | |
runs-on: ubuntu-latest | |
defaults: | |
run: | |
shell: bash | |
strategy: | |
fail-fast: false | |
steps: | |
- name: Cache implicit-hie executable (gen-hie) | |
id: cache-gen-hie | |
uses: actions/cache@v4 | |
with: | |
path: | | |
~/.cabal/bin/gen-hie | |
key: ${{ runner.os }}-cache-gen-hie | |
- name: Install gen-hie if not cached | |
if: steps.cache-gen-hie.outputs.cache-hit != 'true' | |
run: cabal update && cabal install implicit-hie --install-method=copy --overwrite-policy=always | |
- name: Add cabal-bin to PATH | |
run: echo "$HOME/.cabal/bin" >> $GITHUB_PATH | |
- uses: actions/checkout@v4 | |
- name: Regenerate hie.yaml and confirm that it is in sync | |
run: ./scripts/gen-hie.sh | |
branch-history: | |
name: Check branch history | |
runs-on: ubuntu-latest | |
if: ${{ github.base_ref != '' && github.ref != '' }} # Only true for PRs | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Ensure the branch doesn't contain any merges | |
run: | | |
PR_TARGET=${{ github.base_ref }} | |
PR_MERGE=${{ github.ref }} | |
PR_HEAD=${PR_MERGE%/merge}/head | |
git fetch origin -n --refmap= +$PR_TARGET:pr-target +$PR_HEAD:pr-head | |
if git log --merges --oneline --decorate pr-target..pr-head | grep .; then | |
echo 'Branch must not contain merges' | |
false | |
fi | |
notify-nightly-failure: | |
name: Send a slack notification on \#ledger-internal if the nightly build failed | |
runs-on: ubuntu-latest | |
needs: | |
- test | |
if: always() && github.event_name == 'schedule' && needs.test.result == 'failure' | |
steps: | |
- name: Send slack notification | |
id: slack | |
uses: slackapi/[email protected] | |
with: | |
payload: | | |
{ | |
"blocks": [ | |
{ | |
"type": "section", | |
"text": { | |
"type": "mrkdwn", | |
"text": "Nightly Github Actions build failed: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" | |
} | |
} | |
] | |
} | |
env: | |
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} | |
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK | |
SRP-validity: | |
name: Check if formal-ledger-specifications SRP is valid | |
runs-on: ubuntu-latest | |
defaults: | |
run: | |
shell: bash | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Check if provided formal-ledger-specifications SRP commit hash exists | |
run: | | |
TAG=$(sed -ne \ | |
'/ *location: *https:\/\/github.com\/IntersectMBO\/formal-ledger-specifications.git/,/--sha256/ p' \ | |
cabal.project \ | |
| sed -ne 's/^ *tag: *//p') | |
git fetch https://github.com/intersectmbo/formal-ledger-specifications.git MAlonzo-code | |
git show -s $TAG || { \ | |
echo "Commit $TAG was not found on the MAlonzo-code branch of formal-ledger-specifications." | |
exit 1 | |
} |