Skip to content

Build Orchestrator

Build Orchestrator #4

name: Build Orchestrator
on:
workflow_dispatch:
inputs:
version:
description: 'Version (YY.MM.DD - leave empty for auto-generation)'
required: false
type: string
default: ''
custom_url:
description: 'Custom App URL (optional - disables auto-update, version bump, draft)'
required: false
type: string
default: ''
build_macos:
description: '🍎 macOS (x64 + ARM64)'
required: true
type: boolean
default: true
build_windows:
description: '🪟 Windows (x64)'
required: true
type: boolean
default: true
build_linux:
description: '🐧 Linux (AppImage)'
required: true
type: boolean
default: true
build_setapp:
description: '📦 Setapp (Universal macOS)'
required: true
type: boolean
default: true
build_variant:
description: 'Build variant (ignored if custom URL provided)'
required: true
type: choice
options:
- production
- beta
default: production
jobs:
prepare:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.version }}
version_tag: ${{ steps.version.outputs.tag }}
should_bump_version: ${{ steps.logic.outputs.should_bump }}
should_create_draft: ${{ steps.logic.outputs.should_draft }}
build_variant: ${{ steps.logic.outputs.variant }}
steps:
- name: Generate or validate version
id: version
run: |
if [ -z "${{ inputs.version }}" ]; then
VERSION=$(date -u +'%y.%-m.%-d')
echo "📅 Auto-generated: v$VERSION"
else
VERSION="${{ inputs.version }}"
if [[ ! "$VERSION" =~ ^[0-9]{2}\.[0-9]{1,2}\.[0-9]{1,2}(-beta\.[0-9]+)?$ ]]; then
echo "❌ Invalid version format"
exit 1
fi
echo "✅ Using: v$VERSION"
fi
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "tag=v$VERSION" >> $GITHUB_OUTPUT
- name: Determine workflow logic
id: logic
run: |
SHOULD_BUMP="true"
SHOULD_DRAFT="false"
VARIANT="${{ inputs.build_variant }}"
# Custom URL overrides
if [ -n "${{ inputs.custom_url }}" ]; then
echo "::notice title=Custom URL Mode::Auto-update disabled, version bump skipped, draft release skipped"
SHOULD_BUMP="false"
SHOULD_DRAFT="false"
VARIANT="custom"
# Verify only standard platforms selected
if [ "${{ inputs.build_setapp }}" == "true" ]; then
echo "::error title=Invalid Configuration::Setapp builds not allowed with custom URL"
exit 1
fi
fi
# Draft release only for production + all platforms
if [ "$VARIANT" == "production" ] && \
[ "${{ inputs.build_macos }}" == "true" ] && \
[ "${{ inputs.build_windows }}" == "true" ] && \
[ "${{ inputs.build_linux }}" == "true" ] && \
[ "${{ inputs.build_setapp }}" == "true" ]; then
SHOULD_DRAFT="true"
fi
# Beta builds don't get draft releases
if [ "$VARIANT" == "beta" ]; then
SHOULD_DRAFT="false"
fi
echo "should_bump=$SHOULD_BUMP" >> $GITHUB_OUTPUT
echo "should_draft=$SHOULD_DRAFT" >> $GITHUB_OUTPUT
echo "variant=$VARIANT" >> $GITHUB_OUTPUT
bump-version:
needs: prepare
if: needs.prepare.outputs.should_bump_version == 'true'
uses: ./.github/workflows/bump-version.yml
with:
version: ${{ needs.prepare.outputs.version }}
# Always creates temp branch - will merge to main only if draft release succeeds
build-macos:
needs: [prepare, bump-version]
if: |
always() &&
inputs.build_macos == true &&
(needs.bump-version.result == 'success' || needs.bump-version.result == 'skipped')
uses: ./.github/workflows/release_desktop_app.yml
secrets: inherit
with:
platform: macos-latest
build_variant: ${{ needs.prepare.outputs.build_variant }}
custom_url: ${{ inputs.custom_url }}
git_ref: ${{ needs.bump-version.outputs.branch_name || github.ref }}
build-windows:
needs: [prepare, bump-version]
if: |
always() &&
inputs.build_windows == true &&
(needs.bump-version.result == 'success' || needs.bump-version.result == 'skipped')
uses: ./.github/workflows/release_desktop_app.yml
secrets: inherit
with:
platform: windows-latest
build_variant: ${{ needs.prepare.outputs.build_variant }}
custom_url: ${{ inputs.custom_url }}
git_ref: ${{ needs.bump-version.outputs.branch_name || github.ref }}
build-linux:
needs: [prepare, bump-version]
if: |
always() &&
inputs.build_linux == true &&
(needs.bump-version.result == 'success' || needs.bump-version.result == 'skipped')
uses: ./.github/workflows/release_desktop_app.yml
secrets: inherit
with:
platform: ubuntu-latest
build_variant: ${{ needs.prepare.outputs.build_variant }}
custom_url: ${{ inputs.custom_url }}
git_ref: ${{ needs.bump-version.outputs.branch_name || github.ref }}
checkout_branch: '' # Use git_ref instead - will fall back to current branch
build-setapp:
needs: [prepare, bump-version]
if: |
always() &&
inputs.build_setapp == true &&
inputs.custom_url == '' &&
(needs.bump-version.result == 'success' || needs.bump-version.result == 'skipped')
uses: ./.github/workflows/build-setapp.yml
secrets: inherit
with:
git_ref: ${{ needs.bump-version.outputs.branch_name || github.ref }}
create-draft:
needs: [prepare, build-macos, build-windows, build-linux]
if: |
always() &&
needs.prepare.outputs.should_create_draft == 'true' &&
(needs.build-macos.result == 'success' || needs.build-macos.result == 'skipped') &&
(needs.build-windows.result == 'success' || needs.build-windows.result == 'skipped') &&
(needs.build-linux.result == 'success' || needs.build-linux.result == 'skipped')
uses: ./.github/workflows/create-draft-release.yml
secrets: inherit
with:
version: ${{ needs.prepare.outputs.version }}
version_tag: ${{ needs.prepare.outputs.version_tag }}
artifact_names: 'macos-build,windows-build,linux-build'
merge-to-main:
needs: [prepare, bump-version, create-draft]
if: |
always() &&
needs.create-draft.result == 'success' &&
needs.bump-version.result == 'success'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{ github.ref_name }}
fetch-depth: 0
- name: Merge temporary branch to main
run: |
TEMP_BRANCH="${{ needs.bump-version.outputs.branch_name }}"
TARGET_BRANCH="${{ github.ref_name }}"
echo "📦 Merging $TEMP_BRANCH → $TARGET_BRANCH"
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
# Fetch the temp branch
git fetch origin "$TEMP_BRANCH"
# Merge temp branch (fast-forward, should be clean)
git merge --ff-only "origin/$TEMP_BRANCH" -m "Merge version bump v${{ needs.prepare.outputs.version }}
Draft release created successfully.
Temporary branch: $TEMP_BRANCH
🤖 Generated by GitHub Actions
Run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
# Push to main
git push origin "HEAD:$TARGET_BRANCH"
echo "✅ Merged $TEMP_BRANCH → $TARGET_BRANCH"
- name: Delete temporary branch
run: |
TEMP_BRANCH="${{ needs.bump-version.outputs.branch_name }}"
echo "🗑️ Deleting temporary branch: $TEMP_BRANCH"
git push origin --delete "$TEMP_BRANCH"
echo "✅ Deleted: $TEMP_BRANCH"
- name: Summary
run: |
echo "### ✅ Version Merged to Main" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "- **Version**: v${{ needs.prepare.outputs.version }}" >> $GITHUB_STEP_SUMMARY
echo "- **Target Branch**: ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY
echo "- **Temporary Branch**: ${{ needs.bump-version.outputs.branch_name }} (deleted)" >> $GITHUB_STEP_SUMMARY
summary:
needs: [prepare, build-macos, build-windows, build-linux, build-setapp, create-draft, merge-to-main]
if: always()
runs-on: ubuntu-latest
steps:
- name: Generate summary
run: |
echo "# 📦 Build Complete: v${{ needs.prepare.outputs.version }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Variant**: ${{ needs.prepare.outputs.build_variant }}" >> $GITHUB_STEP_SUMMARY
if [ -n "${{ inputs.custom_url }}" ]; then
echo "**Custom URL**: ${{ inputs.custom_url }}" >> $GITHUB_STEP_SUMMARY
fi
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Platforms Built**:" >> $GITHUB_STEP_SUMMARY
echo "- macOS: ${{ needs.build-macos.result == 'success' && '✅' || '⬜' }}" >> $GITHUB_STEP_SUMMARY
echo "- Windows: ${{ needs.build-windows.result == 'success' && '✅' || '⬜' }}" >> $GITHUB_STEP_SUMMARY
echo "- Linux: ${{ needs.build-linux.result == 'success' && '✅' || '⬜' }}" >> $GITHUB_STEP_SUMMARY
echo "- Setapp: ${{ needs.build-setapp.result == 'success' && '✅' || '⬜' }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if [ "${{ needs.create-draft.result }}" == "success" ]; then
echo "**🎉 Draft Release**: [View Releases](https://github.com/${{ github.repository }}/releases)" >> $GITHUB_STEP_SUMMARY
echo "**✅ Version**: Merged to ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY
else
echo "**📥 Artifacts**: [Download from Run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})" >> $GITHUB_STEP_SUMMARY
if [ "${{ needs.bump-version.result }}" == "success" ]; then
echo "**⚠️ Temporary Branch**: \`${{ needs.bump-version.outputs.branch_name }}\` (not merged to main)" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "_Temp branch will remain until manually cleaned up_" >> $GITHUB_STEP_SUMMARY
fi
fi