Building hyakvnc-freesurfer-ubuntu22.04:latest #87
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Build and Deploy Apptainer Container | |
run-name: "Building ${{ inputs.image_name }}:${{ inputs.image_tag }}" | |
on: | |
workflow_dispatch: | |
inputs: | |
image_name: | |
description: 'Name of the container to build and deploy' | |
required: true | |
image_tag: | |
description: 'Tag of the container to build and deploy' | |
required: false | |
default: 'latest' | |
base_image_tag: | |
description: 'Tag of the base image to use' | |
required: false | |
default: 'latest' | |
defaults: | |
run: | |
shell: bash | |
env: | |
APPTAINER_VERSION: 1.2.5 | |
SETUP_DOWNLOADS_DIR: .setup-downloads | |
GH_TOKEN: ${{ github.token }} | |
jobs: | |
build-and-push-image: | |
runs-on: ubuntu-latest | |
name: Build and Deploy Apptainer Container | |
permissions: | |
contents: read | |
packages: write | |
steps: | |
- name: Check out code for the container build | |
uses: actions/checkout@v4 | |
- name: Create SETUP_DOWNLOADS_DIR | |
run: | | |
set -euxo pipefail | |
mkdir -p "${SETUP_DOWNLOADS_DIR}" | |
- name: Cache downloads in SETUP_DOWNLOADS_DIR | |
uses: actions/cache@v3 | |
with: | |
path: ${{ env.SETUP_DOWNLOADS_DIR }} | |
key: ${{ runner.os }} | |
- name: Get container name | |
run: | | |
set -euxo pipefail | |
IMAGE_NAME="${{ inputs.image_name }}" | |
[[ -n "${IMAGE_NAME:-}" ]] || { echo "No container name found." ; exit 1; } | |
echo "Container name is \"${IMAGE_NAME:-}\"" | |
echo "IMAGE_NAME="${IMAGE_NAME}"" >> $GITHUB_ENV | |
[[ -d "${DEF_DIR:=def/${IMAGE_NAME}}" ]] || { echo "No directory found for DEF_DIR at \"${DEF_DIR:-}\"" ; exit 1; } | |
[[ -f "${DEF_DIR}/Singularity" ]] || { echo "No definition file found at \"${DEF_DIR}/Singularity\"" ; exit 1; } | |
echo "DEF_DIR=${DEF_DIR}" >> $GITHUB_ENV | |
IMAGE_TAG="${{ inputs.image_tag }}" | |
IMAGE_TAG="${IMAGE_TAG:-latest}" | |
echo "Container tag is \"${IMAGE_TAG:-}\"" | |
echo "IMAGE_TAG="${IMAGE_TAG}"" >> $GITHUB_ENV | |
# Get the base image name and tag from the container | |
BOOTSTRAP_FROM_IMAGE="$(sed -nE '0,/^\s*BOOTSTRAP_FROM_IMAGE=(\S*).*$/s//\1/p' "${DEF_DIR}/Singularity" || true)" | |
if [[ -n "${BOOTSTRAP_FROM_IMAGE}" ]]; then | |
BASE_IMAGE_NAME="${BOOTSTRAP_FROM_IMAGE}" | |
echo "Base image name is \"${BASE_IMAGE_NAME}\"" | |
echo "BASE_IMAGE_NAME=\"${BASE_IMAGE_NAME}\"" >> $GITHUB_ENV | |
BASE_IMAGE_TAG="${{ inputs.base_image_tag }}" | |
BASE_IMAGE_TAG="${BASE_IMAGE_TAG:-latest}" | |
echo "Base image tag is \"{BASE_IMAGE_TAG}\"" && echo "BASE_IMAGE_TAG=\"${BASE_IMAGE_TAG}\"" >> $GITHUB_ENV | |
fi | |
# Add bootstrap args for derived containers | |
echo "BOOTSTRAP_SOURCE=oras" >> "${DEF_DIR}/.build-arg-file" | |
echo "BOOTSTRAP_IMAGE_NAME=${BASE_IMAGE_NAME:-}" >> "${DEF_DIR}/.build-arg-file" | |
echo "BOOTSTRAP_FROM_REPO=ghcr.io/${{ github.repository }}" >> "${DEF_DIR}/.build-arg-file" | |
echo "BOOTSTRAP_FROM_SUFFIX=:${BASE_IMAGE_TAG:-latest}" >> "${DEF_DIR}/.build-arg-file" | |
echo ".build-arg-file contents:" | |
cat "${DEF_DIR}/.build-arg-file" 2>/dev/null || echo "No build-arg-file found." | |
- name: Delete GitHub AGENT_TOOLSDIRECTORY to free space | |
run: | | |
set -euxo pipefail | |
echo "Disk space before:" && df -hl | |
sudo rm -rf /opt/hostedtoolcache; echo "Done removing /opt/hostedtoolcache" | |
echo "Disk space after:" && df -hl | |
- name: Delete .NET, Android, Haskell tools to free space | |
run: | | |
set -euxo pipefail | |
echo "Disk space before:" && df -hl | |
sudo rm -rf /usr/share/dotnet /opt/ghc /usr/local/lib/android && echo "Done removing .NET, Android, and Haskell tools." | |
echo "Disk space after:" && df -hl | |
- name: Download and Install Apptainer | |
run: | | |
set -euxo pipefail | |
APPTAINER_LATEST_TAGNAME="$(gh release view --repo apptainer/apptainer --json tagName -t '{{.tagName}}' | head -n 1)" | |
[[ -n "${APPTAINER_LATEST_TAGNAME}" ]] || { echo "No latest tag found for apptainer/apptainer"; exit 1; } | |
echo "Latest tag for apptainer/apptainer is \"${APPTAINER_LATEST_TAGNAME}\"" | |
gh release download --repo apptainer/apptainer --pattern 'apptainer_*_amd64.deb' --skip-existing -O "${SETUP_DOWNLOADS_DIR}/apptainer_${APPTAINER_LATEST_TAGNAME}.deb" "${APPTAINER_LATEST_TAGNAME}" | |
sudo dpkg --install --force-depends "${SETUP_DOWNLOADS_DIR}/apptainer_${APPTAINER_LATEST_TAGNAME}.deb" && sudo apt-get install --fix-broken --yes --quiet | |
apptainer --version | |
- name: Download and Install oras-cli | |
run: | | |
set -euxo pipefail | |
ORAS_LATEST_TAGNAME="$(gh release view --repo oras-project/oras --json tagName -t '{{.tagName}}' | head -n 1)" | |
[[ -n "${ORAS_LATEST_TAGNAME}" ]] || { echo "No latest tag found for oras-project/oras"; exit 1; } | |
echo "Latest tag for oras-project/oras is \"${ORAS_LATEST_TAGNAME}\"" | |
gh release download --repo oras-project/oras --pattern '*linux_amd64.tar.gz' --skip-existing -O "${SETUP_DOWNLOADS_DIR}/oras_${ORAS_LATEST_TAGNAME}.tar.gz" "${ORAS_LATEST_TAGNAME}" | |
sudo mkdir -p /opt/local/bin | |
sudo tar -xzf "${SETUP_DOWNLOADS_DIR}/oras_${ORAS_LATEST_TAGNAME}_linux_amd64.tar.gz" -C /opt/local/bin oras && sudo chmod +x /opt/local/bin/oras | |
export PATH="/opt/local/bin:${PATH}" | |
echo "PATH=${PATH}" >> $GITHUB_ENV | |
oras version | |
- name: Build Container | |
run: | | |
set -euxo pipefail | |
export APPTAINER_CACHE_DIR="${SETUP_DOWNLOADS_DIR}/apptainer-cache" | |
mkdir -p sif | |
pushd "${DEF_DIR}" | |
echo "Building \"${IMAGE_NAME}.sif\"" | |
touch .build-arg-file | |
apptainer build --warn-unused-build-args --fix-perms --force --build-arg-file .build-arg-file ../../sif/"${IMAGE_NAME}.sif" Singularity || { echo "Failed to build \"${IMAGE_NAME}.sif\""; exit 1; } | |
echo "Built \"${IMAGE_NAME}.sif\"" | |
popd | |
- name: Login and Deploy Container | |
run: | | |
set -euxo pipefail | |
[[ -r "sif/${IMAGE_NAME}.sif" ]] || { echo "No container named sif/${IMAGE_NAME:-}.sif found."; exit 1; } | |
echo "Container size:" | |
du -h "sif/${IMAGE_NAME}.sif" | |
echo "Disk usage:" | |
df -h | |
echo "Pushing \"sif/${IMAGE_NAME}.sif\" to ghcr.io/${{ github.repository }}/${IMAGE_NAME}:${IMAGE_TAG}" | |
apptainer remote login -u ${{ github.actor }} -p ${{ secrets.TOKEN }} oras://ghcr.io | |
apptainer push -U "sif/${IMAGE_NAME}.sif" oras://ghcr.io/${{ github.repository }}/${IMAGE_NAME}:${IMAGE_TAG} || { echo "Failed to push \"sif/${IMAGE_NAME}.sif\' to ghcr.io/${{ github.repository }}/${IMAGE_NAME}:${IMAGE_TAG}"; exit 1; } | |
echo "Pushed \"sif/${IMAGE_NAME}.sif\" to ghcr.io/${{ github.repository }}/${IMAGE_NAME}:${IMAGE_TAG}" | |
# Add "latest" tag if IMAGE_TAG is not latest | |
if [[ "${IMAGE_TAG}" != "latest" ]]; then | |
oras login -u ${{ github.actor }} -p ${{ secrets.TOKEN }} ghcr.io | |
oras tag ghcr.io/${{ github.repository }}/${IMAGE_NAME}:${IMAGE_TAG} latest | |
fi |