Repository navigation
Merge pull request #449 from NeoHuncho/dev/apple-speech-framework #11
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 (auto) | |
| # Orchestrator. On push to `main` releases to dev; push to `prod` releases the | |
| # consumer-facing channel (CLI, Desktop, Docs); push to `enterprise` releases | |
| # the enterprise channel (Desktop enterprise, Enterprise Admin, Enterprise | |
| # Gateway). Detects which folders changed since the previous commit on that | |
| # branch and invokes the per-component reusable workflows. | |
| # | |
| # Promotion: fast-forward merge `main` into `prod` or `enterprise` → this | |
| # workflow runs on that branch and only the components that changed since | |
| # the last release on that branch ship. | |
| on: | |
| push: | |
| branches: [main, prod, enterprise] | |
| concurrency: | |
| group: release-${{ github.ref_name }}-orchestrator | |
| cancel-in-progress: false | |
| permissions: | |
| contents: write | |
| id-token: write | |
| packages: write | |
| actions: write | |
| jobs: | |
| detect: | |
| name: Detect changed folders | |
| runs-on: ubuntu-latest | |
| outputs: | |
| channel: ${{ steps.env.outputs.channel }} | |
| cli: ${{ steps.filter.outputs.cli }} | |
| desktop: ${{ steps.filter.outputs.desktop }} | |
| docs: ${{ steps.filter.outputs.docs }} | |
| enterprise_admin: ${{ steps.filter.outputs.enterprise_admin }} | |
| enterprise_gateway: ${{ steps.filter.outputs.enterprise_gateway }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Resolve channel from branch | |
| id: env | |
| run: | | |
| case "${{ github.ref_name }}" in | |
| prod) echo "channel=prod" >> "$GITHUB_OUTPUT" ;; | |
| enterprise) echo "channel=enterprise" >> "$GITHUB_OUTPUT" ;; | |
| *) echo "channel=dev" >> "$GITHUB_OUTPUT" ;; | |
| esac | |
| - uses: dorny/paths-filter@v3 | |
| id: filter | |
| with: | |
| base: ${{ github.event.before }} | |
| filters: | | |
| cli: | |
| - 'cli/**' | |
| desktop: | |
| - 'apps/desktop/**' | |
| - 'apps/windows-installer/**' | |
| - 'packages/**' | |
| docs: | |
| - 'apps/docs/**' | |
| enterprise_admin: | |
| - 'enterprise/admin/**' | |
| - 'packages/**' | |
| enterprise_gateway: | |
| - 'enterprise/gateway/**' | |
| - 'packages/**' | |
| cli: | |
| name: CLI | |
| needs: detect | |
| # CLI has no enterprise variant — only dev (main) and prod (prod). | |
| if: | | |
| needs.detect.outputs.cli == 'true' && | |
| (needs.detect.outputs.channel == 'dev' || needs.detect.outputs.channel == 'prod') | |
| uses: ./.github/workflows/release-cli.yml | |
| with: | |
| release_env: ${{ needs.detect.outputs.channel }} | |
| secrets: inherit | |
| desktop: | |
| name: Desktop | |
| needs: detect | |
| # Desktop is released on all three channels. The channel name matches the | |
| # reusable's release_env input directly (dev/prod/enterprise). | |
| if: needs.detect.outputs.desktop == 'true' | |
| uses: ./.github/workflows/_release-desktop-impl.yml | |
| with: | |
| release_env: ${{ needs.detect.outputs.channel }} | |
| secrets: inherit | |
| desktop-enterprise-dev: | |
| name: Desktop (enterprise-dev) | |
| needs: detect | |
| # `main` ships the dev flavor AND the enterprise-dev flavor in parallel, so | |
| # enterprise testers on main get the same commit packaged as the enterprise | |
| # build. Only fires on the dev channel — prod/enterprise have their own flavors. | |
| if: needs.detect.outputs.desktop == 'true' && needs.detect.outputs.channel == 'dev' | |
| uses: ./.github/workflows/_release-desktop-impl.yml | |
| with: | |
| release_env: enterprise-dev | |
| secrets: inherit | |
| docs: | |
| name: Docs | |
| needs: detect | |
| # Docs is a single-environment Firebase deploy — only on `prod`. | |
| if: | | |
| needs.detect.outputs.docs == 'true' && | |
| needs.detect.outputs.channel == 'prod' | |
| uses: ./.github/workflows/release-docs.yml | |
| secrets: inherit | |
| enterprise-admin: | |
| name: Enterprise Admin | |
| needs: detect | |
| # Enterprise admin runs on dev (main) and the enterprise channel maps to | |
| # its `prod` release env. | |
| if: | | |
| needs.detect.outputs.enterprise_admin == 'true' && | |
| (needs.detect.outputs.channel == 'dev' || needs.detect.outputs.channel == 'enterprise') | |
| uses: ./.github/workflows/release-enterprise-admin.yml | |
| with: | |
| release_env: ${{ needs.detect.outputs.channel == 'enterprise' && 'prod' || 'dev' }} | |
| secrets: inherit | |
| enterprise-gateway: | |
| name: Enterprise Gateway | |
| needs: detect | |
| if: | | |
| needs.detect.outputs.enterprise_gateway == 'true' && | |
| (needs.detect.outputs.channel == 'dev' || needs.detect.outputs.channel == 'enterprise') | |
| uses: ./.github/workflows/release-enterprise-gateway.yml | |
| with: | |
| release_env: ${{ needs.detect.outputs.channel == 'enterprise' && 'prod' || 'dev' }} | |
| secrets: inherit | |
| notify: | |
| name: Notify Google Chat | |
| needs: [detect, cli, desktop, desktop-enterprise-dev, docs, enterprise-admin, enterprise-gateway] | |
| if: always() | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Post release summary | |
| env: | |
| WEBHOOK: ${{ secrets.GCHAT_DEPLOY_WEBHOOK }} | |
| CHANNEL: ${{ needs.detect.outputs.channel }} | |
| CLI_CHANGED: ${{ needs.detect.outputs.cli }} | |
| DESKTOP_CHANGED: ${{ needs.detect.outputs.desktop }} | |
| DOCS_CHANGED: ${{ needs.detect.outputs.docs }} | |
| ENTERPRISE_ADMIN_CHANGED: ${{ needs.detect.outputs.enterprise_admin }} | |
| ENTERPRISE_GATEWAY_CHANGED: ${{ needs.detect.outputs.enterprise_gateway }} | |
| CLI_RESULT: ${{ needs.cli.result }} | |
| DESKTOP_RESULT: ${{ needs.desktop.result }} | |
| DESKTOP_ENTERPRISE_DEV_RESULT: ${{ needs['desktop-enterprise-dev'].result }} | |
| DOCS_RESULT: ${{ needs.docs.result }} | |
| ENTERPRISE_ADMIN_RESULT: ${{ needs['enterprise-admin'].result }} | |
| ENTERPRISE_GATEWAY_RESULT: ${{ needs['enterprise-gateway'].result }} | |
| COMMIT_SHA: ${{ github.sha }} | |
| COMMIT_MSG: ${{ github.event.head_commit.message }} | |
| ACTOR: ${{ github.actor }} | |
| RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} | |
| run: | | |
| set -euo pipefail | |
| if [ -z "${WEBHOOK:-}" ]; then | |
| echo "GCHAT_DEPLOY_WEBHOOK not set; skipping notification." | |
| exit 0 | |
| fi | |
| case "$CHANNEL" in | |
| dev) cli_elig=true; desktop_elig=true; ded_elig=true; docs_elig=false; ea_elig=true; eg_elig=true ;; | |
| prod) cli_elig=true; desktop_elig=true; ded_elig=false; docs_elig=true; ea_elig=false; eg_elig=false ;; | |
| enterprise) cli_elig=false; desktop_elig=true; ded_elig=false; docs_elig=false; ea_elig=true; eg_elig=true ;; | |
| *) cli_elig=false; desktop_elig=false; ded_elig=false; docs_elig=false; ea_elig=false; eg_elig=false ;; | |
| esac | |
| lines="" | |
| any_released=false | |
| any_failed=false | |
| add_line() { | |
| local comp="$1" changed="$2" result="$3" eligible="$4" | |
| if [ "$eligible" != "true" ] || [ "$changed" != "true" ]; then | |
| return 0 | |
| fi | |
| any_released=true | |
| local status | |
| case "$result" in | |
| success) status="succeeded" ;; | |
| failure) status="FAILED"; any_failed=true ;; | |
| cancelled) status="cancelled"; any_failed=true ;; | |
| skipped) status="skipped (upstream failed)"; any_failed=true ;; | |
| *) status="$result" ;; | |
| esac | |
| lines+=$'\n'"• ${comp}: ${status}" | |
| } | |
| add_line cli "$CLI_CHANGED" "$CLI_RESULT" "$cli_elig" | |
| add_line desktop "$DESKTOP_CHANGED" "$DESKTOP_RESULT" "$desktop_elig" | |
| add_line desktop-enterprise-dev "$DESKTOP_CHANGED" "$DESKTOP_ENTERPRISE_DEV_RESULT" "$ded_elig" | |
| add_line docs "$DOCS_CHANGED" "$DOCS_RESULT" "$docs_elig" | |
| add_line enterprise-admin "$ENTERPRISE_ADMIN_CHANGED" "$ENTERPRISE_ADMIN_RESULT" "$ea_elig" | |
| add_line enterprise-gateway "$ENTERPRISE_GATEWAY_CHANGED" "$ENTERPRISE_GATEWAY_RESULT" "$eg_elig" | |
| if [ "$any_released" != "true" ]; then | |
| echo "No components released; skipping notification." | |
| exit 0 | |
| fi | |
| if [ "$any_failed" = "true" ]; then | |
| outcome="had failures" | |
| else | |
| outcome="succeeded" | |
| fi | |
| commit_first_line="${COMMIT_MSG%%$'\n'*}" | |
| short_sha="${COMMIT_SHA:0:7}" | |
| text="🎙️ *Voquill* — release to *${CHANNEL}* ${outcome}"$'\n' | |
| text+="${short_sha} by ${ACTOR}" | |
| if [ -n "${commit_first_line}" ]; then | |
| text+=": ${commit_first_line}" | |
| fi | |
| text+="${lines}"$'\n' | |
| text+="<${RUN_URL}|View run>" | |
| jq -n --arg text "$text" '{text: $text}' \ | |
| | curl -sS --fail-with-body -X POST \ | |
| -H 'Content-Type: application/json; charset=UTF-8' \ | |
| -d @- "$WEBHOOK" |