Skip to content

Sean/mandatory kinds #15

Sean/mandatory kinds

Sean/mandatory kinds #15

Workflow file for this run

name: "CI"
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
paths:
- .github/workflows/**/*.yml
- app/**/*
- bundle/**/*
- ci/**/*
- license-generator/**/*
- src/**/*
- test/**/*
- .gitignore
- .hlint.yaml
- .hspec
- cabal.project
- purescript.cabal
- Setup.hs
- stack.yaml
- update-changelog.hs
- weeder.dhall
release:
types: [ "published" ]
defaults:
run:
shell: "bash"
env:
CI_PRERELEASE: "${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}"
CI_RELEASE: "${{ github.event_name == 'release' }}"
STACK_VERSION: "2.9.3"
concurrency:
# We never want two prereleases building at the same time, since they would
# likely both claim the same version number. Pull request builds can happen
# in parallel with anything else, since they don't mutate global state with a
# release. Release builds don't change their behavior based on published
# state, so they don't interfere with each other and there's no point in
# canceling a prerelease build if a release build starts; and we would never
# want a release build to be canceled by a prerelease build either. (GitHub
# Actions is either too cheap to give us `if` expressions or too lazy to
# document them, but we have untyped boolean operators to fall back on.)
group: "${{ github.event_name != 'push' && github.run_id || 'continuous-deployment' }}"
cancel-in-progress: true
jobs:
build:
strategy:
fail-fast: false # do not cancel builds for other OSes if one fails
matrix:
include:
- # If upgrading the Haskell image, also upgrade it in the lint job below
os: ["ubuntu-latest"]
image: haskell:9.2.5@sha256:2597b0e2458165a6635906204f7fac43c22e7d2a46aca1235a811194bb6cd419
- os: ["macOS-11"]
- os: ["windows-2019"]
- os: ["self-hosted", "macos", "ARM64"]
- os: ["self-hosted", "Linux", "ARM64"]
runs-on: "${{ matrix.os }}"
container: "${{ matrix.image }}"
outputs:
do-not-prerelease: "${{ steps.build.outputs.do-not-prerelease }}"
version: "${{ steps.build.outputs.version }}"
steps:
- # We need a proper Git repository, but the checkout step will unpack a tarball instead of doing a clone
# if the Git version is less than 2.18.
name: "(Linux only) Install a newer version of Git"
if: "contains(matrix.os, 'ubuntu-latest')"
run: |
. /etc/os-release
echo deb http://deb.debian.org/debian "$VERSION_CODENAME"-backports main >> /etc/apt/sources.list
apt-get update && apt-get install -y git/"$VERSION_CODENAME"-backports
- # We need `gh` installed on the Linux version. Otherwise, release artifacts won't be uploaded.
name: "(Linux only) Install gh"
if: "contains(matrix.os, 'ubuntu-latest')"
run: |
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg
chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null
apt-get update
apt-get install gh
- uses: "actions/checkout@v2"
- uses: "actions/setup-node@v2"
with:
node-version: "16"
- id: "haskell"
name: "(Non-Linux only) Install Haskell"
# Note: here we exclude the self-hosted runners because this action does not work on ARM
# and their Haskell environment is instead provided by a nix-shell
# See https://github.com/purescript/purescript/pulls/4455
if: "!contains(matrix.os, 'ubuntu-latest') && !contains(matrix.os, 'self-hosted')"
uses: "haskell/actions/setup@v1"
with:
enable-stack: true
stack-version: "${{ env.STACK_VERSION }}"
stack-no-global: true
- name: "(Linux only) Check Stack version and fix working directory ownership"
if: "contains(matrix.os, 'ubuntu-latest')"
run: |
[ "$(stack --numeric-version)" = "$STACK_VERSION" ]
chown root:root .
- uses: "actions/cache@v2"
with:
path: |
/root/.stack
${{ steps.haskell.outputs.stack-root }}
key: "${{ matrix.image || runner.os }}--MdyPsf-${{ hashFiles('stack.yaml') }}"
- name: "(Windows only) Configure Stack to store its programs in STACK_ROOT"
# This ensures that the local GHC and MSYS binaries that Stack installs
# are included in the cache. (This behavior is the default on
# non-Windows OSes.)
if: "${{ runner.os == 'Windows' }}"
run: |
mkdir -p "$STACK_ROOT"
echo "local-programs-path: $STACK_ROOT/programs" > $STACK_ROOT/config.yaml
- id: "build"
run: "ci/fix-home ci/build.sh"
- name: "(Linux only) Build the entire package set"
if: "contains(matrix.os, 'ubuntu-latest')"
# We build in this directory in build.sh, so this is where we need to
# launch `stack exec`. The actual package-set building happens in a
# temporary directory.
working-directory: "sdist-test"
# The presence or absence of the --haddock flag changes the location
# into which stack places all build artifacts. Since we use --haddock
# in our CI builds, in order to actually get stack to find the purs
# binary it created, we need to use the flag here as well.
#
# Moreover, npm has a hook issue that will cause spago to fail to install
# We upgrade npm to fix this
run: |
npm i -g [email protected]
../ci/fix-home stack --haddock exec ../ci/build-package-set.sh
- name: Verify that 'libtinfo' isn't in binary
if: "runner.os == 'Linux'"
working-directory: "sdist-test"
run: |
if [ $(ldd $(../ci/fix-home stack path --local-doc-root)/../bin/purs | grep 'libtinfo' | wc -l) -ge 1 ]; then
echo "libtinfo detected"
ldd $(../ci/fix-home stack path --local-doc-root)/../bin/purs | grep 'libtinfo'
exit 1
fi
- name: "(Self-hosted Linux ARM64 only) Patch the binary to work on non-Nix systems"
if: "runner.os == 'Linux' && runner.arch == 'ARM64'"
working-directory: "sdist-test"
# The self-hosted build happens inside a nix-shell that provides a working stack binary
# on ARM systems, and while the macOS binary is fine - because macOS binaries are almost
# statically linked), the linux ones are all pointing at the nix store.
# So here we first point the binary to the right linker that should work on a generic linux,
# and then fix the RUNPATH with the right location to load the shared libraries from
run: |
patchelf --set-interpreter /usr/lib/ld-linux-aarch64.so.1 --set-rpath /usr/lib/aarch64-linux-gnu $(stack path --local-doc-root)/../bin/purs
- name: "(Release/prerelease only) Create bundle"
if: "${{ env.CI_RELEASE == 'true' || env.CI_PRERELEASE == 'true' && steps.build.outputs.do-not-prerelease != 'true' }}"
run: |
os_name="${{ runner.os }}"
os_arch="${{ runner.arch }}"
case "$os_name" in
Linux)
case "$os_arch" in
ARM64)
bundle_os=linux-arm64;;
*)
bundle_os=linux64;;
esac;;
macOS)
case "$os_arch" in
ARM64)
bundle_os=macos-arm64;;
*)
bundle_os=macos;;
esac;;
Windows)
bundle_os=win64;;
*)
echo "Unknown OS name: $os_name"
exit 1;;
esac
cd sdist-test
../ci/fix-home bundle/build.sh "$bundle_os"
- name: "(Prerelease only) Upload bundle"
if: "${{ env.CI_PRERELEASE == 'true' && steps.build.outputs.do-not-prerelease != 'true' }}"
uses: "actions/upload-artifact@v3"
with:
name: "${{ runner.os }}-${{ runner.arch }}-bundle"
path: |
sdist-test/bundle/*.sha
sdist-test/bundle/*.tar.gz
- name: "(Release only) Publish bundle"
if: "${{ env.CI_RELEASE == 'true' }}"
# This requires the gh command line tool to be installed on our
# self-hosted runners
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
run: "gh release upload --clobber ${{ github.ref_name }} sdist-test/bundle/*.{tar.gz,sha}"
lint:
runs-on: "ubuntu-latest"
# At the moment, this is a different image from the image used for
# compilation, though the GHC versions match. This is because the
# compilation image uses an old version of glibc, which we want because it
# means our published binaries will work on the widest number of platforms.
# But the HLint binary downloaded by this job requires a newer glibc
# version.
container: haskell:9.2.5@sha256:2597b0e2458165a6635906204f7fac43c22e7d2a46aca1235a811194bb6cd419
steps:
- # We need a proper Git repository, but the checkout step will unpack a tarball instead of doing a clone
# if the Git version is less than 2.18.
name: "Install a newer version of Git"
run: |
. /etc/os-release
echo deb http://deb.debian.org/debian "$VERSION_CODENAME"-backports main >> /etc/apt/sources.list
apt-get update && apt-get install -y git/"$VERSION_CODENAME"-backports
- uses: "actions/checkout@v2"
- name: "Fix working directory ownership"
run: |
chown root:root .
- uses: "actions/cache@v2"
with:
path: |
/root/.stack
key: "lint-${{ hashFiles('stack.yaml') }}"
- run: "ci/fix-home ci/run-hlint.sh --git"
env:
VERSION: "3.5"
# Note: the weeder version will need to be updated when we next update our version
# of GHC.
#
# weeder-2.2.0 has somewhat strange version deps. It doesn't appear to
# support the exact versions of dhall and generic-lens in LTS-18.
# However, forcing it to use the versions of dhall and generic-lens in
# LTS-18 doesn't cause any problems when building, so the following
# commands build weeder while ignoring version constraints.
- name: Install weeder
run: |
# The `stack.yaml` file is copied to a separate file so that
# adding `allow-newer: true` doesn't affect any subsequant
# calls to `stack`.
cp stack.yaml stack-weeder.yaml
# `allow-newer: true` is needed so that weeder-2.2.0 can be
# installed with the dependencies present in LTS-18.
echo 'allow-newer: true' >> stack-weeder.yaml
ci/fix-home stack --no-terminal --jobs=2 build --copy-compiler-tool --stack-yaml ./stack-weeder.yaml weeder-2.4.0
- run: "ci/fix-home stack --no-terminal --jobs=2 build --fast --ghc-options -fwrite-ide-info"
- run: "ci/fix-home stack exec weeder"
# Now do it again, with the test suite included. We don't want a
# reference from our test suite to count in the above check; the fact
# that a function is tested is not evidence that it's needed. But we also
# don't want to leave weeds lying around in our test suite either.
- run: "ci/fix-home stack --no-terminal --jobs=2 build --fast --test --no-run-tests --ghc-options -fwrite-ide-info"
- run: "ci/fix-home stack exec weeder"
make-prerelease:
runs-on: "ubuntu-latest"
needs:
- "build"
- "lint"
if: "${{ github.event_name == 'push' && needs.build.outputs.do-not-prerelease != 'true' }}"
steps:
- uses: "actions/download-artifact@v3"
- uses: "ncipollo/[email protected]"
with:
tag: "v${{ needs.build.outputs.version }}"
artifacts: "*-bundle/*"
prerelease: true
body: "This is an automated preview release. Get the latest stable release [here](https://github.com/purescript/purescript/releases/latest)."
- uses: "actions/checkout@v3"
- uses: "actions/setup-node@v3"
with:
node-version: "16.x"
registry-url: "https://registry.npmjs.org"
- name: "Publish npm package"
working-directory: "npm-package"
env:
BUILD_VERSION: "${{ needs.build.outputs.version }}"
NODE_AUTH_TOKEN: "${{ secrets.NPM_TOKEN }}"
run: |
src_version=$(node -pe 'require("./package.json").version')
npm version --allow-same-version "$BUILD_VERSION"
sed -i -e "s/--purs-ver=${src_version//./\\.}/--purs-ver=$BUILD_VERSION/" package.json
npm publish --tag next