Skip to content

CI

CI #125

Workflow file for this run

name: CI
on:
push:
branches:
- master
repository_dispatch:
types: [test workflow]
workflow_dispatch:
inputs:
ignore_cache:
description: 'Ignore cache when collecting manifests'
required: false
default: true
type: boolean
schedule:
# Runs "At 04:15." (see https://crontab.guru)
- cron: '15 4 * * *'
env:
IMAGE_REPO: containers.intersystems.com/intersystems
ORGNAME: intersystemsdc
IMAGE: |
iris-community
irishealth-community
TAG: |
latest-em
latest-cd
latest-preview
jobs:
prepare:
runs-on: ubuntu-latest
outputs:
images: ${{ steps.collect.outputs.images }}
targets: ${{ steps.collect.outputs.targets }}
do_build: ${{ steps.collect.outputs.do_build }}
steps:
- name: Checkout repository
uses: actions/checkout@v3
- uses: actions/cache/restore@v4
if: ${{ github.event.inputs.ignore_cache != 'true' }}
id: restore-cache
with:
path: manifests.txt
key: manifests
restore-keys: |
manifests-
- name: collect manifests
id: collect
run: |
IMAGE="${{ env.IMAGE }}"
TAG="${{ env.TAG }}"
for baseimage in ${IMAGE[@]}; do
for tag in ${TAG[@]}; do
image="${{ env.IMAGE_REPO }}/${baseimage}:${tag}"
echo "Inspecting $image"
docker manifest inspect $image | jq ".manifests[] | ( .platform.architecture + \" ${baseimage}\" + \" ${tag}\" + \" \" + .digest )" -r
done
done > latest_manifests.txt
cat latest_manifests.txt
images=$(while IFS= read -r line; do
if ! grep "$line" manifests.txt >/dev/null 2>&1; then
echo $line | awk -F' ' '{printf "{\"platform\": \"linux/%s\", \"image\": \"%s\", \"tag\": \"%s\"}\n", $1,$2,$3}'
fi
done < "latest_manifests.txt" | jq -cs '.[] | (select(.platform == "linux/arm64" ) | .runner = "ubuntu-24.04-arm"), (select(.platform == "linux/amd64" ) | .runner = "ubuntu-latest")' | jq -cs '.' )
mv latest_manifests.txt manifests.txt
images=$(echo $images | jq 'map(.target=.image)' | jq -cs '.[]' )
images=$(echo $images | jq 'map(.ml=false)' | jq -cs '.[]' )
# add ml variants
images=$(echo $images | jq 'map([.+{ml:false},.+{ml:true,target:(.target|sub("-";"-ml-"))}] | .[])' | jq -cs '.[]' )
[ ! -z "${{ vars.DOCKER_ORGNAME }}" ] && ORGNAME="${{ vars.DOCKER_ORGNAME }}"
images=$(echo $images | jq "map(.orgname=\"$ORGNAME\")" -c )
echo $images | jq
echo images="$images" >> $GITHUB_OUTPUT
([[ "$images" != "[]" ]] && echo do_build=true || echo do_build=false ) >> $GITHUB_OUTPUT
targets=$(echo $images | jq '.[] | {target, tag, orgname}' | jq -cs '.[]' | sort | uniq | jq -cs '.' )
echo targets="$targets" >> $GITHUB_OUTPUT
- name: Upload file
uses: actions/upload-artifact@v4
with:
name: manifests
path: manifests.txt
- uses: actions/cache/save@v4
with:
key: manifests-${{ github.run_id }}
path: manifests.txt
build:
needs: prepare
if: ${{ needs.prepare.outputs.do_build != 'false' }}
strategy:
fail-fast: false
matrix:
include: ${{ fromJson(needs.prepare.outputs.images) }}
runs-on: ${{ matrix.runner }}
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Pull image
id: image
run: |
base=${{ env.IMAGE_REPO }}/${{ matrix.image }}:${{ matrix.tag }}
docker pull $base
version=$(docker image inspect --format '{{index .Config.Labels "com.intersystems.platform-version"}}' $base | cut -d'.' -f1-2)
echo base=$base >> $GITHUB_OUTPUT
echo version=$version >> $GITHUB_OUTPUT
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and push by digest
id: build
uses: docker/build-push-action@v6
with:
context: .
build-args: |
BASE_IMAGE=${{ env.IMAGE_REPO }}/${{ matrix.image }}:${{ matrix.tag }}
ML=${{ matrix.ml }}
push: true
tags: ${{ matrix.orgname }}/${{ matrix.target }}
outputs: type=image,push-by-digest=true,name-canonical=true,push=true
- name: Save digest as artifact
run: |
mkdir -p "$RUNNER_TEMP/digests"
digest="${{ steps.build.outputs.digest }}"
# strip "sha256:" prefix, use remainder as filename
echo ${{ steps.image.outputs.version }} > "$RUNNER_TEMP/digests/${digest#sha256:}"
shell: bash
- name: Upload digest
uses: actions/upload-artifact@v4
with:
name: digests-${{ matrix.target }}-${{ matrix.tag }}-${{ matrix.runner }}
path: ${{ runner.temp }}/digests/*
if-no-files-found: error
retention-days: 1
merge:
needs:
- prepare
- build
strategy:
fail-fast: false
matrix:
include: ${{ fromJson(needs.prepare.outputs.targets) }}
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Download digests
uses: actions/download-artifact@v4
with:
path: ${{ runner.temp }}/digests
pattern: digests-${{ matrix.target }}-${{ matrix.tag }}-*
merge-multiple: true
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Create multi-arch manifest and push
working-directory: ${{ runner.temp }}/digests
run: |
# turn each file name (a sha256 without prefix) into IMAGE@sha256:...
version=$(cat * | head -1)
docker buildx imagetools create \
-t ${{ matrix.orgname }}/${{ matrix.target }}:${{ matrix.tag }} \
-t ${{ matrix.orgname }}/${{ matrix.target }}:${{ matrix.tag }}-zpm \
-t ${{ matrix.orgname }}/${{ matrix.target }}:${version} \
-t ${{ matrix.orgname }}/${{ matrix.target }}:${version}-zpm \
$([[ "${{ matrix.tag }}" == "latest-em" ]] && echo -t ${{ matrix.orgname }}/${{ matrix.target }}:latest ) \
$([[ "${{ matrix.tag }}" == "latest-preview" ]] && echo -t ${{ matrix.orgname }}/${{ matrix.target }}:preview ) \
$(printf '${{ matrix.orgname }}/${{ matrix.target }}@sha256:%s ' *)
- name: Inspect final image (optional)
run: docker buildx imagetools inspect ${{ matrix.orgname }}/${{ matrix.target }}:${{ matrix.tag }}