Files
open-design/.github/workflows/notify-release-feishu.yml
lefarcenandGitHub d82385309f chore(release): retire the transitional prerelease webhook card (#7867)
The progressive Feishu card (release-prerelease-card.yml) has carried four
real prereleases: correct rendering, per-platform refresh, correct changelog,
smoke wired through. The one-shot custom-bot webhook card it superseded was
kept alongside it on purpose — a gap in release notification is worse than a
duplicate — and its own TRANSITIONAL comment named the retirement scope.

Deletes notify-release-feishu.yml's `notify` job, leaving that workflow as
what its remaining job already is: the push-to-release/** prerelease build
entry point.

tools/release/src/notifications/feishu.ts stays. notify-daily-feishu.yml
renders the beta download card through it and `tools-release notify feishu`
exposes it, so only the prerelease call path is removed. The
FEISHU_RELEASE_WEBHOOK / FEISHU_RELEASE_SIGN_SECRET secrets stay too — six
other workflows post through them, and keeping them leaves a rollback open.
2026-09-08 01:26:40 +00:00

144 lines
8.3 KiB
YAML

name: notify-release-feishu
# On every push to a release/** branch, build a full prerelease package by reusing
# release-prerelease. The Feishu notification is NOT posted from here:
# release-prerelease.yml dispatches release-prerelease-card.yml, which posts one
# progressive card through the Feishu application bot (download links, code tests,
# packaged smoke, changelog since the previously published prerelease) and edits it
# in place as each lane reports in. Consecutive pushes to the same branch
# are throttled, not debounced: an in-flight build is allowed to finish (so a
# busy release branch always produces a prerelease), while pushes that arrive
# during it coalesce into a single trailing build of the latest commit. With
# cancel-in-progress the previous behavior starved — pushes spaced closer than
# the build duration kept cancelling each other and no package was ever cut.
#
# Also dispatchable by hand (workflow_dispatch) so a prerelease + Feishu card can be
# cut without an actual push. The normal manual path is to dispatch ON a
# release/vX.Y.Z branch with `ref`/`release_version` empty — release-prerelease then
# derives the version from the branch name exactly like the push trigger does.
# Building from a non-release ref such as main is also possible but requires
# `release_version` (e.g. 0.10.0, matching apps/packaged/package.json), because
# the branch name carries no version; the resulting package is labelled
# X.Y.Z-prerelease.N on that same version line. Either way the build's actual commit
# (not the dispatch ref) anchors the changelog and the card.
on:
push:
branches:
- "release/**"
workflow_dispatch:
inputs:
ref:
description: "Git ref (branch/tag/SHA) to build a prerelease from. Empty builds the ref this workflow is dispatched on. Dispatch on release/vX.Y.Z and leave empty for the normal path."
required: false
type: string
default: ""
release_version:
description: "Base version (x.y.z) — ONLY needed to build from a non-release ref such as main, where the branch name carries no version. Must equal apps/packaged/package.json. Leave empty on a release/vX.Y.Z branch."
required: false
type: string
default: ""
amr_profile:
description: "Optional AMR profile to bake (test / feature-test enable the Workspace Team transport). Empty uses the per-branch default: test on release/v0.18.0, otherwise prod."
required: false
type: string
default: ""
win_x64_smoke_mode:
description: "Windows x64 packaged smoke coverage (skip/core/full). Empty uses core. Smoke failures are reported on the download card but do not block publication."
required: false
type: string
default: ""
enable_mac_x64:
description: "Also build the macOS Intel (x64) package. ON by default — stable ships Intel and is gated on validated prerelease artifacts, so an Intel-less prerelease cannot be promoted. Uncheck only when this run is explicitly not about Intel and you want the ~12 min back."
required: false
type: boolean
default: true
enable_smoke:
description: "Also run the packaged smoke suites (mac arm64, mac Intel, Windows). ON by default. They no longer run inside the build jobs: release-prerelease-smoke.yml re-downloads the published packages from R2 after they ship, so smoke costs this pipeline nothing."
required: false
type: boolean
default: true
enable_tests:
description: "Also dispatch the code test suites (P0 Functional E2E, E2E Vitest, daemon shards, verify) into release-prerelease-tests.yml. ON by default; they gate nothing and run in a workflow of their own."
required: false
type: boolean
default: true
mac_sign_mode:
description: "macOS signing depth: no / sign-only / notarize. Empty uses sign-only — codesigned (which the stable promotion gate requires) but not sent to Apple's notary service. Use notarize for the last prerelease before a stable promotion."
required: false
type: string
default: ""
permissions:
contents: write
actions: write
concurrency:
group: feishu-release-${{ github.ref }}
# Throttle, not debounce: let the running build finish and coalesce the
# queued pushes into one trailing build. GitHub keeps the in-progress run and
# only the newest pending run in the group (older pending runs are cancelled),
# so a busy release branch still cuts a prerelease and converges on the latest
# commit, at most one build running plus one queued.
cancel-in-progress: false
jobs:
build:
name: Build prerelease from release branch
if: github.repository == 'nexu-io/open-design'
uses: ./.github/workflows/release-prerelease.yml
secrets: inherit
with:
# Empty on push events (inputs context is unset there), so release-prerelease
# falls back to building the pushed commit. On workflow_dispatch this
# carries the operator-chosen ref (or empty = the dispatch ref).
ref: ${{ inputs.ref }}
# Empty on push and on release/vX.Y.Z dispatches (branch name carries the
# version). Only set when building from a non-release ref like main, where
# release-prerelease cannot derive the base version from the branch name.
release_version: ${{ inputs.release_version }}
# Workspace Team profile baked into the packaged build (see
# apps/packaged/src/workspace-team.ts + release-prerelease.yml). Release
# builds ship `prod`: production's Vela backend now serves the feature, so
# a release prerelease points users at the production console rather than
# an internal test environment. A manual dispatch can still override to
# test / feature-test to cut a build against those backends.
#
# (This replaces a temporary `test` default on release/v0.18.0 that
# existed only while prod's resource-hub storage was unconfigured.)
amr_profile: ${{ inputs.amr_profile || 'prod' }}
# Windows packaged smoke is advisory to publication: a failed smoke is
# recorded in the report and annotated on the full download card without
# blocking platform or metadata publication. The final arm must name a
# real profile, NOT ''. A workflow_call
# `default:` applies only when an input is omitted, so forwarding an empty
# string defeats the callee's declared `core` default; the empty value
# then reaches the spec, reads as "not core", and selects the updater path
# — which demands a fixture only a genuine `full` request wires up, so the
# job dies before the smoke starts. That is how release/v0.18.1's first
# prerelease failed on its branch-cut commit.
win_x64_smoke_mode: ${{ inputs.win_x64_smoke_mode || 'core' }}
# macOS Intel builds on every prerelease, because stable ships Intel and
# stable's gate is a validated prerelease artifact.
#
# `|| true` would NOT express that. `inputs` is unset on push, so the
# obvious `${{ inputs.enable_mac_x64 || true }}` reads correctly there —
# but on a dispatch where the operator UNCHECKED the box, `false || true`
# is also true, and the switch would be unturnoffable. Test the event
# instead: push short-circuits to a real `true`, and a dispatch forwards
# the operator's own boolean.
enable_mac_x64: ${{ github.event_name != 'workflow_dispatch' || inputs.enable_mac_x64 }}
# Same shape, same reason. Packaged smoke now runs in
# release-prerelease-smoke.yml against the artifacts re-downloaded from
# R2, so it costs the build nothing and defaults on.
enable_smoke: ${{ github.event_name != 'workflow_dispatch' || inputs.enable_smoke }}
# Same shape. The code suites run in release-prerelease-tests.yml and gate
# nothing; the switch exists only to skip them outright.
enable_tests: ${{ github.event_name != 'workflow_dispatch' || inputs.enable_tests }}
# Same failure mode as win_x64_smoke_mode above: a `workflow_call`
# `default:` only applies to an OMITTED input, so the final arm must name
# a real mode, never ''. sign-only keeps platforms.mac.signed == true,
# which is what the stable promotion gate reads; it drops only the Apple
# notary round-trip, which no prerelease consumer needs.
mac_sign_mode: ${{ inputs.mac_sign_mode || 'sign-only' }}