Skip to content

fixup! Improve test parallelism #63

fixup! Improve test parallelism

fixup! Improve test parallelism #63

---
name: Integration Tests
on:
pull_request:
paths:
- "action.yaml"
- ".github/workflows/integration-tests.yaml"
push:
paths:
- "action.yaml"
- ".github/workflows/integration-tests.yaml"
concurrency:
group: integration-tests-${{ github.sha }}
cancel-in-progress: true
jobs:
filter-matrix:
name: Filter Matrix
runs-on: ubuntu-latest
outputs:
json: ${{ steps.filter.outputs.json }}
steps:
- name: Filter Matrix
id: filter
run: |
# Remove any entries with keys containing `null` values.
output_yaml="$(yq 'map(select(to_entries | map(.value != null) | all))' <<<"${matrix:?}")"
# Output our multiline YAML document using GH action flavored heredoc
# https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#multiline-strings
{
echo "json<<EOF"
yq -o json <<<"$output_yaml"
echo "EOF"
echo "packages<<EOF"
yq 'map(.package) | unique' -o json <<<"$output_yaml"
echo "EOF"
} | tee -a "$GITHUB_OUTPUT"
env:
# We need to avoid running concurrent tests using the same commit SHA and
# writing to the same image-repository. If we do not then we could see false
# positive test results if one of them doesn't actually push cache layers. We
# address this problem by:
#
# 1. Ensuring tests which run in parallel either use separate image repositories
# or different Git commit SHAs.
# 2. Utilizing concurrency groups to avoid having multiple instances of this
# workflow run in parallel when triggered on the same commit SHA.
# 3. Deleting the `cache-sha-*` entry for the images we're about to build to
# ensure those entries were produced by the running workflow.
#
# I also considered revising the action to avoid pushing images entirely.
# Doing this may be challenging in otherways as pushing the image is a
# requirement for getting the digests in some contexts:
# https://github.com/docker/build-push-action/issues/906#issuecomment-1674567311
matrix: |
- title: ${{ github.event_name == 'pull_request' && 'Merge Commit' || '' }}
package : temporary/whalesay
commit-sha: ${{ github.sha }}
from-scratch: false
- title: Head Commit
package: temporary/whalesay
commit-sha: ${{ github.event.pull_request.head.sha || github.sha }}
from-scratch: false
- title: ${{ github.event_name == 'pull_request' && 'Merge Commit From Scratch' || '' }}
package: temporary/whalesay-from-scratch
commit-sha: ${{ github.sha }}
from-scratch: true
- title: Head Commit From Scratch
package: temporary/whalesay-from-scratch
commit-sha: ${{ github.event.pull_request.head.sha || github.sha }}
from-scratch: true
test:
name: Test ${{ matrix.test.title }}
needs: filter-matrix
# These permissions are needed to:
# - Checkout the repo
permissions:
contents: read
packages: write
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
test: ${{ fromJSON(needs.filter-matrix.outputs.json) }}
steps:
- name: Job started at
id: job-started
run: |
job_started_at="$(date --utc --iso-8601=seconds)"
echo "at=$job_started_at" | tee -a "$GITHUB_OUTPUT"
- uses: actions/checkout@v4
with:
ref: ${{ matrix.test.commit-sha }}
# Remove cache layer for SHA as this will be distinct within the provided job matrix
- uses: dataaxiom/ghcr-cleanup-action@cd0cdb900b5dbf3a6f2cc869f0dbb0b8211f50c4 # v1.0.16
with:
package: ${{ matrix.test.package }}
delete-tags: cache-sha-${{ matrix.test.commit-sha }}
- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ github.token }}
- uses: ./
id: build
with:
image-repository: ghcr.io/beacon-biosignals/${{ matrix.test.package }}
context: test
build-args: |
DEBIAN_VERSION=12.9
from-scratch: ${{ matrix.test.from-scratch || 'false' }}
- name: Validate image works
run: |
docker pull "${{ steps.build.outputs.image }}"
output="$(docker run "${{ steps.build.outputs.image }}")"
if [[ "$(wc -l <<<"$output")" -lt 14 ]]; then
echo "$output"
exit 1
fi
debian_version="$(docker run --entrypoint=/bin/cat "${{ steps.build.outputs.image }}" /etc/debian_version)"
[[ "$debian_version" == "12.9" ]] || exit 2
- name: Layer created at
id: layer-created
run: |
layer_created_at="$(docker run --entrypoint=/bin/cat "${{ steps.build.outputs.image }}" /etc/layer-created-at)"
echo "at=$layer_created_at" | tee -a "$GITHUB_OUTPUT"
- name: Validate layer caching
if: ${{ matrix.test.from-scratch == false }}
run: |
[[ "$(date -d "$layer_created_at" +%s)" -lt "$(date -d "$job_started_at" +%s)" ]] || exit 1
env:
job_started_at: ${{ steps.job-started.outputs.at }}
layer_created_at: ${{ steps.layer-created.outputs.at }}
- name: Validate no layer caching
if: ${{ matrix.test.from-scratch == true }}
run: |
[[ "$(date -d "$layer_created_at" +%s)" -gt "$(date -d "$job_started_at" +%s)" ]] || exit 1
env:
job_started_at: ${{ steps.job-started.outputs.at }}
layer_created_at: ${{ steps.layer-created.outputs.at }}
- name: Validate cache images
run: |
docker manifest inspect "${{ steps.build.outputs.image-repository }}:cache-sha-${{ matrix.test.commit-sha }}"
docker manifest inspect "${{ steps.build.outputs.image-repository }}:cache-branch-${branch//[^[:alnum:]]/-}"
env:
branch: ${{ github.head_ref || (github.ref_type == 'branch' && github.ref_name) }}
- name: Validate annotations
run: |
set -x
json="$(docker manifest inspect "${{ steps.build.outputs.image }}")"
[[ "$(jq -r '.annotations."org.opencontainers.image.revision"' <<<"$json")" == "${{ matrix.test.commit-sha }}" ]] || exit 1
- name: Validate docker/metadata-output environment variables are overwritten
shell: bash
run: |
if [[ "$(printenv | grep '^DOCKER_METADATA_OUTPUT_' | grep -c '[^=]$')" -ne 0 ]]; then
printenv | grep '^DOCKER_METADATA_OUTPUT_'
exit 1
fi
cleanup:
name: Cleanup
needs:
- filter-matrix
- test
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
package: ${{ fromJSON(needs.filter-matrix.outputs.packages) }}
steps:
- uses: dataaxiom/ghcr-cleanup-action@cd0cdb900b5dbf3a6f2cc869f0dbb0b8211f50c4 # v1.0.16
with:
package: ${{ matrix.package }}
older-than: 1 day
keep-n-tagged: 0
exclude-tags: branch-main,cache-branch-main