Skip to content

Commit

Permalink
attempt to use local actions
Browse files Browse the repository at this point in the history
Extremely experimental, and with all the limitations and
restrictions I keep finding in GitHub Actions it'll probably fail
in the messiest way it can.

At present this is incomplete but sufficient to see if this has
any chance of working to begin with. If it somehow does, I'll
look into abstracting out the other sub-jobs, then making an
overnight validate for Tier 2 platforms and probably a prerelease
job (which would fix the recently revealed problem where if there
is no need to rebase on merge, no prerelease is made).
  • Loading branch information
geekosaur committed Nov 2, 2024
1 parent 9e2b2db commit 5420578
Show file tree
Hide file tree
Showing 5 changed files with 418 additions and 273 deletions.
161 changes: 161 additions & 0 deletions .github/actions/cabal-setup/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
name: Cabal setup
description: Set up a workflow for Cabal

inputs:
ghc:
description: ghc version to use
required: true
extra-ghc:
description: additional ghc for tests
required: false
default: ''
allow-newer:
description: allow-newer line
required: false
default: ''
constraints:
description: constraints line
required: false
default: ''
static:
description: whether to build statically
required: false
default: 'false'
shell:
description: shell to use
required: false
default: 'bash'
with_cache:
description: whether to instantiate cache
required: false
default: 'true'

outputs:
ghc-exe:
description: Path to ghc installed by setup-haskell
value: ${{ steps.setup-haskell.outputs.ghc-exe }}

runs:
using: composite
steps:
- name: Make sure ghc is specified
if: inputs.ghc == ''
shell: ${{ inputs.shell }}
run: exit 1

- name: Work around existence of XDG directories (haskell-actions/setup#62)
if: runner.os == 'macOS'
shell: ${{ inputs.shell }}
run: |
rm -rf ~/.config/cabal
rm -rf ~/.cache/cabal
- name: "WIN: Setup TMP environment variable"
if: runner.os == 'Windows'
shell: ${{ inputs.shell }}
run: |
echo "TMP=${{ runner.temp }}" >> "$GITHUB_ENV"
# See https://github.com/haskell/cabal/blob/master/CONTRIBUTING.md#hackage-revisions
- name: Add manually supplied allow-newer
if: inputs.allow-newer != ''
shell: ${{ inputs.shell }}
run: |
echo "allow-newer: ${{ inputs.allow-newer }}" >> cabal.validate.project
- name: Add manually supplied constraints
if: inputs.constraints != ''
shell: ${{ inputs.shell }}
run: |
echo "constraints: ${{ inputs.constraints }}" >> cabal.validate.project
- name: Enable statically linked executables
if: inputs.static == 'true'
shell: ${{ inputs.shell }}
run: |
echo 'executable-static: true' >> cabal.validate.project
# must happen before the main setup so the correct ghc is default
# hm, but what if setup-haskell needs to install ghcup?
- name: Install extra ghc for tests
if: inputs.extra_ghc != ''
shell: ${{ inputs.shell }}
run: |
ghcup install ghc ${{ inputs.extra_ghc }}
- uses: haskell-actions/setup@v2
id: setup-haskell
with:
ghc-version: ${{ inputs.ghc }}
cabal-version: 3.12.1.0 # see https://github.com/haskell/cabal/pull/10251
ghcup-release-channel: https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-prereleases-0.0.8.yaml

# See the following link for a breakdown of the following step
# https://github.com/haskell/actions/issues/7#issuecomment-745697160
- uses: actions/cache@v4
if: inputs.with_cache != 'false'
with:
# validate.sh uses a special build dir
path: |
${{ steps.setup-haskell.outputs.cabal-store }}
dist-*
key: ${{ runner.os }}-${{ inputs.ghc }}-${{ github.sha }}
restore-keys: ${{ runner.os }}-${{ inputs.ghc }}-

# The tool is not essential to the rest of the test suite. If
# hackage-repo-tool is not present, any test that requires it will
# be skipped.
# We want to keep this in the loop but we don't want to fail if
# hackage-repo-tool breaks or fails to support a newer GHC version.
- name: Install hackage-repo-tool
continue-on-error: true
shell: ${{ inputs.shell }}
run: |
cabal install --ignore-project hackage-repo-tool
# Needed by cabal-testsuite/PackageTests/Configure/setup.test.hs
- name: "MAC: Install Autotools"
if: runner.os == 'macOS'
shell: ${{ inputs.shell }}
run: |
brew install automake
# Needed by cabal-testsuite/PackageTests/Configure/setup.test.hs
- name: "WIN: Install Autotools"
if: runner.os == 'Windows'
shell: ${{ inputs.shell }}
run: |
/usr/bin/pacman --noconfirm -S autotools
- name: Set validate inputs
shell: ${{ inputs.shell }}
run: |
FLAGS="$COMMON_FLAGS"
if [[ "${{ inputs.ghc }}" == "$GHC_FOR_SOLVER_BENCHMARKS" ]]; then
FLAGS="$FLAGS --solver-benchmarks"
fi
if [[ "${{ matrix.ghc }}" == "$GHC_FOR_COMPLETE_HACKAGE_TESTS" ]]; then
FLAGS="$FLAGS --complete-hackage-tests"
fi
echo "FLAGS=$FLAGS" >> "$GITHUB_ENV"
- name: Validate print-config
shell: ${{ inputs.shell }}
run: |
sh validate.sh $FLAGS -s print-config
- name: Validate print-tool-versions
shell: ${{ inputs.shell }}
run: |
sh validate.sh $FLAGS -s print-tool-versions
- name: Canonicalize architecture
shell: ${{ inputs.shell }}
run: |
case ${{ runner.arch }} in
X86) arch=i386 ;;
X64) arch=x86_64 ;;
ARM64) arch=aarch64 ;;
*) echo "Unsupported architecture, please fix validate.yaml" 2>/dev/null; exit 1 ;;
esac
echo "CABAL_ARCH=$arch" >> "$GITHUB_ENV"
145 changes: 145 additions & 0 deletions .github/actions/validate-full/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
name: Validate full
description: Run a full validate on a ghc version
inputs:
ghc:
description: ghc version to use
required: true
allow-newer:
description: allow-newer line
required: false
constraints:
description: constraints line
required: false
static:
description: whether to build statically
required: false
default: 'false'
shell:
description: shell to use
required: false
default: 'bash'
with_cache:
description: whether to instantiate cache
required: false
default: 'true'

