diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index f268079..21344cb 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -1,53 +1,65 @@ name: CI -# Trigger the workflow on push or pull request on: push: - branches: - - master - - cygwin* pull_request: - -env: - CHERE_INVOKING: 1 + workflow_call: + workflow_dispatch: jobs: test: - name: ${{ matrix.gap-branch }} ${{ matrix.ABI }} - Packages ${{ matrix.GAP_PKGS_TO_BUILD }} - HPCGAP ${{ matrix.HPCGAP }} - ${{ matrix.os }} + name: ${{ matrix.gap-version }} on ${{ matrix.os }} with ${{ matrix.configflags }} runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: - os: [ubuntu-latest] - gap-branch: - - master - ABI: [''] - GAP_PKGS_TO_BUILD: - - '' - - 'default' - HPCGAP: ['no'] - include: - - os: ubuntu-latest - gap-branch: master - GAP_PKGS_TO_BUILD: '' - HPCGAP: yes - - os: ubuntu-latest - gap-branch: master - ABI: 32 - GAP_PKGS_TO_BUILD: 'default' - HPCGAP: no + os: [ubuntu-latest, macos-latest, windows-latest] + gap-version: + - v4.10 + - v4.11.1 + - stable-4.12 + - v4.13.0-alpha2 + - 4.15.0-beta1 + - 4 + - latest + - default + - v4.16dev + configflags: ['', '--with-gmp=builtin'] + exclude: + - os: windows-latest + configflags: '--with-gmp=builtin' + - os: macos-latest + gap-version: stable-4.12 + - os: macos-latest + gap-version: v4.10 - os: macos-latest - gap-branch: master - GAP_PKGS_TO_BUILD: '' - HPCGAP: no + gap-version: v4.11.1 + configflags: '--with-gmp=builtin' steps: - - uses: actions/checkout@v5 - - if: ${{ matrix.os == 'windows-latest' }} - uses: gap-actions/setup-cygwin@v1 - - uses: ./ + - name: "Checkout" + uses: actions/checkout@v5 + + - name: "Setup Cygwin" + if: ${{ matrix.os == 'windows-latest' }} + uses: gap-actions/setup-cygwin@v2 + + - name: "Setup GAP" + uses: ./ with: - GAPBRANCH: ${{ matrix.gap-branch }} - ABI: ${{ matrix.ABI }} - GAP_PKGS_TO_BUILD: ${{ matrix.GAP_PKGS_TO_BUILD }} - HPCGAP: ${{ matrix.HPCGAP }} + gap-version: ${{ matrix.gap-version }} + configflags: ${{ matrix.configflags }} + + - name: "Check if GAP can run" + shell: bash + run: | + gap -A </`. + - The inputs `GAP_PKGS_TO_CLONE` and `GAP_PKGS_TO_BUILD` have been removed. This should now be done by the user in a separate step in + the workflow, e.g. by using `git clone` or the [PackageManager](https://gap-packages.github.io/PackageManager/) package. See the + Examples section below. + - The input `GAP_PKGS_TO_BUILD` has been renamed to `gap-pkgs-to-build`. It can only be used to build packages distributed with GAP. + In addition to `IO` and `profiling`, the package `json` is now also built by default. + - The inputs `HPCGAP` and `ABI` have been removed, and support for both HPC-GAP and 32-bit builds has been removed. + - The (previously undocumented) input `CONFIGFLAGS` has been renamed to `configflags`. + - The input `GAP_BOOTSTRAP` has been removed. GAP will always come with all distributed packages. + - An input `repository` has been added, which allows building a version of GAP hosted on a repository different from `gap-system/gap`. + +#### Changes to functionality: + - There is no longer a separate branch for running this action on Windows. This action should work on Windows, assuming it is + preceded by version v2 or later of [setup-cygwin](https://github.com/gap-actions/setup-gap). + - The installation location of GAP is stored in the environment variable `GAPROOT`, which can be used in subsequent steps in the workflow. + - The GAP executable is added to `PATH`, thus GAP can now always be started by calling `gap`. + +### Examples + +The following is a minimal example to run this action. + +```yaml +name: CI + +on: + push: + pull_request: + +jobs: + # The CI test job + test: + name: CI test + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v5 + - uses: gap-actions/setup-gap@v3 + # ... additional steps using GAP will usually follow here +``` + +A more extensive example: + +```yaml +name: CI + +on: + push: + pull_request: + +jobs: + # The CI test job + test: + name: CI test + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + gap-version: + - latest + - v4.15.0-beta1 + - master + + steps: + - uses: gap-actions/setup-cygwin@v2 + if: ${{ matrix.os == 'windows-latest' }} + - uses: actions/checkout@v5 + - uses: gap-actions/setup-gap@v3 + with: + gap-version: ${{ matrix.gap-version }} + - shell: bash + run: | + # Install package via 'git clone' + cd $HOME/.gap/pkg + git clone https://github.com/gap-packages/io + cd io + sh autogen.sh + ./configure --with-gaproot=$GAPROOT + make -j4 + - shell: bash + run: | + # Install packages via PackageManager + gap -c 'LoadPackage("PackageManager"); InstallPackage("https://github.com/gap-packages/orb"); QUIT;' + gap -c 'LoadPackage("PackageManager"); InstallPackage("cvec"); QUIT;' +``` ## Contact Please submit bug reports, suggestions for improvements and patches via diff --git a/action.yml b/action.yml index 75e19f5..391d534 100644 --- a/action.yml +++ b/action.yml @@ -1,139 +1,153 @@ name: 'Setup GAP for package testing' -description: 'Download and compile CI scripts, GAP and its packages' +description: 'Download and compile GAP and its packages' inputs: - GAP_PKGS_TO_CLONE: - description: 'the GAP packages to clone' + gap-version: + description: 'The GAP version or branch to build' required: false - default: '' - GAP_PKGS_TO_BUILD: - description: 'the GAP packages to build' - required: false - default: 'io profiling' - GAPBRANCH: - description: 'the gap branch to clone' - required: false - default: 'master' - HPCGAP: - description: 'build HPC-GAP if set to yes' - required: false - default: 'no' - ABI: - description: 'set to 32 to use 32bit build flags for the package' + default: 'latest' + repository: + description: 'The GitHub repository from which to clone GAP' required: false - default: '' - CONFIGFLAGS: - description: 'arguments to pass to the GAP configure script (e.g. --enable-debug)' + default: 'gap-system/gap' + configflags: + description: 'Arguments to pass to the GAP configure script (e.g. --enable-debug)' required: false default: '' - GAP_BOOTSTRAP: - description: 'make bootstrap-pkg-? (i.e. full/minimal)' - required: false - default: 'full' -env: - CHERE_INVOKING: 1 + runs: using: "composite" steps: - - name: "Install dependencies" - run: | - echo "Installing dependencies" - if [ "${{runner.os}}" = "Linux" ]; then - if [ "${{inputs.ABI}}" = "32" ]; then - sudo dpkg --add-architecture i386 - sudo apt-get update - packages=( - libgmp-dev:i386 - libreadline-dev:i386 - zlib1g-dev:i386 - gcc-multilib - g++-multilib - ) + + - name: "Install dependencies" + shell: bash + if: ${{ runner.os != 'Windows' }} + run: | + if [[ "${{ runner.os }}" == "Linux" ]] ; then + sudo apt-get install libgmp-dev libreadline-dev zlib1g-dev + elif [[ "${{ runner.os }}" = "macOS" ]] ; then + # Note: readline is installed by default, adding it here causes warnings in GitHub runners + brew install zlib autoconf && brew link zlib --force + fi + + - name: "Determine GAP version" + id: version + shell: bash + run: | + VERSION="" + IS_RELEASE=false + + # Select only those releases we wish to allow, with or without pre-releases + + if [[ -z "${{ inputs.gap-version }}" || "${{ inputs.gap-version }}" == "latest" ]] ; then + echo "Version: latest release" + IS_RELEASE=true + VERSION=$(wget --header="Authorization: Bearer ${{ github.token }}" -qO- "https://api.github.com/repos/${{ inputs.repository }}/releases/latest" | jq -r '.tag_name') + elif [[ "${{ inputs.gap-version }}" =~ ^(master|main|default)$ ]] ; then + echo "Version: default branch" + VERSION=$(git ls-remote --symref https://github.com/${{ inputs.repository }}.git HEAD | head -n 1 | sed 's|ref: refs/heads/||; s|\tHEAD||') + else + echo "Checking releases" + GIT_RELS_JSON=$(wget --header="Authorization: Bearer ${{ github.token }}" -qO- "https://api.github.com/repos/${{ inputs.repository }}/releases") + GIT_RELS=$(echo "$GIT_RELS_JSON" | jq -r '.[].tag_name' | sort -V) + GIT_NPRS=$(echo "$GIT_RELS_JSON" | jq -r '.[] | select((.draft == false) and (.prerelease == false)) | .tag_name' | sort -V) + + # Add "v" in front if missing + REL=${{ inputs.gap-version }} + REL=v${REL#v} + + if echo "$GIT_RELS" | grep -qx "$REL" ; then + echo "Version: exact release match" + IS_RELEASE=true + VERSION=$REL + elif echo "$GIT_NPRS" | grep -q "^$REL\." ; then + echo "Version: expanded to release" + IS_RELEASE=true + VERSION=$(echo "$GIT_NPRS" | grep "^$REL\." | tail -n 1) + else + echo "Checking branches and tags" + if git ls-remote --heads https://github.com/${{ inputs.repository }}.git | sed 's|.*refs/heads/||' | grep -qx "${{ inputs.gap-version }}" ; then + echo "Version: exact branch match" + VERSION=${{ inputs.gap-version }} + elif git ls-remote --tags --refs https://github.com/${{ inputs.repository }}.git | sed 's|.*refs/tags/||' | grep -qx "${{ inputs.gap-version }}" ; then + echo "Version: exact tag match" + VERSION=${{ inputs.gap-version }} else - packages=( - libgmp-dev - libreadline-dev - zlib1g-dev - ) - fi - sudo apt-get install "${packages[@]}" - elif [ "${{runner.os}}" = "macOS" ]; then - if [ "${{inputs.ABI}}" = "32" ]; then - echo "Can't use macOS with 32bit!" + echo "No release, branch or tag with name ${{ inputs.gap-version }} found" exit 1 fi - brew install gmp zlib autoconf && brew link zlib fi - shell: bash + fi - - name: "Clone GAP" - shell: bash - run: git clone --depth=2 -b ${{ inputs.GAPBRANCH }} https://github.com/gap-system/gap.git $HOME/gap + echo "VERSION=$VERSION" >> "$GITHUB_OUTPUT" + echo "IS_RELEASE=$IS_RELEASE" >> "$GITHUB_OUTPUT" - - name: "Build GAP" - shell: bash - env: - ABI: ${{ inputs.ABI }} - run: | - cd $HOME/gap - CONFIGFLAGS="${{ inputs.CONFIGFLAGS }}" - # for HPC-GAP, add suitable flags - if [[ ${{ inputs.HPCGAP }} = yes ]]; then - CONFIGFLAGS="$CONFIGFLAGS --enable-hpcgap" - fi + - name: "Set GAPROOT" + shell: bash + run: | + GAPROOT="$HOME/gap" + mkdir -p $GAPROOT + echo "GAPROOT=$GAPROOT" >> "$GITHUB_ENV" + + - name: "Download or clone GAP" + shell: bash + env: + VERSION: ${{ steps.version.outputs.VERSION }} + IS_RELEASE: ${{ steps.version.outputs.IS_RELEASE }} + run: | + if [[ "$IS_RELEASE" == "true" ]] ; then + WGET="wget -q -N --no-check-certificate --tries=5 --waitretry=5 --retry-connrefused" + URL=https://github.com/${{ inputs.repository }}/releases/download/$VERSION/ + FILE=gap-${VERSION#v}.tar.gz + $WGET $URL$FILE + tar xzf $FILE -C $GAPROOT --strip-components=1 + else + git clone --branch $VERSION --depth=1 --single-branch https://github.com/${{ inputs.repository }}.git $GAPROOT + fi - # build GAP in a subdirectory + - name: "Build GAP" + shell: bash + run: | + cd $GAPROOT + CONFIGFLAGS="${{ inputs.configflags }}" + + if [ -f "autogen.sh" ] ; then + echo "::group:: Running autogen" ./autogen.sh - ./configure $CONFIGFLAGS - make -j4 V=1 + fi + + if [[ "${{ runner.os }}" = "macOS" ]] ; then + BP=$(brew --prefix) + CONFIGFLAGS="--with-gmp=$BP --with-readline=$BP/opt/readline $CONFIGFLAGS" + fi + echo "::group:: Running configure with flags $CONFIGFLAGS" + ./configure $CONFIGFLAGS + + echo "::group:: Running make" + make -j4 V=1 - # make it available - ln -s $HOME/gap/gap /usr/local/bin/gap + - name: "Make GAP executable" + shell: bash + run: | + mkdir -p /tmp/gaproot/pkg/ + ln -f -s $PWD /tmp/gaproot/pkg/ - - name: "Download packages" - shell: bash - run: | - cd $HOME/gap + if [ -f "$GAPROOT/gap" ] ; then + EXEC="$GAPROOT/gap" + else + EXEC="sh $GAPROOT/bin/gap.sh" + fi + echo -e '#!/bin/bash\n'"$EXEC"' -l "/tmp/gaproot;" "$@"\n' > /usr/local/bin/gap - # download packages; instruct wget to retry several times if the - # connection is refused, to work around intermittent failures. - # for older versions, set WGET, for GAP >= 4.11 set DOWNLOAD - WGET="wget -N --no-check-certificate --tries=5 --waitretry=5 --retry-connrefused" - make bootstrap-pkg-${{ inputs.GAP_BOOTSTRAP }} DOWNLOAD="$WGET" WGET="$WGET" + # Make it executable + chmod +x /usr/local/bin/gap - - name: "Clone additional GAP packages" - shell: bash - run: | - # optionally: clone specific package versions, in case we need to test - # with development versions - cd $HOME/gap/pkg - for pkg in ${{ inputs.GAP_PKGS_TO_CLONE }}; do - # delete any existing variants of the package to avoid multiple versions - # from being compiled later on - rm -rf "${pkg##*/}"* - if [[ "$pkg" =~ ^http ]] ; then - # looks like a full URL - git clone "$pkg" - elif [[ "$pkg" =~ ^[^/]+/[^/]+$ ]] ; then - # looks like ORG/REPO - git clone https://github.com/"$pkg" - elif [[ "$pkg" =~ ^[^/]+$ ]] ; then - # looks like just a REPO name - git clone https://github.com/gap-packages/"$pkg" - else - echo "Invalid package name or URL '$pkg' in GAP_PKGS_TO_CLONE" - exit 1 - fi - done + echo 'GAP="gap --quitonbreak"' >> "$GITHUB_ENV" - - name: "Build additional GAP packages" - shell: bash - env: - ABI: ${{ inputs.ABI }} - run: | - # build some packages - BuildPackagesOptions="--strict" - shopt -s nocaseglob - cd $HOME/gap/pkg - for pkg in ${{inputs.GAP_PKGS_TO_BUILD}}; do - ../bin/BuildPackages.sh ${BuildPackagesOptions} $pkg* - done + - name: "Download GAP packages" + shell: bash + if: ${{ steps.version.outputs.IS_RELEASE == 'false' }} + run: | + cd $GAPROOT + WGET="wget -q -N --no-check-certificate --tries=5 --waitretry=5 --retry-connrefused" + # For GAP >= 4.11 set DOWNLOAD, for older versions set WGET + make bootstrap-pkg-full DOWNLOAD="$WGET" WGET="$WGET"