Skip to content

Release Flow Simulation (Current Architecture) #18

Release Flow Simulation (Current Architecture)

Release Flow Simulation (Current Architecture) #18

name: Release Flow Simulation (Current Architecture)
# ============================================================================
# Workflow Overview
# ============================================================================
# This workflow simulates the release.yml flow for quick validation.
# Fully synced with release.yml architecture for testing workflow logic.
#
# Architecture:
# - validate-tag: Validates git ref and computes version
# - build-windows: Simulates Windows amd64 build
# - build-macos: Matrix simulation for macOS (amd64 + aarch64)
# - upload-to-s3: Simulates S3 upload and OTA feed generation
#
# ============================================================================
# Purpose
# ============================================================================
# - Quickly validate workflow flow logic (< 5 minutes)
# - Test conditional logic correctness
# - Verify artifact naming and passing
# - No actual build execution, only creates simulated artifacts
#
# Note: This simulation does not include Inno Setup installation or
# language pack processing. The actual release.yml uses .islu
# (Unicode) language files exclusively.
#
# ============================================================================
# Supported Test Scenarios
# ============================================================================
# 1. platform=windows, arch=amd64 - Build Windows only
# 2. platform=macos, arch=amd64 - Build macOS Intel only
# 3. platform=macos, arch=aarch64 - Build macOS ARM only
# 4. platform=macos, arch=all - Build all macOS
# 5. platform=all, arch=amd64 - Build all Intel
# 6. platform=all, arch=aarch64 - Build macOS ARM only (Windows doesn't support ARM)
# 7. platform=all, arch=all - Complete build
on:
workflow_dispatch:
inputs:
platform:
description: 'Build platform (windows, macos, all)'
required: true
default: 'all'
type: choice
options:
- all
- windows
- macos
arch:
description: 'CPU architecture (all, amd64, aarch64)'
required: true
default: 'all'
type: choice
options:
- all
- amd64
- aarch64
ref:
description: 'Git ref to build (not used in simulation)'
required: true
default: 'master'
type: string
upload_artifacts:
description: 'Upload artifacts to GitHub Artifacts (debug only)'
required: false
default: 'false'
type: choice
options:
- 'true'
- 'false'
concurrency:
group: ecan-release-sim-${{ github.ref }}-${{ github.event.inputs.platform }}-${{ github.event.inputs.arch }}
cancel-in-progress: true
jobs:
# ============================================================================
# VALIDATION LAYER: Tag and Version Validation
# ============================================================================
validate-tag:
runs-on: ubuntu-latest
outputs:
tag-valid: ${{ steps.out.outputs.valid }}
version: ${{ steps.out.outputs.version }}
steps:
- id: out
run: |
echo "valid=true" >> $GITHUB_OUTPUT
echo "version=0.0.0-sim" >> $GITHUB_OUTPUT
# ============================================================================
# BUILD LAYER: Windows amd64 (Simulation)
# ============================================================================
build-windows:
name: Build Windows amd64
needs: validate-tag
if: |
needs.validate-tag.outputs.tag-valid == 'true' &&
(github.event.inputs.platform == 'windows' ||
github.event.inputs.platform == 'all') &&
(github.event.inputs.arch == 'amd64' ||
github.event.inputs.arch == 'all')
runs-on: ubuntu-latest # Use ubuntu for faster simulation
env:
BUILD_ARCH: amd64
steps:
# Note: Frontend is always built in real workflow (no change detection)
# Simulation doesn't need frontend build steps
- name: Simulate Windows build
run: |
echo "=== Simulating Windows amd64 Build ==="
echo "Platform: Windows"
echo "Architecture: $BUILD_ARCH"
echo "Note: Real workflow always builds frontend (no skip logic)"
VERSION="${{ needs.validate-tag.outputs.version }}"
mkdir -p dist artifacts
echo "fake windows installer" > "dist/eCan-${VERSION}-windows-${BUILD_ARCH}-Setup.exe"
cp "dist/eCan-${VERSION}-windows-${BUILD_ARCH}-Setup.exe" artifacts/
echo "✅ Windows build simulated"
- name: Upload Windows artifacts for S3 transfer (always, short retention)
uses: actions/upload-artifact@v4
with:
name: eCan-windows-amd64-${{ needs.validate-tag.outputs.version }}-s3-transfer
path: artifacts/
retention-days: 1
compression-level: 6
if-no-files-found: error
- name: Upload Windows artifacts for users (optional, long retention)
if: github.event.inputs.upload_artifacts == 'true'
uses: actions/upload-artifact@v4
with:
name: eCan-Windows-${{ needs.validate-tag.outputs.version }}
path: artifacts/
retention-days: 30
compression-level: 6
# ============================================================================
# BUILD LAYER: macOS (Matrix: amd64 + aarch64) (Simulation)
# ============================================================================
build-macos:
name: Build macOS
needs: validate-tag
if: |
needs.validate-tag.outputs.tag-valid == 'true' &&
(github.event.inputs.platform == 'macos' ||
github.event.inputs.platform == 'all')
runs-on: ubuntu-latest # Use ubuntu for faster simulation
strategy:
fail-fast: false
matrix:
include:
- arch: amd64
runner: macos-14-intel # Would use Intel runner in real workflow (macos-13 deprecated)
target_arch: x86_64
pyinstaller_arch: x86_64
- arch: aarch64
runner: macos-latest # Would use Apple Silicon runner in real workflow
target_arch: arm64
pyinstaller_arch: arm64
env:
BUILD_ARCH: ${{ matrix.arch }}
TARGET_ARCH: ${{ matrix.target_arch }}
PYINSTALLER_TARGET_ARCH: ${{ matrix.pyinstaller_arch }}
steps:
# ------------------------------------------------------------------------
# Step 0: Architecture Filtering (MUST BE FIRST - No dependencies)
# ------------------------------------------------------------------------
- name: Check if this architecture should be built
id: arch_check
run: |
ARCH="${{ matrix.arch }}"
INPUT="${{ github.event.inputs.arch }}"
echo "Matrix architecture: $ARCH"
echo "Requested architecture: $INPUT"
if [ "$INPUT" = "all" ] || [ -z "$INPUT" ] || [ "$INPUT" = "$ARCH" ]; then
echo "✅ This architecture will be built"
echo "should_build=true" >> $GITHUB_OUTPUT
else
echo "⏭️ Skipping this architecture (not requested)"
echo "should_build=false" >> $GITHUB_OUTPUT
exit 0
fi
# Early exit if architecture not needed - saves all setup time
- name: Exit early if architecture not needed
if: steps.arch_check.outputs.should_build != 'true'
run: |
echo "Architecture ${{ matrix.arch }} not needed for this build"
echo "Exiting early to save resources"
exit 0
# Note: Frontend is always built in real workflow (no change detection)
# Simulation doesn't need frontend build steps
- name: Simulate macOS build
if: steps.arch_check.outputs.should_build == 'true'
run: |
echo "=== Simulating macOS ${{ matrix.arch }} Build ==="
echo "Platform: macOS"
echo "Architecture: ${{ matrix.arch }} (${{ matrix.target_arch }})"
echo "Note: Real workflow always builds frontend (no skip logic)"
VERSION="${{ needs.validate-tag.outputs.version }}"
ARCH="${{ matrix.arch }}"
mkdir -p dist artifacts
echo "fake macos installer" > "dist/eCan-${VERSION}-macos-${ARCH}.pkg"
cp "dist/eCan-${VERSION}-macos-${ARCH}.pkg" artifacts/
echo "✅ macOS ${{ matrix.arch }} build simulated"
- name: Upload macOS artifacts for S3 transfer (always, short retention)
if: steps.arch_check.outputs.should_build == 'true'
uses: actions/upload-artifact@v4
with:
name: eCan-macos-${{ matrix.arch }}-${{ needs.validate-tag.outputs.version }}-s3-transfer
path: artifacts/
retention-days: 1
compression-level: 6
if-no-files-found: error
- name: Upload macOS artifacts for users (optional, long retention)
if: steps.arch_check.outputs.should_build == 'true' && github.event.inputs.upload_artifacts == 'true'
uses: actions/upload-artifact@v4
with:
name: eCan-macos-${{ matrix.arch }}-${{ needs.validate-tag.outputs.version }}
path: artifacts/
retention-days: 30
compression-level: 6
# ============================================================================
# DISTRIBUTION LAYER: S3 Upload and OTA Feed Generation (Simulation)
# ============================================================================
# This layer uses reusable workflows (same as release.yml) in simulation mode:
# 1. upload-to-s3: Simulates S3 upload (shared-s3-upload.yml)
# 2. generate-appcast: Simulates appcast generation (shared-appcast-generation.yml)
# 3. generate-download-links: Simulates download links (shared-download-links.yml)
# ============================================================================
# ----------------------------------------------------------------------------
# Step 1: Upload artifacts to S3 (Simulation)
# ----------------------------------------------------------------------------
upload-to-s3:
name: Upload to S3 (Simulation)
needs: [validate-tag, build-windows, build-macos]
if: |
always() &&
needs.validate-tag.outputs.tag-valid == 'true' &&
(needs.build-windows.result == 'success' || needs.build-windows.result == 'skipped') &&
(needs.build-macos.result == 'success' || needs.build-macos.result == 'skipped')
uses: ./.github/workflows/shared-s3-upload.yml
with:
version: ${{ needs.validate-tag.outputs.version }}
windows-build-result: ${{ needs.build-windows.result }}
macos-build-result: ${{ needs.build-macos.result }}
macos-built-amd64: ${{ (github.event.inputs.platform == 'macos' || github.event.inputs.platform == 'all') && (github.event.inputs.arch == 'amd64' || github.event.inputs.arch == 'all') }}
macos-built-aarch64: ${{ (github.event.inputs.platform == 'macos' || github.event.inputs.platform == 'all') && (github.event.inputs.arch == 'aarch64' || github.event.inputs.arch == 'all') }}
is-simulation: true
secrets: inherit
# ----------------------------------------------------------------------------
# Step 2: Generate OTA update feeds (Simulation)
# ----------------------------------------------------------------------------
generate-appcast:
name: Generate Appcast (Simulation)
needs: [validate-tag, upload-to-s3]
if: |
always() &&
needs.validate-tag.outputs.tag-valid == 'true' &&
needs.upload-to-s3.result == 'success'
uses: ./.github/workflows/shared-appcast-generation.yml
with:
version: ${{ needs.validate-tag.outputs.version }}
s3-base-url: ${{ needs.upload-to-s3.outputs.s3-base-url }}
channel: stable
release-body: ''
is-simulation: true
secrets: inherit
# ----------------------------------------------------------------------------
# Step 3: Generate download links (Simulation)
# ----------------------------------------------------------------------------
generate-download-links:
name: Generate Download Links (Simulation)
needs: [validate-tag, build-windows, build-macos, upload-to-s3]
if: |
always() &&
needs.validate-tag.outputs.tag-valid == 'true' &&
needs.upload-to-s3.result == 'success'
uses: ./.github/workflows/shared-download-links.yml
with:
version: ${{ needs.validate-tag.outputs.version }}
windows-build-result: ${{ needs.build-windows.result }}
macos-build-result: ${{ needs.build-macos.result }}
macos-built-amd64: ${{ (github.event.inputs.platform == 'macos' || github.event.inputs.platform == 'all') && (github.event.inputs.arch == 'amd64' || github.event.inputs.arch == 'all') }}
macos-built-aarch64: ${{ (github.event.inputs.platform == 'macos' || github.event.inputs.platform == 'all') && (github.event.inputs.arch == 'aarch64' || github.event.inputs.arch == 'all') }}
secrets: inherit
# ----------------------------------------------------------------------------
# Step 4: Final status summary (Simulation)
# ----------------------------------------------------------------------------
final-status:
name: Final Status Summary (Simulation)
needs: [validate-tag, build-windows, build-macos, upload-to-s3, generate-appcast, generate-download-links]
if: always()
uses: ./.github/workflows/shared-final-status.yml
with:
version: ${{ needs.validate-tag.outputs.version }}
windows-result: ${{ needs.build-windows.result }}
macos-result: ${{ needs.build-macos.result }}
upload-result: ${{ needs.upload-to-s3.result }}
appcast-result: ${{ needs.generate-appcast.result }}
links-result: ${{ needs.generate-download-links.result }}
is-simulation: true
secrets: inherit