runs:
using: composite
steps:
- uses: ./.github/actions/cabal-setup
id: cabal-setup
with:
shell: ${{ inputs.shell }}
ghc: ${{ inputs.ghc }}
allow-newer: ${{ inputs.allow-newer }}
constraints: ${{ inputs.constraints }}
static: ${{ inputs.static }}
with_cache: ${{ inputs.with_cache }}

- name: Validate build
shell: ${{ inputs.shell }}
run: |
echo ::group::Build
sh validate.sh $FLAGS -s build
- name: Tar cabal head executable
if: matrix.ghc == env.GHC_FOR_RELEASE
shell: ${{ inputs.shell }}
run: |
echo ::group::Tar
CABAL_EXEC=$(cabal list-bin --builddir=dist-newstyle-validate-ghc-${{ matrix.ghc }} --project-file=cabal.validate.project cabal-install:exe:cabal)
# We have to tar the executable to preserve executable permissions
# see https://github.com/actions/upload-artifact/issues/38
if [[ "${{ runner.os }}" == "Windows" ]]; then
# `cabal list-bin` gives us a windows path but tar needs the posix one
CABAL_EXEC=$(cygpath "$CABAL_EXEC")
fi
if [[ "${{ runner.os }}" == "macOS" ]]; then
# Workaround to avoid bsdtar corrupting the executable
# such that executing it after untar throws `cannot execute binary file`
# see https://github.com/actions/virtual-environments/issues/2619#issuecomment-788397841
sudo /usr/sbin/purge
fi
DIR=$(dirname "$CABAL_EXEC")
FILE=$(basename "$CABAL_EXEC")
CABAL_EXEC_TAR="cabal-head-${{ runner.os }}-$CABAL_ARCH.tar.gz"
tar -czvf "$CABAL_EXEC_TAR" -C "$DIR" "$FILE"
echo "CABAL_EXEC_TAR=$CABAL_EXEC_TAR" >> "$GITHUB_ENV"
# We upload the cabal executable built with the ghc used in the release for:
# - Reuse it in the dogfooding job (although we could use the cached build dir)
# - Make it available in the workflow to make easier testing it locally
- name: Upload cabal-install executable to workflow artifacts
if: inputs.ghc == env.GHC_FOR_RELEASE
uses: actions/upload-artifact@v4
with:
name: cabal-${{ runner.os }}-${{ env.CABAL_ARCH }}
path: ${{ env.CABAL_EXEC_TAR }}

