diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index c53eb6a..75585c0 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -6,40 +6,82 @@ on: branches: - main pull_request: + workflow_dispatch: jobs: test: - name: "Test on ${{ matrix.gap-version }}, use-latex: ${{ matrix.use-latex }}, ignore-errors: ${{ matrix.ignore-errors }}" - runs-on: ubuntu-latest + name: "Test on ${{ matrix.os }}, GAP version ${{ matrix.gap-version }}" + runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: + os: [ubuntu-latest, macos-latest, windows-latest] gap-version: - 'devel' + - '4.15' - '4.14' - '4.13' - '4.12' - '4.11' - - '4.10' - use-latex: ["true","false"] - ignore-errors: ["true","false"] - exclude: - - use-latex: "false" - ignore-errors: "false" - + steps: + - name: "Setup Cygwin" + uses: gap-actions/setup-cygwin@v2 + if: ${{ matrix.os == 'windows-latest' }} + - name: "Check out this repository" - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: path: this-action/ - - uses: gap-actions/setup-gap@v3 + + - name: "Setup GAP" + uses: gap-actions/setup-gap@v3 with: gap-version: ${{ matrix.gap-version }} - - uses: ./this-action/ + + - name: "Install additional GAP packages" + uses: ./this-action/ with: packages: | - https://github.com/gap-packages/sophus.git - utils + Example@devel + gap-packages/AutoDoc + PrImGrP + groupoids@1.80 + gap-packages/utils@0.92 https://github.com/gap-packages/grpconst/releases/download/v2.6.2/grpconst-2.6.2.tar.gz - use-latex: ${{ matrix.use-latex }} - ignore-errors: ${{ matrix.ignore-errors }} + https://github.com/gap-packages/forms/releases/download/v1.2.14/forms-1.2.14.zip + + - name: "Check if packages were installed" + shell: bash + run: | + $GAP -A -q < fail; + end;; + bool := [ + chck( "example", "4.4.1" ), + chck( "autodoc", "2026.03.18" ), + chck( "primgrp", "4.0.2" ), + chck( "groupoids", "1.80" ), + chck( "utils", "0.92" ), + chck( "grpconst", "2.6.2" ), + chck( "forms", "1.2.14" ) + ];; + QUIT_GAP( ForAll( bool, x -> x ) ); + GAPInput + + test-scripts: + name: "Test the scripts used by this action" + runs-on: ubuntu-slim + + steps: + + - name: "Check out this repository" + uses: actions/checkout@v6 + + - name: "Shellcheck" + shell: bash + run: shellcheck -e SC2034,SC2154 -o all *.sh diff --git a/README.md b/README.md index dc0db00..4867654 100644 --- a/README.md +++ b/README.md @@ -6,13 +6,13 @@ This GitHub action installs additional GAP packages. The action `install-pkg` has to be called by the workflow of a GAP package. -It installs the package(s) using PackageMaker. (TODO: link) +It installs the package(s) in GAP's `pkg` subfolder. ## Migration from setup-gap@v2 This package is intended to replace the `gap-pkgs-to-clone` input, though with some -notable changes. PackageManager will also build the package, and install other -packages if needed. +notable changes. Packages will **not** be built, this has to be done by a subsequent +`build-pkg` action. ### Inputs @@ -20,25 +20,12 @@ packages if needed. The following input is mandatory: - `packages`: - - Space-separated or newline-separated list of packages to install. - Can be the name of the package, the link to a git repo (ending in `.git'`'), or - the link to a release archive. - - default: `'true'` - -The following inputs are all optional: - -- `ignore-errors`: - - Ignore errors raised by PackageManager. Can be of use when it - fails to build documentation that you don't need anyway. - - default: `'false'` -- `use-latex`: - - Install and use LaTeX (only works on Linux). - - default: `'false'` - - -### What's new in v1 - -- EVERYTHING + - Space-separated or newline-separated list of packages to install. Packages are either + given as `package`, as `package@version`, or by an URL pointing to a release archive. + Here, `package` can either be the name of a package in the GAP package distribution or + the name of a GitHub repository (of the form "org/repo"). The optional suffix `version` + is either `latest`, `devel`, or a version number. + - default: `''` ### Examples @@ -63,7 +50,10 @@ jobs: - uses: gap-actions/setup-gap@v3 - uses: gap-actions/install-pkg@v1 with: - packages: 'example' + packages: | + gap-packages/smallgrp + autpgrp@devel + https://github.com/gap-packages/primgrp/releases/download/v4.0.2/primgrp-4.0.2.tar.gz ``` ## Contact diff --git a/action.yml b/action.yml index 577e055..dddc227 100644 --- a/action.yml +++ b/action.yml @@ -1,48 +1,87 @@ name: 'Install packages' description: 'Install additional GAP packages' + inputs: packages: - description: 'Space-separated list of packages to install' + description: 'Space-separated or newline-separated list of packages to install' required: true default: '' - ignore-errors: - description: 'Ignore errors when installing' - required: false - default: 'false' - use-latex: - description: "Install and use latex (only works on Linux)" - required: false - default: "false" runs: using: "composite" steps: - - name: "Install TeX Live" - if: ${{ inputs.use-latex == 'true' }} + + - name: Install bsdtar + if: ${{ runner.os == 'Linux' }} shell: bash - run: | - sudo apt-get install --no-install-recommends texlive-latex-base texlive-latex-recommended texlive-latex-extra texlive-fonts-recommended - - name: "Run tests" + run: sudo apt install -y libarchive-tools # bsdtar + + - name: Install GAP packages shell: bash run: | # Convert newlines to spaces - PKGS=$(echo "${{ inputs.packages }}" | tr '\n' ' ') - - error_found=false - # Use `gap` instead of `$GAP` to avoid quitonbreak - for pkg in $PKGS; do - if ! gap -A <= ${version}" + wget --header="${WGET_HEADER}" -qO "${TMPDIR}/releases.json" "https://api.github.com/repos/${repo}/releases" + + local release + release=$(jq -c --arg v "${version}" ' + map(. + {ver:(.tag_name|sub("^v";""))}) + | sort_by(.ver) + | map(select(.ver >= $v)) + | .[0] + ' "${TMPDIR}/releases.json") + + if [[ "${release}" = "null" ]] || [[ -z "${release}" ]]; then + echo "::error::No release >= ${version} found" + exit 1 + fi + + echo "${release}" > "${TMPDIR}/release.json" + rm "${TMPDIR}/releases.json" + fi + + local asset_url + asset_url=$(jq -r ' + .assets[] + | select(.name=="package-info.json") + | .browser_download_url + ' "${TMPDIR}/release.json") + rm "${TMPDIR}/release.json" + + if [[ -z "${asset_url}" ]] || [[ "${asset_url}" = "null" ]]; then + echo "::error::Release has no package-info.json asset" + exit 1 + fi + + local info + info="${TMPDIR}/package-info.json" + wget -qO "${info}" "${asset_url}" + + local archive_base + local formats + archive_base=$(jq -r '.ArchiveURL' "${info}") + formats=$(jq -r '.ArchiveFormats' "${info}") + formats=$(echo "${formats}" | tr ' ' '\n') + + version=$(jq -r '.Version' "${info}") + echo "Selected version ${version} from ${repo} releases" + combine_url "${archive_base}" "${formats}" + rm "${info}" +} + +# Get PackageDistro information +get_package_distro() { + if [[ ! -f "${PKG_DISTRO}" ]]; then + echo "Downloading packages-infos.json from PackageDistro" + local distro="${TMPDIR}/package-infos.json.gz" + wget -qO "${distro}" "https://github.com/gap-system/PackageDistro/releases/download/latest/package-infos.json.gz" + gunzip "${distro}" + if [[ ! -s "${PKG_DISTRO}" ]]; then + echo "::error::Could not download PackageDistro json" + exit 1 + fi + fi +} + +# Get repository name from package name using PackageDistro +get_repo_from_name() { + local name="$1" + + # Create the required file at $PKG_DISTRO + get_package_distro + + local pkg + pkg=$(jq -c --arg n "${name}" '.[$n]' "${PKG_DISTRO}") + + if [[ "${pkg}" = "null" ]] || [[ -z "${pkg}" ]]; then + echo "::error::Package ${name} not found in PackageDistro" + exit 1 + fi + + # Don't try to get URL from PackageDistro - latest version not be merged yet! + local repo_url + repo_url=$(echo "${pkg}" | jq -r '.SourceRepository.URL') || { + echo "::error::Package ${name} not found in PackageDistro" + exit 1 + } + repo=${repo_url#https://github.com/} +} + +# Use GAP to check if package-version combination is already installed +check_pkg_availability() { + local pkg="$1" + local ver="$2" + gap -A -q < fail ); +GAPINPUT + return $? +} + +# Remove existing package versions +clear_dest() { + local dest="$1" + rm -rf "${dest}" + rm -rf "${dest}-*" +}