Skip to content

chore: update pre-commit hooks (#164) #712

chore: update pre-commit hooks (#164)

chore: update pre-commit hooks (#164) #712

Workflow file for this run

# The logic of the file is a bit convoluted so I'll describe what should
# happen. Dockerfiles are expected to be labeled based on how they should be
# released/tagged. See example below to decide how to define your dockerfile.
# Note: one must define version and/or ref.name (enforced by 'check' job.)
#
# * on a PR:
# - changed images
# ✓ build
# ✓ run
# X deploy
# X release (re-tag)
# X unchanged images
#
# * on a push to main:
# - changed images
# ✓ build
# ✓ run
# ✓ deploy image to org.opencontainers.image.version if set (e.g., version "x.y.z")
# ✓ deploy image to org.opencontainers.image.ref.name if set (e.g., "latest")
# X release (re-tag)
# X unchanged images
#
# * on a tag:
# X changed images
# X unchanged images
#
# * on a published release:
# X changed images
# - unchanged images
# ✓ build
# ✓ run
# X deploy
# ✓ release latest images as $RELEASE if org.opencontainers.image.version unset
# ✓ release latest images as stable
#
# Dockerfile/${IMAGE_NAME}-{SUFFIX}
# LABEL org.opencontainers.image.version=${VERSION}
# LABEL org.opencontainers.image.ref.name=${REFNAME}
#
# Containers can have a suffix which will be appropriately added to all above tags accordingly if the suffix is not latest.
# Containers labeled with image.ref.name will have an associated tag on push, but
# Containers labeled with image.version will not have a mapyde-release associated tag, but will have a "-stable" associated tag.
#
# -------------------------------------------------------------------------------------
#
# Example of above logic for container registry tags for following containers:
#
# - Dockerfiles/pyplotting
# LABEL org.opencontainers.image.ref.name=latest
#
# - Dockerfiles/delphes-snowmass
# LABEL org.opencontainers.image.version=snowmass
# LABEL org.opencontainers.image.ref.name=snowmass
#
# - Dockerfiles/delphes
# LABEL org.opencontainers.image.version=3.5.0
# LABEL org.opencontainers.image.ref.name=latest
#
# - Dockerfiles/pyplotting-arm
# LABEL org.opencontainers.image.ref.name=latest
#
# - Dockerfile/pyplotting-cuda
# LABEL org.opencontainers.image.ref.name=latest
# LABEL org.opencontainers.image.version=alternate
#
# * on a PR:
# - changed images: nothing
# - unchanged images: nothing
#
# * on a push to main:
# - changed images: pyplotting:latest, pyplotting:latest-arm, pyplotting:latest-cuda, pyplotting:alternate-cuda, delphes:snowmass, delphes:3.5.0, delphes:latest, delphes:latest-snowmass
# X unchanged images
#
# * on a tag:
# X changed images
# X unchanged images
#
# * on a published release (x.y.z):
# X changed images
# - unchanged images: pyplotting:x.y.z, pyplotting:x.y.z-arm, pyplotting:stable, pyplotting:stable-arm, pyplotting:stable-cuda, delphes:latest-stable
#
# =====================================================================================
name: Docker Images
on:
push:
branches:
- main
pull_request:
branches:
- main
release:
types: [published]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
check:
name: Check Dockerfiles
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Verify labels
run: |
fail=0
for dockerfile in $(find Dockerfiles/ -type f); do
if grep -q -E 'org\.opencontainers\.image\.(version|ref\.name)' ${dockerfile}
then
if grep -q -E 'org\.opencontainers\.image\.version.*=.*(latest|latest-stable)$' ${dockerfile}
then
echo -e " \033[0;31mX\033[0m ${dockerfile}: version=latest or version=latest-stable"
fail=1
else
echo -e " \033[0;32m✓\033[0m ${dockerfile}: ok"
fi
else
echo -e " \033[0;31mX\033[0m ${dockerfile}: labels missing"
fail=1
fi
done
if [[ $fail == 1 ]]; then
exit 1
fi
changes:
needs: [check]
runs-on: ubuntu-latest
outputs:
changed: ${{ steps.filter.outputs.changed }}
all_images: ${{ steps.set.outputs.all_images }}
changed_images: ${{ steps.set.outputs.changed_images }}
unchanged_images: ${{ steps.set.outputs.unchanged_images }}
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
id: filter
with:
list-files: json
filters: |
changed: Dockerfiles/**
- id: set
run: |
ALL_IMAGES=$(find Dockerfiles/ -type f | xargs -n1 basename | jq -R -s -c 'split("\n")[:-1]' | tr '-' ':')
echo "::set-output name=all_images::${ALL_IMAGES}"
printf "Setting all_images=${ALL_IMAGES}\n"
CHANGED_IMAGES=$(printf ${{ toJSON(steps.filter.outputs.changed_files) }} | jq -c '.[] |= split("/")[1]' | tr '-' ':')
echo "::set-output name=changed_images::${CHANGED_IMAGES}"
printf "Setting changed_images=${CHANGED_IMAGES}\n"
UNCHANGED_IMAGES=$(jq -n -c --argjson all_images ${ALL_IMAGES} --argjson changed_images ${CHANGED_IMAGES} '$all_images-$changed_images')
echo "::set-output name=unchanged_images::${UNCHANGED_IMAGES}"
printf "Setting unchanged_images=${UNCHANGED_IMAGES}\n"
build:
name: Build ${{ matrix.image }}
needs: [changes]
if: ${{ needs.changes.outputs.changed == 'true' }}
runs-on: ubuntu-latest
strategy:
matrix:
image: ${{ fromJSON(needs.changes.outputs.changed_images) }}
steps:
- name: Get more space # https://github.com/actions/runner-images/issues/2840#issuecomment-790492173
run: |
sudo rm -rf /usr/share/dotnet
sudo rm -rf /opt/ghc
sudo rm -rf "/usr/local/share/boost"
sudo rm -rf "$AGENT_TOOLSDIRECTORY"
- uses: actions/checkout@v4
- name: Prepare
id: prep
run: |
echo ::set-output name=created::$(date -u +'%Y-%m-%dT%H:%M:%SZ')
echo ::set-output name=dockerfile::$(echo "${{ matrix.image }}" | tr ':' '-')
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build image (amd64)
id: docker_build_test_amd64
uses: docker/build-push-action@v6
with:
context: Dockerfiles
tags: ghcr.io/${{github.repository}}/${{ matrix.image }}
file: Dockerfiles/${{ steps.prep.outputs.dockerfile }}
labels: |
org.opencontainers.image.source=${{ github.event.repository.html_url }}
org.opencontainers.image.created=${{ steps.prep.outputs.created }}
org.opencontainers.image.revision=${{ github.sha }}
outputs: type=docker,dest=image.tar
platforms: linux/amd64
- name: Build image (arm64)
if: false
id: docker_build_test_arm64
uses: docker/build-push-action@v6
with:
context: Dockerfiles
tags: ghcr.io/${{github.repository}}/${{ matrix.image }}
file: Dockerfiles/${{ steps.prep.outputs.dockerfile }}
labels: |
org.opencontainers.image.source=${{ github.event.repository.html_url }}
org.opencontainers.image.created=${{ steps.prep.outputs.created }}
org.opencontainers.image.revision=${{ github.sha }}
outputs: type=docker,dest=image.tar
platforms: linux/arm64
- name: Image digest
run: |
echo ${{ steps.docker_build_test_amd64.outputs.digest }}
# echo ${{ steps.docker_build_test_arm64.outputs.digest }}
- name: List built images
run: docker images
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ${{ steps.prep.outputs.dockerfile }}
path: image.tar
# run is skipped if build is skipped (no changed images)
run:
needs: [build]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: 3.9
- name: Download artifact
uses: actions/download-artifact@v4
- name: Load images
run: |
ls -lavh
for image in */image.tar; do
echo ::group::$(dirname $image)
test -f "$image" && docker load --input $image |
awk '{print $NF}' | xargs docker inspect
echo ::endgroup::
done
docker image ls -a
- name: Install MaPyDe
run: |
python -m pip install --upgrade pip setuptools wheel
python -m pip install --upgrade .
- name: List installed Python packages
run: python -m pip list
- name: Prepare Inputs for Generation
run: |
python3 -m pip install .
mapyde config parse ci/charginos.toml
mapyde config generate-mg5 ci/charginos.toml
- name: Run Madgraph
# prettier-ignore
run: >-
docker run --rm
-v $PWD/githubci:/data
-v $PWD/cards:/cards
-w /output
ghcr.io/${{ github.repository }}/madgraph:latest
"mg5_aMC /data/run.mg5; rsync -rav PROC_madgraph /data/madgraph"
- name: Run Delphes
# prettier-ignore
run: >-
docker run --rm
-v $PWD/githubci:/data
-v $PWD/cards:/cards
-w /output
ghcr.io/${{ github.repository }}/delphes:latest
'cp $(find /data/ -name "*hepmc.gz") hepmc.gz; gunzip hepmc.gz;
/usr/local/share/delphes/delphes/DelphesHepMC /cards/delphes/delphes_card_ATLAS.tcl delphes.root hepmc;
rsync -rav --exclude hepmc . /data/delphes'
- name: Run Analysis
# prettier-ignore
run: >-
docker run --rm
-v $PWD/githubci:/data
-v $PWD/cards:/cards
-v $PWD/scripts:/scripts
-w /output
ghcr.io/${{ github.repository }}/delphes:latest
"/scripts/SimpleAna.py --input /data/delphes/delphes.root --output histograms.root;
rsync -rav . /data/analysis"
# deploy skipped if build/run skipped
deploy:
needs: [changes, build, run]
name: Deploy ${{ matrix.image }}
runs-on: ubuntu-latest
strategy:
matrix:
image: ${{ fromJSON(needs.changes.outputs.changed_images) }}
steps:
- name: Prepare
id: prep
run: |
echo ::set-output name=dockerfile::$(echo "${{ matrix.image }}" | tr ':' '-')
- name: Login to GitHub Container Registry
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: ${{ steps.prep.outputs.dockerfile }}
path: images
- name: Load images
run: |
docker load --input images/image.tar
- name: List images
run: |
echo ::group::all_images
docker images -a
echo ::endgroup::
echo ::group::${{ matrix.image }}
docker images -f 'label=org.opencontainers.image.revision=${{ github.sha }}' --format='{{.Repository}}:{{.Tag}}'
echo ::endgroup::
- name: Check label
id: label
run: |
# split by delimiter ':' into two variables
IFS=: read -r IMAGE_NAME SUFFIX <<< "${{ matrix.image }}"
echo "Parsed IMAGE_NAME=${IMAGE_NAME}, SUFFIX=${SUFFIX:=latest}"
IMAGE="ghcr.io/${{github.repository}}/${IMAGE_NAME}"
VERSION=$(docker image inspect --format '{{ index .Config.Labels "org.opencontainers.image.version"}}' "${IMAGE}:${SUFFIX}")
REFNAME=$(docker image inspect --format '{{ index .Config.Labels "org.opencontainers.image.ref.name"}}' "${IMAGE}:${SUFFIX}")
LATEST="latest"
# if the suffix is not latest, we need to add it to VERSION and REFNAME (if not duplicated)
if [ "${SUFFIX}" != "latest" ]
then
LATEST="latest-${SUFFIX}"
if [ "${VERSION}" ] && [ "${VERSION}" != "${SUFFIX}" ]
then
VERSION="${VERSION}-${SUFFIX}"
fi
if [ "${REFNAME}" ] && [ "${REFNAME}" != "${SUFFIX}" ]
then
REFNAME="${REFNAME}-${SUFFIX}"
fi
fi
if [ "${REFNAME}" == "${VERSION}" ]
then
echo "REFNAME and VERSION are the same. Setting VERSION=''"
VERSION=''
fi
if [ "${LATEST}" == "${REFNAME}" ]
then
echo "LATEST and REFNAME are the same. Setting REFNAME=''"
REFNAME=''
fi
if [ "${LATEST}" == "${VERSION}" ]
then
echo "LATEST and VERSION are the same. Setting VERSION=''"
VERSION=''
fi
[ "${VERSION}" ] && [ "${SUFFIX}" != "${VERSION}" ] && docker image tag "${IMAGE}:${SUFFIX}" "${IMAGE}:${VERSION}"
[ "${VERSION}" ] && [ "${SUFFIX}" != "${VERSION}" ] && echo "Tagging ${IMAGE}:${SUFFIX} as ${IMAGE}:${VERSION}"
[ "${REFNAME}" ] && [ "${SUFFIX}" != "${REFNAME}" ] && docker image tag "${IMAGE}:${SUFFIX}" "${IMAGE}:${REFNAME}"
[ "${REFNAME}" ] && [ "${SUFFIX}" != "${REFNAME}" ] && echo "Tagging ${IMAGE}:${SUFFIX} as ${IMAGE}:${REFNAME}"
[ "${SUFFIX}" != "${LATEST}" ] && docker image tag "${IMAGE}:${SUFFIX}" "${IMAGE}:${LATEST}"
[ "${SUFFIX}" != "${LATEST}" ] && echo "Tagging ${IMAGE}:${SUFFIX} as ${IMAGE}:${LATEST}"
echo "Setting image=${IMAGE}"
echo "Setting latest=${LATEST}"
echo "Setting version=${VERSION}"
echo "Setting refname=${REFNAME}"
echo ::set-output name=image::${IMAGE}
echo ::set-output name=latest::${LATEST}
echo ::set-output name=version::${VERSION}
echo ::set-output name=refname::${REFNAME}
- name: "Deploy as latest: ${{ steps.label.outputs.latest }}"
if: |
github.event_name == 'push' && github.ref == 'refs/heads/main' &&
github.repository == 'scipp-atlas/mapyde'
run: |
docker image push "${{ steps.label.outputs.image }}:${{
steps.label.outputs.latest }}"
- name: "Deploy as version: ${{ steps.label.outputs.version }}"
if: |
github.event_name == 'push' && github.ref == 'refs/heads/main' && github.repository == 'scipp-atlas/mapyde' &&
steps.label.outputs.version
run: |
docker image push "${{ steps.label.outputs.image }}:${{
steps.label.outputs.version }}"
- name: "Deploy as refname: ${{ steps.label.outputs.refname }}"
if: |
github.event_name == 'push' && github.ref == 'refs/heads/main' && github.repository == 'scipp-atlas/mapyde' &&
steps.label.outputs.refname
run: |
docker image push "${{ steps.label.outputs.image }}:${{
steps.label.outputs.refname }}"
# why such a complicated if statement? see https://github.com/actions/runner/issues/491#issuecomment-850884422
release:
needs: [changes, build, run]
name: Release ${{ matrix.image }}
if: |
always() &&
(needs.build.result == 'success' || needs.build.result == 'skipped') &&
(needs.run.result == 'success' || needs.run.result == 'skipped') &&
github.event_name == 'release' && github.event.action == 'published' && github.repository == 'scipp-atlas/mapyde'
runs-on: ubuntu-latest
strategy:
matrix:
image: ${{ fromJSON(needs.changes.outputs.unchanged_images) }}
steps:
- uses: actions/checkout@v4
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Prepare
id: prep
run: |
echo ::set-output name=dockerfile::$(echo "${{ matrix.image }}" | tr ':' '-')
- name: Check label
id: label
run: |
VERSION_UNSET='false'
if grep -q -E 'org\.opencontainers\.image\.version' Dockerfiles/"${{ steps.prep.outputs.dockerfile }}"
then
VERSION_UNSET='true'
fi
echo "Setting version_unset=${VERSION_UNSET}"
echo ::set-output name=version_unset::${VERSION_UNSET}
# split by delimiter ':' into two variables
IFS=: read -r IMAGE_NAME SUFFIX <<< "${{ matrix.image }}"
echo "Parsed IMAGE_NAME=${IMAGE_NAME}, SUFFIX=${SUFFIX:=latest}"
IMAGE="ghcr.io/${{github.repository}}/${IMAGE_NAME}"
LATEST="latest"
STABLE="stable"
TAG=${{ github.event.release.tag_name }}
# if the suffix is not latest, we need to add it to VERSION and REFNAME (if not duplicated)
if [ "${SUFFIX}" != "latest" ]
then
LATEST="latest-${SUFFIX}"
STABLE="stable-${SUFFIX}"
TAG="${TAG}-${SUFFIX}"
fi
echo "Setting image=${IMAGE}"
echo "Setting latest=${LATEST}"
echo "Setting stable=${STABLE}"
echo "Setting tag=${TAG}"
echo ::set-output name=image::${IMAGE}
echo ::set-output name=latest::${LATEST}
echo ::set-output name=stable::${STABLE}
echo ::set-output name=tag::${TAG}
- name: Tag latest as stable
uses: akhilerm/tag-push-action@v2.2.0
with:
src: |
${{ steps.label.outputs.image }}:${{ steps.label.outputs.latest }}
dst: |
${{ steps.label.outputs.image }}:${{ steps.label.outputs.stable }}
- name: Tag latest as ${{ github.event.release.tag_name }}
if: ${{ steps.label.outputs.version_unset == 'true' }}
uses: akhilerm/tag-push-action@v2.2.0
with:
src: |
${{ steps.label.outputs.image }}:${{ steps.label.outputs.latest }}
dst: |
${{ steps.label.outputs.image }}:${{ steps.label.outputs.tag }}