Skip to content
Draft
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
44 changes: 44 additions & 0 deletions .github/actions/check-release-commit/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Check release commit
description: >
Detects (pre-)release commits from the HEAD commit message. Single authority
for the release/non-release decision, shared by edr-npm-ci.yml (which skips
itself on release pushes) and edr-npm-release.yml (which only proceeds on
them). Requires the repository to be checked out.

outputs:
tag:
description: npm dist-tag ('next' for pre-releases, 'latest' for releases, empty otherwise)
value: ${{ steps.check.outputs.tag }}
is-release:
description: "'true' when the HEAD commit triggers a (pre-)release"
value: ${{ steps.check.outputs.tag != '' }}

runs:
using: composite
steps:
- id: check
shell: bash
run: |
# matches with pre-release commits: edr release name but ends with - and some postfix like beta
if git log -1 --pretty=%B | grep "^edr-[0-9]\+\.[0-9]\+\.[0-9]\+-";
then
if [ "$GITHUB_EVENT_NAME" = "push" ]
then
echo "pre-release commit: tag=next"
echo "tag=next" >> "$GITHUB_OUTPUT"
else
echo "pre-release commit, but event is $GITHUB_EVENT_NAME, not push: not a release run"
fi
# matches with release commit
elif git log -1 --pretty=%B | grep "^edr-[0-9]\+\.[0-9]\+\.[0-9]\+\s*";
then
if [ "$GITHUB_REF" = "refs/heads/main" ] || [ "$GITHUB_REF" = "refs/heads/hh2" ]
then
echo "release commit: tag=latest"
echo "tag=latest" >> "$GITHUB_OUTPUT"
else
echo "release commit, but $GITHUB_REF is not main or hh2: not a release run"
fi
else
echo "not a release commit: not a release run"
fi
54 changes: 49 additions & 5 deletions .github/actions/select-node-image/action.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
name: Select node image
description: Resolves the node Docker image for a job. Normal runs use the GHCR mirror (see mirror-docker-images.yml); release runs pull the official Docker Hub image directly, keeping the mirror out of the supply chain of published binaries.
description: Resolves the node Docker image for a job, waiting (up to 15 minutes) for any in-flight mirror run first. Normal runs use the GHCR mirror (see mirror-docker-images.yml); release runs pull the official Docker Hub image directly, keeping the mirror out of the supply chain of published binaries.

inputs:
tag:
description: node image tag, e.g. 24-bullseye-slim or 22-alpine
required: true
release-tag:
description: check_commit's release tag; non-empty marks a release run
is-release:
description: edr-npm-build.yml's release input; 'true' marks a release run
required: true

outputs:
Expand All @@ -17,13 +17,57 @@ outputs:
runs:
using: composite
steps:
# On PRs/pushes that touch mirror-docker-images.yml, pulls can race ahead
# of the mirror run for the same SHA and fail with "manifest unknown"; no
# run means nothing to wait for. Best-effort: never fails the job — the
# pull itself is the authoritative failure for a genuinely missing tag.
- name: Wait for in-flight mirror run
if: inputs.is-release != 'true'
shell: bash
env:
GH_TOKEN: ${{ github.token }}
# For pull_request events the mirror run is recorded against the PR
# head SHA, not the merge commit that github.sha points at.
HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
run: |
set -euo pipefail
DEADLINE=$(( $(date +%s) + 15 * 60 ))
while true; do
RUN=$(gh api \
"repos/${GITHUB_REPOSITORY}/actions/workflows/mirror-docker-images.yml/runs?head_sha=${HEAD_SHA}&per_page=1" \
--jq '.workflow_runs[0] // empty')
if [ -z "$RUN" ]; then
echo "No mirror run for ${HEAD_SHA}; not waiting."
exit 0
fi
STATUS=$(jq -r .status <<<"$RUN")
if [ "$STATUS" = "completed" ]; then
CONCLUSION=$(jq -r .conclusion <<<"$RUN")
URL=$(jq -r .html_url <<<"$RUN")
case "$CONCLUSION" in
success) echo "Mirror run succeeded: $URL" ;;
# The mirror job skips itself on fork PRs; the tags it would
# have re-copied already exist.
skipped) echo "Mirror run was skipped: $URL" ;;
*) echo "::warning::Mirror run for ${HEAD_SHA} concluded '$CONCLUSION' ($URL); proceeding anyway" ;;
esac
exit 0
fi
if [ "$(date +%s)" -ge "$DEADLINE" ]; then
echo "::warning::Timed out waiting for the mirror run for ${HEAD_SHA}; proceeding anyway"
exit 0
fi
echo "Mirror run in progress (status: $STATUS); retrying in 30s..."
sleep 30
done

- id: select
shell: bash
env:
TAG: ${{ inputs.tag }}
RELEASE_TAG: ${{ inputs.release-tag }}
IS_RELEASE: ${{ inputs.is-release }}
run: |
if [ -n "$RELEASE_TAG" ]; then
if [ "$IS_RELEASE" = "true" ]; then
echo "ref=node:${TAG}" >> "$GITHUB_OUTPUT"
else
echo "ref=ghcr.io/nomicfoundation/edr/mirror/node:${TAG}" >> "$GITHUB_OUTPUT"
Expand Down
Loading
Loading