Skip to content

Commit 62faf79

Browse files
committed
Added workflows
1 parent 47de74e commit 62faf79

File tree

5 files changed

+720
-0
lines changed

5 files changed

+720
-0
lines changed

.build-scripts/tag-release.sh

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#!/usr/bin/env bash
2+
# shellcheck shell=bash
3+
set -euo pipefail
4+
[[ "${XDEBUG:-0}" =~ ^[1yYtT] ]] && set -x
5+
6+
IMAGE_TAG_SEP="@"
7+
8+
IMAGE_NAME="${1:-}"
9+
[[ -n "${IMAGE_NAME:-}" ]] || { echo "IMAGE_NAME is empty" >&2; exit 1; }
10+
shift
11+
12+
IMAGE_TAG="${1:-}"
13+
if [[ -z "${IMAGE_TAG:-}" ]]; then
14+
IMAGE_TAG="latest"
15+
echo "IMAGE_TAG is empty, using default: ${IMAGE_TAG}" >&2
16+
else
17+
shift
18+
fi
19+
20+
FULL_CONTAINER_NAME="${IMAGE_NAME}:${IMAGE_TAG}"
21+
22+
GIT_TAG="${IMAGE_NAME}${IMAGE_TAG_SEP}${IMAGE_TAG}"
23+
24+
[[ -n "${GIT_TAG:-}" ]] || { echo "GIT_TAG is empty" >&2; exit 1; }
25+
26+
comment="${1:-}"
27+
if [[ -z "${comment:-}" ]]; then
28+
comment="${FULL_CONTAINER_NAME}"
29+
echo "comment is empty, using default: ${comment}" >&2
30+
else
31+
shift
32+
fi
33+
34+
git_tag_args=()
35+
git_commit_args=()
36+
if [[ -n "${comment:-}" ]]; then
37+
git_tag_args+=(-m "${comment}")
38+
git_commit_args+=(-m "${comment}")
39+
fi
40+
41+
for arg in "$@"; do
42+
git_tag_args+=(-m "${arg}")
43+
git_commit_args+=(-m "${arg}")
44+
done
45+
46+
echo "git_tag_args: ${git_commit_args[*]}" >&2
47+
echo "git_commit_args: ${git_commit_args[*]}" >&2
48+
49+
if git tag -l "${GIT_TAG:-}" | grep -q "^${GIT_TAG:-}$"; then
50+
echo "git tag ${GIT_TAG} already exists" >&2
51+
if [[ -t 1 ]]; then
52+
choice=y
53+
read -rp "Do you want to continue? [Y/n] " choice
54+
[[ "${choice:-y}" =~ ^[Yy]$ ]] || exit 1
55+
fi
56+
fi
57+
58+
if [[ -t 1 ]]; then
59+
echo "git tag -fa ${GIT_TAG} ${git_tag_args[*]}"
60+
choice=y
61+
read -rp "Do you want to continue? [Y/n] " choice
62+
[[ "${choice:-y}" =~ ^[Yy]$ ]] || exit 1
63+
fi
64+
65+
git commit --allow-empty "${git_commit_args[@]}"
66+
git push
67+
git tag -fa "${GIT_TAG}" "${git_tag_args[@]}"
68+
69+
echo 'Tag contents:'
70+
git tag -l --format='%(contents)' "$(git describe --tags --abbrev=0 || true)"
71+
72+
if [[ -t 1 ]]; then
73+
choice=y
74+
75+
if git remote get-url origin 2>/dev/null 1>&2; then
76+
read -rp "Do you want to push to origin? [Y/n] " choice
77+
[[ "${choice:-y}" =~ ^[Yy]$ ]] && git push -f origin "${GIT_TAG}"
78+
fi
79+
80+
if git remote get-url upstream 2>/dev/null 1>&2; then
81+
read -rp "Do you want to push to upstream? [Y/n] " choice
82+
[[ "${choice:-y}" =~ ^[Yy]$ ]] && git push -f upstream "${GIT_TAG}"
83+
fi
84+
fi
+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#!/bin/sh
2+
# shellcheck shell=sh
3+
4+
# Write the build labels to the build labels path for both the org.label-schema and org.opencontainers.image formats
5+
6+
[ -n "${XDEBUG:-}" ] && set -x
7+
8+
write_to_build_labels() {
9+
while [ $# -gt 1 ]; do
10+
eval "[ -n \"\${$#}\" ] && printf '%s %s\n' \"$1\" \"\${$#}\"" >>"${BUILD_LABELS_PATH:-/dev/stdout}"
11+
shift
12+
done
13+
return 0
14+
}
15+
16+
write_apptainer_labels() {
17+
#[ -n "${APPTAINER_ROOTFS:-}" ] || return 1 # Exit if not in an apptainer build
18+
#BUILD_LABELS_PATH="${BUILD_LABELS_PATH:-${APPTAINER_ROOTFS:+${APPTAINER_ROOTFS}/.build.labels}}" # Set the default build labels path
19+
if [ -n "${APPTAINER_ROOTFS:-}" ]; then
20+
BUILD_LABELS_PATH="${BUILD_LABELS_PATH:-${APPTAINER_ROOTFS}/.build.labels}"
21+
else
22+
BUILD_LABELS_PATH="${BUILD_LABELS_PATH:-/dev/stdout}"
23+
fi
24+
25+
# Try to fill in the build labels via git if not already set and git is available
26+
if git tag >/dev/null 2>&1; then
27+
IMAGE_VCS_URL="${IMAGE_VCS_URL:-$(git remote get-url origin || true)}" # Set the default VCS URL to the origin remote
28+
[ -z "${IMAGE_URL:-}" ] && [ -n "${IMAGE_VCS_URL:-}" ] && IMAGE_URL="${IMAGE_VCS_URL%%.git}" # Set the default URL to the VCS URL without the .git extension
29+
IMAGE_VCS_REF="${IMAGE_VCS_REF:-$(git rev-parse --short HEAD || true)}" # Set the default VCS ref to the short hash of HEAD
30+
31+
IMAGE_GIT_TAG="${GITHUB_REF_NAME:-"$(git tag --points-at HEAD --list '*@*' --sort=-"creatordate:iso" || true)"}" # Set the default git tag to the most recent tag matching the format *@* sorted by date
32+
33+
if [ -n "${IMAGE_GIT_TAG:-}" ]; then
34+
if [ -z "${IMAGE_TAG:-}" ]; then
35+
IMAGE_TAG="$(echo "${IMAGE_GIT_TAG:-}" | sed -nE 's/.*[@]//; s/^v//; 1p')"
36+
[ -z "${IMAGE_TAG:-}" ] && IMAGE_TAG='latest'
37+
fi
38+
39+
if [ -n "${IMAGE_TITLE:-}" ]; then
40+
IMAGE_TITLE="$(echo "${IMAGE_GIT_TAG}" | sed -nE 's/[@].*$//; 1p')"
41+
fi
42+
fi
43+
fi
44+
IMAGE_TAG="${IMAGE_TAG:-latest}" # Set the default tag to latest if no tag was found
45+
IMAGE_TITLE="${IMAGE_TITLE:-"$(basename "${PWD}")"}" # Set the default title to the current directory name
46+
IMAGE_VERSION="${IMAGE_VERSION:-${IMAGE_TAG:-}}" # Set the default version to the tag if set, otherwise the tag if set, otherwise empty
47+
48+
# If no image vendor is set, try to set it to the GitHub organization:
49+
if [ -z "${IMAGE_VENDOR:=${IMAGE_VENDOR:-}}" ]; then
50+
# If the GitHub organization is not set, try to set it to the GitHub organization of the upstream remote:
51+
[ -z "${GH_ORG:-}" ] && GH_ORG="$(git remote get-url upstream | sed -n 's/.*github.com[:/]\([^/]*\)\/.*/\1/p' || true)"
52+
# If the GitHub organization is not set, try to set it to the GitHub organization of the origin remote:
53+
[ -z "${GH_ORG:-}" ] && GH_ORG="$(git remote get-url origin | sed -n 's/.*github.com[:/]\([^/]*\)\/.*/\1/p' || true)"
54+
55+
# Assign the image vendor to the GitHub organization or username if it is set, otherwise leave it empty:
56+
IMAGE_VENDOR="${GH_ORG:-}"
57+
58+
# If the GitHub organization is set to uw-psych, set the image vendor to the University of Washington Department of Psychology:
59+
[ "${IMAGE_VENDOR:-}" = 'uw-psych' ] && IMAGE_VENDOR='University of Washington Department of Psychology'
60+
fi
61+
62+
# Try to set image author from GITHUB_REPOSITORY_OWNER if not set:
63+
IMAGE_AUTHOR="${IMAGE_AUTHOR:-${GITHUB_REPOSITORY_OWNER:-}}"
64+
65+
# If no image author is set, try to set it to the git author via git config:
66+
if [ -z "${IMAGE_AUTHOR:-}" ] && command -v git >/dev/null 2>&1; then
67+
[ -n "${IMAGE_AUTHOR_EMAIL:-}" ] || IMAGE_AUTHOR_EMAIL="$(git config --get user.email || git config --get github.email || true)"
68+
[ -n "${IMAGE_AUTHOR_NAME:-}" ] || IMAGE_AUTHOR_NAME="$(git config --get user.name || git config --get github.user || true)"
69+
IMAGE_AUTHOR="${IMAGE_AUTHOR_NAME:+${IMAGE_AUTHOR_NAME} }<${IMAGE_AUTHOR_EMAIL:-}>"
70+
fi
71+
72+
# Write the build labels to the build labels path for both the org.label-schema and org.opencontainers.image formats:
73+
write_to_build_labels "org.label-schema.title" "org.opencontainers.image.title" "${IMAGE_TITLE:-}"
74+
write_to_build_labels "org.label-schema.url" "org.opencontainers.image.url" "${IMAGE_URL:-}"
75+
write_to_build_labels "org.label-schema.vcs-ref" "org.opencontainers.image.revision" "${IMAGE_VCS_REF:-}"
76+
write_to_build_labels "org.label-schema.vcs-url" "org.opencontainers.image.source" "${IMAGE_VCS_URL:-}"
77+
write_to_build_labels "org.label-schema.vendor" "org.opencontainers.image.vendor" "${IMAGE_VENDOR:-}"
78+
write_to_build_labels "MAINTAINER" "maintainer" "org.opencontainers.image.authors" "${IMAGE_AUTHOR:-}"
79+
write_to_build_labels "org.label-schema.description" "org.opencontainers.image.description" "${IMAGE_DESCRIPTION:-}"
80+
write_to_build_labels "org.label-schema.usage" "org.opencontainers.image.documentation" "${IMAGE_DOCUMENTATION:-}"
81+
write_to_build_labels "org.label-schema.version" "org.opencontainers.image.version" "${IMAGE_VERSION:-}"
82+
}
83+
84+
! (return 0 2>/dev/null) || write_apptainer_labels "$@"

.github/workflows/apptainer-image.yml

+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
name: Apptainer Build
2+
on:
3+
push:
4+
tags:
5+
- "*@*"
6+
7+
defaults:
8+
run:
9+
shell: bash
10+
11+
env:
12+
APPTAINER_VERSION: 1.2.5
13+
ORAS_VERSION: 1.1.0
14+
15+
jobs:
16+
build-and-push-image:
17+
runs-on: ubuntu-latest
18+
name: Build Apptainer image
19+
permissions:
20+
contents: write
21+
packages: write
22+
23+
steps:
24+
- name: Download Apptainer
25+
run: |
26+
set -eux -o pipefail
27+
curl -o "apptainer-${APPTAINER_VERSION}.deb" -L https://github.com/apptainer/apptainer/releases/download/v${APPTAINER_VERSION}/apptainer_${APPTAINER_VERSION}_amd64.deb
28+
export DEBIAN_FRONTEND=noninteractive
29+
sudo apt-get update -yq || echo "Couldn't update apt packages. Will attempt installation without update" >&2
30+
sudo dpkg --install --force-depends "apptainer-${APPTAINER_VERSION}.deb" && sudo apt-get install --fix-broken --yes --quiet
31+
apptainer >&2 --version && echo >&2 "Apptainer installed successfully!"
32+
apptainer remote login -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} oras://ghcr.io && echo "Logged in to remote registry successfully" >&2
33+
34+
- name: Install ORAS
35+
run: |
36+
set -eux -o pipefail
37+
curl -o "oras_${ORAS_VERSION}.tar.gz" -L "https://github.com/oras-project/oras/releases/download/v${ORAS_VERSION}/oras_${ORAS_VERSION}_linux_amd64.tar.gz"
38+
39+
# Install the executable:
40+
tar -xvf oras_${ORAS_VERSION}.tar.gz && chmod +x oras && sudo mv oras /usr/local/bin/oras
41+
sudo mv "${DOWNLOAD_PATH}" /usr/local/bin/oras && sudo chmod +x /usr/local/bin/oras & oras >&2 version && echo >&2 "oras installed successfully!"
42+
oras login -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} ghcr.io && echo "Logged in to remote registry successfully" >&2
43+
44+
- name: Check out code for the container build
45+
uses: actions/checkout@v4
46+
47+
- name: Build Container
48+
run: |
49+
set -eux -o pipefail
50+
if [[ "${GITHUB_REF_TYPE:-}" == "tag" ]] && [[ "${GITHUB_REF}" =~ ^.*@.*$ ]]; then
51+
[[ -z "${IMAGE_NAME:-}" ]] && IMAGE_NAME="${GITHUB_REF%%@*}" && IMAGE_NAME="${IMAGE_NAME##refs/tags/}"
52+
[[ -z "${IMAGE_TAG:-}" ]] && IMAGE_TAG="${GITHUB_REF##*@}" && IMAGE_TAG="${IMAGE_TAG##*v}"
53+
fi
54+
55+
[[ -z "${IMAGE_NAME:-}" ]] && IMAGE_NAME="${GITHUB_REPOSITORY##*/}"
56+
[[ -z "${IMAGE_TAG:-}" ]] && IMAGE_TAG="$(date +%s)"
57+
58+
if [[ -d "${IMAGE_NAME}" ]] && [[ -f "${IMAGE_NAME}/Singularity" ]]; then
59+
cd "${IMAGE_NAME}"
60+
echo "Using Singularity file in ${PWD}" >&2
61+
elif [[ -f Singularity ]]; then
62+
echo "Using Singularity file in root directory" >&2
63+
else
64+
echo "No Singularity file found in \"${IMAGE_NAME:-}\" or root directory" >&2
65+
exit 1
66+
fi
67+
68+
IMAGE_PATH="${GITHUB_WORKSPACE}/${IMAGE_NAME}".sif
69+
70+
echo "IMAGE_NAME=${IMAGE_NAME}" >> $GITHUB_ENV
71+
echo "IMAGE_TAG=${IMAGE_TAG}" >> $GITHUB_ENV
72+
echo "IMAGE_PATH=${IMAGE_PATH}" >> $GITHUB_ENV
73+
74+
echo "IMAGE_NAME=${IMAGE_NAME}" >&2
75+
echo "IMAGE_TAG=${IMAGE_TAG}" >&2
76+
echo "IMAGE_PATH=${IMAGE_PATH}" >&2
77+
78+
apptainer build --nv --fix-perms --disable-cache --force "${IMAGE_PATH}" Singularity
79+
80+
echo "Container built successfully" >&2
81+
82+
echo "Container size:" >&2
83+
du -h "${IMAGE_PATH}" >&2
84+
85+
echo "Container labels:" >&2
86+
apptainer inspect "${IMAGE_PATH}" >&2
87+
88+
- name: Push Container
89+
run: |
90+
set -eux -o pipefail
91+
92+
if [[ "${GITHUB_REF_TYPE:-}" == "tag" ]] && [[ "${GITHUB_REF}" =~ ^.*@.*$ ]]; then
93+
[[ -z "${IMAGE_NAME:-}" ]] && IMAGE_NAME="${GITHUB_REF%%@*}" && IMAGE_NAME="${IMAGE_NAME##refs/tags/}"
94+
[[ -z "${IMAGE_TAG:-}" ]] && IMAGE_TAG="${GITHUB_REF##*@}" && IMAGE_TAG="${IMAGE_TAG##*v}"
95+
fi
96+
97+
[[ -z "${IMAGE_NAME:-}" ]] && IMAGE_NAME="${GITHUB_REPOSITORY##*/}"
98+
[[ -z "${IMAGE_TAG:-}" ]] && IMAGE_TAG="$(date +%s)"
99+
100+
# Log in:
101+
apptainer remote login -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} oras://ghcr.io
102+
103+
# Push the image:
104+
apptainer push -U "${IMAGE_PATH}" oras://ghcr.io/${{ github.repository }}/${IMAGE_NAME}:${IMAGE_TAG}
105+
106+
# Tag the image as latest if it's not a pre-release:
107+
if [[ "${IMAGE_TAG}" != "latest" ]] && [[ ! "${IMAGE_TAG}" =~ ^[0-9]+\.[0-9]+\.[0-9]+-.+$ ]]; then
108+
oras tag -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} ghcr.io/${{ github.repository }}/${IMAGE_NAME}:${IMAGE_TAG} latest
109+
fi
110+
echo "Done" >&2
+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
name: Apptainer Build
2+
on:
3+
push:
4+
branches:
5+
- main
6+
paths:
7+
- README.md.esh
8+
- .github/workflows/scripts/esh
9+
- .github/workflows/build-documentation.yml
10+
11+
jobs:
12+
build-and-push-image:
13+
runs-on: ubuntu-latest
14+
name: Build documentation
15+
permissions: write-all
16+
steps:
17+
- name: Check out code for the container build
18+
uses: actions/checkout@v4
19+
with:
20+
fetch-depth: 0
21+
- name: Build documentation
22+
shell: bash
23+
run: |
24+
set -eux -o pipefail
25+
26+
# Run esh to fill in the variables:
27+
"${GITHUB_WORKSPACE}/.github/workflows/scripts/esh" "${GITHUB_WORKSPACE}/README.md.esh" > "${GITHUB_WORKSPACE}/README.md"
28+
29+
# Stage files:
30+
git add README.md
31+
32+
# Build additions to commit message:
33+
commit_args=()
34+
35+
# Get the last commit message, if any:
36+
last_commit_msg="$(git log -1 --pretty=format:%B || true)"
37+
38+
if git diff --staged --name-only "README.md" | grep -Fq "README.md"; then
39+
commit_args+=(-m "GITHUB_ACTION=\"${GITHUB_ACTION:-}\": Templated \"README.md\" for GITHUB_REPOSITORY=\"${GITHUB_REPOSITORY}\"")
40+
fi
41+
42+
if (( "${#commit_args[@]}" > 1 )); then
43+
44+
# Don't append to commit message:
45+
if [[ "${GITHUB_REF_TYPE:-}" == "tag" ]] && [[ "${GITHUB_REF}" =~ ^.*@.*$ ]]; then
46+
echo "Not appending commit messages because this is a tagged release" >&2
47+
commit_args=()
48+
fi
49+
50+
# Set up git config for push:
51+
git config --local user.email "${{ github.event.sender.id }}+${{ github.event.sender.login }}@users.noreply.github.com"
52+
git config --local user.name ${{ github.event.sender.login }}
53+
git commit -a "${last_commit_msg:+-m ${last_commit_msg:-}}" "${commit_args[@]}" && git push --force
54+
fi

0 commit comments

Comments
 (0)