Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: Kleidukos/get-tested
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.1.5.0
Choose a base ref
...
head repository: Kleidukos/get-tested
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: main
Choose a head ref

Commits on Sep 25, 2023

  1. Update README

    Kleidukos committed Sep 25, 2023
    Copy the full SHA
    1ec6ae3 View commit details
  2. Fix linting

    Kleidukos committed Sep 25, 2023
    Copy the full SHA
    370bf61 View commit details
  3. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    f440563 View commit details
  4. Bump actions/checkout from 2 to 4 (#17)

    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored Sep 25, 2023

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    cd361be View commit details
  5. Bump rwe/actions-hlint-run from 1 to 2 (#18)

    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored Sep 25, 2023

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    15131a0 View commit details
  6. Bump haskell/actions from 1 to 2 (#21)

    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored Sep 25, 2023

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    469ef11 View commit details
  7. Bump actions/cache from 2.1.3 to 3.3.2 (#20)

    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored Sep 25, 2023

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    e9085e1 View commit details
  8. Use fourmolu-actions v8

    Kleidukos committed Sep 25, 2023
    Copy the full SHA
    40d7582 View commit details

Commits on Jan 6, 2024

  1. Add github action (#23)

    Co-authored-by: Manuel Bärenz <m.baerenz@sonnen.de>
    turion and Manuel Bärenz authored Jan 6, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    992fd26 View commit details
  2. Use this repo

    Kleidukos committed Jan 6, 2024
    Copy the full SHA
    d25e192 View commit details
  3. Add description

    Kleidukos committed Jan 6, 2024
    Copy the full SHA
    caa5715 View commit details
  4. Bump version to 0.1.6.0

    Kleidukos committed Jan 6, 2024
    Copy the full SHA
    06c91e5 View commit details
  5. Factorise static build project file

    Kleidukos committed Jan 6, 2024
    Copy the full SHA
    ef5a28f View commit details
  6. Support OS choice via action inputs (#24)

    Kleidukos authored Jan 6, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    6fab350 View commit details
  7. fix environment variables syntax

    Kleidukos committed Jan 6, 2024
    Copy the full SHA
    3126586 View commit details
  8. Debug inputs

    Kleidukos committed Jan 6, 2024
    Copy the full SHA
    3021032 View commit details
  9. Re-enable ref

    Kleidukos committed Jan 6, 2024
    Copy the full SHA
    f889b17 View commit details
  10. fix equality checking

    Kleidukos committed Jan 6, 2024
    Copy the full SHA
    59c71c2 View commit details
  11. try something else

    Kleidukos committed Jan 6, 2024
    Copy the full SHA
    bee6741 View commit details
  12. correct syntax

    Kleidukos committed Jan 6, 2024
    Copy the full SHA
    34bf65d View commit details
  13. try splitting steps

    Kleidukos committed Jan 6, 2024
    Copy the full SHA
    88f35e7 View commit details
  14. Use checkout@v4

    Kleidukos committed Jan 6, 2024
    Copy the full SHA
    7fac38e View commit details
  15. a bit more debugging

    Kleidukos committed Jan 6, 2024
    Copy the full SHA
    62ceb2e View commit details
  16. debug output

    Kleidukos committed Jan 6, 2024
    Copy the full SHA
    97376c9 View commit details
  17. Improve readme (#25)

    turion authored Jan 6, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    1059bb1 View commit details
  18. Remove unused dependencies

    Kleidukos committed Jan 6, 2024
    Copy the full SHA
    a2c7ad4 View commit details
  19. Implement OS selection (#26)

    Kleidukos authored Jan 6, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    243f28f View commit details
  20. Update README

    Kleidukos committed Jan 6, 2024
    Copy the full SHA
    2ff7f29 View commit details
  21. Update README for Action description

    Kleidukos committed Jan 6, 2024
    Copy the full SHA
    8d5f0b7 View commit details

Commits on Jan 7, 2024

  1. enable split-sections

    Kleidukos committed Jan 7, 2024
    Copy the full SHA
    a9872cd View commit details

Commits on Jan 15, 2024

  1. Bump actions/cache from 3.3.2 to 3.3.3 (#28)

    Bumps [actions/cache](https://github.com/actions/cache) from 3.3.2 to 3.3.3.
    - [Release notes](https://github.com/actions/cache/releases)
    - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
    - [Commits](actions/cache@v3.3.2...v3.3.3)
    
    ---
    updated-dependencies:
    - dependency-name: actions/cache
      dependency-type: direct:production
      update-type: version-update:semver-patch
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored Jan 15, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    6931193 View commit details

Commits on Jan 21, 2024

  1. Use hlint v3.8

    Kleidukos committed Jan 21, 2024
    Copy the full SHA
    9bc240b View commit details

Commits on Jan 22, 2024

  1. Bump actions/cache from 3.3.3 to 4.0.0 (#29)

    Bumps [actions/cache](https://github.com/actions/cache) from 3.3.3 to 4.0.0.
    - [Release notes](https://github.com/actions/cache/releases)
    - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
    - [Commits](actions/cache@v3.3.3...v4.0.0)
    
    ---
    updated-dependencies:
    - dependency-name: actions/cache
      dependency-type: direct:production
      update-type: version-update:semver-major
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored Jan 22, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    5412453 View commit details

Commits on Jan 29, 2024

  1. Bump fourmolu/fourmolu-action from 8 to 10 (#30)

    Bumps [fourmolu/fourmolu-action](https://github.com/fourmolu/fourmolu-action) from 8 to 10.
    - [Release notes](https://github.com/fourmolu/fourmolu-action/releases)
    - [Changelog](https://github.com/haskell-actions/run-fourmolu/blob/master/CHANGELOG.md)
    - [Commits](haskell-actions/run-fourmolu@v8...v10)
    
    ---
    updated-dependencies:
    - dependency-name: fourmolu/fourmolu-action
      dependency-type: direct:production
      update-type: version-update:semver-major
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored Jan 29, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    d6aa5a1 View commit details

Commits on Mar 4, 2024

  1. Bump actions/cache from 4.0.0 to 4.0.1 (#31)

    Bumps [actions/cache](https://github.com/actions/cache) from 4.0.0 to 4.0.1.
    - [Release notes](https://github.com/actions/cache/releases)
    - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
    - [Commits](actions/cache@v4.0.0...v4.0.1)
    
    ---
    updated-dependencies:
    - dependency-name: actions/cache
      dependency-type: direct:production
      update-type: version-update:semver-patch
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored Mar 4, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    3faac3b View commit details

Commits on Mar 7, 2024

  1. Support explicit versions (#33)

    * Support explicit versions
    
    * Add new inputs
    Kleidukos authored Mar 7, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    dceb7ef View commit details
  2. Enable optimisations by default

    Kleidukos committed Mar 7, 2024
    Copy the full SHA
    59cf8ed View commit details
  3. Add --version to the CLI

    Kleidukos committed Mar 7, 2024
    Copy the full SHA
    cb1af96 View commit details
  4. Use v0.1.7.0-rc1 (#34)

    * Use v0.1.7.0-rc1
    Kleidukos authored Mar 7, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    d4a41f1 View commit details
  5. update README

    Kleidukos committed Mar 7, 2024
    Copy the full SHA
    560d838 View commit details

Commits on Mar 11, 2024

  1. Bump kleidukos/get-tested from 801427d to 5b105f5 (#35)

    Bumps [kleidukos/get-tested](https://github.com/kleidukos/get-tested) from 801427d to 5b105f5.
    - [Release notes](https://github.com/kleidukos/get-tested/releases)
    - [Changelog](https://github.com/Kleidukos/get-tested/blob/main/CHANGELOG.md)
    - [Commits](801427d...5b105f5)
    
    ---
    updated-dependencies:
    - dependency-name: kleidukos/get-tested
      dependency-type: direct:production
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored Mar 11, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    43f42cd View commit details

Commits on Mar 25, 2024

  1. Bump actions/cache from 4.0.1 to 4.0.2 (#36)

    Bumps [actions/cache](https://github.com/actions/cache) from 4.0.1 to 4.0.2.
    - [Release notes](https://github.com/actions/cache/releases)
    - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
    - [Commits](actions/cache@v4.0.1...v4.0.2)
    
    ---
    updated-dependencies:
    - dependency-name: actions/cache
      dependency-type: direct:production
      update-type: version-update:semver-patch
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored Mar 25, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    c3ac9b0 View commit details

Commits on Apr 5, 2024

  1. Support GHC 9.8 (#37)

    Kleidukos authored Apr 5, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    5b8b204 View commit details

Commits on May 13, 2024

  1. Use GHC 9.10 (#38)

    Kleidukos authored May 13, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    79fb722 View commit details

Commits on Jul 20, 2024

  1. Automate releases with Github Actions (#41)

    Kleidukos authored Jul 20, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    4ae4ae6 View commit details
  2. Copy the full SHA
    61f298f View commit details
  3. Reshape the cabal project files

    Kleidukos committed Jul 20, 2024
    Copy the full SHA
    f6a36a8 View commit details
  4. Try out the release pipeline with 0.1.7.1

    Kleidukos committed Jul 20, 2024
    Copy the full SHA
    2f60c77 View commit details
  5. Fix CI?

    Kleidukos committed Jul 20, 2024
    Copy the full SHA
    3ffc181 View commit details
  6. Stay on upload-artifact@v3 (#42)

    Kleidukos authored Jul 20, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    2a0564a View commit details
10 changes: 10 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Set update schedule for GitHub Actions

version: 2
updates:

- package-ecosystem: "github-actions"
directory: "/"
schedule:
# Check for updates to GitHub Actions every week
interval: "weekly"
211 changes: 191 additions & 20 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
name: CI
name: Tests Pipeline

# Trigger the workflow on push or pull request, but only for the main branch
on:
pull_request:
push:
@@ -9,44 +8,216 @@ on:
jobs:
generate-matrix:
name: "Generate matrix from cabal"
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
runs-on: ubuntu-latest
steps:
- name: Checkout base repo
uses: actions/checkout@v3
- name: Extract the tested GHC versions
id: set-matrix
run: |
wget https://github.com/Kleidukos/get-tested/releases/download/v0.1.3.0/get-tested-0.1.3.0-linux-amd64 -O get-tested
chmod +x get-tested
./get-tested --ubuntu --macos get-tested.cabal >> $GITHUB_OUTPUT
tests:
uses: kleidukos/get-tested@0.1.7.1
with:
cabal-file: get-tested.cabal
ubuntu-version: 'latest'
macos-version: 'latest'
version: 0.1.7.0
build:
name: ${{ matrix.ghc }} on ${{ matrix.os }}
needs: generate-matrix
runs-on: ${{ matrix.os }}
strategy:
matrix: ${{ fromJSON(needs.generate-matrix.outputs.matrix) }}
steps:

- name: "Install tools"
if: ${{ matrix.os == 'ubuntu-latest' }}
run: |
sudo apt install upx-ucl
- name: Checkout base repo
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Set up Haskell
id: setup-haskell
uses: haskell/actions/setup@v1
uses: haskell-actions/setup@v2
with:
ghc-version: ${{ matrix.ghc }}
cabal-version: 'latest'
cabal-version: "latest"

- name: Configure
run: |
ARCHITECTURE=$(uname -m)
echo "ARCH=$ARCHITECTURE" >> $GITHUB_ENV
echo "REPORT_NAME=report-${{ runner.os }}-ghc-${{ matrix.ghc }}.xml" >> $GITHUB_ENV
- name: Freeze
run: cabal freeze --project-file=cabal.release.project

- name: Cache
uses: actions/cache@v4
with:
key: ${{ runner.os }}-ghc-${{ matrix.ghc }}-${{ hashFiles('**/plan.json') }}
path: ${{ steps.setup-haskell.outputs.cabal-store }}
restore-keys: ${{ runner.os }}-ghc-${{ matrix.ghc }}-

- name: Build
run: cabal build --project-file=cabal.release.project

- name: Test
run: |
cabal test --project-file=cabal.release.project --test-options "--xml=../get-tested/${{ env.REPORT_NAME }}" all
- name: Upload the test report
uses: actions/upload-artifact@v4
if: success() || failure() # always run even if the previous step fails
with:
name: ${{ env.REPORT_NAME }}
path: ${{ env.REPORT_NAME }}

- name: Install
run: |
bin=$(cabal -v0 --project-file=cabal.release.project list-bin get-tested)
mkdir distribution
cp ${bin} distribution/get-tested
- name: Post-process executables
if: ${{ matrix.os == 'ubuntu-latest' }}
run: |
strip distribution/get-tested
upx -9 distribution/get-tested
- name: Package the get-tested executable
run: |
executable=distribution/get-tested
ARTIFACT_NAME="get-tested-head-${{ runner.os }}-${{ env.ARCH }}"
echo "ARTIFACT_NAME=${ARTIFACT_NAME}" >> $GITHUB_ENV
mv ./distribution/get-tested ${ARTIFACT_NAME}
- name: Upload the get-tested executable
uses: actions/upload-artifact@v4
with:
name: ${{ env.ARTIFACT_NAME }}
path: ${{ env.ARTIFACT_NAME }}

build-alpine:
name: 9.10.1 on alpine-3.20
runs-on: ubuntu-latest
container: "alpine:3.20"
needs: generate-matrix
steps:
- name: Install extra dependencies
shell: sh
run: |
apk add bash binutils-gold curl \
curl file g++ gcc git gmp-dev \
jq libc-dev libffi-dev make \
musl-dev ncurses-dev perl pkgconfig \
sudo tar upx xz zlib-dev zlib-static
- uses: actions/checkout@v4

- uses: haskell-actions/setup@v2
id: setup-haskell
with:
ghc-version: "9.10.1"
cabal-version: "latest"

- name: Configure
run: cabal new-configure --enable-tests
run: |
ARCHITECTURE=$(uname -m)
echo "ARCH=$ARCHITECTURE" >> $GITHUB_ENV
echo "REPORT_NAME=report-alpine.xml" >> $GITHUB_ENV
- name: Freeze
run: cabal freeze
run: cabal freeze --project-file=cabal.static.project

- name: Cache
uses: actions/cache@v2.1.3
uses: actions/cache@v4
with:
key: ${{ runner.os }}-ghc-${{ matrix.ghc }}-${{ hashFiles('**/plan.json') }}
path: ${{ steps.setup-haskell.outputs.cabal-store }}
key: ${{ runner.os }}-${{ matrix.ghc }}-${{ hashFiles('cabal.project.freeze') }}
restore-keys: ${{ runner.os }}-${{ matrix.ghc }}-
restore-keys: ${{ runner.os }}-ghc-${{ matrix.ghc }}-

- name: Build
run: cabal new-build
run: cabal build --project-file=cabal.static.project

- name: Test
run: cabal new-test all
run: |
cabal test --project-file=cabal.static.project --test-options "--xml=../get-tested/${{ env.REPORT_NAME }}" all
- name: Upload the test report
uses: actions/upload-artifact@v4
if: success() || failure() # always run even if the previous step fails
with:
name: ${{ env.REPORT_NAME }}
path: ${{ env.REPORT_NAME }}

- name: Install
run: |
bin=$(cabal -v0 --project-file=cabal.static.project list-bin get-tested)
mkdir distribution
cp ${bin} distribution/get-tested
- name: Post-process executables
run: |
strip distribution/get-tested
upx -9 distribution/get-tested
- name: Create artifact name
run: |
ARTIFACT_NAME="get-tested-head-${{ runner.os }}-static-${{ env.ARCH }}"
echo "ARTIFACT_NAME=${ARTIFACT_NAME}" >> $GITHUB_ENV
mv ./distribution/get-tested ${ARTIFACT_NAME}
- name: Upload get-tested executable to workflow artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ env.ARTIFACT_NAME }}
path: ${{ env.ARTIFACT_NAME }}

collect-test-results:
name: Collect test results
runs-on: ubuntu-latest
if: ${{ always() }}
needs: ['build', 'build-alpine']
steps:
- name: Install junitparser
run: |
pip install junitparser==3.2.0
- name: Download Test Report
uses: actions/download-artifact@v4
with:
pattern: report-*
merge-multiple: true

- name: Merge XML files
run: |
junitparser merge --glob *.xml final-report.xml
- name: Publish Test Report
uses: mikepenz/action-junit-report@v5
with:
commit: ${{github.event.workflow_run.head_sha}}
report_paths: 'final-report.xml'

prerelease-head:
name: Create a GitHub prerelease with the binary artifacts
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
needs: ["build", "build-alpine"]
permissions:
contents: write

steps:
- uses: actions/download-artifact@v4
with:
pattern: get-tested-*
merge-multiple: true
path: ./out

- name: Pre-release
uses: softprops/action-gh-release@v2
with:
prerelease: true
files: ./out/*
tag_name: get-tested-head
16 changes: 9 additions & 7 deletions .github/workflows/linting.yml
Original file line number Diff line number Diff line change
@@ -9,25 +9,27 @@ jobs:
fourmolu:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4

- uses: fourmolu/fourmolu-action@v5
- uses: fourmolu/fourmolu-action@v11
with:
pattern: |
app/**/*.hs
src/**/*.hs
test/**/*.hs
hlint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4

- name: 'Set up HLint'
uses: rwe/actions-hlint-setup@v1
uses: haskell-actions/hlint-setup@v2
with:
version: '3.5'
version: '3.8'

- name: 'Run HLint'
uses: rwe/actions-hlint-run@v1
uses: haskell-actions/hlint-run@v2
with:
path: '["app/"]'
path: '["app", "test", "src"]'
fail-on: warning
245 changes: 245 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
name: Release Pipeline

on:
push:
branches: ['main']
tags:
- "v*"

jobs:
generate-matrix:
if: startsWith(github.ref, 'refs/tags/v')
name: 'Generate matrix from cabal'
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
runs-on: ubuntu-latest
steps:
- name: Extract the tested GHC versions
id: set-matrix
uses: kleidukos/get-tested@0.1.7.1
with:
cabal-file: get-tested.cabal
ubuntu-version: 'latest'
macos-version: 'latest'
version: 0.1.7.0
build:
name: ${{ matrix.ghc }} on ${{ matrix.os }}
needs: generate-matrix
runs-on: ${{ matrix.os }}
strategy:
matrix: ${{ fromJSON(needs.generate-matrix.outputs.matrix) }}
steps:

- name: "Install tools"
if: ${{ matrix.os == 'ubuntu-latest' }}
run: |
sudo apt install upx-ucl
- name: Checkout base repo
uses: actions/checkout@v4

- name: Set up Haskell
id: setup-haskell
uses: haskell-actions/setup@v2
with:
ghc-version: ${{ matrix.ghc }}
cabal-version: 'latest'

- name: Configure
run: |
ARCHITECTURE=$(uname -m)
echo "ARCH=$ARCHITECTURE" >> $GITHUB_ENV
echo "REPORT_NAME=report-${{ runner.os }}-ghc-${{ matrix.ghc }}.xml" >> $GITHUB_ENV
- name: Freeze
run: cabal freeze --project-file=cabal.release.project

- name: Cache
uses: actions/cache@v4
with:
key: ${{ runner.os }}-ghc-${{ matrix.ghc }}-${{ hashFiles('**/plan.json') }}
path: ${{ steps.setup-haskell.outputs.cabal-store }}
restore-keys: ${{ runner.os }}-ghc-${{ matrix.ghc }}-

- name: Build
run: cabal build --project-file=cabal.release.project

- name: Test
run: |
cabal test --project-file=cabal.release.project --test-options "--xml=../get-tested/${{ env.REPORT_NAME }}" all
- name: Upload the test report
uses: actions/upload-artifact@v4
if: success() || failure() # always run even if the previous step fails
with:
name: ${{ env.REPORT_NAME }}
path: ${{ env.REPORT_NAME }}

- name: Install
run: |
bin=$(cabal -v0 --project-file=cabal.release.project list-bin get-tested)
mkdir distribution
cp ${bin} distribution/get-tested
- name: Post-process executables
if: ${{ matrix.os == 'ubuntu-latest' }}
run: |
strip distribution/get-tested
upx -9 distribution/get-tested
- id: version
run: |
version=$(./distribution/get-tested --version)
echo "VERSION=${version}" >> "$GITHUB_ENV"
- name: Create artifact name
run: |
ARTIFACT_NAME="get-tested-${{ env.VERSION }}-${{ runner.os }}-${{ env.ARCH }}"
echo "ARTIFACT_NAME=${ARTIFACT_NAME}" >> $GITHUB_ENV
- name: Upload the get-tested executable
uses: actions/upload-artifact@v4
with:
name: ${{ env.ARTIFACT_NAME }}
path: distribution/get-tested

build-alpine:
env:
os: alpine-3.20
name: 9.10.1 on alpine-3.20
runs-on: ubuntu-latest
container: 'alpine:3.20'
needs: generate-matrix
outputs:
version: ${{ steps.version.output.version }}
steps:
- name: Install extra dependencies
shell: sh
run: |
apk add bash binutils-gold curl \
curl file g++ gcc git gmp-dev \
jq libc-dev libffi-dev make \
musl-dev ncurses-dev perl pkgconfig \
sudo tar upx xz zlib-dev zlib-static
- uses: actions/checkout@v4

- uses: haskell-actions/setup@v2
id: setup-haskell
with:
ghc-version: '9.10.1'
cabal-version: 'latest'

- name: Configure
run: |
ARCHITECTURE=$(uname -m)
echo "ARCH=$ARCHITECTURE" >> $GITHUB_ENV
echo "REPORT_NAME=report-alpine-ghc-$(uname -m).xml" >> $GITHUB_ENV
echo ${{ env.ARCH }}
- name: Freeze
run: cabal freeze --project-file=cabal.static.project

- name: Cache
uses: actions/cache@v4
with:
key: $os-ghc-${{ matrix.ghc }}-${{ hashFiles('**/plan.json') }}
path: ${{ steps.setup-haskell.outputs.cabal-store }}
restore-keys: $os-ghc-${{ matrix.ghc }}-

- name: Build
run: cabal build --project-file=cabal.static.project

- name: Test
run: |
cabal test --project-file=cabal.static.project --test-options "--xml=../get-tested/${{ env.REPORT_NAME }}" all
- name: Upload the test report
uses: actions/upload-artifact@v4
if: success() || failure() # always run even if the previous step fails
with:
name: ${{ env.REPORT_NAME }}
path: ${{ env.REPORT_NAME }}

- name: Install
run: |
bin=$(cabal -v0 --project-file=cabal.static.project list-bin get-tested)
mkdir distribution
cp ${bin} distribution/get-tested
- id: version
run: |
version=$(./distribution/get-tested --version)
echo "version=${version}" >> "$GITHUB_OUTPUT"
echo "VERSION=${version}" >> "$GITHUB_ENV"
- name: File type
run: file distribution/get-tested

- name: Post-process executables
run: |
strip distribution/get-tested
upx -9 distribution/get-tested
- name: get-tested executable
run: |
ARTIFACT_NAME="get-tested-${{ env.VERSION }}-${{ runner.os }}-static-${{ env.ARCH }}"
echo "ARTIFACT_NAME=${ARTIFACT_NAME}" >> $GITHUB_ENV
mv ./distribution/get-tested ${ARTIFACT_NAME}
- name: Upload get-tested executable to workflow artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ env.ARTIFACT_NAME }}
path: ${{ env.ARTIFACT_NAME }}

collect-test-results:
name: Collect test results
runs-on: ubuntu-latest
if: ${{ always() }}
needs: ['build', 'build-alpine']
steps:
- name: Install junitparser
run: |
pip install junitparser==3.2.0
- name: Download Test Report
uses: actions/download-artifact@v4
with:
pattern: report-*
merge-multiple: true

- name: Merge XML files
run: |
junitparser merge --glob *.xml final-report.xml
- name: Publish Test Report
uses: mikepenz/action-junit-report@v5
with:
commit: ${{github.event.workflow_run.head_sha}}
report_paths: 'final-report.xml'

release:
name: Create a GitHub Release with the binary artifacts
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/v')
needs: ['build', 'build-alpine']
permissions:
contents: write

steps:
- uses: actions/download-artifact@v4
with:
pattern: get-tested-*
merge-multiple: true
path: ./out

- name: Release
uses: softprops/action-gh-release@v2
with:
draft: true
files: ./out/*
name: v${{ env.version }}
fail_on_unmatched_files: true
env:
version: ${{ needs.build-alpine.outputs.version }}
63 changes: 63 additions & 0 deletions .github/workflows/test-action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
name: Test actions pipeline

on:
pull_request:
branches: ['main']

push:
branches: ['main']

jobs:
test-action:
name: 'Test get-tested action'
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@v4

- name: Extract the tested GHC versions
id: create-matrix
uses: ./
with:
cabal-file: get-tested.cabal
ubuntu-version: 'latest'
macos-version: 'latest'

- name: Output matrix
run: |
jq '.' <<< '${{ steps.create-matrix.outputs.matrix }}'
test-setup-action:
name: 'Test setup-get-tested action'
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@v4

- name: Set up without options
id: setup
uses: ./setup-get-tested

- name: Set up with explicit directory
id: setup-with-directory
uses: ./setup-get-tested
with:
directory: "my-bin-dir"

- name: Output results
run: |
echo "${{ steps.setup.outputs.path }}"
if [[ -x "${{ steps.setup.outputs.path }}" ]]; then
echo "Is executable"
else
echo "Is NOT executable"
exit 1
fi
echo "${{ steps.setup-with-directory.outputs.path }}"
if [[ -x "${{ steps.setup-with-directory.outputs.path }}" ]]; then
echo "Is executable"
else
echo "Is NOT executable"
exit 1
fi
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
# Revision history for get-tested
# CHANGELOG

## 0.1.8.1 -- 2024-09-13

* Fix the setup action

## 0.1.8.0 -- 2024-09-06

* Provide the `--newest` and `--oldest` flags to pick the newest or oldest-supported GHC. ([55](https://github.com/Kleidukos/get-tested/pull/55))

## 0.1.5.0 -- 2023-09-25

6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -11,10 +11,10 @@ test: ## Run the test suite
@cabal test

lint: ## Run the code linter (HLint)
@find app -name "*.hs" | xargs -P $(PROCS) -I {} hlint --refactor-options="-i" --refactor {}
@find app src test -name "*.hs" | xargs -P $(PROCS) -I {} hlint --refactor-options="-i" --refactor {}

style: ## Run the code styler (stylish-haskell)
@fourmolu -q --mode inplace app
style: ## Run the code styler (fourmolu)
@fourmolu -q --mode inplace app src test
@cabal-fmt -i *.cabal

help: ## Display this help message
111 changes: 88 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,98 @@
# get-tested

A CLI tool that retrieves the `tested-with` stanza of a cabal file and formats it in such a way that GitHub Actions can use it.
A CLI tool that retrieves the `tested-with` stanza of a cabal file and formats
it in such a way that GitHub Actions can use it.

## Usage

Put this in your GitHub Action file
The inputs of the action (under the `with:` stanza) are the following:

* `cabal-file:` \
The path to your cabal file, e.g. somefolder/myproject.cabal.
\
_Required:_ true

* `version:` \
The version of the get-tested tool that is used.
\
_Required:_ false \
_Default:_ The latest release

* `windows:` \
**(deprecated)** Enable Windows runner, latest version.
\
_Required:_ false \
_Default:_ false

* `windows-version:` \
Enable Windows runner. If both `windows` and `windows-version` inputs are
set, the explicit version will take priority.
\
_Required:_ false \
_Default:_ Not set

* `macos:` \
**(deprecated)** Enable macOS runner, latest version.
\
_Required:_ false \
_Default:_ false

* `macos-version:` \
Enable macOS runner. If both `macos` and `macos-version` inputs are set, the
explicit version will take priority.
\
_Required:_ false \
_Default:_ Not set

* `ubuntu:` \
**(deprecated)** Enable Ubuntu runner, latest version.
\
_Required:_ false \
_Default:_ false

* `ubuntu-version:` \
Enable Ubuntu runner. If both `ubuntu` and `ubuntu-version` inputs are set,
the explicit version will take priority.
\
_Required:_ false \
_Default:_ Not set

* `newest:` \
Enable only the newest GHC version found in the cabal file
\
_Required:_ false \
_Default:_ false

* `oldest:` \
Enable only the oldest GHC version found in the cabal file
\
_Required:_ false \
_Default:_ false

See below for an example:

```yaml
jobs:
generateMatrix:
name: "Generate matrix from cabal"
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- name: Checkout base repo
uses: actions/checkout@v2
- name: Extract the tested GHC versions
id: set-matrix
run: |
wget https://github.com/Kleidukos/get-tested/releases/download/v0.1.4.0/get-tested-0.1.4.0-linux-amd64 -O get-tested
chmod +x get-tested
./get-tested --ubuntu --macos my-project.cabal >> $GITHUB_OUTPUT
tests:
name: ${{ matrix.ghc }} on ${{ matrix.os }}
needs: generateMatrix
runs-on: ${{ matrix.os }}
strategy:
matrix: ${{ fromJSON(needs.generateMatrix.outputs.matrix) }}
jobs:
generate-matrix:
name: "Generate matrix from cabal"
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
runs-on: ubuntu-latest
steps:
- name: Extract the tested GHC versions
id: set-matrix
uses: kleidukos/get-tested@v0.1.7.1
with:
cabal-file: get-tested.cabal
ubuntu-version: "latest"
macos-version: "latest"
version: 0.1.7.1
tests:
name: ${{ matrix.ghc }} on ${{ matrix.os }}
needs: generate-matrix
runs-on: ${{ matrix.os }}
strategy:
matrix: ${{ fromJSON(needs.generate-matrix.outputs.matrix) }}
```
![](./showcase.png)
148 changes: 148 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
name: "Test supported GHC versions"
description: "Generate a test matrix from your cabal file's `tested-with` stanza"

inputs:
cabal-file:
description: "The path to your cabal file, e.g. somefolder/myproject.cabal"
required: true
version:
description: "Version of the get-tested tool"
required: false
default: ""
windows:
description: "Enable Windows runner, latest version"
required: false
default: false
deprecationMessage: "Please use 'windows-version: latest' instead."
windows-version:
description: "Enable Windows runner. If both `windows` and `windows-version` inputs are set, the explicit version will take priority"
required: false
default: ""
macos:
description: "Enable macOS runner, latest version"
required: false
default: false
deprecationMessage: "Please use 'macos-version: latest' instead."
macos-version:
description: "Enable macOS runner. If both `macos` and `macos-version` inputs are set, the explicit version will take priority"
required: false
default: ""
ubuntu:
description: "Enable Ubuntu runner, latest version"
required: false
default: false
deprecationMessage: "Please use 'ubuntu-version: latest' instead."
ubuntu-version:
description: "Enable Ubuntu runner. If both `ubuntu` and `ubuntu-version` inputs are set, the explicit version will take priority"
required: false
default: ""
newest:
description: "Enable only the newest GHC version found in the cabal file"
required: false
default: false
oldest:
description: "Enable only the oldest GHC version found in the cabal file"
required: false
default: false

outputs:
matrix:
description: "The GHC version matrix"
value: ${{ steps.set-matrix.outputs.matrix }}

runs:
using: "composite"
steps:
- name: Checkout base repo
uses: actions/checkout@v4

# The following does not work:
#
# uses: Kleidukos/get-tested/setup-get-tested@${{ github.action_ref }}
#
# See: https://github.com/actions/runner/issues/895
- name: Set up get-tested
uses: Kleidukos/get-tested/setup-get-tested@5f873c05c435a1f50e4c5ce815d687c1bff3b93b
with:
version: ${{ inputs.version }}

- name: Set up Windows options
shell: bash
run: |
echo "::debug::windows: ${{ inputs.windows-version }}"
if [[ "${{ inputs.windows-version }}" != "" ]]
then
echo "::debug::Windows explicit enabled: ${{ inputs.windows-version }}"
echo "WINDOWS=--windows-version=${{ inputs.windows-version }}" >> $GITHUB_ENV
elif [[ ${{ inputs.windows }} == "true" ]]
then
echo "::warning title=Legacy option `windows`::Windows fallback enabled: ${{ inputs.windows }}"
echo "WINDOWS=--windows" >> $GITHUB_ENV
else echo "WINDOWS=" >> $GITHUB_ENV
fi
- name: Set up macOS options
shell: bash
run: |
echo "::debug::macOS: ${{ inputs.macos-version }}"
if [[ "${{ inputs.macos-version }}" != "" ]]
then
echo "::debug::macOS explicit version enabled: ${{ inputs.macos-version }}"
echo "MACOS=--macos-version=${{ inputs.macos-version }}" >> $GITHUB_ENV
elif [[ ${{ inputs.macos }} == "true" ]]
then
echo "::warning title=Legacy option `macos`::macOS fallback enabled: ${{ inputs.macos }}"
echo "MACOS=--macos" >> $GITHUB_ENV
else echo "MACOS=" >> $GITHUB_ENV
fi
- name: Set up Ubuntu options
shell: bash
run: |
echo "::debug::ubuntu: ${{ inputs.ubuntu-version }}"
if [[ "${{ inputs.ubuntu-version }}" != "" ]]
then
echo "::debug::Ubuntu explicit version enabled: ${{ inputs.ubuntu-version }}"
echo "UBUNTU=--ubuntu-version=${{ inputs.ubuntu-version }}" >> $GITHUB_ENV
elif [[ ${{ inputs.ubuntu }} == "true" ]]
then
echo "::warning title=Legacy option `ubuntu`::Ubuntu fallback enabled: ${{ inputs.ubuntu }}"
echo "UBUNTU=--ubuntu" >> $GITHUB_ENV
else echo "UBUNTU=" >> $GITHUB_ENV
fi
- name: Set up `oldest` and `newest` options
shell: bash
run: |
echo "::debug::Is --newest enabled: ${{ inputs.newest }}"
echo "::debug::Is --oldest enabled: ${{ inputs.oldest }}"
if [[ "${{ inputs.oldest}} == "true" " && "${{ inputs.newest }}" == "true" ]]
then
echo "::error title=Incompatible options::You cannot use the 'oldest' and 'newest' options together!"
exit 1
fi
if [[ ${{ inputs.oldest }} == "true" ]]
then
echo "::debug::oldest version enabled"
echo "RELATIVE_VERSION=--oldest" >> $GITHUB_ENV
elif [[ ${{ inputs.newest }} == "true" ]]
then
echo "::debug::newest version enabled"
echo "RELATIVE_VERSION=--newest" >> $GITHUB_ENV
else
echo "::debug::No relative version selected"
fi
- name: Extract the tested GHC versions
id: set-matrix
shell: bash
run: |
./get-tested $WINDOWS $MACOS $UBUNTU $RELATIVE_VERSION ${{ inputs.cabal-file }} >> $GITHUB_OUTPUT
branding:
icon: 'list'
color: 'blue'
86 changes: 0 additions & 86 deletions app/Extract.hs

This file was deleted.

116 changes: 86 additions & 30 deletions app/Main.hs
Original file line number Diff line number Diff line change
@@ -1,61 +1,117 @@
module Main where

import Control.Monad (when)
import Data.Aeson qualified as Aeson
import Data.ByteString.Lazy (ByteString)
import Data.ByteString.Lazy.Char8 qualified as ByteString
import Data.Function ((&))
import Data.Text (Text)
import Data.Text qualified as Text
import Data.Text.Display (display)
import Data.Vector (Vector)
import Data.Vector qualified as Vector
import Data.Version (showVersion)
import Effectful
import Effectful.Console.ByteString (Console)
import Effectful.Console.ByteString qualified as Console
import Effectful.Error.Static
import Options.Applicative
import Effectful.Error.Static qualified as Error
import Effectful.FileSystem (FileSystem)
import Effectful.FileSystem qualified as FileSystem
import Options.Applicative hiding (action)
import System.Exit

import Extract
import Types

data Options = Options
{ path :: FilePath
, macosFlag :: Bool
, ubuntuFlag :: Bool
, windowsFlag :: Bool
}
deriving stock (Show, Eq)
import GetTested.CLI.Types
import GetTested.Extract
import GetTested.Types
import Paths_get_tested (version)

main :: IO ()
main = do
result <- execParser (parseOptions `withInfo` "Extract the tested-with stanza from your cabal file")
processingResult <- runEff . runErrorNoCallStack $ runOptions result
result <- execParser (parseOptions `withInfo` "Generate a test matrix from the tested-with stanza of your cabal file")
processingResult <- runCLIEff $ runOptions result
case processingResult of
Right json -> ByteString.putStrLn json
Right json -> putStrLn $ ByteString.unpack json
Left (CabalFileNotFound path) -> do
putStrLn $ "Could not find cabal file at path " <> path
putStrLn $ "get-tested: Could not find cabal file at path " <> path
exitFailure
Left (CabalFileCouldNotBeParsed path) -> do
putStrLn $ "Could not parse cabal file at path " <> path
putStrLn $ "get-tested: Could not parse cabal file at path " <> path
exitFailure
Left (NoCompilerVersionsFound path) -> do
putStrLn $ "get-tested: No compilers found in" <> path
exitFailure
Left (IncompatibleOptions opt1 opt2) -> do
putStrLn $ Text.unpack $ "get-tested: Incompatible options: " <> opt1 <> " and " <> opt2 <> " cannot be passed simultaneously."
exitFailure

parseOptions :: Parser Options
parseOptions =
Options
<$> argument str (metavar "FILE")
<*> switch (long "macos" <> help "Enable the macOS platform")
<*> switch (long "ubuntu" <> help "Enable the ubuntu platform")
<*> switch (long "windows" <> help "Enable the windows platform")
<*> switch (long "macos" <> help "(legacy) Enable the macOS runner's latest version")
<*> optional (strOption (long "macos-version" <> metavar "VERSION" <> help "Enable the macOS runner with the selected version"))
<*> switch (long "ubuntu" <> help "(legacy) Enable the Ubuntu runner's latest version")
<*> optional (strOption (long "ubuntu-version" <> metavar "VERSION" <> help "Enable the Ubuntu runner with the selected version"))
<*> switch (long "windows" <> help "(legacy) Enable the Windows runner's latest version")
<*> optional (strOption (long "windows-version" <> metavar "VERSION" <> help "Enable the Windows runner with the selected version"))
<*> switch (long "newest" <> help "Enable only the newest GHC version found in the cabal file")
<*> switch (long "oldest" <> help "Enable only the oldest GHC version found in the cabal file")
<**> simpleVersioner (showVersion version)

runOptions :: Options -> Eff [Error ProcessingError, IOE] ByteString
runOptions :: Options -> Eff [Console, FileSystem, Error ProcessingError, IOE] ByteString
runOptions options = do
checkIncompatibleRelativeOptions options
genericPackageDescription <- loadFile options.path
let supportedCompilers = extractTestedWith genericPackageDescription
filteredList =
osList
& (if options.macosFlag then id else Vector.filter (/= "macos-latest"))
& (if options.windowsFlag then id else Vector.filter (/= "windows-latest"))
& (if options.ubuntuFlag then id else Vector.filter (/= "ubuntu-latest"))
pure $ if null filteredList
then Aeson.encode supportedCompilers
selectedCompilers <-
filterCompilers options
<$> extractTestedWith options.path genericPackageDescription
let filteredList =
processOSFlag MacOS options.macosFlag options.macosVersion
<> processOSFlag Ubuntu options.ubuntuFlag options.ubuntuVersion
<> processOSFlag Windows options.windowsFlag options.windowsVersion
if null filteredList
then pure $ Aeson.encode selectedCompilers
else do
let include = PlatformAndVersion <$> filteredList <*> supportedCompilers
"matrix=" <> Aeson.encode (ActionMatrix include)
let include = PlatformAndVersion <$> filteredList <*> selectedCompilers
pure $ "matrix=" <> Aeson.encode (ActionMatrix include)

withInfo :: Parser a -> String -> ParserInfo a
withInfo opts desc = info (helper <*> opts) $ progDesc desc

processOSFlag
:: RunnerOS
-- ^ OS flag we're processing
-> Bool
-- ^ legacy fallback
-> Maybe Text
-- ^ explicit version
-> Vector Text
processOSFlag runnerOS legacyFallback mExplicitVersion =
case mExplicitVersion of
Just explicitVersion -> Vector.singleton (display runnerOS <> "-" <> explicitVersion)
Nothing ->
if legacyFallback
then Vector.singleton $ display runnerOS <> "-latest"
else Vector.empty

checkIncompatibleRelativeOptions
:: (Error ProcessingError :> es)
=> Options
-> Eff es ()
checkIncompatibleRelativeOptions options = do
when (options.newest && options.oldest) $
throwError $
IncompatibleOptions
"--newest"
"--oldest"

runCLIEff
:: Eff [Console, FileSystem, Error ProcessingError, IOE] a
-> IO (Either ProcessingError a)
runCLIEff action = do
action
& Console.runConsole
& FileSystem.runFileSystem
& Error.runErrorNoCallStack
& runEff
23 changes: 21 additions & 2 deletions cabal.project
Original file line number Diff line number Diff line change
@@ -1,14 +1,33 @@
packages: ./

with-compiler: ghc-9.4
with-compiler: ghc-9.10

jobs: 8
optimization: 2

tests: True

semaphore: True

multi-repl: True

allow-newer: all

test-show-details: direct

package *
ghc-options: +RTS -A32m -RTS -j
split-sections: True

allow-newer:
tasty-test-reporter:mtl
, tasty-test-reporter:ansi-terminal
, tasty-test-reporter:text
, tasty-test-reporter:tasty
, tasty-test-reporter:containers
, tasty-test-reporter:filepath
, tasty-test-reporter:base

source-repository-package
type: git
location: https://github.com/goodlyrottenapple/tasty-test-reporter
tag: b704130
9 changes: 9 additions & 0 deletions cabal.release.project
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import: cabal.project

optimization: 2

documentation: False

executable-stripping: True

library-stripping: True
22 changes: 3 additions & 19 deletions cabal.static.project
Original file line number Diff line number Diff line change
@@ -1,20 +1,4 @@
packages: ./

with-compiler: ghc-9.4

jobs: 8

tests: True

allow-newer: all

test-show-details: direct

package *
ghc-options: +RTS -A32m -RTS -j

package get-tested
ghc-options: -static
cc-options: -static
ld-options: -static -pthread
import: ./cabal.release.project

executable-static: true
split-sections: True
116 changes: 81 additions & 35 deletions get-tested.cabal
Original file line number Diff line number Diff line change
@@ -1,68 +1,114 @@
cabal-version: 3.4
name: get-tested
version: 0.1.5.0
version: 0.1.8.1
synopsis: Get the tested-with stanza of your Cabal file

-- description:
homepage: https://github.com/Kleidukos/get-tested
license: BSD-3-Clause
license-file: LICENSE
author: Hécate Moonlight
author: Hécate Kleidukos
maintainer: hecate+github@glitchbra.in
tested-with: GHC ==9.6.2
tested-with: GHC ==9.10.1

-- copyright:
category: Development
build-type: Simple
extra-doc-files: CHANGELOG.md

executable get-tested
main-is: Main.hs
ghc-options:
-Wall -Wcompat -Widentities -Wincomplete-record-updates
-Wincomplete-uni-patterns -Wpartial-fields -Wredundant-constraints
-fhide-source-paths -Wno-unused-do-bind -fshow-hole-constraints
-fprint-potential-instances -Wno-unticked-promoted-constructors
-Werror=unused-imports -flate-specialise -funbox-strict-fields
-finline-generics-aggressively -fexpose-all-unfoldings -threaded
"-with-rtsopts=-N -T"

common extensions
default-extensions:
NoStarIsType
DataKinds
DeriveAnyClass
DerivingStrategies
DerivingVia
DuplicateRecordFields
LambdaCase
OverloadedLabels
NoStarIsType
OverloadedRecordDot
OverloadedStrings
PackageImports
PolyKinds
QuasiQuotes
RecordWildCards
StrictData
TypeFamilies
ViewPatterns

other-modules:
Extract
Types
default-language: GHC2024

common ghc-options
ghc-options:
-Wall -Wcompat -Widentities -Wincomplete-record-updates
-Wincomplete-uni-patterns -Wpartial-fields -Wredundant-constraints
-fhide-source-paths -Wno-unused-do-bind -fshow-hole-constraints
-fprint-potential-instances -Wno-unticked-promoted-constructors
-Werror=unused-imports -flate-specialise -funbox-strict-fields
-finline-generics-aggressively -fexpose-all-unfoldings -threaded
-Wunused-packages

ghc-prof-options: -fprof-auto -fno-prof-count-entries -fprof-auto-calls

common rts-options
ghc-options: -rtsopts -threaded "-with-rtsopts=-N -T"

library
import: extensions
import: ghc-options
hs-source-dirs: src

-- cabal-fmt: expand src/
exposed-modules:
GetTested.CLI.Types
GetTested.Extract
GetTested.Types

build-depends:
, aeson ^>=2.1
, base ^>=4.16
, aeson ^>=2.2
, base ^>=4.19
, bytestring ^>=0.11
, Cabal-syntax ^>=3.10.3
, effectful ^>=2.3
, effectful-core ^>=2.3
, nonempty-vector ^>=0.2.3
, text ^>=2.1
, text-display ^>=0.0.1
, vector ^>=0.13

executable get-tested
import: extensions
import: ghc-options
import: rts-options
main-is: Main.hs
other-modules: Paths_get_tested
build-depends:
, aeson ^>=2.2
, base ^>=4.19
, bytestring ^>=0.11
, Cabal-syntax ^>=3.8
, containers ^>=0.6
, directory ^>=1.3
, effectful-core ^>=2.2
, filepath ^>=1.4
, optparse-applicative ^>=0.17
, text ^>=2.0
, text-display ^>=0.0
, effectful ^>=2.3
, effectful-core ^>=2.3
, get-tested
, optparse-applicative ^>=0.18
, text ^>=2.1
, text-display ^>=0.0.1
, vector ^>=0.13

hs-source-dirs: app
default-language: GHC2021
hs-source-dirs: app

test-suite get-tested-test
import: extensions
import: ghc-options
import: rts-options
type: exitcode-stdio-1.0
hs-source-dirs: test
main-is: Main.hs
other-modules:
ExtractTest
Utils

build-depends:
, base
, Cabal-syntax
, effectful
, effectful-core
, get-tested
, tasty
, tasty-hunit
, tasty-test-reporter
, vector
51 changes: 51 additions & 0 deletions setup-get-tested/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: "Set up get-tested"
description: "Fetches the get-tested tool"

inputs:
version:
description: "The version of the get-tested tool. Defaults to 'latest' if unspecified."
required: false
default: ""
directory:
description: "The directory where the get-tested executable should be placed."
required: false
default: "."

outputs:
path:
description: "The path to the get-tested executable."
value: ${{ steps.setup.outputs.path }}

runs:
using: "composite"
steps:
- name: Set up get-tested
id: setup
shell: bash
env:
GH_TOKEN: ${{ github.token }}
run: |
tmpdir="$(mktemp --directory "${RUNNER_TEMP}/setup-get-tested.XXX")"
trap "rm -rf ${tmpdir}" EXIT
gh_release_flags=(
--repo Kleidukos/get-tested
--pattern 'get-tested-*-Linux-static-x86_64.tar.gz'
--output "${tmpdir}/get-tested.tar.gz"
)
if [[ "${{ inputs.version }}" != "" ]]; then
gh release download "v${{ inputs.version }}" "${gh_release_flags[@]}"
else
gh release download "${gh_release_flags[@]}"
fi
mkdir -p "${{ inputs.directory }}"
tar -x -v -z -f "${tmpdir}/get-tested.tar.gz" -C "${{ inputs.directory }}"
path="${{ inputs.directory }}/get-tested"
chmod a+x "${path}"
echo "path=${path}" >> "${GITHUB_OUTPUT}"
branding:
icon: 'list'
color: 'blue'
16 changes: 16 additions & 0 deletions src/GetTested/CLI/Types.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module GetTested.CLI.Types where

import Data.Text (Text)

data Options = Options
{ path :: FilePath
, macosFlag :: Bool
, macosVersion :: Maybe Text
, ubuntuFlag :: Bool
, ubuntuVersion :: Maybe Text
, windowsFlag :: Bool
, windowsVersion :: Maybe Text
, newest :: Bool
, oldest :: Bool
}
deriving stock (Show, Eq)
111 changes: 111 additions & 0 deletions src/GetTested/Extract.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}

module GetTested.Extract
( loadFile
, extractTestedWith
, filterCompilers
) where

import Control.Monad
import Data.ByteString qualified as BS
import Data.Function ((&))
import Data.Text (Text)
import Data.Text.Display (display)
import Data.Text.Encoding qualified as Text
import Data.Vector (Vector)
import Data.Vector qualified as Vector
import Data.Vector.NonEmpty (NonEmptyVector)
import Data.Vector.NonEmpty qualified as NEVector
import Distribution.Compiler (CompilerFlavor (..))
import Distribution.Fields
import Distribution.PackageDescription
import Distribution.PackageDescription.Parsec
import Distribution.Types.Version (Version)
import Distribution.Types.VersionRange.Internal (VersionRange (..))
import Effectful
import Effectful.Console.ByteString (Console)
import Effectful.Console.ByteString qualified as Console
import Effectful.Error.Static (Error, throwError)
import Effectful.FileSystem (FileSystem)
import Effectful.FileSystem qualified as FileSystem
import Effectful.FileSystem.IO.ByteString qualified as FileSystem

import GetTested.CLI.Types
import GetTested.Types

-- | Loads and parses a Cabal file
loadFile
:: (Console :> es, FileSystem :> es, Error ProcessingError :> es)
=> FilePath
-- ^ The absolute path to the Cabal file
-> Eff es GenericPackageDescription
loadFile path = do
exists <- FileSystem.doesFileExist path
unless exists $
throwError $
CabalFileNotFound path
content <- FileSystem.readFile path
parseString path content

parseString
:: (Console :> es, Error ProcessingError :> es)
=> String
-- ^ File name
-> BS.ByteString
-> Eff es GenericPackageDescription
parseString name bs = do
let (_warnings, result) = runParseResult (parseGenericPackageDescription bs)
case result of
Right x -> pure x
Left err -> do
logAttention (display $ show err)
throwError $ CabalFileCouldNotBeParsed name

extractTestedWith
:: (Error ProcessingError :> es)
=> FilePath
-> GenericPackageDescription
-> Eff es (NonEmptyVector Version)
extractTestedWith path genericPackageDescription = do
let exactVersions =
Vector.fromList genericPackageDescription.packageDescription.testedWith
& Vector.filter (\(flavour, _) -> flavour == GHC)
& expandUnionVersionRanges
& Vector.filter (\(_, versionRange) -> isExactVersion versionRange)
case NEVector.fromVector exactVersions of
Nothing ->
throwError $ NoCompilerVersionsFound path
Just compilers ->
pure $
compilers
& NEVector.map (\(flavour, ThisVersion version) -> (flavour, version))
& NEVector.map snd

isExactVersion :: VersionRange -> Bool
isExactVersion (ThisVersion _) = True
isExactVersion _ = False

logAttention :: (Console :> es) => Text -> Eff es ()
logAttention message = Console.putStrLn $ Text.encodeUtf8 message

expandUnionVersionRanges
:: Vector (CompilerFlavor, VersionRange)
-> Vector (CompilerFlavor, VersionRange)
expandUnionVersionRanges ranges =
Vector.concatMap
( \(f, range) ->
let expandedVersions = expandUnionVersionRange range
in Vector.map (\v -> (f, v)) expandedVersions

Check warning on line 98 in src/GetTested/Extract.hs

GitHub Actions / hlint

Suggestion in expandUnionVersionRanges in module GetTested.Extract: Use tuple-section ▫︎ Found: "\\ v -> (f, v)" ▫︎ Perhaps: "(f,)" ▫︎ Note: may require `{-# LANGUAGE TupleSections #-}` adding to the top of the file
)
ranges

expandUnionVersionRange :: VersionRange -> Vector VersionRange
expandUnionVersionRange (ThisVersion v) = Vector.singleton (ThisVersion v)
expandUnionVersionRange (UnionVersionRanges r1 r2) = expandUnionVersionRange r1 <> expandUnionVersionRange r2
expandUnionVersionRange _ = Vector.empty

filterCompilers :: Options -> NonEmptyVector Version -> Vector Version
filterCompilers options supportedCompilers
| options.newest = Vector.generate 1 $ const $ NEVector.maximum supportedCompilers
| options.oldest = Vector.generate 1 $ const $ NEVector.minimum supportedCompilers
| otherwise = NEVector.toVector supportedCompilers
15 changes: 14 additions & 1 deletion app/Types.hs → src/GetTested/Types.hs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{-# OPTIONS_GHC -Wno-orphans #-}

module Types where
module GetTested.Types where

import Data.Aeson
import Data.Text (Text)
@@ -19,11 +19,24 @@ import GHC.Generics (Generic)
data ProcessingError
= CabalFileNotFound FilePath
| CabalFileCouldNotBeParsed FilePath
| NoCompilerVersionsFound FilePath
| IncompatibleOptions Text Text
deriving stock (Eq, Ord, Show)
deriving
(Display)
via ShowInstance ProcessingError

data RunnerOS
= Ubuntu
| Windows
| MacOS
deriving stock (Eq, Ord, Show)

instance Display RunnerOS where
displayBuilder Ubuntu = "ubuntu"
displayBuilder Windows = "windows"
displayBuilder MacOS = "macos"

instance ToJSON CompilerFlavor where
toJSON = toJSON . Pretty.prettyShow

63 changes: 63 additions & 0 deletions test/ExtractTest.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
module ExtractTest where

import Data.Vector qualified as Vector
import Distribution.Types.Version qualified as Version
import Test.Tasty (TestTree)

import GetTested.CLI.Types
import GetTested.Extract qualified as Extract
import Utils

spec :: TestEff TestTree
spec =
testThese
"Symlink Checks"
[ testThis "Filter the newest compiler" testFilteringNewestCompiler
, testThis "Filter the oldest compiler" testFilteringOldestCompiler
]

testFilteringNewestCompiler :: TestEff ()
testFilteringNewestCompiler = do
let options =
Options
{ path = "./test/fixtures/one.cabal"
, macosFlag = False
, macosVersion = Nothing
, ubuntuFlag = False
, ubuntuVersion = Just "latest"
, windowsFlag = False
, windowsVersion = Nothing
, newest = True
, oldest = False
}
genericPackageDescription <- Extract.loadFile "./test/fixtures/one.cabal"
result <-
Extract.filterCompilers options
<$> Extract.extractTestedWith options.path genericPackageDescription
assertEqual
""
(Vector.singleton $ Version.mkVersion [9, 10, 1])
result

testFilteringOldestCompiler :: TestEff ()
testFilteringOldestCompiler = do
let options =
Options
{ path = "./test/fixtures/one.cabal"
, macosFlag = False
, macosVersion = Nothing
, ubuntuFlag = False
, ubuntuVersion = Just "latest"
, windowsFlag = False
, windowsVersion = Nothing
, newest = False
, oldest = True
}
genericPackageDescription <- Extract.loadFile "./test/fixtures/one.cabal"
result <-
Extract.filterCompilers options
<$> Extract.extractTestedWith options.path genericPackageDescription
assertEqual
""
(Vector.singleton $ Version.mkVersion [8, 10, 7])
result
24 changes: 24 additions & 0 deletions test/Main.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
module Main (main) where

import GHC.List (List)
import System.IO
import Test.Tasty
import Test.Tasty.Runners.Reporter qualified as Reporter

import ExtractTest qualified
import Utils

main :: IO ()
main = do
hSetBuffering stdout LineBuffering
spec <- traverse (\comp -> runTestEff comp) specs
defaultMainWithIngredients
[Reporter.ingredient]
$ testGroup
"Confer Tests"
spec

specs :: List (TestEff TestTree)
specs =
[ ExtractTest.spec
]
58 changes: 58 additions & 0 deletions test/Utils.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
module Utils where

import Data.Function ((&))
import Effectful
import Effectful.Console.ByteString (Console)
import Effectful.Console.ByteString qualified as Console
import Effectful.Error.Static (Error)
import Effectful.Error.Static qualified as Error
import Effectful.FileSystem (FileSystem)
import Effectful.FileSystem qualified as FileSystem
import GHC.Stack
import Test.Tasty (TestTree)
import Test.Tasty qualified as Test
import Test.Tasty.HUnit qualified as Test

import GetTested.Types

type TestEff =
Eff [Console, FileSystem, Error ProcessingError, IOE]

runTestEff
:: Eff [Console, FileSystem, Error ProcessingError, IOE] a
-> IO a
runTestEff action = do
result <-
action
& Console.runConsole
& FileSystem.runFileSystem
& Error.runErrorNoCallStack
& runEff
case result of
Left e -> Test.assertFailure $ show e
Right a -> pure a

testThis :: String -> TestEff () -> TestEff TestTree
testThis name assertion = do
let test = runTestEff assertion
pure $
Test.testCase name test

testThese :: String -> [TestEff TestTree] -> TestEff TestTree
testThese groupName tests = fmap (Test.testGroup groupName) newTests
where
newTests :: TestEff [TestTree]
newTests = sequenceA tests

assertBool :: Bool -> TestEff ()
assertBool boolean = liftIO $ Test.assertBool "" boolean

assertEqual
:: (Eq a, Show a, HasCallStack)
=> String
-> a
-- ^ Expected
-> a
-- ^ Actual
-> TestEff ()
assertEqual label expected actual = liftIO $ Test.assertEqual label expected actual
9 changes: 9 additions & 0 deletions test/fixtures/one.cabal
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
cabal-version: 3.4
name: one
version: 0.1.0.0
license: BSD-3-Clause
license-file: LICENSE
author: Hécate Kleidukos
maintainer: hecate+github@glitchbra.in
tested-with: GHC ==9.10.1 || ==8.10.7 || ==9.6.6