Release Stage 2 - Scheduled - Build and Push alpha Docker Images #21
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Release Stage 2 - Build and Push Docker Images | |
run-name: Release Stage 2 - ${{ github.event.inputs.Scheduled}} - Build and Push ${{ inputs.release_type }} Docker Images | |
on: | |
workflow_dispatch: | |
inputs: | |
release_type: | |
description: 'Choose release type: "stable" (builds latest version), "beta" (builds beta version with beta-YYYY-MM-DD tag), or "alpha" (builds alpha version with alpha-YYYY-MM-DD tag).' | |
required: true | |
type: choice | |
options: | |
- stable | |
- beta | |
- alpha | |
default: beta | |
Scheduled: | |
description: 'Whether this is a scheduled run' | |
required: false | |
type: choice | |
options: | |
- Scheduled | |
- Manual | |
default: Manual | |
concurrency: | |
group: stage-2-build-and-push | |
cancel-in-progress: false | |
jobs: | |
set-versions: | |
runs-on: ubuntu-latest | |
outputs: | |
DOCKER_HOMEBRIDGE_VERSION: ${{ steps.docker_version.outputs.DOCKER_HOMEBRIDGE_VERSION }} | |
IS_BETA: ${{ steps.check_beta.outputs.IS_BETA }} | |
IS_ALPHA: ${{ steps.check_alpha.outputs.IS_ALPHA }} | |
HOMEBRIDGE_APT_PKG_VERSION: ${{ steps.pkg_version.outputs.HOMEBRIDGE_APT_PKG_VERSION }} | |
HOMEBRIDGE_APT_PKG_FILE: ${{ steps.pkg_version.outputs.HOMEBRIDGE_APT_PKG_FILE }} | |
FFMPEG_FOR_HOMEBRIDGE_VERSION: ${{ steps.pkg_version.outputs.FFMPEG_FOR_HOMEBRIDGE_VERSION }} | |
RELEASE_TITLE: ${{ steps.set_title.outputs.RELEASE_TITLE }} | |
DOCKER_TAG: ${{ steps.pkg_version.outputs.DOCKER_TAG }} | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Set Docker Homebridge version | |
id: docker_version | |
run: | | |
if [[ "${{ inputs.release_type }}" == "beta" ]]; then | |
export DOCKER_HOMEBRIDGE_VERSION="beta-$(date +%Y-%m-%d)" | |
elif [[ "${{ inputs.release_type }}" == "alpha" ]]; then | |
export DOCKER_HOMEBRIDGE_VERSION="alpha-$(date +%Y-%m-%d)" | |
else | |
export DOCKER_HOMEBRIDGE_VERSION="$(date +%Y-%m-%d)" | |
fi | |
echo "DOCKER_HOMEBRIDGE_VERSION=${DOCKER_HOMEBRIDGE_VERSION}" >> $GITHUB_OUTPUT | |
- name: Check for beta release | |
id: check_beta | |
run: | | |
if [[ "${{ inputs.release_type }}" == "beta" ]]; then | |
if [[ -f beta/package.json ]]; then | |
echo "IS_BETA=true" >> $GITHUB_OUTPUT | |
else | |
echo "Error: beta/package.json is missing for beta release" | |
exit 1 | |
fi | |
else | |
echo "IS_BETA=false" >> $GITHUB_OUTPUT | |
fi | |
- name: Check for alpha release | |
id: check_alpha | |
run: | | |
if [[ "${{ inputs.release_type }}" == "alpha" ]]; then | |
if [[ -f alpha/package.json ]]; then | |
echo "IS_ALPHA=true" >> $GITHUB_OUTPUT | |
else | |
echo "Error: alpha/package.json is missing for alpha release" | |
exit 1 | |
fi | |
else | |
echo "IS_ALPHA=false" >> $GITHUB_OUTPUT | |
fi | |
- name: Set Package Versions | |
id: pkg_version | |
run: | | |
if [[ "${{ steps.check_beta.outputs.IS_BETA }}" == "true" ]]; then | |
export HOMEBRIDGE_APT_PKG_VERSION=$(jq -r '.dependencies["@homebridge/homebridge-apt-pkg"]' beta/package.json | sed 's/\^//') | |
export HOMEBRIDGE_APT_PKG_FILE=$(echo "$HOMEBRIDGE_APT_PKG_VERSION" | sed 's/\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\)-beta\(\.[0-9][0-9]*\)/\1.beta\2/') | |
export FFMPEG_FOR_HOMEBRIDGE_VERSION=$(jq -r '.dependencies["ffmpeg-for-homebridge"]' beta/package.json | sed 's/\^//') | |
echo "HOMEBRIDGE_APT_PKG_FILE=v${HOMEBRIDGE_APT_PKG_FILE}" >> $GITHUB_OUTPUT | |
echo "DOCKER_TAG=beta" >> $GITHUB_OUTPUT | |
elif [[ "${{ steps.check_alpha.outputs.IS_ALPHA }}" == "true" ]]; then | |
export HOMEBRIDGE_APT_PKG_VERSION=$(jq -r '.dependencies["@homebridge/homebridge-apt-pkg"]' alpha/package.json | sed 's/\^//') | |
export HOMEBRIDGE_APT_PKG_FILE=$(echo "$HOMEBRIDGE_APT_PKG_VERSION" | sed 's/\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\)-alpha\(\.[0-9][0-9]*\)/\1.alpha\2/') | |
export FFMPEG_FOR_HOMEBRIDGE_VERSION=$(jq -r '.dependencies["ffmpeg-for-homebridge"]' alpha/package.json | sed 's/\^//') | |
echo "HOMEBRIDGE_APT_PKG_FILE=v${HOMEBRIDGE_APT_PKG_FILE}" >> $GITHUB_OUTPUT | |
echo "DOCKER_TAG=alpha" >> $GITHUB_OUTPUT | |
else | |
export HOMEBRIDGE_APT_PKG_VERSION=$(jq -r '.dependencies["@homebridge/homebridge-apt-pkg"]' package.json | sed 's/\^//') | |
export FFMPEG_FOR_HOMEBRIDGE_VERSION=$(jq -r '.dependencies["ffmpeg-for-homebridge"]' package.json | sed 's/\^//') | |
echo "DOCKER_TAG=latest" >> $GITHUB_OUTPUT | |
fi | |
echo "HOMEBRIDGE_APT_PKG_VERSION=v${HOMEBRIDGE_APT_PKG_VERSION}" >> $GITHUB_OUTPUT | |
echo "FFMPEG_FOR_HOMEBRIDGE_VERSION=v${FFMPEG_FOR_HOMEBRIDGE_VERSION}" >> $GITHUB_OUTPUT | |
- name: Set Release Title | |
id: set_title | |
run: | | |
if [[ "${{ steps.check_beta.outputs.IS_BETA }}" == "true" ]]; then | |
echo "RELEASE_TITLE=BETA: Homebridge Docker Release ${{ steps.docker_version.outputs.DOCKER_HOMEBRIDGE_VERSION }}" >> $GITHUB_OUTPUT | |
elif [[ "${{ steps.check_alpha.outputs.IS_ALPHA }}" == "true" ]]; then | |
echo "RELEASE_TITLE=ALPHA: Homebridge Docker Release ${{ steps.docker_version.outputs.DOCKER_HOMEBRIDGE_VERSION }}" >> $GITHUB_OUTPUT | |
else | |
echo "RELEASE_TITLE=Homebridge Docker Release ${{ steps.docker_version.outputs.DOCKER_HOMEBRIDGE_VERSION }}" >> $GITHUB_OUTPUT | |
fi | |
- name: Output versions | |
run: | | |
echo "::group::Version Information" | |
echo "DOCKER_HOMEBRIDGE_VERSION=${{ steps.docker_version.outputs.DOCKER_HOMEBRIDGE_VERSION }}" | |
echo "IS_BETA=${{ steps.check_beta.outputs.IS_BETA }}" | |
echo "IS_ALPHA=${{ steps.check_alpha.outputs.IS_ALPHA }}" | |
echo "HOMEBRIDGE_APT_PKG_VERSION=${{ steps.pkg_version.outputs.HOMEBRIDGE_APT_PKG_VERSION }}" | |
echo "HOMEBRIDGE_APT_PKG_FILE=${{ steps.pkg_version.outputs.HOMEBRIDGE_APT_PKG_FILE }}" | |
echo "FFMPEG_FOR_HOMEBRIDGE_VERSION=${{ steps.pkg_version.outputs.FFMPEG_FOR_HOMEBRIDGE_VERSION }}" | |
echo "RELEASE_TITLE=${{ steps.set_title.outputs.RELEASE_TITLE }}" | |
echo "DOCKER_TAG=${{ steps.pkg_version.outputs.DOCKER_TAG }}" | |
echo "::endgroup::" | |
build-images: | |
runs-on: ubuntu-latest | |
needs: set-versions | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Set up QEMU | |
uses: docker/setup-qemu-action@v3 | |
- name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@v3 | |
- name: Log into GitHub Container registry | |
uses: docker/login-action@v3 | |
with: | |
registry: ghcr.io | |
username: ${{ github.actor }} | |
password: ${{ secrets.GITHUB_TOKEN }} | |
- name: Build and Push Image to GitHub Container Registry | |
uses: docker/build-push-action@v5 | |
with: | |
context: . | |
file: ./Dockerfile | |
platforms: linux/amd64,linux/arm/v7,linux/arm64 | |
push: true | |
build-args: | | |
HOMEBRIDGE_APT_PKG_VERSION=${{ needs.set-versions.outputs.HOMEBRIDGE_APT_PKG_VERSION }} | |
${{ (needs.set-versions.outputs.IS_BETA == 'true' || needs.set-versions.outputs.IS_ALPHA == 'true') && format('HOMEBRIDGE_APT_PKG_FILE={0}', needs.set-versions.outputs.HOMEBRIDGE_APT_PKG_FILE) || '' }} | |
FFMPEG_FOR_HOMEBRIDGE_VERSION=${{ needs.set-versions.outputs.FFMPEG_FOR_HOMEBRIDGE_VERSION }} | |
DOCKER_HOMEBRIDGE_VERSION=${{ needs.set-versions.outputs.DOCKER_HOMEBRIDGE_VERSION }} | |
tags: | | |
${{ (needs.set-versions.outputs.IS_BETA == 'false' && needs.set-versions.outputs.IS_ALPHA == 'false') && 'ghcr.io/homebridge/homebridge:ubuntu' || '' }} | |
ghcr.io/homebridge/homebridge:${{ needs.set-versions.outputs.DOCKER_TAG }} | |
ghcr.io/homebridge/homebridge:${{ needs.set-versions.outputs.DOCKER_HOMEBRIDGE_VERSION }} | |
- name: Log into Docker Hub | |
uses: docker/login-action@v3 | |
if: github.repository == 'homebridge/docker-homebridge' | |
with: | |
registry: docker.io | |
username: ${{ secrets.DOCKER_USERNAME }} | |
password: ${{ secrets.DOCKER_PASSWORD }} | |
- name: Build and Push Image to Docker Hub | |
if: github.repository == 'homebridge/docker-homebridge' | |
uses: docker/build-push-action@v5 | |
with: | |
context: . | |
file: ./Dockerfile | |
platforms: linux/amd64,linux/arm/v7,linux/arm64 | |
push: true | |
build-args: | | |
HOMEBRIDGE_APT_PKG_VERSION=${{ needs.set-versions.outputs.HOMEBRIDGE_APT_PKG_VERSION }} | |
${{ (needs.set-versions.outputs.IS_BETA == 'true' || needs.set-versions.outputs.IS_ALPHA == 'true') && format('HOMEBRIDGE_APT_PKG_FILE={0}', needs.set-versions.outputs.HOMEBRIDGE_APT_PKG_FILE) || '' }} | |
FFMPEG_FOR_HOMEBRIDGE_VERSION=${{ needs.set-versions.outputs.FFMPEG_FOR_HOMEBRIDGE_VERSION }} | |
DOCKER_HOMEBRIDGE_VERSION=${{ needs.set-versions.outputs.DOCKER_HOMEBRIDGE_VERSION }} | |
tags: | | |
${{ (needs.set-versions.outputs.IS_BETA == 'false' && needs.set-versions.outputs.IS_ALPHA == 'false') && 'homebridge/homebridge:ubuntu' || '' }} | |
homebridge/homebridge:${{ needs.set-versions.outputs.DOCKER_HOMEBRIDGE_VERSION }} | |
homebridge/homebridge:${{ needs.set-versions.outputs.DOCKER_TAG }} | |
extract-manifest: | |
runs-on: ubuntu-latest | |
needs: [set-versions, build-images] | |
outputs: | |
manifest_file: ${{ steps.extract.outputs.manifest_file }} | |
package_changes: ${{ steps.extract_changes.outputs.package_changes }} | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Extract Docker.manifest from Image | |
id: extract | |
run: | | |
docker create --name temp-homebridge ghcr.io/homebridge/homebridge:${{ needs.set-versions.outputs.DOCKER_HOMEBRIDGE_VERSION }} | |
docker cp temp-homebridge:/opt/homebridge/Docker.manifest ./manifest.md | |
docker rm temp-homebridge | |
echo "manifest_file=manifest.md" >> $GITHUB_OUTPUT | |
- name: Generate Release Notes with Changes | |
id: generate_notes | |
run: | | |
# Get the previous release tag (excluding current one) | |
if [[ "${{ needs.set-versions.outputs.IS_BETA }}" == "true" ]]; then | |
PREVIOUS_TAG=$(gh release list --limit 50 | cut -f3 | grep -E "^beta-[0-9]{4}-[0-9]{2}-[0-9]{2}" | head -1) | |
elif [[ "${{ needs.set-versions.outputs.IS_ALPHA }}" == "true" ]]; then | |
PREVIOUS_TAG=$(gh release list --limit 50 | cut -f3 | grep -E "^alpha-[0-9]{4}-[0-9]{2}-[0-9]{2}" | head -1) | |
else | |
PREVIOUS_TAG=$(gh release list --limit 50 | cut -f3 | grep -vE "^(beta|alpha)-" | head -1) | |
fi | |
echo "Previous release tag: $PREVIOUS_TAG" | |
if [[ -n "$PREVIOUS_TAG" ]]; then | |
# Download previous manifest if it exists | |
if gh release download "$PREVIOUS_TAG" --pattern "Docker.manifest" --dir ./previous 2>/dev/null; then | |
echo -e "\n## Changes Since Previous Release ($PREVIOUS_TAG)\n" >> manifest.md | |
# Compare manifests and show differences | |
if ! diff -u ./previous/Docker.manifest ./manifest.md > manifest.diff 2>/dev/null; then | |
echo "### Package Version Changes" >> manifest.md | |
echo "\`\`\`diff" >> manifest.md | |
# Sort the diff output by package name for better readability | |
cat manifest.diff | grep -E "^[+-] \|" | sort -k2 | head -20 >> manifest.md | |
echo "\`\`\`" >> manifest.md | |
else | |
echo "No package version changes detected." >> manifest.md | |
fi | |
# Show Docker image specific changes | |
echo -e "\n### Docker Image Changes" >> manifest.md | |
echo "See [commit history](https://github.com/homebridge/docker-homebridge/compare/$PREVIOUS_TAG...${{ needs.set-versions.outputs.DOCKER_HOMEBRIDGE_VERSION }}) for Docker-specific changes." >> manifest.md | |
else | |
echo -e "\n## Changes Since Previous Release\n" >> manifest.md | |
echo "Previous release manifest not available for comparison." >> manifest.md | |
fi | |
else | |
echo -e "\n## Initial Release\n" >> manifest.md | |
echo "This appears to be the initial release." >> manifest.md | |
fi | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
- name: Extract package changes for Discord | |
id: extract_changes | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
run: | | |
# Get the latest release to compare against (excluding the current one being created) | |
if [[ "${{ needs.set-versions.outputs.IS_BETA }}" == "true" ]]; then | |
# For beta releases, compare with the latest beta release | |
LATEST_RELEASE=$(gh release list --limit 50 --json tagName | jq -r '.[] | select(.tagName | startswith("beta-")) | .tagName' | head -1) | |
else | |
# For stable releases, compare with the latest stable release (no beta prefix) | |
LATEST_RELEASE=$(gh release list --limit 50 --json tagName | jq -r '.[] | select(.tagName | startswith("beta-") | not) | .tagName' | head -1) | |
fi | |
echo "Comparing with latest release: $LATEST_RELEASE" | |
if [[ -n "$LATEST_RELEASE" ]]; then | |
# Get the previous release manifest | |
PREV_MANIFEST=$(gh release view "$LATEST_RELEASE" --json body | jq -r '.body') | |
# Extract package versions from current manifest | |
CURRENT_MANIFEST=$(cat manifest.md) | |
# Parse package versions from both manifests | |
extract_package_version() { | |
local manifest="$1" | |
local package="$2" | |
echo "$manifest" | grep "|$package|" | awk -F'|' '{print $3}' | tr -d ' ' | |
} | |
# Compare packages and build changes summary | |
PACKAGE_CHANGES="" | |
packages=("Ubuntu" "ffmpeg for homebridge" "Homebridge APT Package" "NodeJS" "Homebridge UI" "Homebridge") | |
for package in "${packages[@]}"; do | |
current_version=$(extract_package_version "$CURRENT_MANIFEST" "$package") | |
prev_version=$(extract_package_version "$PREV_MANIFEST" "$package") | |
if [[ "$current_version" != "$prev_version" && -n "$current_version" && -n "$prev_version" ]]; then | |
if [[ -n "$PACKAGE_CHANGES" ]]; then | |
PACKAGE_CHANGES="$PACKAGE_CHANGES\n" | |
fi | |
PACKAGE_CHANGES="${PACKAGE_CHANGES}• **$package**: $prev_version → $current_version" | |
fi | |
done | |
if [[ -z "$PACKAGE_CHANGES" ]]; then | |
PACKAGE_CHANGES="• No package version changes detected" | |
fi | |
else | |
PACKAGE_CHANGES="• Initial release - no previous version to compare" | |
fi | |
echo "Package changes:" | |
echo -e "$PACKAGE_CHANGES" | |
# Set output using multiline string | |
{ | |
echo 'package_changes<<EOF' | |
echo -e "$PACKAGE_CHANGES" | |
echo 'EOF' | |
} >> $GITHUB_OUTPUT | |
- name: Upload manifest artifact | |
uses: actions/upload-artifact@v4 | |
with: | |
name: manifest | |
path: manifest.md | |
create-release: | |
runs-on: ubuntu-latest | |
needs: [set-versions, extract-manifest] | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Download manifest artifact | |
uses: actions/download-artifact@v4 | |
with: | |
name: manifest | |
path: . | |
- name: Create GitHub Release | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
run: | | |
TAG_NAME=${{ needs.set-versions.outputs.DOCKER_HOMEBRIDGE_VERSION }} | |
# Copy manifest for release asset with proper name | |
cp manifest.md Docker.manifest | |
gh release create "${TAG_NAME}" \ | |
--title "${{ needs.set-versions.outputs.RELEASE_TITLE }}" \ | |
--notes-file manifest.md \ | |
--draft=false \ | |
Docker.manifest | |
- name: Release created | |
run: | | |
echo "::notice::Release ${{ needs.set-versions.outputs.DOCKER_HOMEBRIDGE_VERSION }} - ${{ needs.set-versions.outputs.RELEASE_TITLE }} created successfully." | |
discord-notification: | |
name: Discord Webhooks | |
needs: [set-versions, create-release, extract-manifest] | |
uses: homebridge/.github/.github/workflows/discord-webhooks.yml@latest | |
with: | |
title: "${{ needs.set-versions.outputs.RELEASE_TITLE }}" | |
description: | | |
Version `${{ needs.set-versions.outputs.DOCKER_HOMEBRIDGE_VERSION }}` | |
url: "https://github.com/homebridge/docker-homebridge/releases/tag/${{ needs.set-versions.outputs.DOCKER_HOMEBRIDGE_VERSION }}" | |
**Package Changes:** | |
${{ needs.extract-manifest.outputs.package_changes }} | |
secrets: | |
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK_URL_LATEST }} | |
validate-container: | |
name: Validate Docker Container | |
needs: [set-versions, create-release, discord-notification] | |
uses: ./.github/workflows/validate-docker-container.yml | |
with: | |
release_tag: ${{ needs.set-versions.outputs.DOCKER_TAG }} |