Fix post-publish pipeline failures for v6.0.0-rc.6

promote-floating-tags.yml waited on rcourtman/pulse-agent:${TAG} and
promoted floating tags for it, but publish-docker.yml never pushes the
agent image — Pulse Agent ships as GitHub Release binaries
(publish-docker.yml line 199 confirms). The wait timed out after 5
minutes on every release since the pulse-agent push step was removed,
leaving floating tags unpromoted. Stripped the vestigial wait block,
the agent promote step, and the agent line in the summary. Updated
header comments in both files to drop the past-tense reference.

install-sh-smoke.yml booted jrei/systemd-debian:12 without
--cgroupns=host, so on GHA ubuntu-24.04 (cgroup v2 unified hierarchy)
the container's systemd PID 1 exited before mounting the cgroup tree
and the container disappeared during readiness polling. Added
--cgroupns=host, an explicit /run/lock tmpfs, and dropped --rm so the
container persists for diagnostic capture on failure (trap handles
cleanup). Added an "is container still running" probe inside the
readiness loop and richer diagnostic output on timeout.
This commit is contained in:
rcourtman
2026-05-27 22:08:15 +01:00
parent b0a1937106
commit 7c35977fcb
3 changed files with 41 additions and 75 deletions
+7 -8
View File
@@ -1117,15 +1117,14 @@ jobs:
app_version: ${{ needs.prepare.outputs.version }}
# Defensive backup to promote-floating-tags.yml's workflow_run chain off
# publish-docker.yml. The chain works when publish-docker succeeds, but a
# publish-docker failure (rc.3 → rc.5 all failed at the now-removed
# pulse-agent push) silently left latest/major/minor tags unpromoted —
# customers pulling rcourtman/pulse:latest stayed on whatever the previous
# successful release tagged. Calling promote-floating-tags as workflow_call
# after validate_release_assets succeeds (which itself waits for the docker
# publish-docker.yml. The chain works when publish-docker succeeds, but
# when it fails the floating tags don't advance and customers pulling
# rcourtman/pulse:latest stay on whatever the previous successful release
# tagged. Calling promote-floating-tags as workflow_call after
# validate_release_assets succeeds (which itself waits for the docker
# image to be pullable) guarantees the floating tags advance. Draft-only
# runs must not promote floating tags because the release is still private
# promotion state.
# runs must not promote floating tags because the release is still in
# private promotion state.
promote_floating_tags:
needs:
- prepare
+17 -2
View File
@@ -185,10 +185,17 @@ jobs:
# jrei/systemd-debian:12 is a community systemd-in-Docker image used
# for Ansible / Molecule testing — small, no Pulse-specific assumptions.
docker run -d --rm \
# GHA ubuntu-24.04 runners use cgroup v2 unified hierarchy; without
# --cgroupns=host the container gets its own cgroup namespace and
# systemd PID 1 exits before it can mount the cgroup tree, causing
# the container to disappear mid-boot. /run/lock must also be tmpfs
# for systemd-tmpfiles. We drop --rm so a failed boot leaves logs
# behind for diagnosis; the trap removes the container on exit.
docker run -d \
--name "${container_name}" \
--privileged \
--tmpfs /tmp --tmpfs /run \
--cgroupns=host \
--tmpfs /tmp --tmpfs /run --tmpfs /run/lock \
-v /sys/fs/cgroup:/sys/fs/cgroup:rw \
-v "$(pwd)/smoke-workspace:/smoke" \
-p 7655:7655 \
@@ -196,11 +203,19 @@ jobs:
echo "Waiting for systemd to be ready inside the container..."
for i in $(seq 1 30); do
if ! docker inspect -f '{{.State.Running}}' "${container_name}" 2>/dev/null | grep -q true; then
echo "::error::Container ${container_name} is no longer running."
docker inspect -f 'ExitCode={{.State.ExitCode}} Error={{.State.Error}}' "${container_name}" || true
docker logs "${container_name}" || true
exit 1
fi
if docker exec "${container_name}" systemctl is-system-running --wait 2>/dev/null | grep -qE '^(running|degraded)$'; then
break
fi
if [ "$i" -eq 30 ]; then
docker logs "${container_name}" || true
docker exec "${container_name}" systemctl --no-pager status || true
docker exec "${container_name}" journalctl --no-pager --lines=120 || true
echo "::error::systemd did not become ready inside the container"
exit 1
fi
+17 -65
View File
@@ -1,12 +1,15 @@
name: Promote Floating Tags
run-name: Promote Floating Tags ${{ inputs.tag }}
# Promotes floating tags for the Pulse server image after a release. Only
# rcourtman/pulse + ghcr.io/<owner>/pulse are promoted; the Pulse agent
# ships as GitHub Release binaries (see publish-docker.yml line 199), not
# as a Docker image, so there are no agent floating tags to promote.
#
# Triggers:
# - workflow_run: chains off publish-docker.yml completion. Historically the
# primary path, but the chain only fires when publish-docker succeeds — and
# when publish-docker fails (rc.3 → rc.5 all failed at the now-removed
# pulse-agent push step), the floating tags don't promote and customers
# pulling rcourtman/pulse:latest are stuck on whatever the previous tag was.
# - workflow_run: chains off publish-docker.yml completion. Historically
# this was the only path; it remains the default for releases that go
# straight through publish-docker.yml.
# - workflow_call: called explicitly from create-release.yml after
# validate_release_assets succeeds. Defensive backup so a workflow_run
# failure doesn't silently leave latest/major/minor tags unpromoted.
@@ -172,43 +175,24 @@ jobs:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Wait for Docker images to be available
- name: Wait for Pulse server image to be available
env:
TAG: ${{ steps.extract.outputs.tag }}
run: |
echo "Waiting for Docker images with tag ${TAG} to be available..."
echo "Waiting for rcourtman/pulse:${TAG} to be available..."
MAX_ATTEMPTS=30
ATTEMPT=0
# Wait for main pulse image
while [ $ATTEMPT -lt $MAX_ATTEMPTS ]; do
if docker manifest inspect rcourtman/pulse:${TAG} > /dev/null 2>&1; then
echo "Image rcourtman/pulse:${TAG} is available!"
break
exit 0
fi
ATTEMPT=$((ATTEMPT + 1))
echo "Attempt $ATTEMPT/$MAX_ATTEMPTS - pulse image not yet available, waiting 10s..."
sleep 10
done
if [ $ATTEMPT -ge $MAX_ATTEMPTS ]; then
echo "Timeout waiting for pulse Docker image"
exit 1
fi
# Also wait for unified agent image
ATTEMPT=0
while [ $ATTEMPT -lt $MAX_ATTEMPTS ]; do
if docker manifest inspect rcourtman/pulse-agent:${TAG} > /dev/null 2>&1; then
echo "Image rcourtman/pulse-agent:${TAG} is available!"
exit 0
fi
ATTEMPT=$((ATTEMPT + 1))
echo "Attempt $ATTEMPT/$MAX_ATTEMPTS - agent image not yet available, waiting 10s..."
sleep 10
done
echo "Timeout waiting for agent Docker image"
echo "Timeout waiting for pulse Docker image"
exit 1
- name: Promote Pulse server image tags
@@ -246,39 +230,6 @@ jobs:
ghcr.io/${OWNER}/pulse:${TAG}
fi
- name: Promote Pulse agent image tags
env:
TAG: ${{ steps.extract.outputs.tag }}
PRERELEASE: ${{ steps.extract.outputs.prerelease }}
OWNER: ${{ github.repository_owner }}
run: |
set -euo pipefail
VERSION="${TAG#v}"
BASE_VERSION="${VERSION%%-*}"
IFS='.' read -r MAJOR MINOR PATCH <<< "$BASE_VERSION"
MINOR=${MINOR:-0}
MAJOR_MINOR="$MAJOR.$MINOR"
if [ "$PRERELEASE" = "true" ]; then
docker buildx imagetools create \
-t rcourtman/pulse-agent:rc \
rcourtman/pulse-agent:${TAG}
docker buildx imagetools create \
-t ghcr.io/${OWNER}/pulse-agent:rc \
ghcr.io/${OWNER}/pulse-agent:${TAG}
else
docker buildx imagetools create \
-t rcourtman/pulse-agent:latest \
-t rcourtman/pulse-agent:${MAJOR_MINOR} \
-t rcourtman/pulse-agent:${MAJOR} \
rcourtman/pulse-agent:${TAG}
docker buildx imagetools create \
-t ghcr.io/${OWNER}/pulse-agent:latest \
-t ghcr.io/${OWNER}/pulse-agent:${MAJOR_MINOR} \
-t ghcr.io/${OWNER}/pulse-agent:${MAJOR} \
ghcr.io/${OWNER}/pulse-agent:${TAG}
fi
- name: Promotion summary
env:
TAG: ${{ steps.extract.outputs.tag }}
@@ -288,9 +239,10 @@ jobs:
BASE_VERSION="${VERSION%%-*}"
IFS='.' read -r MAJOR MINOR PATCH <<< "$BASE_VERSION"
MAJOR_MINOR="$MAJOR.${MINOR:-0}"
if [ "$PRERELEASE" = "true" ]; then
echo "✅ Updated :rc tags to point to ${TAG} for both server and agent images."
echo "✅ Updated :rc tag to point to ${TAG} for the Pulse server image."
else
echo "✅ Updated :latest, :${MAJOR_MINOR}, :${MAJOR} tags to point to ${TAG} for both server and agent images."
echo "✅ Updated :latest, :${MAJOR_MINOR}, :${MAJOR} tags to point to ${TAG} for the Pulse server image."
fi
echo "Pulse Agent ships as GitHub Release binaries, not a Docker image."