Skip to content

Commit 42fc0e5

Browse files
committed
Added initial singularity / apptainer container image recipe, as well as a CI image building workflow
1 parent 4dcd624 commit 42fc0e5

2 files changed

Lines changed: 165 additions & 0 deletions

File tree

.github/workflows/container.yml

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
name: Singularity Build (docker)
2+
on:
3+
workflow_dispatch:
4+
push:
5+
tags:
6+
- 'v*'
7+
8+
# # Do the builds on all pull requests (to test them)
9+
# pull_request:
10+
11+
jobs:
12+
#changes:
13+
# name: "Changed Singularity Recipes"
14+
# runs-on: ubuntu-latest
15+
# outputs:
16+
# changed_file: ${{ steps.files.outputs.added_modified }}
17+
# steps:
18+
# - id: files
19+
# uses: jitterbit/get-changed-files@d06c756e3609dd3dd5d302dde8d1339af3f790f2
20+
# with:
21+
# format: 'json'
22+
gather-metadata:
23+
runs-on: ubuntu-latest
24+
outputs:
25+
tags: ${{ steps.meta.outputs.tags }}
26+
labels: ${{ steps.meta.outputs.labels }}
27+
# Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job.
28+
permissions:
29+
contents: read
30+
packages: write
31+
attestations: write
32+
id-token: write
33+
#
34+
steps:
35+
- name: Extract metadata (tags, labels) for Docker
36+
id: meta
37+
uses: docker/metadata-action@v6.0.0
38+
with:
39+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
40+
41+
build-test-containers:
42+
needs:
43+
- gather-metadata
44+
# - changes
45+
runs-on: ubuntu-latest
46+
strategy:
47+
# Keep going on other deployments if anything bloops
48+
fail-fast: false
49+
matrix:
50+
# changed_file: ${{ fromJson(needs.changes.outputs.changed_file) }}
51+
changed_file: [ 'installation/Singularity.def' ]
52+
singularity_version:
53+
- '4.3.1'
54+
55+
container:
56+
image: quay.io/singularity/singularity:v${{ matrix.singularity_version }}
57+
options: --privileged
58+
59+
name: Check ${{ matrix.changed_file }}
60+
steps:
61+
62+
- name: Check out code for the container builds
63+
uses: actions/checkout@v6
64+
65+
- name: Continue if Singularity Recipe
66+
run: |
67+
# Continue if we have a changed Singularity recipe
68+
case "${{ matrix.changed_file }}" in
69+
*/Singularity*def)
70+
echo "keepgoing=true" >> "$GITHUB_ENV"
71+
;;
72+
esac
73+
74+
- name: Build Container
75+
if: ${{ env.keepgoing == 'true' }}
76+
env:
77+
recipe: ${{ matrix.changed_file }}
78+
run: |
79+
ls
80+
if [ -f "$recipe" ]; then
81+
sudo -E singularity build --build-arg treecript_checkout=${{ github.sha }} container.sif "$recipe"
82+
tag="${recipe/Singularity\./}"
83+
if [ "$tag" == "def" ]; then
84+
tag=latest
85+
fi
86+
# Build the container and name by tag
87+
echo "Tag is $tag."
88+
echo "tag=$tag" >> "$GITHUB_ENV"
89+
else
90+
echo "$recipe is not found."
91+
echo "Present working directory: $PWD"
92+
ls
93+
fi
94+
95+
- name: Login and Deploy Container
96+
if: (github.event_name != 'pull_request')
97+
env:
98+
keepgoing: ${{ env.keepgoing }}
99+
run: |
100+
if [[ "${keepgoing}" == "true" ]]; then
101+
echo "${{ secrets.GITHUB_TOKEN }}" | singularity remote login -u "${{ secrets.GHCR_USERNAME }}" --password-stdin oras://ghcr.io
102+
declare -a tags=( ${{ needs.gather-metadata.outputs.tags }} )
103+
for tag in "${tags[@]}" ; do
104+
echo singularity push container.sif "oras://ghcr.io/${GITHUB_REPOSITORY}:${tag}"
105+
done
106+
fi

installation/Singularity.def

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
Bootstrap: docker
2+
From: python:3.13-slim-trixie
3+
Stage: build
4+
5+
%arguments
6+
# The default images of python are based on debian
7+
# These arguments help customizing what it is included in the generated image
8+
treecript_checkout=db83dbc42e988cb22bd3570e92348b70f64ed3e5
9+
10+
%post
11+
set -ue
12+
13+
cd /
14+
15+
apt-get update
16+
apt-get install -y --no-install-recommends build-essential git
17+
18+
# Install treecript, trusting the installers in the commit rather than the
19+
# one in the docker recipe
20+
git clone --filter=blob:none --no-checkout https://github.com/inab/treecript.git
21+
cd treecript
22+
git sparse-checkout init --cone
23+
PYVER=$(python -c 'import sys; import platform ; print("{}{}.{}".format("pypy" if platform.python_implementation() == "PyPy" else "", sys.version_info.major, sys.version_info.minor))')
24+
git sparse-checkout set installation/constraints-${PYVER}.txt
25+
git checkout "{{ treecript_checkout }}"
26+
grep -vF git+ installation/constraints-${PYVER}.txt > installation/constraints-${PYVER}.txt-relaxed
27+
pip install --no-cache-dir --upgrade pip wheel
28+
pip install --no-cache-dir "git+https://github.com/inab/treecript.git@{{ treecript_checkout }}" -c installation/constraints-"${PYVER}".txt-relaxed
29+
python -m compileall "$(python -c 'import sys; print(sys.prefix)')"
30+
31+
Bootstrap: docker
32+
From: python:3.13-slim-trixie
33+
Stage: image
34+
35+
%files from build
36+
/usr/local /usr
37+
38+
%post
39+
set -ue
40+
41+
# # Install docker-ce-cli
42+
# # Cleanups
43+
# DPKG_ARCH=$(dpkg --print-architecture) && \
44+
# python -c 'import urllib.request ; urllib.request.urlretrieve("https://download.docker.com/linux/debian/gpg", "/etc/apt/keyrings/docker.asc")' && \
45+
# chmod a+r /etc/apt/keyrings/docker.asc && \
46+
# echo \
47+
# "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \
48+
# $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
49+
# tee /etc/apt/sources.list.d/docker.list > /dev/null && \
50+
# apt-get update && \
51+
# apt-get install -y --no-install-recommends docker-ce-cli
52+
53+
%runscript
54+
cd /
55+
exec /bin/bash bash "$@"
56+
57+
%startscript
58+
cd /
59+
exec /bin/bash bash "$@"

0 commit comments

Comments
 (0)