Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 42 additions & 13 deletions .github/workflows/announce-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,28 @@
# failure, with no way to send it afterwards short of re-running the whole
# promotion over an already-tagged release.
#
# This exposes the same script on its own, so a missed announcement is a dispatch
# rather than a recovery operation. It reads nothing but the tag and the matching
# milestone, so it produces the identical message whenever it runs.
# It now runs off the release itself, which is the only event every path shares.
# Being a step of the two ceremony workflows meant it announced what those two
# workflows happened to do, not what actually shipped: a release cut by pushing a
# tag straight to build.yml — which is how 1.9.2 shipped — went out silent,
# because neither ceremony ran. Worse, prerelease.yml announced immediately after
# DISPATCHING build.yml rather than after it finished, so the RC message could
# precede the artifacts it pointed at by the length of a full matrix build.
#
# `release: published` fires for both, and `github.event.release.prerelease`
# already carries the stable/rc distinction that was previously hand-passed. This
# works only because build.yml creates the release with OPENSCREEN_RELEASE_TOKEN:
# releases created with the default GITHUB_TOKEN trigger no workflows at all.
#
# The dispatch inputs stay, for the case this was extracted for — a missed
# announcement is still a dispatch rather than a recovery operation. The script
# reads nothing but the tag and the matching milestone, so it produces the
# identical message whichever way it is entered.
name: Announce a release on Discord

on:
release:
types: [published]
workflow_dispatch:
inputs:
tag:
Expand All @@ -34,12 +50,24 @@ permissions:

