Skip to content

Release

Release #29

Workflow file for this run

name: Release
on:
workflow_dispatch:
inputs:
tag:
description: "Git tag to release (e.g., v1.0.0) - Leave empty to auto-calculate from GitVersion"
required: false
type: string
create_docker:
description: "Also create Docker image"
required: false
default: true
type: boolean
env:
DOTNET_VERSION: "9.0.x"
PROJECT_NAME: "KnxMonitor"
DOTNET_NOLOGO: true
DOTNET_CLI_TELEMETRY_OPTOUT: true
jobs:
calculate-version:
runs-on: ubuntu-latest
timeout-minutes: 5
outputs:
version: ${{ steps.gitversion.outputs.semVer }}
tag: ${{ steps.determine-tag.outputs.tag }}
informational-version: ${{ steps.gitversion.outputs.informationalVersion }}
assembly-version: ${{ steps.gitversion.outputs.assemblySemVer }}
is-prerelease: ${{ steps.gitversion.outputs.preReleaseLabel != '' }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
- name: Install GitVersion
uses: gittools/actions/gitversion/setup@v0.10.2
with:
versionSpec: "6.x"
- name: Determine Version
id: gitversion
uses: gittools/actions/gitversion/execute@v0.10.2
with:
useConfigFile: true
- name: Determine Tag
id: determine-tag
run: |
if [[ -n "${{ needs.calculate-version.outputs.tag }}" ]]; then
# Use provided tag
TAG="${{ needs.calculate-version.outputs.tag }}"
echo "Using provided tag: $TAG"
else
# Auto-calculate tag from GitVersion
TAG="v${{ steps.gitversion.outputs.semVer }}"
echo "Auto-calculated tag: $TAG"
fi
echo "tag=$TAG" >> $GITHUB_OUTPUT
- name: Display GitVersion outputs
run: |
echo "SemVer: ${{ steps.gitversion.outputs.semVer }}"
echo "FullSemVer: ${{ steps.gitversion.outputs.fullSemVer }}"
echo "InformationalVersion: ${{ steps.gitversion.outputs.informationalVersion }}"
echo "AssemblySemVer: ${{ steps.gitversion.outputs.assemblySemVer }}"
echo "PreReleaseLabel: ${{ steps.gitversion.outputs.preReleaseLabel }}"
echo "Final Tag: ${{ steps.determine-tag.outputs.tag }}"
build:
needs: calculate-version
runs-on: ${{ matrix.os }}
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
include:
- runtime: win-x64
os: ubuntu-latest
- runtime: linux-x64
os: ubuntu-latest
- runtime: linux-arm64
os: ubuntu-latest
- runtime: osx-x64
os: macos-13
- runtime: osx-arm64
os: macos-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
- name: Install GitVersion
uses: gittools/actions/gitversion/setup@v0.10.2
with:
versionSpec: "6.x"
- name: Determine Version
id: gitversion
uses: gittools/actions/gitversion/execute@v0.10.2
with:
useConfigFile: true
- name: Cache NuGet packages
uses: actions/cache@v4
with:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj', '**/Directory.Packages.props') }}
restore-keys: |
${{ runner.os }}-nuget-
- name: Restore dependencies
run: dotnet restore --verbosity minimal
- name: Run tests
run: dotnet test --configuration Release --verbosity normal --no-restore
- name: Build and publish
run: |
echo "DEBUG: Building for runtime: ${{ matrix.runtime }}"
if [[ "${{ matrix.runtime }}" == "linux-x64" || "${{ matrix.runtime }}" == "linux-arm64" ]]; then
echo "DEBUG: Using framework-dependent deployment for Linux"
# Framework-dependent deployment for Docker (Linux)
dotnet publish ${{ env.PROJECT_NAME }} \
--configuration Release \
--runtime ${{ matrix.runtime }} \
--self-contained false \
--output ./publish/${{ matrix.runtime }} \
--verbosity minimal
else
echo "DEBUG: Using self-contained deployment for non-Linux platforms"
# Self-contained deployment with proper single executable
dotnet publish ${{ env.PROJECT_NAME }} \
--configuration Release \
--runtime ${{ matrix.runtime }} \
--self-contained true \
--property:PublishSingleFile=true \
--property:IncludeNativeLibrariesForSelfExtract=true \
--output ./publish/${{ matrix.runtime }} \
--verbosity minimal
fi
echo "DEBUG: Build completed. Checking output:"
ls -la ./publish/${{ matrix.runtime }}/ | head -10
- name: Code sign macOS binaries
if: startsWith(matrix.runtime, 'osx-')
env:
APPLE_CERTIFICATE_P12: ${{ secrets.APPLE_CERTIFICATE_P12 }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_DEVELOPER_ID: ${{ secrets.APPLE_DEVELOPER_ID }}
run: |
# Create temporary keychain
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
KEYCHAIN_PASSWORD=$(openssl rand -base64 32)
# Create keychain and set as default
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH"
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security list-keychains -d user -s "$KEYCHAIN_PATH"
# Import certificate
if [ -z "$APPLE_CERTIFICATE_P12" ]; then
echo "Error: APPLE_CERTIFICATE_P12 secret is empty"
exit 1
fi
echo "$APPLE_CERTIFICATE_P12" | base64 -D > certificate.p12
if [ ! -f certificate.p12 ] || [ ! -s certificate.p12 ]; then
echo "Error: Failed to decode certificate"
exit 1
fi
security import certificate.p12 -k "$KEYCHAIN_PATH" -P "$APPLE_CERTIFICATE_PASSWORD" -T /usr/bin/codesign
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
# Sign the binary
BINARY_PATH="./publish/${{ matrix.runtime }}/${{ env.PROJECT_NAME }}"
codesign --sign "Developer ID Application: Fabian Schmieder ($APPLE_DEVELOPER_ID)" \
--verbose \
--force \
--options runtime \
--entitlements entitlements.plist \
--timestamp \
"$BINARY_PATH"
# Verify signature
codesign --verify --verbose "$BINARY_PATH"
# Check Gatekeeper status (non-blocking - notarization not required for CLI tools)
echo "Checking Gatekeeper status (informational only):"
spctl --assess --type execute --verbose "$BINARY_PATH" || echo "Note: Binary is signed but not notarized (expected for CLI tools)"
# Clean up
rm certificate.p12
security delete-keychain "$KEYCHAIN_PATH"
- name: Create archive
run: |
cd ./publish/${{ matrix.runtime }}
if [[ "${{ matrix.runtime }}" == win-* ]]; then
zip -r ../../${{ env.PROJECT_NAME }}-${{ needs.calculate-version.outputs.version }}-${{ matrix.runtime }}.zip .
else
tar -czf ../../${{ env.PROJECT_NAME }}-${{ needs.calculate-version.outputs.version }}-${{ matrix.runtime }}.tar.gz .
fi
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ env.PROJECT_NAME }}-${{ matrix.runtime }}
path: |
*.zip
*.tar.gz
retention-days: 1
compression-level: 9
docker:
needs: [calculate-version, build]
if: inputs.create_docker
runs-on: ubuntu-latest
timeout-minutes: 20
permissions:
contents: read
packages: write
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository_owner }}/${{ env.PROJECT_NAME }}
tags: |
type=raw,value=${{ needs.calculate-version.outputs.version }}
type=raw,value=latest,enable=${{ needs.calculate-version.outputs.is-prerelease == 'false' }}
labels: |
org.opencontainers.image.title=KNX Monitor
org.opencontainers.image.description=KNX/EIB bus monitoring and debugging tool
org.opencontainers.image.vendor=metaneutrons
org.opencontainers.image.version=${{ needs.calculate-version.outputs.version }}
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
org.opencontainers.image.documentation=${{ github.server_url }}/${{ github.repository }}/blob/main/README.md
org.opencontainers.image.licenses=GPL-3.0
- name: Download Linux binaries for Docker
uses: actions/download-artifact@v4
with:
pattern: ${{ env.PROJECT_NAME }}-linux-*
path: ./docker-artifacts
merge-multiple: false
- name: Prepare Docker context for multi-arch build
run: |
mkdir -p docker-context/publish-amd64 docker-context/publish-arm64
# Extract x64 binary (maps to amd64 in Docker)
cd docker-artifacts/${{ env.PROJECT_NAME }}-linux-x64
tar -xzf ${{ env.PROJECT_NAME }}-${{ needs.calculate-version.outputs.version }}-linux-x64.tar.gz
# Copy entire framework-dependent deployment
cp -r * ../../docker-context/publish-amd64/
# Extract arm64 binary
cd ../${{ env.PROJECT_NAME }}-linux-arm64
tar -xzf ${{ env.PROJECT_NAME }}-${{ needs.calculate-version.outputs.version }}-linux-arm64.tar.gz
# Copy entire framework-dependent deployment
cp -r * ../../docker-context/publish-arm64/
# Copy CI/CD Dockerfile
cd ../..
cp Dockerfile.ci docker-context/Dockerfile
# Verify binaries
echo "AMD64 deployment:"
ls -la docker-context/publish-amd64/ | head -10
echo "ARM64 deployment:"
ls -la docker-context/publish-arm64/ | head -10
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: ./docker-context
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
build-args: |
VERSION=${{ needs.calculate-version.outputs.version }}
BUILD_DATE=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.created'] }}
VCS_REF=${{ github.sha }}
provenance: true
sbom: true
release:
needs: [calculate-version, build, docker]
if: always() && needs.calculate-version.result == 'success' && needs.build.result == 'success' && (needs.docker.result == 'success' || needs.docker.result == 'skipped')
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: write
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: ./artifacts
- name: Prepare release assets
run: |
mkdir -p ./release-assets
find ./artifacts -name "*.zip" -o -name "*.tar.gz" | xargs -I {} cp {} ./release-assets/
ls -la ./release-assets/
- name: Create and push Git tag
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
# Check if tag already exists
if git rev-parse "${{ needs.calculate-version.outputs.tag }}" >/dev/null 2>&1; then
echo "Tag ${{ needs.calculate-version.outputs.tag }} already exists, skipping tag creation"
else
echo "Creating new tag ${{ needs.calculate-version.outputs.tag }}"
git tag -a ${{ needs.calculate-version.outputs.tag }} -m "Release ${{ needs.calculate-version.outputs.tag }}"
git push origin ${{ needs.calculate-version.outputs.tag }}
fi
- name: Generate release notes
id: release_notes
run: |
cat << EOF > release_notes.md
## 🚀 KNX Monitor ${{ needs.calculate-version.outputs.version }}
### 📋 Version Information
- **Version**: ${{ needs.calculate-version.outputs.version }}
- **GitVersion**: ${{ needs.calculate-version.outputs.informational-version }}
- **Assembly Version**: ${{ needs.calculate-version.outputs.assembly-version }}
### 📦 Installation
#### Homebrew (macOS/Linux)
\`\`\`bash
brew install metaneutrons/tap/knxmonitor
\`\`\`
#### Docker
\`\`\`bash
docker run --rm -it ghcr.io/metaneutrons/knxmonitor:${{ needs.calculate-version.outputs.version }} --help
\`\`\`
#### Manual Installation
Download the appropriate binary for your platform from the assets below.
### 🏗️ Build Information
- **.NET Version**: 9.0
- **Build Date**: $(date -u +"%Y-%m-%d %H:%M:%S UTC")
- **Commit**: ${{ github.sha }}
- **Tag**: ${{ needs.calculate-version.outputs.tag }}
### 📋 Supported Platforms
- **Windows x64** (knxmonitor-${{ needs.calculate-version.outputs.version }}-win-x64.zip)
- **Linux x64** (knxmonitor-${{ needs.calculate-version.outputs.version }}-linux-x64.tar.gz)
- **macOS x64** (knxmonitor-${{ needs.calculate-version.outputs.version }}-osx-x64.tar.gz)
- **macOS ARM64** (knxmonitor-${{ needs.calculate-version.outputs.version }}-osx-arm64.tar.gz)
- **Docker** (ghcr.io/metaneutrons/knxmonitor:${{ needs.calculate-version.outputs.version }})
### 🔧 Quick Start
\`\`\`bash
# Show version
knxmonitor --version
# Monitor KNX bus via IP routing
knxmonitor --connection-type routing
# Monitor with IP tunneling
knxmonitor --connection-type tunneling --host 192.168.1.100
\`\`\`
---
**Full Changelog**: https://github.com/${{ github.repository }}/compare/${{ needs.calculate-version.outputs.tag }}...HEAD
EOF
- name: Create GitHub Release
uses: softprops/action-gh-release@v1
with:
tag_name: ${{ needs.calculate-version.outputs.tag }}
name: "KNX Monitor ${{ needs.calculate-version.outputs.version }}"
body_path: release_notes.md
files: ./release-assets/*
draft: false
prerelease: ${{ needs.calculate-version.outputs.is-prerelease == 'true' }}
generate_release_notes: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
update-homebrew:
needs: [calculate-version, release, docker]
if: always() && needs.calculate-version.outputs.is-prerelease == 'false' && needs.release.result == 'success' && (needs.docker.result == 'success' || needs.docker.result == 'skipped')
runs-on: ubuntu-latest
timeout-minutes: 10
continue-on-error: false # Don't fail the entire release if Homebrew update fails
steps:
- name: Download macOS artifacts
uses: actions/download-artifact@v4
with:
pattern: ${{ env.PROJECT_NAME }}-osx-*
path: ./macos-artifacts
- name: Calculate checksums
id: checksums
run: |
# Calculate SHA256 for macOS x64
MACOS_X64_SHA=$(sha256sum ./macos-artifacts/${{ env.PROJECT_NAME }}-osx-x64/${{ env.PROJECT_NAME }}-${{ needs.calculate-version.outputs.version }}-osx-x64.tar.gz | cut -d' ' -f1)
echo "macos_x64_sha=${MACOS_X64_SHA}" >> $GITHUB_OUTPUT
# Calculate SHA256 for macOS ARM64
MACOS_ARM64_SHA=$(sha256sum ./macos-artifacts/${{ env.PROJECT_NAME }}-osx-arm64/${{ env.PROJECT_NAME }}-${{ needs.calculate-version.outputs.version }}-osx-arm64.tar.gz | cut -d' ' -f1)
echo "macos_arm64_sha=${MACOS_ARM64_SHA}" >> $GITHUB_OUTPUT
echo "macOS x64 SHA256: ${MACOS_X64_SHA}"
echo "macOS ARM64 SHA256: ${MACOS_ARM64_SHA}"
- name: Update Homebrew formula (if token available)
if: env.HOMEBREW_UPDATE_TOKEN != ''
uses: peter-evans/repository-dispatch@v3
with:
token: ${{ secrets.HOMEBREW_UPDATE_TOKEN }}
repository: metaneutrons/homebrew-tap
event-type: update-formula
client-payload: |
{
"version": "${{ needs.calculate-version.outputs.version }}",
"macos_x64_sha": "${{ steps.checksums.outputs.macos_x64_sha }}",
"macos_arm64_sha": "${{ steps.checksums.outputs.macos_arm64_sha }}"
}
env:
HOMEBREW_UPDATE_TOKEN: ${{ secrets.HOMEBREW_UPDATE_TOKEN }}
- name: Create Homebrew update instructions (fallback)
if: env.HOMEBREW_UPDATE_TOKEN == ''
env:
HOMEBREW_UPDATE_TOKEN: ${{ secrets.HOMEBREW_UPDATE_TOKEN }}
run: |
cat << EOF > homebrew-update.md
## 🍺 Homebrew Formula Update Required
**Version**: ${{ needs.calculate-version.outputs.version }}
**macOS x64 SHA256**: \`${{ steps.checksums.outputs.macos_x64_sha }}\`
**macOS ARM64 SHA256**: \`${{ steps.checksums.outputs.macos_arm64_sha }}\`
### Manual Update Steps:
1. Go to [homebrew-tap repository](https://github.com/metaneutrons/homebrew-tap)
2. Edit \`knxmonitor.rb\`
3. Update version to: \`${{ needs.calculate-version.outputs.version }}\`
4. Update Intel Mac SHA256 to: \`${{ steps.checksums.outputs.macos_x64_sha }}\`
5. Update Apple Silicon SHA256 to: \`${{ steps.checksums.outputs.macos_arm64_sha }}\`
### Or run the update workflow manually:
\`\`\`bash
gh workflow run update-formula.yml \\
--repo metaneutrons/homebrew-tap \\
--field version=${{ needs.calculate-version.outputs.version }} \\
--field macos_x64_sha=${{ steps.checksums.outputs.macos_x64_sha }} \\
--field macos_arm64_sha=${{ steps.checksums.outputs.macos_arm64_sha }}
\`\`\`
EOF
- name: Upload Homebrew update instructions
uses: actions/upload-artifact@v4
with:
name: homebrew-update-instructions
path: homebrew-update.md
retention-days: 30
- name: Display update information
env:
HOMEBREW_UPDATE_TOKEN: ${{ secrets.HOMEBREW_UPDATE_TOKEN }}
run: |
echo "## 🍺 Homebrew Update Information" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Version**: ${{ needs.calculate-version.outputs.version }}" >> $GITHUB_STEP_SUMMARY
echo "**macOS x64 SHA256**: \`${{ steps.checksums.outputs.macos_x64_sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "**macOS ARM64 SHA256**: \`${{ steps.checksums.outputs.macos_arm64_sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if [[ -n "$HOMEBREW_UPDATE_TOKEN" ]]; then
echo "✅ Homebrew formula updated automatically via repository dispatch." >> $GITHUB_STEP_SUMMARY
else
echo "ℹ️ Homebrew formula needs to be updated manually. Check the homebrew-update-instructions artifact." >> $GITHUB_STEP_SUMMARY
fi
- name: Release Summary
run: |
echo "## 🎉 Release Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Version**: ${{ needs.calculate-version.outputs.version }}" >> $GITHUB_STEP_SUMMARY
echo "**Tag**: ${{ needs.calculate-version.outputs.tag }}" >> $GITHUB_STEP_SUMMARY
echo "**GitVersion**: ${{ needs.calculate-version.outputs.informational-version }}" >> $GITHUB_STEP_SUMMARY
echo "**Prerelease**: ${{ needs.calculate-version.outputs.is-prerelease }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 📦 Assets" >> $GITHUB_STEP_SUMMARY
echo "- $(ls -1 ./release-assets/ | wc -l) platform binaries" >> $GITHUB_STEP_SUMMARY
if [[ "${{ inputs.create_docker }}" == "true" ]]; then
echo "- Docker image: \`ghcr.io/metaneutrons/knxmonitor:${{ needs.calculate-version.outputs.version }}\`" >> $GITHUB_STEP_SUMMARY
fi
if [[ "${{ needs.calculate-version.outputs.is-prerelease }}" == "false" ]]; then
echo "- Homebrew formula will be updated automatically" >> $GITHUB_STEP_SUMMARY
fi
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 🔗 Links" >> $GITHUB_STEP_SUMMARY
echo "- [Release Page](https://github.com/${{ github.repository }}/releases/tag/${{ needs.calculate-version.outputs.tag }})" >> $GITHUB_STEP_SUMMARY
echo "- [Docker Image](https://github.com/${{ github.repository }}/pkgs/container/knxmonitor)" >> $GITHUB_STEP_SUMMARY
echo "- [Homebrew Tap](https://github.com/metaneutrons/homebrew-tap)" >> $GITHUB_STEP_SUMMARY
# Summary job to show overall status
summary:
needs: [calculate-version, build, docker, release, update-homebrew]
if: always()
runs-on: ubuntu-latest
steps:
- name: Release Summary
run: |
echo "## 🎉 Release Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Version**: ${{ needs.calculate-version.outputs.version }}" >> $GITHUB_STEP_SUMMARY
echo "**Tag**: ${{ needs.calculate-version.outputs.tag }}" >> $GITHUB_STEP_SUMMARY
echo "**GitVersion**: ${{ needs.calculate-version.outputs.informational-version }}" >> $GITHUB_STEP_SUMMARY
echo "**Prerelease**: ${{ needs.calculate-version.outputs.is-prerelease }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 📊 Job Status" >> $GITHUB_STEP_SUMMARY
echo "- **Version Calculation**: ${{ needs.calculate-version.result == 'success' && '✅' || '❌' }}" >> $GITHUB_STEP_SUMMARY
echo "- **Build**: ${{ needs.build.result == 'success' && '✅' || '❌' }}" >> $GITHUB_STEP_SUMMARY
echo "- **Docker**: ${{ needs.docker.result == 'success' && '✅' || needs.docker.result == 'skipped' && '⏭️' || '❌' }}" >> $GITHUB_STEP_SUMMARY
echo "- **Release**: ${{ needs.release.result == 'success' && '✅' || '❌' }}" >> $GITHUB_STEP_SUMMARY
echo "- **Homebrew**: ${{ needs.update-homebrew.result == 'success' && '✅' || needs.update-homebrew.result == 'skipped' && '⏭️' || '❌' }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 📦 Assets" >> $GITHUB_STEP_SUMMARY
if [[ "${{ needs.build.result }}" == "success" ]]; then
echo "- ✅ Platform binaries created" >> $GITHUB_STEP_SUMMARY
fi
if [[ "${{ needs.docker.result }}" == "success" ]]; then
echo "- ✅ Docker image: \`ghcr.io/metaneutrons/knxmonitor:${{ needs.calculate-version.outputs.version }}\`" >> $GITHUB_STEP_SUMMARY
elif [[ "${{ needs.docker.result }}" == "failure" ]]; then
echo "- ❌ Docker image build failed" >> $GITHUB_STEP_SUMMARY
fi
if [[ "${{ needs.update-homebrew.result }}" == "success" ]]; then
echo "- ✅ Homebrew formula updated automatically" >> $GITHUB_STEP_SUMMARY
elif [[ "${{ needs.update-homebrew.result }}" == "failure" ]]; then
echo "- ❌ Homebrew formula update failed (check artifacts for manual instructions)" >> $GITHUB_STEP_SUMMARY
fi
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 🔗 Links" >> $GITHUB_STEP_SUMMARY
if [[ "${{ needs.release.result }}" == "success" ]]; then
echo "- [Release Page](https://github.com/${{ github.repository }}/releases/tag/${{ needs.calculate-version.outputs.tag }})" >> $GITHUB_STEP_SUMMARY
fi
if [[ "${{ needs.docker.result }}" == "success" ]]; then
echo "- [Docker Image](https://github.com/${{ github.repository }}/pkgs/container/knxmonitor)" >> $GITHUB_STEP_SUMMARY
fi
echo "- [Homebrew Tap](https://github.com/metaneutrons/homebrew-tap)" >> $GITHUB_STEP_SUMMARY
# Set overall workflow status
if [[ "${{ needs.build.result }}" != "success" || "${{ needs.release.result }}" != "success" ]]; then
echo "❌ Release failed - critical components failed" >> $GITHUB_STEP_SUMMARY
exit 1
elif [[ "${{ needs.docker.result }}" == "failure" && "${{ inputs.create_docker }}" == "true" ]]; then
echo "⚠️ Release completed with warnings - Docker build failed" >> $GITHUB_STEP_SUMMARY
exit 1
else
echo "✅ Release completed successfully" >> $GITHUB_STEP_SUMMARY
fi