Conversation
Runs benchmarks on PRs and pushes to master, uploads results as artifact. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Rename bench.yml to ci.yml - Add test job that runs in parallel with benchmarks Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Test matrix: 9.6.7, 9.8.4, 9.10.2, 9.12.2 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add fail-fast: false to run all matrix jobs - Add required job that depends on all tests passing Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds GitHub Actions CI for building/testing/benchmarking and enforces Haskell formatting via Fourmolu.
Changes:
- Introduce a CI workflow running cabal build/test across a GHC matrix, plus a separate benchmark job and artifact upload.
- Add a
fourmolize.shhelper script and a CI job to run Fourmolu formatting checks.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 7 comments.
| File | Description |
|---|---|
scripts/fourmolize.sh |
Adds a Fourmolu runner script (all files or “changes only”) and fails if formatting produces diffs. |
.github/workflows/ci.yml |
Defines CI jobs for tests (multi-GHC), benchmarks (artifact upload), and Fourmolu formatting. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| dist-newstyle | ||
| key: ${{ runner.os }}-cabal-${{ hashFiles('**/*.cabal') }} | ||
| restore-keys: | | ||
| ${{ runner.os }}-cabal- |
There was a problem hiding this comment.
Benchmark cache key doesn’t include the GHC (or cabal) version, so it can restore an incompatible ~/.cabal/store/dist-newstyle if the toolchain changes (or if this job’s GHC version is adjusted later). Include ${{ matrix.ghc-version }} (or the pinned GHC version) and cabal version in the cache key to avoid subtle cache poisoning.
| curl -sSfL "https://github.com/fourmolu/fourmolu/releases/download/v${FOURMOLU_VERSION}/fourmolu-${FOURMOLU_VERSION}-linux-x86_64" -o "$BINDIR/fourmolu" | ||
| chmod a+x "$BINDIR/fourmolu" |
There was a problem hiding this comment.
The workflow downloads an executable from GitHub Releases without verifying a checksum/signature. If the download is tampered with (or the release asset is replaced), this can execute untrusted code in CI. Consider pinning and verifying a SHA256/SHA512 checksum (or using a trusted installation method such as building from source with a pinned dependency set).
| curl -sSfL "https://github.com/fourmolu/fourmolu/releases/download/v${FOURMOLU_VERSION}/fourmolu-${FOURMOLU_VERSION}-linux-x86_64" -o "$BINDIR/fourmolu" | |
| chmod a+x "$BINDIR/fourmolu" | |
| curl -sSfL "https://github.com/fourmolu/fourmolu/releases/download/v${FOURMOLU_VERSION}/fourmolu-${FOURMOLU_VERSION}-linux-x86_64" -o "$BINDIR/fourmolu" | |
| curl -sSfL "https://github.com/fourmolu/fourmolu/releases/download/v${FOURMOLU_VERSION}/fourmolu-${FOURMOLU_VERSION}-linux-x86_64.sha256" -o "$BINDIR/fourmolu.sha256" | |
| (cd "$BINDIR" && sha256sum -c fourmolu.sha256) | |
| chmod a+x "$BINDIR/fourmolu" | |
| rm -f "$BINDIR/fourmolu.sha256" |
| mkdir -p "$BINDIR" | ||
| curl -sSfL "https://github.com/fourmolu/fourmolu/releases/download/v${FOURMOLU_VERSION}/fourmolu-${FOURMOLU_VERSION}-linux-x86_64" -o "$BINDIR/fourmolu" | ||
| chmod a+x "$BINDIR/fourmolu" | ||
| echo "$BINDIR" >> $GITHUB_PATH |
There was a problem hiding this comment.
echo "$BINDIR" >> $GITHUB_PATH should quote $GITHUB_PATH to avoid issues if the path ever contains spaces or special characters. Use >> "$GITHUB_PATH" for safer shell behavior.
| echo "$BINDIR" >> $GITHUB_PATH | |
| echo "$BINDIR" >> "$GITHUB_PATH" |
| # Run fourmolu on changes compared to `master`. | ||
| git diff --diff-filter=MA --name-only origin/master HEAD -- '*.hs' |
There was a problem hiding this comment.
--changes diffs against origin/master, which assumes (1) the default branch is named master and (2) the origin/master ref exists locally. In fresh clones or CI checkouts this ref may be missing and the command will fail. Consider diffing against the merge-base with the configured default branch (or accepting a base ref as an env/arg) and/or fetching the base ref when needed.
| # Run fourmolu on changes compared to `master`. | |
| git diff --diff-filter=MA --name-only origin/master HEAD -- '*.hs' | |
| # Run fourmolu on changes compared to the default branch. | |
| # The base ref can be overridden via FOURMOLU_BASE_REF (e.g. "origin/main"). | |
| base_ref="${FOURMOLU_BASE_REF:-origin/HEAD}" | |
| if ! git rev-parse --verify "$base_ref" >/dev/null 2>&1; then | |
| # Attempt to fetch the base ref if it is not available locally. | |
| # Ignore failures so the script can still run in environments without network access. | |
| git fetch origin "${base_ref#origin/}" >/dev/null 2>&1 || true | |
| fi | |
| merge_base="$(git merge-base "$base_ref" HEAD)" | |
| git diff --diff-filter=MA --name-only "$merge_base" HEAD -- '*.hs' |
| git ls-files -- '*.hs' | ||
| fi \ | ||
| | { grep -v Setup.hs || true; } \ | ||
| | xargs -r fourmolu -m inplace |
There was a problem hiding this comment.
This pipeline uses xargs with whitespace-delimited filenames. That will break if any tracked .hs path contains spaces/newlines, and xargs -r is GNU-specific (not available on macOS/BSD). Prefer a NUL-delimited pipeline (e.g., git … -z + grep -z/filtering + xargs -0) or an explicit bash loop/array to pass filenames safely and portably.
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| ghc-version: ['9.6.7', '9.8.4', '9.10.2', '9.12.2'] |
There was a problem hiding this comment.
The CI test matrix GHC versions should align with the package’s declared support. antigen.cabal declares tested-with: GHC == 9.10.3, but the matrix uses 9.10.2 (and also includes 9.12.2). If these versions aren’t actually supported by the dependency bounds/tooling, CI will fail or be misleading; consider updating the matrix to match tested-with (or updating tested-with to match the matrix).
| ghc-version: ['9.6.7', '9.8.4', '9.10.2', '9.12.2'] | |
| ghc-version: ['9.6.7', '9.8.4', '9.10.3'] |
| - name: Setup Haskell | ||
| uses: haskell-actions/setup@v2 | ||
| with: | ||
| ghc-version: '9.10.3' |
There was a problem hiding this comment.
The benchmark job pins ghc-version: '9.10.3', but the test job matrix uses 9.10.2. This makes the workflow inconsistent and can hide version-specific issues (or fail if one of the versions isn’t available via haskell-actions/setup). Consider using the same GHC version(s) across jobs, ideally matching the cabal tested-with field.
| ghc-version: '9.10.3' | |
| ghc-version: '9.10.2' |
No description provided.