Skip to content

Fix prod desktop release failing to create its tag #15

Fix prod desktop release failing to create its tag

Fix prod desktop release failing to create its tag #15

Workflow file for this run

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.
#
# Manual dispatch releases the selected components on the chosen branch —
# the recovery path when a push-triggered release fails, since reruns use
# the original (broken) workflow snapshot.
on:
push:
branches: [main, prod, enterprise]
workflow_dispatch:
inputs:
desktop:
description: "Release desktop"
type: boolean
default: false
cli:
description: "Release CLI"
type: boolean
default: false
docs:
description: "Release docs"
type: boolean
default: false
enterprise_admin:
description: "Release enterprise admin"
type: boolean
default: false
enterprise_gateway:
description: "Release enterprise gateway"
type: boolean
default: false
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: ${{ github.event_name == 'workflow_dispatch' && inputs.cli || steps.filter.outputs.cli }}
desktop: ${{ github.event_name == 'workflow_dispatch' && inputs.desktop || steps.filter.outputs.desktop }}
docs: ${{ github.event_name == 'workflow_dispatch' && inputs.docs || steps.filter.outputs.docs }}
enterprise_admin: ${{ github.event_name == 'workflow_dispatch' && inputs.enterprise_admin || steps.filter.outputs.enterprise_admin }}
enterprise_gateway: ${{ github.event_name == 'workflow_dispatch' && inputs.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
if: github.event_name == 'push'
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"