Deploy hass-addon-sunsynk-multi to ghcr.io #43
This file contains 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: Deploy hass-addon-sunsynk-multi to ghcr.io | |
on: | |
release: | |
types: | |
- published | |
workflow_run: | |
workflows: ["CI"] | |
branches: [main] | |
types: | |
- completed | |
workflow_dispatch: {} | |
env: | |
REGISTRY_IMAGE: ghcr.io/${{ github.repository_owner }}/hass-addon-sunsynk-multi | |
jobs: | |
ci-failure: | |
runs-on: ubuntu-latest | |
if: | | |
github.event_name == 'workflow_run' && | |
github.event.workflow_run.conclusion == 'failure' | |
steps: | |
- run: echo 'CI failed' | |
- run: exit 1 | |
information: | |
name: Gather add-on information | |
runs-on: ubuntu-latest | |
if: | | |
github.event_name == 'workflow_dispatch' || | |
github.event_name == 'release' || | |
(github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success') | |
outputs: | |
architectures: ${{ steps.information.outputs.architectures }} | |
build: ${{ steps.information.outputs.build }} | |
description: ${{ steps.information.outputs.description }} | |
environment: ${{ steps.release.outputs.environment }} | |
name: ${{ steps.information.outputs.name }} | |
slug: ${{ steps.information.outputs.slug }} | |
target: ${{ steps.information.outputs.target }} | |
version: ${{ steps.release.outputs.version }} | |
steps: | |
- name: ⤵️ Check out code from GitHub | |
uses: actions/checkout@v4 | |
- name: 🚀 Run add-on information | |
id: information | |
uses: frenck/action-addon-information@v1.4 | |
with: | |
path: ./hass-addon-sunsynk-multi | |
- name: ℹ️ Gather version and environment | |
id: release | |
run: | | |
sha="${{ github.sha }}" | |
# Default values | |
environment="edge" | |
version="${sha:0:7}" | |
# Check if it's a release event | |
if [[ "${{ github.event_name }}" == "release" ]]; then | |
version="${{ github.event.release.tag_name }}" # Lowercase the tag name | |
version="${version#v}" # Remove 'v' prefix if present | |
environment="stable" | |
# Set environment to beta if it's a prerelease | |
if [[ "${{ github.event.release.prerelease }}" == "true" ]]; then | |
environment="beta" | |
fi | |
fi | |
# Output the environment and version | |
echo "environment=${environment}" >> "$GITHUB_OUTPUT" | |
echo "version=${version}" >> "$GITHUB_OUTPUT" | |
# Log the outputs | |
cat "$GITHUB_OUTPUT" >> $GITHUB_STEP_SUMMARY | |
build: | |
name: 👷 Build & Deploy ${{ matrix.platform }} ${{ needs.information.outputs.environment }}/${{ needs.information.outputs.version }} | |
runs-on: ubuntu-latest | |
needs: information | |
strategy: | |
fail-fast: false | |
matrix: | |
platform: | |
- linux/amd64 | |
- linux/arm/v6 | |
- linux/arm/v7 | |
- linux/arm64 | |
steps: | |
- name: ⤵️ Check out code from GitHub | |
uses: actions/checkout@v4 | |
- name: Prepare Files for Build | |
run: | | |
mkdir -p hass-addon-sunsynk-multi/sunsynk | |
cp -r src hass-addon-sunsynk-multi/sunsynk/ | |
cp setup.* README.md hass-addon-sunsynk-multi/sunsynk/ | |
- name: Set up the correct base image based on platform | |
run: | | |
case "${{ matrix.platform }}" in | |
linux/amd64) echo "BUILD_FROM=ghcr.io/home-assistant/amd64-base-python:3.12-alpine3.21" >> $GITHUB_ENV ;; | |
linux/arm64) echo "BUILD_FROM=ghcr.io/home-assistant/aarch64-base-python:3.12-alpine3.21" >> $GITHUB_ENV ;; | |
linux/arm/v6) echo "BUILD_FROM=ghcr.io/home-assistant/armhf-base-python:3.12-alpine3.21" >> $GITHUB_ENV ;; | |
linux/arm/v7) echo "BUILD_FROM=ghcr.io/home-assistant/armv7-base-python:3.12-alpine3.21" >> $GITHUB_ENV ;; | |
linux/i386) echo "BUILD_FROM=ghcr.io/home-assistant/i386-base-python:3.12-alpine3.21" >> $GITHUB_ENV ;; | |
esac | |
- name: Docker meta | |
id: meta | |
uses: docker/metadata-action@v5 | |
with: | |
images: ${{ env.REGISTRY_IMAGE }} | |
- name: Set up QEMU | |
uses: docker/setup-qemu-action@v3 | |
- name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@v3 | |
- name: Cache Docker layers | |
uses: actions/cache@v4 | |
with: | |
path: /tmp/.buildx-cache # Cache path | |
key: ${{ runner.os }}-buildx-${{ github.sha }} # Unique key for cache | |
restore-keys: | | |
${{ runner.os }}-buildx- | |
- name: Login to GitHub Container Registry | |
uses: docker/#-action@v3 | |
with: | |
registry: ghcr.io | |
username: ${{ github.repository_owner }} | |
password: ${{ secrets.GITHUB_TOKEN }} | |
- name: Prepare sanitized platform name | |
id: sanitize-platform | |
run: | | |
SANITIZED_PLATFORM=$(echo ${{ matrix.platform }} | sed 's/^linux\///; s/\///g') | |
echo "SANITIZED_PLATFORM=${SANITIZED_PLATFORM}" >> $GITHUB_ENV | |
echo "Sanitized platform name: ${SANITIZED_PLATFORM}" | |
- name: Build and push by digest | |
id: build | |
uses: docker/build-push-action@v6 | |
with: | |
context: ./hass-addon-sunsynk-multi # Specify the directory containing your Dockerfile | |
file: ./hass-addon-sunsynk-multi/Dockerfile # Specify the Dockerfile path within the context | |
platforms: ${{ matrix.platform }} | |
cache-from: type=local,src=/tmp/.buildx-cache # Use cache for build | |
cache-to: type=local,dest=/tmp/.buildx-cache,mode=max # Save cache | |
labels: ${{ steps.meta.outputs.labels }} | |
outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true | |
build-args: | | |
BUILD_FROM=${{ env.BUILD_FROM }} | |
- name: Export digest | |
run: | | |
mkdir -p /tmp/digests | |
digest="${{ steps.build.outputs.digest }}" | |
touch "/tmp/digests/${digest#sha256:}" | |
- name: Upload digest | |
uses: actions/upload-artifact@v4 | |
with: | |
name: digests-${{ env.SANITIZED_PLATFORM }} # Use the sanitized platform name | |
path: /tmp/digests/* | |
if-no-files-found: error | |
retention-days: 1 | |
- name: Save platform to file | |
id: save-platform | |
run: | | |
mkdir -p outputs | |
echo ${{ env.SANITIZED_PLATFORM }} >> outputs/${{ env.SANITIZED_PLATFORM }}.txt | |
- name: Artifact platform file for later | |
uses: actions/upload-artifact@v4 | |
with: | |
name: platform-outputs-${{ env.SANITIZED_PLATFORM }} | |
path: outputs/*.txt | |
if-no-files-found: error | |
retention-days: 1 | |
merge: | |
runs-on: ubuntu-latest | |
needs: | |
- information | |
- build | |
if: | | |
always() && | |
needs.information.result == 'success' && | |
needs.build.result != 'failure' | |
steps: | |
- name: Download digests | |
uses: actions/download-artifact@v4 | |
with: | |
path: /tmp/digests | |
pattern: digests-* | |
merge-multiple: true | |
- name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@v3 | |
- name: Docker meta | |
id: meta | |
uses: docker/metadata-action@v5 | |
with: | |
images: ${{ env.REGISTRY_IMAGE }} | |
- name: Login to GitHub Container Registry | |
uses: docker/#-action@v3 | |
with: | |
registry: ghcr.io | |
username: ${{ github.repository_owner }} | |
password: ${{ secrets.GITHUB_TOKEN }} | |
- name: Download platform outputs | |
uses: actions/download-artifact@v4 | |
with: | |
pattern: platform-outputs-* | |
path: outputs | |
merge-multiple: true | |
- name: Load outputs to variable | |
id: platforms_raw | |
run: | | |
ls outputs | |
# Replace newlines with commas, then remove the trailing comma | |
echo "value=$(cat outputs/*.txt | tr '\n' ',' | sed 's/,$//')" >> "$GITHUB_OUTPUT" | |
- name: Generate tags for multi-platform image | |
run: | | |
# Define base tags | |
TAGS=( | |
"-t ${{ env.REGISTRY_IMAGE }}:${{ needs.information.outputs.version }}" | |
"-t ${{ env.REGISTRY_IMAGE }}:${{ needs.information.outputs.environment }}" | |
) | |
# Get the list of platforms from the build job output | |
platforms="${{ steps.platforms_raw.outputs.value }}" | |
# Split the platforms and add platform-specific tags | |
IFS=',' read -ra PLATFORM_ARRAY <<< "$platforms" | |
for PLATFORM in "${PLATFORM_ARRAY[@]}"; do | |
TAGS+=("-t ${{ env.REGISTRY_IMAGE }}/${PLATFORM}:${{ needs.information.outputs.version }}") | |
TAGS+=("-t ${{ env.REGISTRY_IMAGE }}/${PLATFORM}:${{ needs.information.outputs.environment }}") | |
done | |
# Join tags into a string | |
TAGS_STRING=$(printf " %s" "${TAGS[@]}") | |
# Export the tags string to the environment for later use | |
echo "TAGS_STRING=${TAGS_STRING}" >> $GITHUB_ENV | |
# Log the generated tags for debugging | |
echo "Generated tags: ${TAGS_STRING}" | |
- name: Create manifest list and push | |
working-directory: /tmp/digests | |
run: | | |
docker buildx imagetools create $TAGS_STRING \ | |
$(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *) | |
- name: Inspect image | |
run: | | |
# Inspect the image using the first tag from TAGS_STRING (without the leading '-t ' part) | |
INSPECT_TAG=$(echo "${TAGS_STRING}" | awk '{print $2}') | |
# Log the tag being inspected | |
echo "Inspecting image with tag: $INSPECT_TAG" | |
# Run the inspection | |
docker buildx imagetools inspect $INSPECT_TAG | |
publish_addon: | |
name: 🆕 Update addon version to ${{ needs.information.outputs.version }} | |
needs: [information, build, merge] | |
if: | | |
always() && | |
needs.information.result == 'success' && | |
needs.build.result != 'failure' && | |
needs.merge.result == 'success' | |
permissions: | |
contents: write | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
ref: main | |
- name: Configure Git | |
run: | | |
git config --global user.name 'github-actions[bot]' | |
git config --global user.email 'github-actions[bot]@users.noreply.github.com' | |
- name: Update versions and commit changes | |
run: | | |
# Pull latest changes with rebase strategy | |
git pull --rebase origin main | |
# Make the version updates | |
sed -i 's/version:.*/version: "${{ needs.information.outputs.version }}"/g' hass-addon-sunsynk-edge/config.yaml | |
if [[ "${{ needs.information.outputs.environment }}" == "stable" ]]; then | |
sed -i 's/version:.*/version: "${{ needs.information.outputs.version }}"/g' hass-addon-sunsynk-multi/config.yaml | |
fi | |
# Stage and commit changes | |
git add hass-addon-sunsynk-edge/config.yaml hass-addon-sunsynk-multi/config.yaml | |
git commit -m "Update addon version to ${{ needs.information.outputs.version }} [no ci]" || echo "No changes to commit" | |
- name: Push changes | |
run: | | |
# Try to push changes | |
for i in {1..3}; do | |
if git push origin main; then | |
echo "Successfully pushed changes" | |
exit 0 | |
else | |
echo "Push failed, attempting to rebase and retry..." | |
git pull --rebase origin main | |
fi | |
sleep 5 | |
done | |
echo "Failed to push after 3 attempts" | |
exit 1 |