jobs:
announce:
name: Announce ${{ inputs.tag }}
name: Announce ${{ inputs.tag || github.event.release.tag_name }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v7

# Resolved once, in one place, because the channel selection below needs to
# branch on `kind` and a step cannot read an `env:` entry declared beside it.
# On a release event `inputs.*` are empty strings, which GitHub expressions
# treat as falsy, so `||` picks the event side without any explicit test.
- name: Resolve what is being announced
id: ctx
run: |
{
echo "tag=${{ inputs.tag || github.event.release.tag_name }}"
echo "kind=${{ inputs.kind || (github.event.release.prerelease && 'rc' || 'stable') }}"
} >> "$GITHUB_OUTPUT"

- name: Setup Node.js
uses: ./.github/actions/setup

Expand All @@ -49,19 +77,20 @@ jobs:
# The script prefers the RC channel whenever that variable is non-empty,
# so exactly one of these may be set — blanking the other is what selects
# the destination, not the KIND value.
DISCORD_RELEASE_CHANNEL_ID: ${{ inputs.kind == 'stable' && vars.DISCORD_RELEASE_CHANNEL_ID || '' }}
DISCORD_RC_TESTING_CHANNEL_ID: ${{ inputs.kind == 'rc' && vars.DISCORD_RC_TESTING_CHANNEL_ID || '' }}
DISCORD_RELEASE_CHANNEL_ID: ${{ steps.ctx.outputs.kind == 'stable' && vars.DISCORD_RELEASE_CHANNEL_ID || '' }}
DISCORD_RC_TESTING_CHANNEL_ID: ${{ steps.ctx.outputs.kind == 'rc' && vars.DISCORD_RC_TESTING_CHANNEL_ID || '' }}
# Only used to list the closed issues of the matching milestone; the
# announcement still posts without it, just without that section.
GITHUB_TOKEN: ${{ secrets.OPENSCREEN_RELEASE_TOKEN }}
STABLE_TAG: ${{ inputs.tag }}
STABLE_TAG: ${{ steps.ctx.outputs.tag }}
EXTRA: ${{ inputs.release_notes_extra }}
KIND: ${{ inputs.kind }}
KIND: ${{ steps.ctx.outputs.kind }}
# Every path that ends without posting exits 0 by default, which is what
# prerelease.yml and promote.yml need — the release is already out and a
# failed announcement must not report it as broken. Here the contract is
# inverted: this workflow is dispatched *because* an announcement was
# missed, so a green run that posted nothing would recreate exactly the
# failure it was invoked to repair. That is how v1.9.0 shipped silent.
# this was when it lived inside prerelease.yml and promote.yml — the
# release was already out, and a failed announcement had to not report it
# as broken. Standing on its own inverts that: nothing downstream depends
# on this job, so a red run costs a notification and a green run that
# posted nothing recreates exactly the failure it exists to prevent. That
# is how v1.9.0 shipped silent.
STRICT: "1"
run: node .github/scripts/discord-release-announce.mjs
33 changes: 33 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,39 @@ jobs:
exit 1
fi

# The Linux counterpart of the Windows job's "Verify native binaries load under
# package identity", added for the same reason and after the same kind of miss:
# 1.9.1 shipped three sonames that nothing declared and nothing bundled — libgbm.so.1
# and libasound.so.2, needed by the Electron binary itself, so a clean Ubuntu 22.04
# exited 127 before any window, and libgomp.so.1, needed by the whole STT stack, so
# transcription died in ld.so. The symbol-version guard in before-pack.cjs could not
# have seen any of it: it checks how NEW the required symbols are, not whether the
# libraries carrying them are ever installed.
#
# Both misses hid behind the same thing. Desktop metapackages pull all three, so
# every machine anyone tested on had them — libgomp1 only via libfftw3-single3,
# libimagequant0 and libsoxr0, three peripheral media libraries. The check has to run
# somewhere empty or it is not a check, which is why this uses containers rather than
# the runner it is already standing on.
#
# rpm and pacman are verified too, and they are the ones with no other safety net:
# their depends lists are hand-written, no user installs them often enough to report
# a gap quickly, and package names genuinely differ (libgomp.so.1 is `libgomp1` on
# Debian, `libgomp` on Fedora AND on Arch, where it was split out of `gcc-libs`).
#
# The AppImage is deliberately NOT covered. It has no dependency mechanism at all, so
# there is no declaration to verify against — every system soname is "missing" by
# construction and the check would have nothing to say. It stays exposed, which is
# what d3d_linux::diagnose naming the Mesa package is for.
- name: Verify packages resolve on a clean machine
run: |
for fmt in deb rpm pacman; do
PKG="$(find release -type f -name "*.${fmt}" | head -1)"
echo "::group::${fmt}"
bash scripts/verify-linux-package.sh "$fmt" "$PKG"
echo "::endgroup::"
done

- name: Upload Linux packages
uses: actions/upload-artifact@v7
with:
Expand Down
18 changes: 8 additions & 10 deletions .github/workflows/prerelease.yml
Original file line number Diff line number Diff line change
Expand Up @@ -159,15 +159,12 @@ jobs:
-f arch=both \
--repo "$GITHUB_REPOSITORY"

- name: Announce RC on Discord (#rc-testing)
if: success()
env:
DISCORD_BOT_TOKEN: ${{ secrets.DISCORD_BOT_TOKEN }}
DISCORD_RC_TESTING_CHANNEL_ID: ${{ vars.DISCORD_RC_TESTING_CHANNEL_ID }}
GITHUB_TOKEN: ${{ secrets.OPENSCREEN_RELEASE_TOKEN }}
STABLE_TAG: ${{ steps.version.outputs.rc_tag }}
KIND: rc
run: node .github/scripts/discord-release-announce.mjs
# No announcement step here any more — see the note in promote.yml. This one
# was the worse of the two: it ran immediately after DISPATCHING build.yml,
# not after it finished, so #rc-testing was told to go test a build whose
# artifacts would not exist for another twenty minutes. announce-release.yml
# now fires on `release: published`, which by definition means the assets are
# attached, and reads `github.event.release.prerelease` to pick this channel.

- name: Workflow summary
run: |
Expand All @@ -177,5 +174,6 @@ jobs:
echo "- RC tag: \`${{ steps.version.outputs.rc_tag }}\`"
echo "- Stable target: \`v${{ steps.version.outputs.next }}\`"
echo "- Build workflow triggered by the tag push will publish the GitHub pre-release."
echo "- Announce in #rc-testing on Discord, then run \`Promote RC to stable\` when QA is green."
echo "- #rc-testing is announced automatically once the build publishes the pre-release."
echo "- Run \`Promote RC to stable\` when QA is green."
} >> "$GITHUB_STEP_SUMMARY"
20 changes: 9 additions & 11 deletions .github/workflows/promote.yml
Original file line number Diff line number Diff line change
Expand Up @@ -127,17 +127,15 @@ jobs:
-f arch=both \
--repo "$GITHUB_REPOSITORY"

- name: Announce stable on Discord
if: success()
env:
DISCORD_BOT_TOKEN: ${{ secrets.DISCORD_BOT_TOKEN }}
DISCORD_RELEASE_CHANNEL_ID: ${{ vars.DISCORD_RELEASE_CHANNEL_ID }}
GITHUB_TOKEN: ${{ secrets.OPENSCREEN_RELEASE_TOKEN }}
STABLE_TAG: ${{ steps.version.outputs.stable_tag }}
RC_TAG: ${{ steps.version.outputs.rc_tag }}
EXTRA: ${{ inputs.release_notes_extra }}
KIND: stable
run: node .github/scripts/discord-release-announce.mjs
# No announcement step here any more. It moved to announce-release.yml, which
# runs on `release: published` — the one event every release path shares,
# including a tag pushed straight to build.yml with no promotion at all. This
# step could only ever announce what THIS workflow did, and it announced it
# from here, before build.yml had produced a single asset.
#
# `release_notes_extra` consequently no longer reaches Discord from this
# workflow. Pass it to the announce dispatch instead when there is something
# to prepend; the automatic run posts the standard message.

# Bookkeeping, not publishing: the release is already out by now. Allowed to fail
# so a stuck PR never masks a successful release — the summary reports it and it
Expand Down
62 changes: 55 additions & 7 deletions electron-builder.json5
Original file line number Diff line number Diff line change
Expand Up @@ -142,12 +142,32 @@
// Mesa est ce qui garantit qu'au minimum le rastériseur logiciel existe.
//
// `depends` REMPLACE la liste par défaut d'electron-builder au lieu de s'y ajouter
// (app-builder-lib, FpmTarget.getDefaultDepends) : les entrées reprises ci-dessous
// sont donc ce défaut, verbatim, plus la nôtre en dernier. En retirer une casse le
// paquet silencieusement.
// (app-builder-lib, FpmTarget.getDefaultDepends) : les NEUF premières entrées sont
// donc ce défaut, verbatim, suivies des quatre qui nous sont propres. En retirer une
// casse le paquet silencieusement.
//
// L'AppImage n'a pas de mécanisme de dépendances et reste donc exposée : c'est
// pour elle que `d3d_linux::diagnose` nomme le paquet à installer.
//
// Les trois dernières comblent des sonames que rien ne déclarait ni n'embarquait,
// mesurés sur la 1.9.1 installée dans une Ubuntu 22.04 nue :
//
// libgbm1 — réclamé par le binaire Electron LUI-MÊME. Sans lui l'app sort en
// 127 sur `libgbm.so.1: cannot open shared object file`, avant toute
// fenêtre. Absent du défaut d'electron-builder, qui n'a jamais suivi
// le passage de Chromium à GBM.
// libasound2 — même binaire, même conséquence. Sur 24.04+ le paquet réel est
// `libasound2t64`, qui `Provides: libasound2` : le nom court résout
// sur les deux, comme `libgtk-3-0` plus haut.
// libgomp1 — l'OpenMP de GCC, réclamé par les 32 ELF de la pile STT
// (whisper-stt-server, les libggml*, libwhisper, libparakeet). Sans
// lui l'app démarre et seule la transcription meurt dans ld.so.
//
// Aucun n'a été vu avant parce que les métapaquets de bureau les tirent tous les
// trois — libgomp1 seulement via libfftw3-single3, libimagequant0 et libsoxr0, trois
// libs média périphériques. Une install minimale ou un WM monté à la main n'a
// aucune de ces garanties. C'est ce que le job `verify-linux-package` prouve
// désormais à chaque build, en interrogeant le loader plutôt que cette liste.
"deb": {
"depends": [
"libgtk-3-0",
Expand All @@ -159,16 +179,32 @@
"libatspi2.0-0",
"libuuid1",
"libsecret-1-0",
"mesa-vulkan-drivers"
"mesa-vulkan-drivers",
"libgbm1",
"libasound2",
"libgomp1"
]
},
"pacman": {
// `vulkan-swrast` est le lavapipe d'Arch ; il tire `vulkan-icd-loader` avec lui.
//
// Les trois derniers sont les équivalents Arch des sonames décrits sur `deb`.
// Noms relevés dans un conteneur archlinux, pas devinés : `libgomp.so.1`
// appartient à `libgomp` (core), PAS à `gcc-libs` — il en a été sorti.
//
// `http-parser` A ÉTÉ RETIRÉ, et c'est la seule entrée de ce fichier qui s'écarte
// volontairement du défaut d'electron-builder. Arch l'a supprimé de ses dépôts
// (Node est passé à llhttp il y a des années) et RIEN ne le fournit plus, donc
// pacman refusait la transaction entière : « unable to satisfy dependency
// 'http-parser' ». Le paquet Arch de la 1.9.1 est intégralement non installable,
// pour cette seule ligne. Aucun des 49 sonames du payload ne le réclame.
//
// `libappindicator-gtk3` est dans le même état de péremption mais reste correct :
// `libappindicator` le déclare en `Provides` ET en `Replaces`, donc il résout.
"depends": [
"c-ares",
"ffmpeg",
"gtk3",
"http-parser",
"libevent",
"libvpx",
"libxslt",
Expand All @@ -179,7 +215,10 @@
"snappy",
"libnotify",
"libappindicator-gtk3",
"vulkan-swrast"
"vulkan-swrast",
"mesa",
"alsa-lib",
"libgomp"
]
},
"rpm": {
Expand All @@ -195,6 +234,12 @@
// (electron/ai-edition/llm-config-store.ts) et passe par le Secret Service :
// sans lui, `isEncryptionAvailable()` répond faux et l'enregistrement d'une clé
// lève. Une omission d'electron-builder, pas un choix.
//
// Les trois derniers sont les équivalents Fedora des sonames décrits sur `deb`,
// relevés par `dnf provides` : `libgbm.so.1` vient de `mesa-libgbm` et non du
// `mesa` d'Arch. `libgomp` fait partie de l'install de base sur Fedora, donc le
// rpm y était moins exposé que le deb — le déclarer reste ce qui rend la
// contrainte vraie plutôt que chanceuse.
"depends": [
"gtk3",
"libnotify",
Expand All @@ -205,7 +250,10 @@
"at-spi2-core",
"(libuuid or libuuid1)",
"libsecret",
"mesa-vulkan-drivers"
"mesa-vulkan-drivers",
"mesa-libgbm",
"alsa-lib",
"libgomp"
]
},
"win": {
Expand Down
2 changes: 1 addition & 1 deletion nix/package.nix
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ buildNpmPackage {
);
};

npmDepsHash = "sha256-ArM73XLVYUB+92Pz7sCbh4Fj67xwakEusaaOSjxMEe8=";
npmDepsHash = "sha256-I0UeoZ8kWHwg2dZDHhCjBIo5BkPWi5c0DwrMywiphIo=";

env.ELECTRON_SKIP_BINARY_DOWNLOAD = "1";

Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "openscreen",
"private": true,
"version": "1.9.0",
"version": "1.9.2",
"type": "module",
"packageManager": "npm@10.9.4",
"engines": {
Expand Down
Loading
Loading