Skip to content

Release Stage 3 - Package Release - Run 20002627309 - beta-2025-12-07 - beta - beta:20002627309 #117

Release Stage 3 - Package Release - Run 20002627309 - beta-2025-12-07 - beta - beta:20002627309

Release Stage 3 - Package Release - Run 20002627309 - beta-2025-12-07 - beta - beta:20002627309 #117

name: Release Stage 3 - Package Release
run-name: Release Stage 3 - Package Release - Run ${{ inputs.run_id }} - ${{ inputs.HOMEBRIDGE_VM_IMAGE_VERSION }} - ${{ inputs.release_stream }} - ${{ inputs.run_name }}
on:
workflow_dispatch:
inputs:
run_id:
description: 'GitHub Run ID of the build workflow that produced the artifacts'
required: true
type: string
release_stream:
description: 'Release stream (stable, beta, alpha)'
required: true
type: choice
options:
- stable
- beta
- alpha
default: beta
HOMEBRIDGE_VM_IMAGE_VERSION:
description: 'Homebridge VM image version aka release tag'
required: true
type: string
run_name:
description: 'Unique name of the run'
required: false
type: string
default: ''
env:
VDISK_SIZE: 50G # Size of the virtual disk for each VM
concurrency:
group: package-and-release
cancel-in-progress: false
jobs:
create-release:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Download Artifacts
uses: actions/download-artifact@v5
with:
pattern: homebridge-image-*
path: ./output
run-id: ${{ inputs.run_id }}
merge-multiple: true
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: List Downloaded Artifacts
run: ls -lR ./output
- name: Install QEMU
run: |
echo "::group::Installing QEMU"
sudo apt-get update
sudo apt-get install -y qemu-utils
echo "::endgroup::"
- name: Set Release Title
id: set_title
run: |
if [[ "${{ inputs.release_stream }}" == "beta" ]]; then
echo "RELEASE_TITLE=BETA: Homebridge VM Image Release ${{ inputs.HOMEBRIDGE_VM_IMAGE_VERSION }}" >> $GITHUB_OUTPUT
elif [[ "${{ inputs.release_stream }}" == "alpha" ]]; then
echo "RELEASE_TITLE=ALPHA: Homebridge VM Image Release ${{ inputs.HOMEBRIDGE_VM_IMAGE_VERSION }}" >> $GITHUB_OUTPUT
else
echo "RELEASE_TITLE=Homebridge VM Image Release ${{ inputs.HOMEBRIDGE_VM_IMAGE_VERSION }}" >> $GITHUB_OUTPUT
fi
- name: Create Release Body
id: release_body
run: |
./scripts/create-release-body.sh "${{ inputs.release_stream }}"
env:
GH_TOKEN: ${{ github.token }}
- name: Create GitHub Prerelease
id: create_release
uses: docker://ghcr.io/mini-bomba/create-github-release:v1.2.0
with:
token: ${{ secrets.GITHUB_TOKEN }}
tag: ${{ inputs.HOMEBRIDGE_VM_IMAGE_VERSION }}
prerelease: true
draft: false
name: ${{ steps.set_title.outputs.release_title }}
files: |
./output/*.manifest
body: Placeholder, will be updated in next step
if-no-files: true
clear_attachments: true
fail_on_no_files: false
- name: Update release body
uses: tubone24/[email protected]
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG_NAME: ${{ inputs.HOMEBRIDGE_VM_IMAGE_VERSION }}
with:
body_path: ./output/release-body.md
- name: Convert, Compress, and Upload Each Virtual Disk Format
run: |
./scripts/convert-img-to-virtual-disk.sh ${{ inputs.HOMEBRIDGE_VM_IMAGE_VERSION }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Release created
run: |
echo "::notice::Release ${{ steps.set_title.outputs.RELEASE_TITLE }} created successfully."
invoke-appliance-packaging:
needs: [create-release]
runs-on: ubuntu-latest
strategy:
max-parallel: 1
fail-fast: false
matrix:
packaging_workflow: [release-stage-4_package-for-utm.yml, release-stage-4_package-for-virtualbox.yml, release-stage-4_package-for-hyperv.yml]
steps:
# Step 1: Checkout the repository
- name: Checkout repository
uses: actions/checkout@v5
# Step 2: Trigger Packaging and Validation Workflow
- name: Trigger Appliance Packaging Workflow
run: |
gh workflow run "${{ matrix.packaging_workflow }}" \
--ref "latest" \
--field release_stream="${{ inputs.release_stream }}" \
--field run_id="${{ inputs.run_id }}" \
--field HOMEBRIDGE_VM_IMAGE_VERSION="${{ inputs.HOMEBRIDGE_VM_IMAGE_VERSION }}"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Wait for Appliance Packaging Workflow to be visible to GH CLI
run: |
echo "::group::Waiting for ${{ inputs.run_id }} workflow to appear in run list..."
# Initialize variables
WORKFLOW_URL=""
MAX_RETRIES=12 # Retry for up to 1 minute (12 retries * 5 seconds)
RETRY_COUNT=0
# Retry loop
while [[ -z "$WORKFLOW_URL" || "$WORKFLOW_URL" == "null" ]]; do
if [[ $RETRY_COUNT -ge $MAX_RETRIES ]]; then
echo "::error::Could not find triggered ${{ inputs.run_id }} workflow run after 1 minute"
gh run list --workflow "${{ matrix.packaging_workflow }}" --event workflow_dispatch --branch "main" --limit 5 --json url,name
exit 1
fi
# Increment retry count
RETRY_COUNT=$((RETRY_COUNT + 1))
# Check for the workflow run
WORKFLOW_URL=$(gh run list --workflow "${{ matrix.packaging_workflow }}" \
--event workflow_dispatch \
--limit 10 \
--json url,name \
--jq '[.[] | select(.name | contains("${{ inputs.run_id }}"))] | .[].url' | \
head -n 1)
if [[ -z "$WORKFLOW_URL" || "$WORKFLOW_URL" == "null" ]]; then
echo "::notice::Retry $RETRY_COUNT/$MAX_RETRIES: ${{ inputs.run_id }} workflow not found. Retrying in 5 seconds..."
sleep 5
fi
done
echo "::notice::Found triggered ${{ inputs.run_id }} workflow: $WORKFLOW_URL"
echo "::endgroup::"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
wait-for-appliance-packaging:
needs: [invoke-appliance-packaging]
runs-on: ubuntu-latest
steps:
# Step 1: Checkout the repository
- name: Checkout repository
uses: actions/checkout@v5
- name: Wait for all Release Stage 4 packaging workflows with matching run_id to complete
run: |
workflows=$(gh run list --json name,databaseId,status,workflowName \
| jq -r --arg run_id "${{ inputs.run_id }}" '.[] | select(.name | startswith("Release Stage 4 - Package for")) | select(.name | test($run_id)) | "\(.databaseId) \(.name) \(.status)"')
if [ -z "$workflows" ]; then
echo "::error::No matching Release Stage 4 packaging workflows found for run_id: ${{ inputs.run_id }}"
exit 1
fi
while read -r run_id name status; do
echo "::group::Waiting for workflow: $name (run_id: $run_id, status: $status)"
while [ "$status" != "completed" ]; do
sleep 30
status=$(gh run view "$run_id" --json status | jq -r '.status')
echo "Workflow $name (run_id: $run_id) status: $status"
done
conclusion=$(gh run view "$run_id" --json conclusion | jq -r '.conclusion')
echo "Workflow $name (run_id: $run_id) completed with conclusion: $conclusion"
if [ "$conclusion" != "success" ]; then
echo "::error::Workflow $name failed with conclusion: $conclusion"
exit 1
fi
echo "::endgroup::"
done <<< "$workflows"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
cleanup-old-releases-and-tags:
needs: [invoke-appliance-packaging]
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v5
- name: Cleanup older beta and alpha release and tags
if: ${{ inputs.release_stream != 'stable' }}
uses: ./.github/actions/cleanup-old-releases-and-tags
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
release-stream: ${{ inputs.release_stream }}
releases-to-keep: 5
# stable release should be marked as non-prerelease, and latest
finalize-stable-release:
needs: [invoke-appliance-packaging]
if: ${{ inputs.release_stream == 'stable' }}
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v5
# Mark stable release as non-prerelease and latest
- name: Mark Stable Release as Non-Prerelease and Latest
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release edit ${{ inputs.HOMEBRIDGE_VM_IMAGE_VERSION }} \
--prerelease=false \
--latest