diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..dfd0e30 --- /dev/null +++ b/.github/dependabot.yml @@ -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" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..05c1d31 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,168 @@ +name: Tests Pipeline + +on: + push: + branches: ['main'] + +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: dump-decls.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) }} + steps: + - name: Checkout base repo + uses: actions/checkout@v4 + - name: "Install tools" + run: | + .github/workflows/install-tools.sh + - 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 ${{ env.ARCH }} + cabal configure --enable-tests + - name: Freeze + run: cabal freeze --project-file=cabal.release.project + - name: Cache + uses: actions/cache@v4.0.2 + with: + path: ${{ steps.setup-haskell.outputs.cabal-store }} + key: ${{ runner.os }}-ghc-${{ matrix.ghc }}-${{ hashFiles('**/plan.json') }} + restore-keys: ${{ runner.os }}-ghc-${{ matrix.ghc }}- + + - name: Build + run: cabal build --project-file=cabal.release.project + + - name: Install + run: | + bin=$(cabal -v0 --project-file=cabal.static.project list-bin dump-decls) + mkdir distribution + cp ${bin} distribution/dump-decls + + - name: File type + run: file distribution/dump-decls + + - name: Package the dump-decls executable + run: | + GETTESTED_EXEC=distribution/dump-decls + .github/workflows/process-binaries.sh + DIR=$(dirname $GETTESTED_EXEC) + FILE=$(basename $GETTESTED_EXEC) + GETTESTED_EXEC_TAR=dump-decls-head-${{ runner.os }}-${{ env.ARCH }}.tar.gz + tar -czvf $GETTESTED_EXEC_TAR -C $DIR $FILE + echo GETTESTED_EXEC_TAR=$GETTESTED_EXEC_TAR >> $GITHUB_ENV + - name: Upload the dump-decls executable + uses: actions/upload-artifact@v3 + with: + name: artifact + path: ${{ env.GETTESTED_EXEC_TAR }} + + build-alpine: + name: 9.10.1 on alpine-3.19 + runs-on: ubuntu-latest + container: 'alpine:3.19' + 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: | + ARCHITECTURE=$(uname -m) + echo "ARCH=$ARCHITECTURE" >> $GITHUB_ENV + echo ${{ env.ARCH }} + cabal configure --enable-tests + + - name: Freeze + run: cabal freeze --project-file=cabal.static.project + + - uses: actions/cache@v4 + with: + path: ${{ steps.setup-haskell.outputs.cabal-store }} + key: ${{ runner.os }}-ghc-${{ steps.setup.outputs.ghc-version }}-${{ hashFiles('**/plan.json') }} + restore-keys: ${{ runner.os }}-${{ steps.setup.outputs.ghc-version }}- + + - name: Build + run: cabal build --project-file=cabal.static.project + + - name: Test + run: cabal test --project-file=cabal.static.project all + + - name: Install + run: | + bin=$(cabal -v0 --project-file=cabal.static.project list-bin dump-decls) + mkdir distribution + cp ${bin} distribution/dump-decls + + - name: File type + run: file distribution/dump-decls + + - name: Tar dump-decls executable + run: | + GETTESTED_EXEC=distribution/dump-decls + .github/workflows/process-binaries.sh + DIR=$(dirname $GETTESTED_EXEC) + FILE=$(basename $GETTESTED_EXEC) + GETTESTED_EXEC_TAR=dump-decls-head-${{ runner.os }}-static-${{ env.ARCH }}.tar.gz + tar -czvf $GETTESTED_EXEC_TAR -C $DIR $FILE + echo GETTESTED_EXEC_TAR=$GETTESTED_EXEC_TAR >> $GITHUB_ENV + + - name: Upload dump-decls executable to workflow artifacts + uses: actions/upload-artifact@v3 + with: + name: artifact + path: ${{ env.GETTESTED_EXEC_TAR }} + + prerelease-head: + name: Create a GitHub prerelease with the binary artifacts + runs-on: ubuntu-latest + needs: ['tests', 'build-alpine'] + + steps: + - uses: actions/download-artifact@v3 + with: + name: artifact + path: ./out + + - name: Release + uses: softprops/action-gh-release@v2 + if: startsWith(github.ref, 'refs/tags/') + with: + draft: true + files: ./out/* diff --git a/.github/workflows/install-tools.sh b/.github/workflows/install-tools.sh new file mode 100755 index 0000000..c7b613d --- /dev/null +++ b/.github/workflows/install-tools.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +case "$(uname -s)" in + Linux*) sudo apt install upx-ucl;; + Darwin*) exit 0;; +esac diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml new file mode 100644 index 0000000..88ea62e --- /dev/null +++ b/.github/workflows/linting.yml @@ -0,0 +1,35 @@ +name: Linting + +on: + pull_request: + push: + branches: ["main"] + +jobs: + fourmolu: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: fourmolu/fourmolu-action@v10 + with: + pattern: | + app/**/*.hs + src/**/*.hs + + hlint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: 'Set up HLint' + uses: haskell-actions/hlint-setup@v2 + with: + version: '3.8' + + - name: 'Run HLint' + uses: haskell-actions/hlint-run@v2 + with: + path: '["app, src"]' + fail-on: warning + diff --git a/.github/workflows/process-binaries.sh b/.github/workflows/process-binaries.sh new file mode 100755 index 0000000..80e246f --- /dev/null +++ b/.github/workflows/process-binaries.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +GETTESTED_PATH="distribution/dump-decls" + +case "$(uname -s)" in + Linux*) + strip $GETTESTED_PATH + upx -9 $GETTESTED_PATH + ;; + Darwin*) + echo "upx crashes on macOS Ventura and above" ;; +esac diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..50558f5 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,173 @@ +name: Release Pipeline + +on: + push: + branches: ['main'] + tags: + - "v*" + +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: dump-decls.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) }} + steps: + - name: Checkout base repo + uses: actions/checkout@v4 + - name: "Install tools" + run: | + .github/workflows/install-tools.sh + - 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 ${{ env.ARCH }} + cabal configure --enable-tests + - name: Freeze + run: cabal freeze --project-file=cabal.release.project + - name: Cache + uses: actions/cache@v4.0.2 + with: + path: ${{ steps.setup-haskell.outputs.cabal-store }} + key: ${{ runner.os }}-ghc-${{ matrix.ghc }}-${{ hashFiles('**/plan.json') }} + restore-keys: ${{ runner.os }}-ghc-${{ matrix.ghc }}- + + - name: Build + run: cabal build --project-file=cabal.release.project + + - name: Install + run: | + bin=$(cabal -v0 --project-file=cabal.static.project list-bin dump-decls) + mkdir distribution + cp ${bin} distribution/dump-decls + + - name: File type + run: file distribution/dump-decls + + - name: Package the dump-decls executable + run: | + GETTESTED_EXEC=distribution/dump-decls + .github/workflows/process-binaries.sh + DIR=$(dirname $GETTESTED_EXEC) + FILE=$(basename $GETTESTED_EXEC) + version=$(./distribution/dump-decls --version) + GETTESTED_EXEC_TAR=dump-decls-${version}-${{ runner.os }}-${{ env.ARCH }}.tar.gz + tar -czvf $GETTESTED_EXEC_TAR -C $DIR $FILE + echo GETTESTED_EXEC_TAR=$GETTESTED_EXEC_TAR >> $GITHUB_ENV + - name: Upload the dump-decls executable + uses: actions/upload-artifact@v3 + with: + name: artifact + path: ${{ env.GETTESTED_EXEC_TAR }} + + build-alpine: + name: 9.10.1 on alpine-3.19 + runs-on: ubuntu-latest + container: 'alpine:3.19' + 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: | + ARCHITECTURE=$(uname -m) + echo "ARCH=$ARCHITECTURE" >> $GITHUB_ENV + echo ${{ env.ARCH }} + cabal configure --enable-tests + + - name: Freeze + run: cabal freeze --project-file=cabal.static.project + + - uses: actions/cache@v4 + with: + path: ${{ steps.setup-haskell.outputs.cabal-store }} + key: ${{ runner.os }}-ghc-${{ steps.setup.outputs.ghc-version }}-${{ hashFiles('**/plan.json') }} + restore-keys: ${{ runner.os }}-${{ steps.setup.outputs.ghc-version }}- + + - name: Build + run: cabal build --project-file=cabal.static.project + + - name: Test + run: cabal test --project-file=cabal.static.project all + + - name: Install + run: | + bin=$(cabal -v0 --project-file=cabal.static.project list-bin dump-decls) + mkdir distribution + cp ${bin} distribution/dump-decls + + - name: File type + run: file distribution/dump-decls + + - name: Package the dump-decls executable + run: | + GETTESTED_EXEC=distribution/dump-decls + .github/workflows/process-binaries.sh + DIR=$(dirname $GETTESTED_EXEC) + FILE=$(basename $GETTESTED_EXEC) + version=$(./distribution/dump-decls --version) + GETTESTED_EXEC_TAR=dump-decls-${version}-${{ runner.os }}-static-${{ env.ARCH }}.tar.gz + tar -czvf $GETTESTED_EXEC_TAR -C $DIR $FILE + echo GETTESTED_EXEC_TAR=$GETTESTED_EXEC_TAR >> $GITHUB_ENV + + - name: Upload dump-decls executable to workflow artifacts + uses: actions/upload-artifact@v3 + with: + name: artifact + path: ${{ env.GETTESTED_EXEC_TAR }} + + release: + name: Create a GitHub Release with the binary artifacts + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/v') + needs: ['tests', 'build-alpine'] + + steps: + - uses: actions/download-artifact@v3 + with: + name: artifact + path: ./out + + - name: Release + uses: softprops/action-gh-release@v2 + if: startsWith(github.ref, 'refs/tags/') + with: + draft: true + files: ./out/*