Skip to content

Commit 78625a6

Browse files
committed
Merge remote-tracking branch 'origin/main' into feat/git-manage-remotes
2 parents b38a984 + 9f75842 commit 78625a6

793 files changed

Lines changed: 129282 additions & 20907 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/scripts/review-runner-schedule.test.mjs‎

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -119,14 +119,11 @@ describe('review runner schedule', () => {
119119
// The planner's own entry path, driven through a fake `gh` that logs every
120120
// label call and serves PROBE_RUNNERS as the runner listing.
121121
const writeFakeGh = (dir) => {
122-
writeFileSync(
123-
join(dir, 'package.json'),
124-
JSON.stringify({ type: 'commonjs' }),
125-
);
122+
writeFileSync(join(dir, 'package.json'), '{"type":"module"}\n');
126123
writeFileSync(
127124
join(dir, 'gh'),
128125
`#!/usr/bin/env node
129-
const fs = require('node:fs');
126+
import fs from 'node:fs';
130127
const args = process.argv.slice(2);
131128
const method = args[args.indexOf('--method') + 1];
132129
if (!args.includes('--method')) {

‎.github/workflows/.size-baseline‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@
1919
9256 build-and-publish-image.yml
2020
49610 cd-cua-driver.yml
2121
2076 cd-mobile-mcp.yml
22-
134426 ci.yml
22+
137297 ci.yml
2323
1482 codeql.yml
2424
9389 comment-attachment-guard.yml
2525
1634 desktop-packaging-check.yml
26-
31677 desktop-release.yml
26+
35684 desktop-release.yml
2727
2038 docs-page-action.yml
2828
10005 dsw-swe-verified-release.yml
29-
23879 e2e.yml
29+
26717 e2e.yml
3030
11394 finalize-release.yml
3131
16647 live-host-release.yml
3232
5950 live-host.yml
@@ -44,7 +44,7 @@
4444
79041 qwen-fleet-shepherd.yml
4545
22680 qwen-issue-followup-bot.yml
4646
5760 qwen-pr-safety-precheck.yml
47-
1958 qwen-review-runner-schedule.yml
47+
2518 qwen-review-runner-schedule.yml
4848
27648 qwen-triage-finalize.yml
4949
350381 qwen-triage.yml
5050
9657 release-sdk-java.yml
@@ -60,7 +60,7 @@
6060
6777 serve-ab-publish.yml
6161
17013 serve-ab.yml
6262
2641 stale.yml
63-
10920 sync-desktop-to-oss.yml
63+
11328 sync-desktop-to-oss.yml
6464
10018 sync-live-host-to-oss.yml
6565
10988 sync-release-to-oss.yml
6666
2508 tui-parity.yml

‎.github/workflows/ci.yml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ on:
2222
branches:
2323
- 'main'
2424
- 'release/**'
25+
- 'omni-experiment'
2526
merge_group:
2627
# The macOS and Windows lanes' ONLY remaining trigger, and therefore this
2728
# repository's only signal about a host that is not Linux with a GNU

‎.github/workflows/desktop-release.yml‎

Lines changed: 104 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
name: 'Desktop Release'
22

3-
run-name: 'Desktop release ${{ inputs.version }}'
3+
run-name: 'Desktop release ${{ github.event.release.tag_name || inputs.version }}'
44

55
on:
6+
release:
7+
types: ['published']
68
workflow_dispatch:
79
inputs:
810
version:
911
description: 'Desktop version, for example 0.1.0 or v0.1.0.'
1012
required: true
1113
type: 'string'
1214
qwen_code_ref:
13-
description: 'Qwen Code branch, tag, or commit to bundle.'
15+
description: 'Qwen Code branch or commit to bundle, reachable from main. A release tag whose own commit is off main is refused here: dispatch checks the ref itself, while only the release event peels to its parent.'
1416
required: true
1517
default: 'main'
1618
type: 'string'
@@ -65,7 +67,6 @@ on:
6567
clobber:
6668
required: true
6769
type: 'boolean'
68-
6970
permissions:
7071
contents: 'read'
7172

@@ -81,9 +82,20 @@ env:
8182
jobs:
8283
prepare:
8384
name: 'Prepare release metadata'
85+
if: |-
86+
${{
87+
github.event_name != 'release' ||
88+
(
89+
github.repository == 'QwenLM/qwen-code' &&
90+
vars.RELEASE_DESKTOP_SYNC_PUBLISH == 'true' &&
91+
startsWith(github.event.release.tag_name, 'v') &&
92+
github.event.release.prerelease == false
93+
)
94+
}}
8495
runs-on: 'ubuntu-latest'
8596
timeout-minutes: 10
8697
outputs:
98+
already_published: '${{ steps.published.outputs.already_published }}'
8799
qwen_code_sha: '${{ steps.source.outputs.sha }}'
88100
tag: '${{ steps.version.outputs.tag }}'
89101
version: '${{ steps.version.outputs.version }}'
@@ -97,7 +109,7 @@ jobs:
97109
shell: 'bash'
98110
env:
99111
ELECTRON_BRIDGE: '${{ inputs.electron_bridge }}'
100-
INPUT_VERSION: '${{ inputs.version }}'
112+
INPUT_VERSION: '${{ github.event.release.tag_name || inputs.version }}'
101113
IS_DRAFT: '${{ inputs.draft }}'
102114
IS_DRY_RUN: '${{ inputs.dry_run }}'
103115
IS_PRERELEASE: '${{ inputs.prerelease }}'
@@ -112,7 +124,7 @@ jobs:
112124
echo "::error::Desktop prereleases must use a SemVer prerelease suffix, for example 0.2.1-rc.1: $INPUT_VERSION"
113125
exit 1
114126
fi
115-
if [ "$IS_DRY_RUN" = 'false' ] && [ "$IS_DRAFT" = 'false' ] && [ "$IS_PRERELEASE" = 'false' ] && [[ ! "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
127+
if [ "$IS_DRY_RUN" != 'true' ] && [ "$IS_DRAFT" != 'true' ] && [ "$IS_PRERELEASE" != 'true' ] && [[ ! "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
116128
echo "::error::Published stable Desktop versions must use X.Y.Z: $INPUT_VERSION"
117129
exit 1
118130
fi
@@ -127,31 +139,95 @@ jobs:
127139
echo "version=$version" >> "$GITHUB_OUTPUT"
128140
echo "tag=desktop-v$version" >> "$GITHUB_OUTPUT"
129141
142+
- name: 'Check whether stable release is already published'
143+
id: 'published'
144+
shell: 'bash'
145+
env:
146+
ALIYUN_OSS_PUBLIC_BASE_URL: "${{ vars.ALIYUN_OSS_PUBLIC_BASE_URL || 'https://qwen-code-assets.oss-cn-hangzhou.aliyuncs.com' }}"
147+
FEED_TAG: '${{ env.DESKTOP_FEED_TAG }}'
148+
GH_TOKEN: '${{ github.token }}'
149+
RELEASE_CLOBBER: '${{ inputs.clobber }}'
150+
RELEASE_DRAFT: '${{ inputs.draft }}'
151+
RELEASE_DRY_RUN: '${{ inputs.dry_run }}'
152+
RELEASE_ELECTRON_BRIDGE: '${{ inputs.electron_bridge }}'
153+
RELEASE_PRERELEASE: '${{ inputs.prerelease }}'
154+
RELEASE_TAG: '${{ steps.version.outputs.tag }}'
155+
RELEASE_VERSION: '${{ steps.version.outputs.version }}'
156+
run: |
157+
set -euo pipefail
158+
echo 'already_published=false' >> "$GITHUB_OUTPUT"
159+
if [ "$GITHUB_EVENT_NAME" != 'release' ] && {
160+
[ "$RELEASE_DRY_RUN" = 'true' ] ||
161+
[ "$RELEASE_DRAFT" = 'true' ] ||
162+
[ "$RELEASE_PRERELEASE" = 'true' ] ||
163+
[ "$RELEASE_CLOBBER" = 'true' ] ||
164+
[ "$RELEASE_ELECTRON_BRIDGE" = 'true' ];
165+
}; then
166+
exit 0
167+
fi
168+
169+
release="$(gh release view "$RELEASE_TAG" --json isDraft,isPrerelease 2>/dev/null)" || exit 0
170+
if ! jq -e '.isDraft == false and .isPrerelease == false' <<< "$release" >/dev/null 2>&1; then
171+
exit 0
172+
fi
173+
174+
directory="$(mktemp -d)"
175+
trap 'rm -rf "$directory"' EXIT
176+
if ! gh release download "$FEED_TAG" --dir "$directory" --pattern 'desktop-latest.json' >/dev/null 2>&1; then
177+
exit 0
178+
fi
179+
if ! jq -e --arg version "$RELEASE_VERSION" '.version == $version' "$directory/desktop-latest.json" >/dev/null 2>&1; then
180+
exit 0
181+
fi
182+
183+
if ! curl -fsSL --connect-timeout 15 --max-time 300 "$ALIYUN_OSS_PUBLIC_BASE_URL/desktop/latest/desktop-latest.json" -o "$directory/oss-desktop-latest.json" >/dev/null 2>&1; then
184+
exit 0
185+
fi
186+
if ! jq -e --arg version "$RELEASE_VERSION" '.version == $version' "$directory/oss-desktop-latest.json" >/dev/null 2>&1; then
187+
exit 0
188+
fi
189+
190+
echo "::notice::Desktop $RELEASE_VERSION is already published; skipping build, publish and sync-oss. Dispatch this workflow with clobber=true to force a rebuild."
191+
echo 'already_published=true' >> "$GITHUB_OUTPUT"
192+
130193
- name: 'Resolve Qwen Code source'
131194
id: 'source'
132195
shell: 'bash'
133196
env:
134-
INPUT_REF: '${{ inputs.qwen_code_ref }}'
197+
INPUT_REF: '${{ github.event.release.tag_name || inputs.qwen_code_ref }}'
135198
IS_DRY_RUN: '${{ inputs.dry_run }}'
136199
run: |
137200
set -euo pipefail
138201
git fetch origin "$INPUT_REF"
139202
sha="$(git rev-parse FETCH_HEAD)"
140-
if [ "$IS_DRY_RUN" = 'false' ]; then
141-
if [ "$GITHUB_REF_NAME" != 'main' ]; then
142-
echo '::error::Published desktop releases must run from main.'
203+
if [ "$IS_DRY_RUN" != 'true' ]; then
204+
if [ "$GITHUB_REF_NAME" != 'main' ] && [ "$GITHUB_EVENT_NAME" != 'release' ]; then
205+
echo '::error::Published desktop releases must run from main or follow a published release.'
143206
exit 1
144207
fi
208+
# CLI release tags usually point at an off-main version-bump commit
209+
# whose parent is on main. Verify that parent, while still building
210+
# the tag itself; tag-publishing permission remains the trust anchor
211+
# for the version-bump commit.
212+
ancestor="$sha"
213+
if [ "$GITHUB_EVENT_NAME" = 'release' ]; then
214+
ancestor="$(git rev-parse "${sha}^")"
215+
fi
145216
git fetch origin main:refs/remotes/origin/main
146-
if ! git merge-base --is-ancestor "$sha" refs/remotes/origin/main; then
147-
echo '::error::Published desktop releases may only bundle commits reachable from main.'
217+
if ! git merge-base --is-ancestor "$ancestor" refs/remotes/origin/main; then
218+
if [ "$GITHUB_EVENT_NAME" = 'release' ]; then
219+
echo "::error::Release $INPUT_REF: the tag commit's first parent $ancestor is not reachable from main, so this step cannot confirm the release was cut from main. That shape is a non-main source ref, or commits added to the release branch after the version bump; the dispatch arm refuses it too."
220+
else
221+
echo '::error::Published desktop releases may only bundle commits reachable from main.'
222+
fi
148223
exit 1
149224
fi
150225
fi
151226
echo "sha=$sha" >> "$GITHUB_OUTPUT"
152227
153228
build:
154229
name: 'Build ${{ matrix.name }}'
230+
if: "${{ needs.prepare.outputs.already_published != 'true' }}"
155231
needs: 'prepare'
156232
runs-on: '${{ matrix.os }}'
157233
timeout-minutes: 120
@@ -248,7 +324,7 @@ jobs:
248324
run: 'node scripts/version.js "${{ needs.prepare.outputs.version }}"'
249325

250326
- name: 'Require updater signing key for publishing'
251-
if: '${{ inputs.dry_run == false }}'
327+
if: "${{ github.event_name == 'release' || inputs.dry_run == false }}"
252328
shell: 'bash'
253329
env:
254330
TAURI_SIGNING_PRIVATE_KEY: '${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}'
@@ -260,7 +336,7 @@ jobs:
260336
fi
261337
262338
- name: 'Import macOS certificate'
263-
if: "runner.os == 'macOS' && inputs.dry_run == false"
339+
if: "runner.os == 'macOS' && (github.event_name == 'release' || inputs.dry_run == false)"
264340
shell: 'bash'
265341
env:
266342
APPLE_CERTIFICATE: '${{ secrets.APPLE_CERTIFICATE }}'
@@ -296,7 +372,7 @@ jobs:
296372
echo "APPLE_SIGNING_IDENTITY=$identity" >> "$GITHUB_ENV"
297373
298374
- name: 'Configure macOS notarization'
299-
if: "runner.os == 'macOS' && inputs.dry_run == false"
375+
if: "runner.os == 'macOS' && (github.event_name == 'release' || inputs.dry_run == false)"
300376
shell: 'bash'
301377
env:
302378
APPLE_API_ISSUER: '${{ secrets.APPLE_API_ISSUER }}'
@@ -328,7 +404,7 @@ jobs:
328404
} >> "$GITHUB_ENV"
329405
330406
- name: 'Import Windows certificate'
331-
if: "runner.os == 'Windows' && inputs.dry_run == false"
407+
if: "runner.os == 'Windows' && (github.event_name == 'release' || inputs.dry_run == false)"
332408
shell: 'pwsh'
333409
env:
334410
WINDOWS_CERTIFICATE: '${{ secrets.WINDOWS_CERTIFICATE }}'
@@ -382,7 +458,7 @@ jobs:
382458
run: 'npm run test:release'
383459

384460
- name: 'Sign bundled vendor binaries (macOS)'
385-
if: "runner.os == 'macOS' && inputs.dry_run == false"
461+
if: "runner.os == 'macOS' && (github.event_name == 'release' || inputs.dry_run == false)"
386462
working-directory: 'packages/desktop-shell'
387463
shell: 'bash'
388464
env:
@@ -435,7 +511,7 @@ jobs:
435511
echo "Signed and verified ${#mach_o[@]} Mach-O binaries under $runtime_dir."
436512
437513
- name: 'Refresh bundled runtime checksums after signing (macOS)'
438-
if: "runner.os == 'macOS' && inputs.dry_run == false"
514+
if: "runner.os == 'macOS' && (github.event_name == 'release' || inputs.dry_run == false)"
439515
working-directory: 'packages/desktop-shell'
440516
run: 'node scripts/prepare-runtime.js --refresh-checksums'
441517

@@ -447,7 +523,7 @@ jobs:
447523
working-directory: 'packages/desktop-shell'
448524
shell: 'bash'
449525
env:
450-
DRY_RUN: '${{ inputs.dry_run }}'
526+
DRY_RUN: "${{ github.event_name == 'release' && 'false' || inputs.dry_run }}"
451527
TAURI_SIGNING_PRIVATE_KEY: '${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}'
452528
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: '${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}'
453529
WINDOWS_CONFIG: '${{ env.WINDOWS_CONFIG }}'
@@ -462,7 +538,7 @@ jobs:
462538
npm run tauri -- build "${args[@]}"
463539
464540
- name: 'Verify macOS signature'
465-
if: "runner.os == 'macOS' && inputs.dry_run == false"
541+
if: "runner.os == 'macOS' && (github.event_name == 'release' || inputs.dry_run == false)"
466542
shell: 'bash'
467543
run: |
468544
set -euo pipefail
@@ -475,7 +551,7 @@ jobs:
475551
test "$(/usr/libexec/PlistBuddy -c 'Print :com.apple.security.device.audio-input' "$entitlements")" = true
476552
477553
- name: 'Verify Windows signature'
478-
if: "runner.os == 'Windows' && inputs.dry_run == false"
554+
if: "runner.os == 'Windows' && (github.event_name == 'release' || inputs.dry_run == false)"
479555
shell: 'pwsh'
480556
env:
481557
WINDOWS_CONFIG: '${{ env.WINDOWS_CONFIG }}'
@@ -592,12 +668,16 @@ jobs:
592668
593669
publish:
594670
name: 'Publish GitHub release'
595-
if: "${{ inputs.dry_run == false && github.repository == 'QwenLM/qwen-code' }}"
671+
if: "${{ (github.event_name == 'release' || inputs.dry_run == false) && github.repository == 'QwenLM/qwen-code' && needs.prepare.outputs.already_published != 'true' }}"
596672
needs:
597673
- 'prepare'
598674
- 'build'
599675
runs-on: 'ubuntu-latest'
600676
timeout-minutes: 20
677+
# The feed move below overwrites desktop-latest.json with --clobber, so it
678+
# sits behind the same deployment gate as the OSS mirror job.
679+
environment:
680+
name: 'production-release'
601681
permissions:
602682
contents: 'write'
603683
steps:
@@ -670,7 +750,7 @@ jobs:
670750
echo "url=$release_url" >> "$GITHUB_OUTPUT"
671751
672752
- name: 'Update stable updater feed'
673-
if: '${{ inputs.draft == false && inputs.prerelease == false }}'
753+
if: "${{ github.event_name == 'release' || (inputs.draft == false && inputs.prerelease == false) }}"
674754
env:
675755
ELECTRON_BRIDGE: '${{ inputs.electron_bridge }}'
676756
GH_TOKEN: '${{ github.token }}'
@@ -738,7 +818,7 @@ jobs:
738818
739819
sync-oss:
740820
name: 'Mirror stable Desktop release to Aliyun OSS'
741-
if: "${{ github.event_name == 'workflow_dispatch' && inputs.dry_run == false && inputs.draft == false && inputs.prerelease == false && github.repository == 'QwenLM/qwen-code' }}"
821+
if: "${{ github.repository == 'QwenLM/qwen-code' && (github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.dry_run == false && inputs.draft == false && inputs.prerelease == false)) && needs.prepare.outputs.already_published != 'true' }}"
742822
needs:
743823
- 'prepare'
744824
- 'build'
@@ -750,6 +830,7 @@ jobs:
750830
with:
751831
version: '${{ needs.prepare.outputs.version }}'
752832
source: 'artifact'
833+
follows_release: "${{ github.event_name == 'release' }}"
753834
secrets:
754835
ALIYUN_OSS_ACCESS_KEY_ID: '${{ secrets.ALIYUN_OSS_ACCESS_KEY_ID }}'
755836
ALIYUN_OSS_ACCESS_KEY_SECRET: '${{ secrets.ALIYUN_OSS_ACCESS_KEY_SECRET }}'

0 commit comments

Comments
 (0)