Repository navigation
Haskell CI #34088
This file contains hidden or 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 | |
| on: | |
| pull_request: # Required for workflows to be able to be approved from forks | |
| merge_group: | |
| push: | |
| # we need this to populate cache for `main` branch to make it available to the child branches, see | |
| # https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#restrictions-for-accessing-a-cache | |
| branches: | |
| - master | |
| # GH caches are removed when not accessed within 7 days - this schedule runs the job every 6 days making | |
| # sure that we always have some caches on main | |
| schedule: | |
| - cron: '0 0 */6 * *' | |
| # DO NOT DELETE. | |
| # This is required for nightly builds and is invoked by nightly-trigger.yml | |
| # on a schedule trigger. | |
| workflow_dispatch: | |
| inputs: | |
| reason: | |
| description: 'Reason' | |
| required: false | |
| default: manual | |
| tests: | |
| description: 'Tests' | |
| required: false | |
| default: some | |
| jobs: | |
| build: | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| # If you edit these versions, make sure the version in the lonely macos-latest job below is updated accordingly | |
| ghc: [&ghc-stable "9.6", &ghc-latest "9.12", "9.14"] | |
| cabal: [&cabal-version "3.16"] | |
| os: [ubuntu-latest] | |
| include: | |
| # Using include, to make sure there will only be one macOS job, even if the matrix gets expanded later on. | |
| # We want a single job, because macOS runners are scarce. | |
| - ghc: *ghc-stable | |
| cabal: *cabal-version | |
| os: macos-latest | |
| - ghc: *ghc-latest | |
| cabal: *cabal-version | |
| os: windows-latest | |
| - ghc: *ghc-latest | |
| validate-manifest: true | |
| defaults: | |
| run: | |
| shell: bash | |
| env: | |
| # Modify this value to "invalidate" the cabal cache. | |
| CABAL_CACHE_VERSION: "2024-07-26" | |
| concurrency: | |
| group: > | |
| a+${{ github.event_name }} | |
| b+${{ github.workflow_ref }} | |
| c+${{ github.job }} | |
| d+${{ matrix.ghc }} | |
| e+${{ matrix.cabal }} | |
| f+${{ matrix.os }} | |
| g+${{ (startsWith(github.ref, 'refs/heads/gh-readonly-queue/') && github.run_id) || github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| steps: | |
| - name: Concurrency group | |
| run: > | |
| echo | |
| a+${{ github.event_name }} | |
| b+${{ github.workflow_ref }} | |
| c+${{ github.job }} | |
| d+${{ matrix.ghc }} | |
| e+${{ matrix.cabal }} | |
| f+${{ matrix.os }} | |
| g+${{ (startsWith(github.ref, 'refs/heads/gh-readonly-queue/') && github.run_id) || github.event.pull_request.number || github.ref }} | |
| # The macos-26-arm64 image 20261013 ships Command Line Tools 27 (SDK 27.0) | |
| # next to Xcode 26.6, whose ld cannot read the SDK 27 .tbd stubs | |
| # ("tapi error: malformed file ... unknown architecture arm64e.x1"). | |
| # Use the Command Line Tools toolchain so ld and SDK match. | |
| # Remove once https://github.com/actions/runner-images/issues/14940 is fixed | |
| # in the image (its README lists Command Line Tools 26.x again). | |
| - name: Use Command Line Tools toolchain on macOS | |
| if: runner.os == 'macOS' | |
| run: sudo xcode-select -s /Library/Developer/CommandLineTools | |
| - name: Install Haskell | |
| uses: input-output-hk/actions/haskell@dbb6ea6d50ffc37a2d481fd8047aff028bac3223 # latest | |
| id: setup-haskell | |
| with: | |
| ghc-version: ${{ matrix.ghc }} | |
| cabal-version: ${{ matrix.cabal }} | |
| - name: Install system dependencies | |
| uses: input-output-hk/actions/base@6217329012a2fd613c8eec9a3f523684a8e91720 # latest | |
| with: | |
| use-sodium-vrf: true # default is true | |
| - name: Install gRPC system dependencies | |
| uses: input-output-hk/cardano-dev/actions/grpc-deps@7bd271fb5d71f95250fc82bf433605b787dad3d4 # grpc-deps-0.1.0.0 | |
| - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 | |
| with: | |
| persist-credentials: false | |
| - name: Enable long paths on Windows | |
| if: runner.os == 'Windows' | |
| run: git config --system core.longpaths true | |
| - name: Cache and install Cabal dependencies | |
| uses: input-output-hk/cardano-dev/actions/cabal-cache@c7427b0921301778971d96b20ab234e8c34aedc3 # cabal-cache-0.0.1.2 | |
| with: | |
| cabal-store: ${{ steps.setup-haskell.outputs.cabal-store }} | |
| cache-version: ${{ env.CABAL_CACHE_VERSION }} | |
| # Now we build. | |
| - name: Build all | |
| run: cabal build all --enable-tests | |
| - name: Run tests | |
| env: | |
| TMPDIR: ${{ runner.temp }} | |
| TMP: ${{ runner.temp }} | |
| KEEP_WORKSPACE: 1 | |
| run: | | |
| cabal test cardano-testnet cardano-node cardano-node-chairman cardano-submit-api | |
| - name: Validate produced manifest and status output against schemas | |
| if: matrix.validate-manifest | |
| run: | | |
| # This job has no nix, that is why we pin the version with pipx separately. | |
| pipx install check-jsonschema==0.37.1 | |
| # Node sockets live under this directory, so it must stay well below | |
| # the 108-character unix socket path limit ($RUNNER_TEMP is short). | |
| dir="$RUNNER_TEMP/manifest-schema-check" | |
| log="$RUNNER_TEMP/manifest-schema-check.log" | |
| "$(cabal list-bin cardano-testnet)" cardano --output-dir "$dir" > "$log" 2>&1 & | |
| testnet_pid=$! | |
| # The manifest is written at readiness, so the file appearing is the ready signal. | |
| for _ in $(seq 1 120); do | |
| if [ -f "$dir/manifest.json" ]; then break; fi | |
| if ! kill -0 "$testnet_pid" 2>/dev/null; then break; fi | |
| sleep 5 | |
| done | |
| # Exit code 0: the chain is producing blocks. | |
| status_rc=0 | |
| "$(cabal list-bin cardano-testnet)" status --testnet-dir "$dir" --json > "$RUNNER_TEMP/status.json" || status_rc=$? | |
| cat "$RUNNER_TEMP/status.json" | |
| # SIGINT, not SIGTERM: the harness tears its nodes down on SIGINT only | |
| # (see Testnet.Signal.interruptNodesOnSigINT). | |
| kill -INT "$testnet_pid" 2>/dev/null || true | |
| wait "$testnet_pid" 2>/dev/null || true | |
| if [ ! -f "$dir/manifest.json" ]; then | |
| echo "ERROR: testnet did not produce $dir/manifest.json in time" | |
| tail -n 100 "$log" | |
| exit 1 | |
| fi | |
| check-jsonschema --schemafile cardano-testnet/schemas/manifest.schema.json "$dir/manifest.json" | |
| if [ "$status_rc" != 0 ]; then | |
| echo "ERROR: cardano-testnet status exited with $status_rc" | |
| exit 1 | |
| fi | |
| check-jsonschema --schemafile cardano-testnet/schemas/status.schema.json "$RUNNER_TEMP/status.json" | |
| - name: Tar failed tests workspaces | |
| if: ${{ failure() }} | |
| env: | |
| TMP: ${{ runner.temp }} | |
| run: | | |
| cd $TMP | |
| find . -name 'module' -type f -exec dirname {} \; | xargs -I "{}" basename "{}" | sort -u | xargs -I "{}" tar -czvf workspaces.tgz "{}" | |
| - name: Upload workspaces on tests failure | |
| if: ${{ failure() }} | |
| uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 | |
| with: | |
| name: failed-test-workspaces-${{ matrix.os }}-ghc${{ matrix.ghc }}-cabal${{ matrix.cabal }}.tgz | |
| path: ${{ runner.temp }}/workspaces.tgz | |
| - name: "Tar artifacts" | |
| run: | | |
| mkdir -p artifacts | |
| for exe in $(cat dist-newstyle/cache/plan.json | jq -r '."install-plan"[] | select(.style == "local" and (."component-name" | startswith("exe:"))) | ."bin-file"'); do | |
| if [ -f $exe ]; then | |
| echo "Including artifact $exe" | |
| ( cd artifacts | |
| tar -C "$(dirname $exe)" -czf "$(basename $exe).tar.gz" "$(basename $exe)" | |
| ) | |
| else | |
| echo "Skipping artifact $exe" | |
| fi | |
| done | |
| # Uncomment the following back in for debugging. Remember to launch a `pwsh` from | |
| # the tmux session to debug `pwsh` issues. | |
| # | |
| # - name: Setup tmate session | |
| # if: ${{ failure() }} | |
| # uses: mxschmitt/action-tmate@v3 | |
| # with: | |
| # limit-access-to-actor: true | |
| build-complete: | |
| needs: [build] | |
| if: ${{ always() }} | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check if any previous job failed | |
| run: | | |
| if [[ "${{ needs.build.result }}" == "failure" ]]; then | |
| # this ignores skipped dependencies | |
| echo 'Required jobs failed to build.' | |
| exit 1 | |
| else | |
| echo 'Build complete' | |
| fi |