diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml index 5003cb57d..aea82c65f 100644 --- a/.github/workflows/create-release.yml +++ b/.github/workflows/create-release.yml @@ -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 diff --git a/.github/workflows/install-sh-smoke.yml b/.github/workflows/install-sh-smoke.yml index 7b0da17e0..e0149c951 100644 --- a/.github/workflows/install-sh-smoke.yml +++ b/.github/workflows/install-sh-smoke.yml @@ -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 diff --git a/.github/workflows/promote-floating-tags.yml b/.github/workflows/promote-floating-tags.yml index 40fd2928c..fb7e90073 100644 --- a/.github/workflows/promote-floating-tags.yml +++ b/.github/workflows/promote-floating-tags.yml @@ -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//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."