2021-02-06 09:41:50 +00:00
name : 'Setup Common Lisp'
2024-02-23 05:22:33 +00:00
author : Alexander Artemenko
description : This action setup Roswell and a Common Lisp implementation plus Qlot for managing virtual environments.
2021-02-06 09:41:50 +00:00
inputs :
2021-10-18 18:01:38 +00:00
roswell-version :
2021-10-26 15:13:33 +00:00
description : 'Roswell version to install. If not specified, the latest working version will be used; if "latest", the latest version is used'
2021-10-18 18:01:38 +00:00
required : false
2024-01-26 14:39:24 +00:00
default : v23.10.14.114
2024-02-23 05:22:33 +00:00
2021-02-06 09:41:50 +00:00
asdf-system :
description : 'ASDF system to install'
2021-02-06 09:55:24 +00:00
required : false
2024-02-23 05:22:33 +00:00
2021-06-06 21:29:46 +00:00
asdf-version :
2021-10-26 15:13:33 +00:00
description : 'ASDF version to install. If not specified, the latest working version will be used; if "latest", the latest version is used'
2021-06-06 21:29:46 +00:00
required : false
2021-10-26 15:13:33 +00:00
default : 3.3 .5 .3
2024-02-23 05:22:33 +00:00
2021-10-26 15:13:33 +00:00
qlot-version :
description : 'Qlot version to install. If not specified, the latest working version will be used; if "latest", the latest version is used'
required : false
default : 0.11 .5
2024-02-23 05:22:33 +00:00
2021-02-06 09:41:50 +00:00
qlfile-template :
description : "Djula template for qlfile. All environment variables are available in it's context"
required : false
2024-02-23 05:22:33 +00:00
cache :
description : 'If true (default), then cache will be created to speedup repeated action runs.'
required : false
default : true
# GitHub does not support anchors in the action
# and returns error like this:
#
# Anchors are not currently supported. Remove the anchor 'roswell-cache-paths'
#
# That is why I use "input" variable to not repeat this list in two places
roswell-cache-paths :
description : "Internal var. Don't use it."
required : false
default : |
~/.quicklisp-client-fix
~/.roswell
/usr/local/etc/roswell
/usr/local/bin/ros
/usr/local/Cellar/roswell
qlot-cache-paths :
description : "Internal var. Don't use it."
required : false
default : |
path : |
qlfile
qlfile.lock
~/.cache/common-lisp/
.qlot
2021-02-06 09:41:50 +00:00
runs :
using : composite
steps :
2024-02-23 05:22:33 +00:00
- name : Calculate variables
id : locals
shell : bash
run : |
if [[ '${{ inputs.roswell-version }}' == 'latest' ]]
then
echo "windows-package-name=mingw-w64-x86_64-roswell" >> $GITHUB_OUTPUT
else
# Strip v prefix from version number
ROS_VERSION=$(echo ${{ inputs.roswell-version }} | sed 's/v//')
echo "windows-package-name=mingw-w64-x86_64-roswell=$ROS_VERSION" >> $GITHUB_OUTPUT
fi
# echo 'roswell-cache-paths=~/.quicklisp-client-fix\n~/.roswell\n/usr/local/etc/roswell\n/usr/local/bin/ros\n/usr/local/Cellar/roswell' >> $GITHUB_OUTPUT
echo "current-month=$(date -u '+%Y-%m')" >> $GITHUB_OUTPUT
- if : runner.os == 'Windows'
uses : msys2/setup-msys2@cc11e9188b693c2b100158c3322424c4cc1dadea #v2.22.0
2021-10-27 05:16:26 +00:00
with :
# Msys2 has its own PATH, and the following setting enables standard
# PATH manipulation expressions like the one shown below, to succeed:
#
# $ echo /usr/local/bin >> $GITHUB_PATH
path-type : inherit
2021-10-28 11:00:25 +00:00
platform-check-severity : warn
2024-02-23 05:22:33 +00:00
# Installing ASDF requires `make`, so let's make sure it's
# available
install : >-
make
${{ steps.locals.outputs.windows-package-name }}
cache : ${{ inputs.cache }}
2021-10-27 05:16:26 +00:00
- name : Create lispsh
2021-10-26 15:13:33 +00:00
shell : bash
run : |
2024-01-28 05:52:52 +00:00
echo ::group::Set up link to lispsh
2021-10-26 15:13:33 +00:00
# All the steps below, should work without problems on Linux, Mac OS,
# and Windows, provided that they are run with the "right" shell
# parameter, i.e. bash for Linux and Mac OS, and msys2 for Windows.
#
# Unfortunately, composite actions do not support getting the shell
# parameter injected from the parent workflow (read more about this
# here: https://github.com/actions/runner/issues/835), so the
# workaround I came up with is:
#
2021-10-27 05:16:26 +00:00
# 1. Symlink bash/msys2 to a known location, i.e. lispsh
2024-01-26 14:39:24 +00:00
# 2. Use lispsh -eo pipefail {0} as shell parameter
#
# Pay attention to -eo pipefail options. We need them to exit on the
# first error. Without this option, Roswell might fail to install the
# implementation and continue to execute everything with default SBCL.
2021-10-26 15:13:33 +00:00
#
# It's not ideal, but the alternative is to duplicate most of the steps
# below, and have some of them with `shell: bash`, and others with
# `shell: msys2 {0}`.
if [[ "$RUNNER_OS" == "Windows" ]]; then
2024-02-23 05:22:33 +00:00
powershell New-Item -ItemType SymbolicLink -Force \
2021-10-27 05:16:26 +00:00
-Path "D:/a/_temp/setup-msys2/lispsh.cmd" \
2021-10-26 15:13:33 +00:00
-Target "D:/a/_temp/setup-msys2/msys2.cmd"
else
2021-10-27 05:16:26 +00:00
sudo ln -sf $(which bash) /usr/local/bin/lispsh
2021-10-26 15:13:33 +00:00
fi
2024-01-28 05:52:52 +00:00
echo ::endgroup: :
2021-10-18 17:49:38 +00:00
- name : Set up Environment
shell : bash
run : |
echo ::group::Set up Environment
2024-01-26 14:39:24 +00:00
2021-10-18 17:49:38 +00:00
if [[ "$RUNNER_OS" == "Windows" ]]; then
2021-10-26 15:13:33 +00:00
# Roswell internally checks for the MSYSCON env varible to be
# defined, and when not there, it would go and install msys2 (i.e.
# `ros install msys2+`) and rely on the `bash` bonary that comes
# with that installation.
#
# All good except that something is not quite working as it should,
# given that every time Roswell tries to run a `bash` command, it
# would spit out the following:
2021-10-18 17:49:38 +00:00
#
# Unhandled SIMPLE-ERROR in thread #<SB-THREAD:THREAD "main thread" RUNNING
# {1005700003}>:
# Couldn't execute "C:\\Users\\runneradmin\\.roswell\\impls\\x86-64\\windows\\msys2\\NIL\\usr\\bin\\bash": The system cannot find the file specified.
#
# Backtrace for: #<SB-THREAD:THREAD "main thread" RUNNING {1005700003}>
# 0: (SB-DEBUG::DEBUGGER-DISABLED-HOOK #<SIMPLE-ERROR "Couldn't execute ~S: ~A" {1004EEA623}> #<unused argument> :QUIT T)
# 1: (SB-DEBUG::RUN-HOOK SB-EXT:*INVOKE-DEBUGGER-HOOK* #<SIMPLE-ERROR "Couldn't execute ~S: ~A" {1004EEA623}>)
# 2: (INVOKE-DEBUGGER #<SIMPLE-ERROR "Couldn't execute ~S: ~A" {1004EEA623}>)
# 3: (ERROR "Couldn't execute ~S: ~A" "C:\\Users\\runneradmin\\.roswell\\impls\\x86-64\\windows\\msys2\\NIL\\usr\\bin\\bash" "The system cannot find the file specified.")
# 4: (SB-EXT:RUN-PROGRAM "C:\\Users\\runneradmin\\.roswell\\impls\\x86-64\\windows\\msys2\\NIL\\usr\\bin\\bash" ("-lc" "cd \"C:\\\\Users\\\\runneradmin\\\\.roswell\\\\src\\\\asdf-3.3.5.3\\\\\";pwd") :ENV NIL :ENVIRONMENT NIL :WAIT NIL :SEARCH T :INPUT NIL :IF-INPUT-DOES-NOT-EXIST :ERROR :OUTPUT :STREAM :IF-OUTPUT-EXISTS :APPEND :ERROR NIL :IF-ERROR-EXISTS :APPEND :STATUS-HOOK NIL :EXTERNAL-FORMAT :UTF-8 :DIRECTORY NIL :PRESERVE-FDS NIL :ESCAPE-ARGUMENTS T :WINDOW NIL)
# 5: (UIOP/LAUNCH-PROGRAM:LAUNCH-PROGRAM ("C:\\Users\\runneradmin\\.roswell\\impls\\x86-64\\windows\\msys2\\NIL\\usr\\bin\\bash" "-lc" "cd \"C:\\\\Users\\\\runneradmin\\\\.roswell\\\\src\\\\asdf-3.3.5.3\\\\\";pwd") :INPUT NIL :OUTPUT :STREAM :ERROR-OUTPUT NIL :OUTPUT :STRING)
# 6: ((LAMBDA (UIOP/RUN-PROGRAM::REDUCED-INPUT UIOP/RUN-PROGRAM::INPUT-ACTIVITY) :IN UIOP/RUN-PROGRAM::%USE-LAUNCH-PROGRAM) NIL NIL)
# 7: (UIOP/RUN-PROGRAM::%USE-LAUNCH-PROGRAM ("C:\\Users\\runneradmin\\.roswell\\impls\\x86-64\\windows\\msys2\\NIL\\usr\\bin\\bash" "-lc" "cd \"C:\\\\Users\\\\runneradmin\\\\.roswell\\\\src\\\\asdf-3.3.5.3\\\\\";pwd") :OUTPUT :STRING)
# 8: (MINGW-NAMESTRING #P"C:/Users/runneradmin/.roswell/src/asdf-3.3.5.3/")
# 9: (ROSWELL.INSTALL.ASDF::ASDF-INSTALL (:TARGET "asdf" :VERSION "3.3.5.3" :VERSION-NOT-SPECIFIED 0 :ARGV NIL))
#
2021-10-26 15:13:33 +00:00
# The NIL over there, seems to be the result of evaluating the
# following form:
#
# (config "msys2.version")
#
# Now, I am not sure what's going on with that, but since
# we got msys2 installed already, I figured it would be easier to
# tell Roswell about it and ignore all the other installation
# steps.
2021-10-18 17:49:38 +00:00
echo MSYSCON=Stop-Roswell-From-Installing-Msys2 >> $GITHUB_ENV
# Also, for whatever reason Roswell seems to be installing
# ASDF-system-specific scripts inside .roswell/lisp/quicklisp/bin
# and not .roswell/bin, so if we want to enable users of this
# action to directly invoke these scripts, we need to add
# .roswell/lisp/quicklisp/bin to PATH.
echo $HOME/.roswell/lisp/quicklisp/bin >> $GITHUB_PATH
fi
echo $HOME/.roswell/bin >> $GITHUB_PATH
echo ::endgroup: :
2024-02-23 05:22:33 +00:00
# TODO: comment for prod
# - name: Current Env
# shell: bash
# run: |
# echo ::group::Environment
# echo "Current dir:"
# pwd
# echo "Environment Variables:"
# env | sort -u
# echo ::endgroup::
# On Windows we dont have such problems with permission.
# Also we don't have sudo there, so just skip this step
# on this platform:
- if : inputs.cache == 'true' && runner.os != 'Windows'
name : Grant All Perms to Make Roswell Cache Restoring Possible
shell : lispsh -eo pipefail {0}
2021-02-06 09:41:50 +00:00
run : |
2024-02-23 05:22:33 +00:00
sudo mkdir -p /usr/local/etc/roswell
sudo chown "${USER}" /usr/local/etc/roswell
# Here the ros binary will be restored:
sudo chown "${USER}" /usr/local/bin
2021-10-26 15:13:33 +00:00
2024-02-23 05:22:33 +00:00
- if : inputs.cache == 'true'
name : Restore Roswell From Cache
id : roswell-cache-restore
uses : actions/cache/restore@v4
with :
path : ${{ inputs.roswell-cache-paths }}
key : roswell-${{ inputs.roswell-version }}-${{ steps.locals.outputs.current-month }}-${{ env.cache-name }}-${{ runner.os }}-${{ env.LISP }}
- if : inputs.cache == 'true' && steps.roswell-cache-restore.outputs.cache-hit == 'true'
name : Restore Path To Cached Files
shell : lispsh -eo pipefail {0}
run : |
echo $HOME/.roswell/bin >> $GITHUB_PATH
echo .qlot/bin >> $GITHUB_PATH
if [[ "$RUNNER_OS" == "Windows" ]]; then
echo $HOME/.roswell/lisp/quicklisp/bin >> $GITHUB_PATH
fi
# Start the piece which results should be cached
# On Windows we install roswell using Pacman package manager and don't need this step
- if : (inputs.cache == 'false' || steps.roswell-cache-restore.outputs.cache-hit != 'true') && runner.os != 'Windows'
name : Install Roswell
2024-01-26 14:39:24 +00:00
shell : lispsh -eo pipefail {0}
2021-02-06 09:41:50 +00:00
run : |
2021-10-26 15:13:33 +00:00
echo ::group::Installing Roswell dependencies
2024-01-26 14:39:24 +00:00
2021-02-06 10:57:19 +00:00
if [[ "$RUNNER_OS" == "Linux" ]]; then
2021-04-04 18:07:32 +00:00
sudo apt-get update
2021-02-06 09:41:50 +00:00
sudo apt-get -y install git build-essential automake libcurl4-openssl-dev
fi
2021-02-06 10:59:58 +00:00
if [[ "$RUNNER_OS" == "macOS" ]]; then
2021-02-06 09:41:50 +00:00
brew install automake autoconf curl
fi
2024-02-23 05:22:33 +00:00
2021-10-26 15:13:33 +00:00
echo ::endgroup: :
if [[ "${{ inputs.roswell-version }}" != "latest" ]]; then
echo ::group::Installing Roswell ${{ inputs.roswell-version }}
2024-01-28 05:52:52 +00:00
curl -L https://raw.githubusercontent.com/roswell/roswell/${{ inputs.roswell-version }}/scripts/install-for-ci.sh | bash -xeo pipefail
2021-10-26 15:13:33 +00:00
else
echo ::group::Installing latest Roswell
2024-01-28 05:52:52 +00:00
curl -L https://raw.githubusercontent.com/roswell/roswell/master/scripts/install-for-ci.sh | bash -xeo pipefail
2021-10-26 15:13:33 +00:00
fi
2021-02-06 09:41:50 +00:00
echo ::endgroup: :
2024-02-23 05:22:33 +00:00
- if : inputs.cache == 'false' || steps.roswell-cache-restore.outputs.cache-hit != 'true'
name : Upgrade Quicklisp dists
2024-01-26 14:39:24 +00:00
shell : lispsh -eo pipefail {0}
2021-10-26 16:57:25 +00:00
run : |
# The parent workflow might have caching enabled for Roswell and all
# the other Lisp files in general, so it's better to tell Quicklisp
# to update all its dists.
ros -e "(ql:update-all-dists :prompt nil)"
2024-02-23 05:22:33 +00:00
- if : inputs.cache == 'false' || steps.roswell-cache-restore.outputs.cache-hit != 'true'
name : Install Quicklisp patch for package-inferred systems
2024-01-26 14:39:24 +00:00
shell : lispsh -eo pipefail {0}
2023-12-13 21:40:35 +00:00
run : |
git clone \
--no -tags \
--single-branch \
--depth=1 \
https://github.com/40ants/quicklisp-client-fix \
~/.quicklisp-client-fix
2023-12-13 22:29:30 +00:00
mkdir -p ~/.roswell
2023-12-13 21:40:35 +00:00
cat >> ~/.roswell/init.lisp <<EOF
2024-02-25 13:47:08 +00:00
(let ((fix-filename (make-pathname :directory '(:absolute :home ".quicklisp-client-fix")
: name "quicklisp-fix"
: type "lisp")))
(let ((quicklisp-found #+quicklisp t
#-quicklisp nil))
2024-01-26 14:39:24 +00:00
(cond
2024-02-25 13:47:08 +00:00
((not quicklisp-found)
(warn "Quicklisp is not available, skipping fix loading.~%"))
2024-01-26 14:39:24 +00:00
((probe-file fix-filename)
2024-02-25 13:47:08 +00:00
(handler-bind ((warning #'muffle-warning))
(load fix-filename)))
2024-01-26 14:39:24 +00:00
(t
2024-02-25 13:47:08 +00:00
(warn "Quicklisp fix was not found at ~S.~%" fix-filename)))))
2023-12-13 21:40:35 +00:00
EOF
2024-02-23 05:22:33 +00:00
- if : inputs.cache == 'false' || steps.roswell-cache-restore.outputs.cache-hit != 'true'
name : Upgrade ASDF to the Latest Version
2024-01-26 14:39:24 +00:00
shell : lispsh -eo pipefail {0}
2021-02-06 09:41:50 +00:00
run : |
2021-10-26 15:13:33 +00:00
if [[ "${{ inputs.asdf-version }}" != "latest" ]]; then
2021-06-06 21:29:46 +00:00
echo ::group::Installing ASDF ${{ inputs.asdf-version }}
ros install asdf/${{ inputs.asdf-version }}
else
echo ::group::Installing latest ASDF
ros install asdf
fi
2021-02-06 09:41:50 +00:00
echo ::endgroup: :
2024-02-23 05:22:33 +00:00
- if : inputs.cache == 'false' || steps.roswell-cache-restore.outputs.cache-hit != 'true'
name : Install Qlot
2024-01-26 14:39:24 +00:00
shell : lispsh -eo pipefail {0}
2021-02-06 09:41:50 +00:00
run : |
2021-10-26 15:13:33 +00:00
if [[ "${{ inputs.qlot-version }}" != "latest" ]]; then
echo ::group::Installing Qlot ${{ inputs.qlot-version }}
ros install fukamachi/qlot/${{ inputs.qlot-version }}
else
echo ::group::Installing latest Qlot
ros install fukamachi/qlot
fi
2021-02-06 09:41:50 +00:00
echo .qlot/bin >> $GITHUB_PATH
echo ::endgroup: :
2024-02-23 05:22:33 +00:00
- if : inputs.cache == 'true' && steps.roswell-cache-restore.outputs.cache-hit != 'true'
name : Cache Roswell Setup
id : roswell-cache-save
uses : actions/cache/save@v4
with :
path : ${{ inputs.roswell-cache-paths }}
key : ${{ steps.roswell-cache-restore.outputs.cache-primary-key }}
- if : inputs.cache == 'true'
name : Restore Qlot Environment
id : qlot-cache-restore
uses : actions/cache/restore@v4
with :
path : ${{ inputs.qlot-cache-paths }}
key : qlot-${{ steps.locals.outputs.current-month }}-${{ env.cache-name }}-${{ runner.os }}-${{ env.QUICKLISP_DIST }}-${{ env.LISP }}-${{ hashFiles('qlfile', 'qlfile.lock', '*.asd') }}
- if : inputs.cache == 'true' && steps.qlot-cache-restore.outputs.cache-hit == 'true'
name : Restore Path To .qlot/bin
shell : lispsh -eo pipefail {0}
run : |
echo .qlot/bin >> $GITHUB_PATH
- if : inputs.cache == 'false' || steps.qlot-cache-restore.outputs.cache-hit != 'true'
name : Create Qlot Environment
2024-01-26 14:39:24 +00:00
shell : lispsh -eo pipefail {0}
2021-02-06 09:41:50 +00:00
run : |
echo ::group::Create Qlot Environment
2021-02-06 12:32:32 +00:00
if [[ -n "${QLFILE_TEMPLATE}" ]]; then
2023-08-06 14:04:12 +00:00
echo "${QLFILE_TEMPLATE}" | $GITHUB_ACTION_PATH/templater.ros > qlfile
2021-02-06 12:32:32 +00:00
rm -f qlfile.lock
fi
2021-02-06 12:09:39 +00:00
2021-02-22 10:02:37 +00:00
if [[ -e qlfile ]]; then
echo 'Here is content of qlfile:'
echo '==============='
cat qlfile
echo '==============='
echo ''
else
echo 'There is no qlfile. Creating an empty one.'
touch qlfile
fi
2021-10-26 15:13:33 +00:00
2021-02-06 09:41:50 +00:00
qlot install
echo ::endgroup: :
env :
QLFILE_TEMPLATE : ${{ inputs.qlfile-template }}
# This step will install system and
# all possible roswell scripts, if the system
# has them in the roswell/ subdirectory:
2024-02-23 05:22:33 +00:00
- if : inputs.cache == 'false' || steps.qlot-cache-restore.outputs.cache-hit != 'true'
name : Install ASDF System
2024-01-26 14:39:24 +00:00
shell : lispsh -eo pipefail {0}
2021-02-06 09:41:50 +00:00
run : |
echo ::group::Install ASDF System
2024-01-26 14:39:24 +00:00
2021-02-06 10:01:30 +00:00
if [[ -n "${{ inputs.asdf-system }}" ]]; then
qlot exec ros install ${{ inputs.asdf-system }}
else
echo "ASDF system wasn't provided."
fi
2021-02-06 09:41:50 +00:00
echo ::endgroup: :
2024-01-26 14:39:24 +00:00
2024-02-23 05:22:33 +00:00
- if : inputs.cache == 'true' && steps.qlot-cache-restore.outputs.cache-hit != 'true'
name : Cache Qlot Environment
id : qlot-cache-save
uses : actions/cache/save@v4
with :
path : ${{ inputs.qlot-cache-paths }}
key : ${{ steps.qlot-cache-restore.outputs.cache-primary-key }}
# End of the cached piece
2024-01-26 14:39:24 +00:00
- name : Check it is possible to run desired lisp implementation
shell : lispsh -eo pipefail {0}
2024-01-28 05:52:52 +00:00
# Call ${{ github.action_path }}test.ros does not work on windows
# because of backslashes.
#
# Here we are using sed to transform slashes in the path.
# Without this trick it is impossible to run test.ros on Windows.
#
# The other way to do the trick is to change write path to GITHUB_PATH.
# In this case, GitHub itself will convert backslashes. Hovewer, this
# way the path will be added to the PATH variable of the workflow
# which used setup-lisp and I consider this is not desired behaviour.
run : |
echo ::group::Checking if we installed correct Lisp implementation
if [[ "$RUNNER_OS" == "Windows" ]]; then
ACTION_PATH="$(echo '${{ github.action_path }}' | sed -e 's|/|\\|')\\"
else
ACTION_PATH='${{ github.action_path }}/'
fi
${ACTION_PATH}test.ros
echo ::endgroup: :