# We want all the tests to be run even if one fails, but we want to fail the validate
# if any of them fail. It turns out that there is a way to get at the outcome of a step
# before `continue-on-error`` is applied, so the last step uses that.
#
# Note that we can't use filter syntax to look for any such failure, because the
# hackage-repo-tool install is also `continue-on-error` and its failure is legitimate
# (see the comment there). So the final step must list all of the tests, not that I expect
# any new ones to be added.

- name: Validate lib-tests
id: lib-tests
continue-on-error: true
env:
# `rawSystemStdInOut reports text decoding errors`
# test does not find ghc without the full path in windows
GHCPATH: ${{ steps.setup-haskell.outputs.ghc-exe }}
shell: ${{ inputs.shell }}
run: |
echo ::group::Validate lib-tests
sh validate.sh $FLAGS -s lib-tests
- name: Validate lib-suite
id: lib-suite
continue-on-error: true
shell: ${{ inputs.shell }}
run: |
echo ::group::Validate lib-suite
sh validate.sh $FLAGS -s lib-suite
- name: Validate cli-tests
id: cli-tests
continue-on-error: true
shell: ${{ inputs.shell }}
run: |
echo ::group::Validate cli-tests
sh validate.sh $FLAGS -s cli-tests
- name: Validate cli-suite
id: cli-suite
continue-on-error: true
shell: ${{ inputs.shell }}
run: |
echo ::group::Validate cli-suite
sh validate.sh $FLAGS -s cli-suite
- name: Validate solver-benchmarks-tests
id: solver-benchmarks-tests
continue-on-error: true
if: "matrix.ghc == env.GHC_FOR_SOLVER_BENCHMARKS"
shell: ${{ inputs.shell }}
run: |
echo ::group::Validate solver-benchmarks-tests
sh validate.sh $FLAGS -s solver-benchmarks-tests
- name: Validate solver-benchmarks-run
id: solver-benchmarks-run
continue-on-error: true
if: "matrix.ghc == env.GHC_FOR_SOLVER_BENCHMARKS"
shell: ${{ inputs.shell }}
run: |
echo ::group::Validate solver-benchmarks-run
sh validate.sh $FLAGS -s solver-benchmarks-run
- name: Collect test results
if: steps.lib-tests.outcome == 'failure' || steps.lib-suite.outcome == 'failure' || steps.cli-tests.outcome == 'failure' || steps.cli-suite.outcome == 'failure' || steps.solver-benchmarks-tests.outcome == 'failure' || steps.solver-benchmarks-run.outcome == 'failure'
shell: ${{ inputs.shell }}
run: exit 1
16 changes: 16 additions & 0 deletions .github/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# all of these will get "GHC_" prepended
# the single quotes will be consumed by the JSON parser
# note: FOR_RELEASE must be an element of both FOR_VALIDATE and FOR_BOOTSTRAP!
FOR_RELEASE: '9.4.8'
FOR_SOLVER_BENCHMARKS: '${GHC_FOR_RELEASE}'
FOR_COMPLETE_HACKAGE_TESTS: '${GHC_FOR_RELEASE}'
# these will be decoded with fromJSON
# If you remove something from here, then add it to the old-ghcs job.
# Also a removed GHC from here means that we are actually dropping
# support, so the PR *must* have a changelog entry.
FOR_VALIDATE: '["9.10.1", "9.8.2", "9.6.6", "9.4.8", "9.2.8", "9.0.2", "8.10.7", "8.8.4"]'
## GHC 7.10.3 does not install on ubuntu-22.04 with ghcup.
## Older GHCs are not supported by ghcup in the first place.
FOR_VALIDATE_OLD: '["8.4.4", "8.2.2", "8.0.2"]'
FOR_BOOTSTRAP: '["9.8.2", "9.6.6", "9.4.8", "9.2.8", "9.0.2"]'
COMMON_FLAGS: '-j 2 -v'
Loading

0 comments on commit 5420578

Please sign in to comment.