diff --git a/.github/workflows/CI_apptainer.yml b/.github/workflows/CI_apptainer.yml new file mode 100644 index 000000000..e128de233 --- /dev/null +++ b/.github/workflows/CI_apptainer.yml @@ -0,0 +1,40 @@ +name: Apptainer + +on: + push: + branches: + - 'master' + paths: + - '**' + tags: + - 'v*.*.*' + pull_request: + branches: + - 'master' + paths: + - '**' + +jobs: + test: + runs-on: ${{ matrix.os }} + timeout-minutes: 60 + defaults: + run: + shell: bash + strategy: + matrix: + os: [ubuntu-latest] + + steps: + - uses: actions/checkout@v4 + - uses: eWaterCycle/setup-apptainer@v2 + with: + apptainer-version: 1.3.0 + - name: Build apptainer + run: apptainer build --notest pysr.sif Apptainer.def + - name: Test apptainer + run: | + TMPDIR=$(mktemp -d) + cp pysr.sif $TMPDIR + cd $TMPDIR + apptainer test ./pysr.sif diff --git a/Apptainer.def b/Apptainer.def new file mode 100644 index 000000000..962f81687 --- /dev/null +++ b/Apptainer.def @@ -0,0 +1,55 @@ +# Build an Apptainer SIF file containing a working copy of PySR and its prereqs +Bootstrap: docker +From: julia:1.10.4-bullseye +Stage: jl + +Bootstrap: docker +From: python:3.12-bullseye +Stage: runtime + +%environment + # Use the container Julia binary + export PATH="/usr/local/julia/bin:$PATH" + + # Create a stacked environment for additional Julia packages + export JULIA_DEPOT_PATH="$HOME/.pysr:/pysr/depot:$JULIA_DEPOT_PATH" + export JULIA_LOAD_PATH="$HOME/.pysr:/pysr:$JULIA_LOAD_PATH" + +%files from jl + /usr/local/julia /usr/local/julia + +%files + ./requirements.txt /pysr/requirements.txt + ./pyproject.toml /pysr/pyproject.toml + ./setup.py /pysr/setup.py + ./pysr /pysr/pysr + +%post + # Ensure we don't use the local pysr commands: + cd $(mktemp -d) + + export PATH="/usr/local/julia/bin:$PATH" + + # Install IPython and other useful libraries: + pip3 install --no-cache-dir ipython matplotlib pytest nbval + # Install PySR and requirements: + pip3 install --no-cache-dir /pysr + + # Put the Julia dependencies in /pysr/depot + mkdir /pysr/depot + export JULIA_DEPOT_PATH="/pysr/depot" + + # And set a specific environment for Julia dependencies + mkdir /pysr/env + export PYTHON_JULIAPKG_PROJECT="/pysr/env" + + # Pull in all the Julia dependencies + python3 -c 'import pysr; pysr.load_all_packages()' + +%test + python3 -m pysr test main,cli,startup + +%runscript + # Start ipython when the container is executed + [ ! -d $HOME/.pysr ] && mkdir $HOME/.pysr + PYTHONPATH=/pysr ipython diff --git a/pysr/test/test_startup.py b/pysr/test/test_startup.py index 8bc78a6c1..6ad64b624 100644 --- a/pysr/test/test_startup.py +++ b/pysr/test/test_startup.py @@ -134,6 +134,8 @@ def test_notebook(self): self.skipTest("Julia version too old") if platform.system() == "Windows": self.skipTest("Notebook test incompatible with Windows") + if not os.access(Path(__file__).parent, os.W_OK): + self.skipTest("Read-only file system") notebook_file = Path(__file__).parent / "test_nb.ipynb" sanitize_file = Path(__file__).parent / "nb_sanitize.cfg"