Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions .github/workflows/maven-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ on:
required: false
type: boolean
default: false
pre_pull_docker_images:
description: "Comma-separated list of Docker images to pull in the background before the build starts (e.g. images used by Testcontainers). Default: empty, nothing is pulled"
required: false
type: string
default: ""

# cancel in-progress runs of the same workflow
# to avoid unnecessary runs when multiple commits pushed
Expand All @@ -59,12 +64,60 @@ jobs:
fetch-depth: ${{ inputs.fetch_all_commits == true && '0' || '1' }}
persist-credentials: false

# Detached pulls carry on after this step ends, so they overlap with the Java/Maven setup and the build.
# Failures are harmless: Testcontainers pulls any missing image itself when it is first needed.
# Each pull writes <n>.log (image name on the first line, then the pull output) and, once finished,
# <n>.rc (exit code and seconds taken). The 'Report Docker pre-pull results' step prints them.
- name: Pre-pull Docker images in background
if: inputs.pre_pull_docker_images != ''
env:
INPUTS_PRE_PULL_DOCKER_IMAGES: ${{ inputs.pre_pull_docker_images }}
run: |
mkdir -p -- "${RUNNER_TEMP}/pre-pull"
n=0
IFS=',' read -ra images <<< "${INPUTS_PRE_PULL_DOCKER_IMAGES}"
for image in "${images[@]}"; do
image="$(echo "${image}" | xargs)"
[ -n "${image}" ] || continue
if [[ ! "${image}" =~ ^[a-zA-Z0-9][a-zA-Z0-9._/:@-]*$ ]]; then
echo "::warning::Skipping invalid Docker image name '${image}'"
continue
fi
echo "Pre-pulling ${image} in background"
base="${RUNNER_TEMP}/pre-pull/$((++n))"
echo "${image}" > "${base}.log"
# shellcheck disable=SC2016
setsid bash -c 'docker pull -- "$1" >> "$2.log" 2>&1; echo "$? ${SECONDS}" > "$2.rc"' _ "${image}" "${base}" > /dev/null 2>&1 < /dev/null &

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need the setsid thing? Just curious about it.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setsid starts the pull in its own session and process group, so it is detached from the step's shell. This allows it do the pull while the build runs in parallel - so by the time orch gets to e.g. the integration-test-rex, the pull will already have been done.

disown
done

- uses: project-ncl/shared-github-actions/.github/actions/maven-build@e7102dd3bf74f91aaccae7a3539241c03a652d1a # v0.0.27
with:
java_version: ${{ inputs.java_version }}
build_command: ${{ inputs.build_command }}
maven_version: ${{ inputs.maven_version }}

- name: Report Docker pre-pull results
# Also on failure: a failed pre-pull can explain a slow or failing integration test
if: always() && inputs.pre_pull_docker_images != ''
run: |
for log in "${RUNNER_TEMP}"/pre-pull/*.log; do
[ -e "${log}" ] || continue
image="$(head -n 1 "${log}")"
rc="" secs=""
[ ! -f "${log%.log}.rc" ] || read -r rc secs < "${log%.log}.rc"
if [ "${rc}" = "0" ]; then
echo "✅ Pre-pulled ${image} in ${secs}s"
else
status="${rc:+exit ${rc} after ${secs}s}"
echo "::warning::❌ Pre-pull of ${image} did not succeed (${status:-still running}), Testcontainers pulls it on demand instead"
echo "::group::Pre-pull log for ${image}"
# Registry output is untrusted: stop it from being interpreted as workflow commands
sed 's/::/: :/g' "${log}"
echo "::endgroup::"
fi
done

- name: Check for wrong code formatting
# Straight after a maven-release the release plugin might have altered the format slightly. Don't fail
# dependabot updates on formatting changes.
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ the Java version etc. It is possible to use this within a matrix job.
* fetch_all_commits (default: `false`)
* maven_version (default: `3.9.15`)
* upload_artifacts (default: `false`)
* pre_pull_docker_images (default: empty, opt-in): comma-separated list of Docker images (e.g. `quay.io/keycloak/keycloak:21.1.0,redis:7.2`) to `docker pull` in the background right after checkout, so the download overlaps with Java/Maven setup and the build instead of Testcontainers pulling them lazily and serially. No images are cached and no registry login is performed (public images only). A failed pull is harmless: the image is then pulled on demand as usual. As the pulls are detached, a `Report Docker pre-pull results` step after the build prints one line per image (✅ with the time taken), and a warning plus the full pull log for any pull that failed or was still running
- **Permissions**: `contents: read`

<details>
Expand Down
Loading