Commit graph

54 commits

Author SHA1 Message Date
Salman Chishti
df6be035e1
Upgrade GitHub Actions for Node 24 compatibility (#5157)
* Upgrade GitHub Actions for Node 24 compatibility

Signed-off-by: Salman Muin Kayser Chishti <13schishti@gmail.com>

* ci: update remaining checkout pins

---------

Signed-off-by: Salman Muin Kayser Chishti <13schishti@gmail.com>
Co-authored-by: qwen-code-dev-bot <qwen-code-dev-bot@users.noreply.github.com>
Co-authored-by: 易良 <1204183885@qq.com>
Co-authored-by: yiliang114 <effortyiliang@gmail.com>
2026-07-07 12:17:22 +00:00
易良
e48999ddb2
fix(ci): require maintainer-applied autofix/approved label for tier-1 fast-path (#6276)
* fix(ci): require maintainer-applied `autofix/approved` label for tier-1 fast-path

The scheduled scan and `issues:labeled` event paths in `qwen-autofix.yml`
previously trusted the `status/ready-for-agent` label alone, which is
applied by an LLM reading untrusted issue text. An attacker could craft
issue content to trick the triage LLM into labeling it ready, bypassing
human review.

Introduce an `autofix/approved` label that only maintainers (write+
permission) can apply. Both the cron scan and event-triggered paths now
require this label alongside `status/ready-for-agent` before entering the
autonomous fix pipeline (dual-factor: LLM signal + human confirmation).

Also:
- `release.yml` automatically adds `autofix/approved` on workflow-created
  release-failure issues (trusted source, preserves existing automation)
- Forced-issue path (non-dispatch) also checks for the new label
- Claim step strips `autofix/approved` to keep processed issues clean

Closes #5634

* fix(ci): address autofix approval review

* fix(ci): address autofix approval follow-ups

* test(ci): cover autofix approval gate

* fix(ci): harden autofix approval revalidation

* fix(ci): avoid autofix approval retry loop

* fix(ci): harden autofix claim handling

* fix(ci): clarify autofix reapproval label

* fix(ci): make autofix claim label update non-destructive
2026-07-04 08:06:27 +00:00
易良
b16baf1ffc
ci(release): optimize validation steps (#6133)
* ci(release): optimize validation steps

* fix(ci): address release validation review comments

* fix(ci): document prepare skip contract

* test(ci): cover prepare failure exit

* fix(ci): prefix prepare error logs

* fix(ci): keep release quality build artifacts

* fix(ci): address release validation comments

* fix(ci): preserve release publish hooks

* test(ci): cover prepare failure paths

* fix(ci): disable release coverage safely
2026-07-02 23:53:08 +00:00
Salman Chishti
34678cfbd9
Upgrade GitHub Actions to latest versions (#3683)
Some checks are pending
E2E Tests / E2E Test (Linux) - sandbox:docker (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:none (push) Waiting to run
E2E Tests / E2E Test - macOS (push) Waiting to run
* Upgrade GitHub Actions to latest versions

Signed-off-by: Salman Muin Kayser Chishti <13schishti@gmail.com>

* ci: restore ratchet annotations on upgraded actions

The action version bumps had replaced '# ratchet:owner/repo@<ver>'
annotations with bare '# vX.Y.Z' comments, which silently breaks
ratchet's ability to track and update these SHA pins. Restore the
annotations on every changed line (updated to the new major), matching
each line's pre-existing convention on main.

---------

Signed-off-by: Salman Muin Kayser Chishti <13schishti@gmail.com>
Co-authored-by: qwen-code-dev-bot <qwen-code-dev-bot@users.noreply.github.com>
Co-authored-by: yiliang114 <effortyiliang@gmail.com>
2026-06-27 17:03:32 +00:00
qqqys
a4203da49d
fix(packaging): bundle audio capture for mirror installs (#5747)
* fix(packaging): bundle audio capture for mirror installs

* fix(packaging): include audio prebuilds before packaging

* fix(cli): narrow native audio load error wrapping

* test(packaging): cover native audio fallback paths

* fix(packaging): require native audio artifacts

* fix(packaging): allow fork release without audio prebuilds

* fix(packaging): keep fork audio dependency fallback

* test(packaging): harden audio bundle coverage

* fix(packaging): validate native audio artifacts

* fix(packaging): harden native audio fallback paths

* fix(packaging): tighten audio bundle copy
2026-06-25 08:13:45 +00:00
易良
cead6a626b
ci(release): make release flow merge-queue-safe and keep release PRs out of notes (#5832)
* ci(release): drop --delete-branch from auto-merge (incompatible with merge queue)

main now has a merge queue, and gh pr merge rejects --delete-branch when one is enabled, failing the release workflow's final step. The queue owns the merge, so head-branch deletion is governed by the repo's auto-delete setting instead.

* ci(release): drop --delete-branch from remaining auto-merge workflows

release-sdk, release-sdk-python and desktop-release all run
'gh pr merge --auto --delete-branch' against main, which now has a merge
queue. gh rejects --delete-branch when a queue is enabled, so each would
fail at the auto-merge step on its next real release. Mirror the
release.yml fix: drop the flag and let the repo's 'Automatically delete
head branches' setting govern cleanup.

* ci(release): label release PRs skip-changelog to keep them out of notes

Every release workflow opens a 'chore(release): …' PR against main (version
bump + changelog sync). Those PRs merge before the next release, so GitHub's
--generate-notes picks them up as line items in the next release's notes.
.github/release.yml already excludes the 'skip-changelog' label, but the
release PRs were never tagged with it. Add --label 'skip-changelog' to each
'gh pr create' so the automated release PRs drop out of generated notes.

* ci(release): use --squash for Python SDK auto-merge

main's ruleset is squash-only; --merge would fail at the merge-queue
stage. Aligns release-sdk-python.yml with the other three release
workflows.

---------

Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com>
2026-06-25 06:12:35 +00:00
易良
caad0ff2cb
ci(release): queue release failures for autofix (#5551)
* ci(release): dispatch autofix for release failures

* ci(release): harden autofix dispatch

* ci(release): tighten autofix review safeguards

* ci(release): harden release autofix safeguards

* ci(release): keep autofix dispatch resilient

* ci(release): keep dispatch failure comments best-effort

* ci(release): keep autofix trigger scoped

* ci(release): queue release failures for autofix

* ci(release): avoid event-triggered autofix

* ci(release): dispatch autofix after failure issue

* fix(ci): filter unattended autofix candidates

* ci(release): deduplicate failure issues

* ci(release): respect autofix exclusion labels

* ci(release): harden autofix dispatch

* ci(autofix): drop unused comment fetch in ready-for-agent scan

Tier-1 scans type/bug + status/ready-for-agent and takes candidates
directly without the unattended (human-engagement) filter, so the
`comments` field was fetched and immediately discarded. Drop it from the
issue-list `--json` and the now-redundant `del(.comments)`. Tier-2 still
fetches comments for its own filter.

* ci(release): harden release-failure issue dedup

- Anchor reuse on the exact "Release Failed for <tag> on " title prefix
  so a tag that is a prefix of another (v0.18.1 vs v0.18.10) can't reuse
  the wrong release's issue (in:title is a fuzzy full-text search).
- Prefer a github-actions[bot]-owned match so a same-titled human/foreign
  issue sorting first can't make us skip an existing bot issue and open
  duplicates.
- Emit a :⚠️: when an existing issue carries an autofix exclusion
  label so the skipped dispatch is visible instead of a silent green job.
2026-06-22 12:49:12 +00:00
qqqys
8809c16b57
fix(voice): bundle native audio addon into standalone archives (#5628)
Standalone archives shipped only curated dist/ entries, so the esbuild-external
@qwen-code/audio-capture addon couldn't be resolved at runtime — streaming voice
was unavailable in standalone installs (batch only, and only with SoX on PATH).

create-standalone-package.js now bundles the addon into lib/node_modules (where
the bundled lib/cli.js resolves bare specifiers): the trimmed package.json
(install hook removed; type/exports kept for ESM resolution) + dist + only this
target's prebuild (win-x64 -> win32-x64) + its zero-dep runtime dependency
node-gyp-build. Targets without a matching prebuild (e.g. local builds) ship
without it and degrade to SoX/arecord as before (warns, doesn't fail). The
release pipeline already downloads prebuilds before packaging.

Refs: #5502, #5590.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-06-22 12:08:33 +00:00
qqqys
b9c5e3566b
feat(voice): voice dictation with native capture, streaming, and biasing (#5502)
* feat(voice): voice dictation with native capture, streaming, and biasing

Add voice dictation for the prompt input:
- /voice [hold|tap|off|status] command + general.voice.{enabled,mode,language,protocol} settings; push-to-talk via Space, /model --voice to pick the model
- Native microphone capture (@qwen-code/audio-capture, miniaudio N-API) with arecord/SoX fallback, silence auto-stop, cold-start warm-up, and macOS permission query
- Batch transcription via DashScope Qwen-ASR (OpenAI-compatible chat/completions + input_audio) with language + keyterm biasing and an echo guard
- Live streaming over the DashScope realtime WebSocket (fun-asr-realtime / paraformer-realtime-v2) with interim text and an input-level waveform, behind voice.protocol=dashscope-realtime
- Rich VoiceIndicator UI (state, level meter, live partial transcript)
- Cross-platform prebuilds via prebuildify + node-gyp-build and a CI matrix

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* feat(cli): route voice ASR by model

* feat(cli): polish voice realtime parity

* ci: fix voice workflow checks

* fix(cli): address voice review blockers

* fix(cli): harden voice transcription failures

* fix(cli): address voice PR review blockers

* fix(cli): harden voice review follow-ups

* fix(voice): handle realtime review blockers

* fix(cli): add voice command i18n keys

* fix(cli): address voice review blockers

* fix(cli): address voice review follow-ups

* fix(voice): harden review edge cases

* fix(voice): address release and realtime review blockers

* fix(voice): address realtime suggestion followups

* fix(voice): handle realtime review followups

* fix(voice): address realtime review blockers

* fix(voice): address review feedback

* fix(voice): address recorder review feedback

* docs(voice): document ssrf guard boundary

* fix(voice): address review feedback

* fix(voice): preserve warm recorder session safety

* fix(voice): address stream review suggestions

* fix(voice): address multi-round review findings

Realtime/streaming:
- Salvage an already-committed transcript when the WebSocket closes right
  after finish() instead of rejecting the whole dictation
  (qwenAsrRealtimeSession, voiceStreamSession) + regression tests.

useVoiceInput state machine:
- Single-shot finalize guard so a tap-stop racing the silence auto-stop can't
  double-stop the recorder and surface a spurious failure.
- Reset mountedRef on (re)mount so StrictMode (DEBUG) can't freeze the voice UI.
- Widen the hold-mode first-press release window above common key-repeat delays.

Model selection:
- Reject ids with no ASR transport at /model --voice and in the model dialog via
  a new isSelectableVoiceModel; move resolveVoiceTransport into voiceModel so the
  record-time config resolver stays transport-agnostic (+ tests).

macOS mic permission:
- Surface the not-determined state in voice warmup so the first dictation isn't
  silently lost behind the TCC dialog.

Native packaging:
- Make the audio-capture native install non-fatal (falls back to SoX/arecord) so
  a voice-only build failure can't break npm ci.
- Download audio-capture prebuilds before building standalone release archives.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(voice): address review blockers

* fix(voice): update batch recording audio level

* fix(voice): tap-mode transcript loss, stream leaks, and dead keyterm cleanup

- Tap-mode dictation submitted a stale empty buffer.text, wiping the just-
  inserted transcript and sending nothing: thread the resulting prompt text
  through onSubmit(text) instead of reading buffer.text back synchronously
  after the async insert (useVoiceInput, InputPrompt).
- Streaming finalize leaked the WebSocket session when recorder.drain() threw:
  abort the session before propagating the error.
- voiceStreamSession: reject the connect promise when 'task-finished' arrives
  before 'task-started' instead of hanging forever in 'transcribing'.
- Remove dead keyterm enrichment (project/branch/recent-file paths were
  unreachable after the privacy fix) and the now-inert CJK echo guard, plus the
  tests that asserted that removed behavior; fix the misleading "OpenAI prompt
  field" comment.
- Add the missing 'Voice Model' and macOS mic-permission i18n keys to
  en/zh/zh-TW (they were falling back to English; check-i18n doesn't flag keys
  absent from en).

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(voice): reject partial stream transcripts

* fix(cli): let dialogs consume voice keys first

* fix(voice): reject incomplete qwen realtime transcripts

* fix(voice): handle stream review blockers

* fix(voice): salvage qwen realtime transcript on close

* fix(voice): sanitize streamed transcript text

* test(audio): run audio capture tests in CI

* fix(voice): address review blockers

* fix(voice): report stream close while recording

* fix(voice): reduce keyterm echo false positives

* fix(voice): handle realtime close diagnostics

* fix(voice): address realtime review blockers

* fix(lint): allow legacy voice filenames

* chore(cli): rename voice files to kebab-case

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-06-22 14:33:36 +08:00
易良
aa625765c7
ci(release): trigger CI from release branch pushes (#5543)
* ci(release): trigger CI from release branch pushes

* ci(release): use PAT for publish checkout
2026-06-21 12:59:43 +08:00
易良
cf0d9be585
ci(release): report required Test checks on release PRs and auto-approve (#5250)
* ci(release): report required Test checks on release PRs and auto-approve

Release-sync PRs skipped the matrix Test job at job level, so the required "Test (os, Node 22.x)" contexts were never reported and the PR could not merge. Move the skip to step level so the job still expands its matrix and concludes as a work-free pass. Also add a CI_DEV_BOT_PAT approval on the release PR to cover one of the two required reviews.

* ci: single-quote the test job if expression for yamllint

After dropping the inner 'true' comparison, double quotes are no longer required, so yamllint's quoted-strings rule wants single quotes.
2026-06-17 22:30:04 +08:00
顾盼
32fbedabd6
feat(ci): add auto-generated CHANGELOG.md synced from releases (#4872) (#4881)
* feat(ci): add auto-generated CHANGELOG.md synced from releases (#4872)

Add a Keep a Changelog CHANGELOG.md that is fully derived from the project's
GitHub Releases, so users no longer have to dig through commit history to see
what changed between versions.

- scripts/generate-changelog.js: fetch releases via the gh CLI, keep only
  stable vX.Y.Z tags (nightly/preview omitted), and re-group each release's
  auto-generated "What's Changed" list into Added/Changed/Fixed/Performance/
  Documentation/Other sections by the conventional-commit prefix every PR title
  uses. Zero runtime deps (node builtins + gh).
- release.yml: regenerate and commit CHANGELOG.md on stable releases; the
  commit rides the existing release-branch PR into main.
- package.json: add 'npm run changelog'.
- .prettierignore: skip the generated file.
- Seed CHANGELOG.md from the current stable release history.

Closes #4872

* ci(release): make CHANGELOG regeneration non-blocking

Add continue-on-error to the CHANGELOG step. Its only realistic failures
(the gh API read and the git push) are transient, and the generator rebuilds
from the full release history each run, so a skipped update self-heals on the
next stable release. This keeps a changelog hiccup from blocking the
version-bump PR to main that follows.

* fix(ci): harden changelog generator per review

Address review findings on the changelog generator:

- Command injection: fetchReleasesJsonl built a shell string with the repo
  interpolated; switch to execFileSync (no shell) plus an owner/name format
  check so --repo can never be a shell payload.
- Empty-response clobber: if the API returns zero stable releases (rate limit,
  auth, 5xx), refuse to overwrite CHANGELOG.md and exit 1 instead of committing
  a header-only stub. Paired with set -euo pipefail in the workflow so the
  failure is visible and the non-blocking step self-heals next release.
- Arg parsing: switch getArgs() to parseArgs() (already imported) so a --dryrun
  typo errors instead of silently overwriting, and -h works as documented.
- Breaking changes: capture the conventional-commit ! marker and prefix the
  entry with **BREAKING** (the repo uses feat()!:/refactor()!: in practice).
- Bot authors: ENTRY_RE now accepts a trailing [bot] so GitHub App authors
  (e.g. @dependabot[bot]) are not dropped from release notes.

Regenerates CHANGELOG.md (two entries now flagged **BREAKING**).

* refactor(ci): simplify changelog generator

Quality-only cleanup (output is byte-identical; 23 tests green):

- Single source of truth for sections: derive TYPE_TO_SECTION and
  SECTION_ORDER from one SECTIONS list so they can't drift.
- Parse each entry once: formatRelease now reuses the categorize() result for
  the noise check, section lookup, and formatEntry (was parsed up to 3x).
- Drop the redundant sortKey field; sort directly from version.
- Collapse the duplicated double-.map() setup in the selectStableReleases test.
2026-06-10 14:04:43 +08:00
易良
5493888c15
ci: split Aliyun OSS sync into a separate post-release workflow (#4492)
* ci: split Aliyun OSS sync into a separate post-release workflow

The OSS upload and verification steps were adding significant time to the
release workflow's critical path. Move them into a new `sync-release-to-oss.yml`
workflow that triggers on `release: published`, running asynchronously after
the release completes.

Key changes:
- Extract all OSS steps (ossutil install, credential config, asset upload,
  verification, hosted installation sync, latest VERSION pointer) into
  `sync-release-to-oss.yml`
- Switch `gh release create` to use CI_BOT_PAT so the release event can
  trigger the new downstream workflow (GITHUB_TOKEN events don't trigger
  other workflows)
- Add `workflow_dispatch` input for manual re-runs on failure
- New workflow downloads release assets from GitHub Release instead of
  rebuilding them

This decouples publishing from CDN distribution: the release finishes as
soon as npm publish + GitHub Release are done, and China CDN sync happens
in parallel without blocking.

* fix(test): update install-script test to check sync-release-to-oss.yml

The test asserts OSS sync steps exist in the workflow. Now that these
steps live in sync-release-to-oss.yml instead of release.yml, update the
test to read from the correct file and add assertions that release.yml
no longer contains OSS logic.

* fix(ci): address review feedback for OSS sync split

- Add 'Verify Standalone Archives' step before gh release create in
  release.yml as a pre-publish safety gate (wenshao)
- Add concurrency group to sync-release-to-oss.yml to prevent race
  conditions when multiple releases publish close together (wenshao)
- Update test to assert verify step exists in release.yml

* chore: add comment explaining CI_BOT_PAT requirement [skip ci]
2026-05-25 19:34:21 +08:00
易良
d59c9e7b77
feat(installer): add standalone hosted install and uninstall flow (#3828)
* feat(installer): add standalone archive installation

* fix(installer): harden standalone archive installs

* fix(installer): address standalone review findings

* chore(installer): clarify review followups

* fix(installer): stabilize standalone script checks

* chore(installer): remove internal planning docs

* chore(installer): simplify standalone release review fixes

* test(installer): add Windows batch install smoke

* test(installer): fix Windows batch smoke quoting

* test(installer): preserve Windows cmd quotes

* fix(installer): use robust Windows checksum hashing

* ci: narrow installer debug matrix

* fix(installer): address standalone review hardening

* fix(installer): avoid Windows validation parse errors

* fix(installer): simplify Windows option validation

* fix(installer): harden standalone review fixes

* feat(installer): publish release installer assets

* fix(installer): address release asset review feedback

* fix(installer): avoid prerelease installer asset links

* test(installer): isolate standalone dist fixture

* feat(installer): add hosted install release alias

* chore: no changes - code review requested

Agent-Logs-Url: https://github.com/QwenLM/qwen-code/sessions/38467aec-15b9-4b76-9139-0b2cfe40477a

* fix(installer): pin versioned installer assets

* fix: parallelize Node.js binary downloads in standalone release build

Use Promise.all instead of sequential for...of+await for
the 5 independent Node.js runtime downloads, reducing CI
release build time by ~4-5x.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(installer): address release asset review followups

* refactor(installer): share release CLI parsing

* fix(installer): address release asset review followups

- sh: reject CR/LF in archive entry names before the literal `..` glob so
  a `..\r` entry cannot bypass path validation.
- bat: prefer Tls12+Tls13 in PowerShell helpers, fall back to Tls12 alone
  on older .NET Framework where the Tls13 enum is missing.
- bat: document the implicit `:ValidateOptions` dependency next to the
  qwen.cmd wrapper writer so loosening the validator stays a conscious
  choice.
- build-standalone-release: surface the `xz-utils` host requirement for
  Linux Node downloads in `--help`.
- release-script-utils: support `--key=value` form in `parseCliArgs`.
- tests: cover the new CRLF message, TLS string, and `--key=value` parsing;
  register process-level signal/exit handlers in `ensureMinimalDist` so a
  crashed test still restores `dist/`.

* fix(installer): unblock Windows CI for standalone install path

Three CI failures and a few review followups in one pass.

- ensureMinimalDist places its dist/ backup beside dist/ instead of
  under os.tmpdir(). On Windows GitHub runners the workspace lives on
  D: while os.tmpdir() is on C:, so renameSync raised EXDEV for every
  test that needed to swap dist/ in.
- create-standalone-package.js and the matching test fixture build
  win-x64 zips with [IO.Compression.ZipFile]::CreateFromDirectory.
  Compress-Archive emits backslash entry names that the .bat
  installer's path-traversal guard then rejected, so every freshly
  built archive failed the standalone install path on Windows.
- :ValidateArchiveContents normalizes entry separators to '/' before
  checking for '..', absolute paths, and drive prefixes - archives
  from any Windows zip tool still install while real traversal
  entries remain rejected.
- createWindowsTraversalStandaloneArchive runs PowerShell via -File
  instead of a single -Command line; the joined-with-'; ' form had a
  function definition the runner's PowerShell refused to parse.

Drive-by review followups:

- replaceRequired uses replaceAll so a future duplicate placeholder
  cannot silently keep the trailing copy as 'latest'.
- :ValidateOptions runs the unsafe-character check on SOURCE
  alongside the other variables.
- build-installation-assets.js drops a dead INSTALLATION_ASSETS
  re-export; consumers already import from release-asset-config.js.
- .gitignore covers the new sibling .qwen-dist-backup-* directory.

* fix(installer): address release asset review findings

* fix(installer): keep installer entrypoint hosted

* fix(installer): reject stale hosted assets

* fix(installer): refine hosted asset staging

* fix(installer): tighten hosted default-version check, flag legacy URL

- Replace the loose `latest` fragment check with per-format regex patterns
  in HOSTED_INSTALLER_DEFAULT_VERSION_PATTERNS so an unrelated occurrence
  of `latest` (comment, help text) cannot satisfy the staging guard. The
  patterns still tolerate whitespace variation, only the default-version
  assignment itself must be intact.
- Add a "Hosted endpoint status" callout in INSTALLATION_GUIDE.md before
  the curl examples. The documented `--version` flow does not work against
  the OSS URL today because it currently serves the legacy NVM-based
  installer; the callout points users at a local checkout until the next
  release sync.
- Tests: drop `latest` from the fragments equality assertion, add positive
  and negative regex coverage, add a failure-path case for sources whose
  default version is not `latest`, and pin the new guide markers so the
  callout cannot silently disappear.

* feat(installer): verify installation release assets

Adds `npm run verify:installation-release` and wires it into the release
workflow after `Build Standalone Archives`, so a broken release directory
fails CI before publishing.

Local mode (`--dir PATH`) checks:
- All five `qwen-code-{platform}.{ext}` standalone archives exist.
- `SHA256SUMS` covers exactly those five — missing or unexpected entries fail.
- Each archive's actual SHA256 matches its `SHA256SUMS` entry.

Remote mode (`--base-url URL`) checks:
- `SHA256SUMS` is downloadable, parseable, and contains exactly the expected
  archive entries.
- Each archive URL is reachable via HEAD, with a 1-byte ranged GET fallback
  for hosts that disable HEAD.

Hosted installer scripts (`install-qwen.sh` / `install-qwen.bat`) are
intentionally out of scope here — they are served from the hosted endpoint
prepared by `package:hosted-installation` (PR #3853), not from the GitHub
Release surface this verifier targets.

* fix(installer): tighten verifier base-url + clarify test helper

Three small refinements from the second review pass:

- normalizeHttpsBaseUrl rejects everything except https, since real release
  URLs are always HTTPS. Accepting http previously would let an operator
  silently target a stale or attacker-controlled mirror.
- Drop EXPECTED_RELEASE_ASSET_NAMES from the public exports; it was only
  used internally for the verification log line.
- Rename the test helper standaloneChecksumContent to
  placeholderChecksumContent and document that the hashes in its output are
  placeholders — the remote verifier does not download archives or compare
  hashes, it only validates that SHA256SUMS lists the expected names and
  that each archive URL is reachable.

The non-https rejection test now also covers `http://` in addition to the
existing `file://` case.

* fix(installer): address standalone review follow-ups

* fix(installer): repair Windows installer tests

* fix(release): tighten standalone asset checks

* fix(installer): stabilize Windows managed install checks

* test(installer): relax Windows installer timeout

* fix(test): escape release asset regex

* test(cli): avoid POSIX node path in relaunch test

* fix(installer): align npm fallback node gate with engines

* test(installer): allow Windows archive validation more time

* fix(installer): remove stale node 20 installer references

* docs(installer): clarify hosted endpoint sync requirement

* refactor(installer): reuse standaloneArchiveName in release verifier

The verify-installation-release script was duplicating the archive name
derivation logic with a hardcoded ternary instead of reusing the
standaloneArchiveName helper from build-standalone-release. Export the
helper and import it so the extension mapping lives in one place.

* fix(scripts): address release verifier review feedback

* feat(installer): add standalone archive installer with multi-platform release workflow

- Add standalone archive installer (bat/sh) that downloads platform binaries
  from GitHub/Aliyun without requiring Node.js or npm on the target machine
- Add fork-friendly release-test workflow for manual GitHub Release creation
  covering all 5 platforms (darwin-arm64/x64, linux-arm64/x64, win-x64)
- Add OSS upload/mirror tools for staging and release distribution
- Update .gitignore to exclude generated build artifacts (release-staging/,
  hosted-staging/)
- Fix Windows PowerShell test command in copy-release-to-latest tool

* feat(installer): support QWEN_INSTALL_GITHUB_REPO env var for custom repo

* chore(installer): exclude local-only staging tools from PR

The tools/ directory contained personal staging-OSS upload helpers
(upload-staging, upload-release-mirror, copy-release-to-latest,
test-upload-one) that should not ship in the public PR. They reference
a personal staging bucket and only exist to validate the installer
end-to-end before production release.

Removes them from git tracking via `git rm --cached` (files stay on
disk for the author's local use) and adds /tools/ to root .gitignore
so they cannot be re-added accidentally.

No runtime / installer code change. Production CI on ubuntu-latest is
unaffected.

* fix(installer): enforce CRLF line endings for .bat files via gitattributes

cmd.exe requires CRLF in batch scripts; the global eol=lf was causing
every line to be misparsed on Windows, producing errors like
'QWEN_VALIDATE_METHOD=detect is not recognized as a command'.

* fix(installer): store .bat files with CRLF in git blob for raw GitHub downloads

GitHub raw file serving bypasses gitattributes eol conversion and serves
blob bytes directly, so eol=crlf alone was not enough. Use -text to disable
normalization and commit with actual CRLF so raw downloads work on Windows.

* fix(installer): follow HTTP redirects in UrlExists and RaceMirrorHead probes

GitHub release asset URLs return HTTP 302 to objects.githubusercontent.com.
[Net.WebRequest] with HEAD does not auto-redirect by default, so the
existence check and mirror-race probe both incorrectly reported the file
as missing. Set AllowAutoRedirect=true on HttpWebRequest instances.

* fix(installer): surface download errors and add MaximumRedirection 10

* feat(installer): add hosted install-qwen.ps1 shim for irm|iex one-liner

The previous Windows quick-install one-liner used `Invoke-WebRequest -OutFile
(Join-Path $env:TEMP 'install-qwen.bat'); & (Join-Path …)`. When pasted into a
narrow terminal, line wrap could land on `-OutFile`, orphaning the parameter
from its value and producing the "missing argument for OutFile" failure
followed by a "file not found" when the second `&` ran. PowerShell's line
continuation rules cannot resolve this for parameter-name-at-EOL.

Add `install-qwen.ps1` as a thin hosted entrypoint that downloads
`install-qwen.bat` into TEMP, runs it, and cleans up. Documented one-liner
becomes the standard pattern used by bun, uv, scoop, deno, pnpm:

    powershell -ExecutionPolicy Bypass -c "irm <url>/install-qwen.ps1 | iex"

The `.bat` remains the source of truth for installer behavior; `.ps1` is just
the modern hosted entrypoint. Version pinning via `$env:QWEN_INSTALL_VERSION`
flows through unchanged. Stored with `*.ps1 -text` so CRLF survives both
GitHub raw and OSS uploads, matching the existing `.bat` handling.

* fix(installer): stage direct hosted install scripts

* chore(installer): trim hosted release diff scope

* chore(installer): narrow hosted release diff

* feat(installer): restore hosted PowerShell entrypoint

* chore(installer): stage standalone hosted entrypoints

* fix(installer): address hosted installer review followups

* fix(installer): stabilize Windows installer tests

* fix(installer): make Windows option validation readable

* feat(installer): wire Aliyun OSS sync, address review followups

- Add Aliyun OSS sync steps to release workflow: package hosted assets,
  install pinned ossutil, configure credentials, upload versioned and
  latest paths, and verify upload via verify:installation-release plus
  curl probes against the hosted installer endpoint.
- Document required production-release environment secrets and bucket
  variables in INSTALLATION_GUIDE.md.
- Restructure hosted endpoint guidance to lead with the pre-sync
  warning, splitting "Run today" (local checkout) from "After the OSS
  sync" (hosted one-liners) so users no longer copy a one-liner that
  silently installs latest.
- Distinguish mirror auto-selection timeout from successful selection
  in install-qwen-standalone.sh and install-qwen-standalone.bat: emit
  a "timed out; defaulting to github" log instead of pretending the
  HEAD probe picked github.
- Support QWEN_INSTALLER_BAT_URL override (https only) in the
  PowerShell shim so staging mirrors can be exercised without forking
  the file.
- Strip a leading UTF-8 BOM in verify-installation-release.js
  parseSha256Sums so BOM-prefixed SHA256SUMS reports a useful
  "Missing checksum entry" error instead of "Malformed SHA256SUMS
  line 1".
- Add tests for verifier HEAD→Range fallback, partial-failure
  formatting, all-failure wording, and BOM tolerance.

* ci(installer): add temporary OSS smoke test

* fix(installer): make OSS release assets public-readable

* chore(installer): remove temporary OSS smoke workflow

* fix(installer): address hosted installer review gaps

* feat(installer): refactor argument parsing and utility functions for release scripts

* fix(installer): harden hosted release script checks

* fix(installer): suppress PowerShell progress bar in hosted entrypoint shim

Add $ProgressPreference = 'SilentlyContinue' to the .ps1 wrapper so
Invoke-WebRequest downloads don't render a progress bar when invoked
via the irm | iex one-liner.

* fix(installer): suppress PowerShell progress bar in bat installer downloads

Add $ProgressPreference = 'SilentlyContinue' to DownloadFile so the
full-screen progress UI does not appear during archive downloads in
interactive PowerShell sessions, consistent with the .ps1 shim.

* fix(installer): use curl.exe -# progress bar in Windows downloads

Prefer curl.exe with -# (hash-mark progress bar) for archive and installer
downloads on Windows 10+. Falls back to Invoke-WebRequest (which shows its
own progress bar) when curl.exe is unavailable. Matches the approach used
by code-server (curl -#fL) and bun.sh (curl.exe -#SfLo).

* fix(installer): suppress progress bars for small downloads and Expand-Archive

- .ps1: replace curl.exe -# with silent mode, suppress Invoke-WebRequest
  progress bar; save/restore $global:ProgressPreference
- .bat: add $ProgressPreference = 'SilentlyContinue' before Expand-Archive
  to prevent full-screen extraction progress UI
- .sh: remove --progress-bar / --show-progress from download_file, always
  use silent curl/wget

* fix(installer): auto-backup non-qwen directories and simplify output

- ensure_managed_install_dir / :EnsureManagedInstallDir now back up
  non-qwen directories instead of refusing to install, so users
  upgrading from npm or old installers don't hit a hard error
- Simplify header/footer output: remove banner bars, verbose INFO
  lines, and redundant "Installation completed!" message
- Match bun.sh / code-server style: minimal, to the point

* fix(installer): revert Expand-Archive progress suppression in bat

The inline $ProgressPreference = 'SilentlyContinue' caused a cmd.exe
parsing error ("此时不应有 >") on Chinese Windows. Revert to the
original Expand-Archive invocation.

* fix(installer): fix cmd.exe parsing error in backup fallback code

The %s in the for /f fallback command string was interpreted as a variable
reference by cmd.exe, causing "此时不应有 >" on Chinese Windows. Replace
with a safe fallback and re-enable Expand-Archive progress suppression.

* fix(installer): always persist install bin to user PATH

Previously MaybeUpdateUserPath was only called when shadow qwen
executables were detected. When no shadow was found, the PATH update
was skipped entirely, leaving the user without qwen on PATH after
restarting their terminal.

Now always persist the bin directory to PATH (unless --no-modify-path
is set), regardless of whether other qwen installations exist.

* fix(installer): persist PATH to current terminal session on Windows

Use the `endlocal & set` trick (same as bun/Rust installers) to export
the install bin directory from the setlocal scope to the current cmd
session. qwen is now usable immediately without restarting the terminal.

* docs(installer): document cmd.exe one-liner for immediate PATH availability

Add curl-based one-liner for cmd.exe users. Running the .bat directly
in the current cmd session makes `qwen` available immediately via the
`endlocal & set` trick. The `powershell -c "irm | iex"` path creates
a child process so PATH changes cannot propagate to the parent.

* feat(installer): make qwen usable immediately from PowerShell after install

- .ps1: detect parent process, update current session PATH, and for
  cmd.exe parents emit a `set PATH=...` command
- .bat: skip final instructions when called from PowerShell to avoid
  duplicate "Run: qwen" output

* fix(installer): remove non-functional doskey approach for cmd parent

doskey /exename from a child PowerShell process cannot modify the
parent cmd.exe session. Replace with a simple set PATH=... command
that the user can copy-paste.

* fix(installer): make Windows standalone shim available in cmd

* feat(installer): add standalone uninstall scripts

* fix(uninstall): match shell-quoted paths when removing the wrapper

The installer's write_unix_wrapper shell-quotes the binary path, so
paths containing single quotes (or other shell metacharacters) appear
as shell-quoted strings in the generated wrapper file. The uninstall
script's literal grep -qF missed these, leaving the wrapper orphaned.

Add shell_quote to the uninstall script and match against both the raw
and shell-quoted forms before removing the wrapper.

* fix(installer): update download commands to use progress indicators for curl and wget

* fix(installer): resolve Aliyun latest via version pointer

* fix(installer): cleanup mirror probe temp dirs

* fix(installer): harden standalone release fallback

* fix(installer): address standalone review feedback

* style(installer): align standalone install output

* fix(installer): print standalone uninstall commands

* fix(installer): address release review follow-ups

* fix(installer): harden Windows target detection

* test(installer): stabilize Windows fake tool path

* fix(installer): allow explicit Windows curl path

* test(installer): use cmd fake curl on Windows

* test(installer): cover Windows fake curl helper

* test(installer): inject Windows arch overrides in cmd

* test(cli): wait for prompt suggestion render

* test(cli): revert prompt suggestion wait tweak

* fix(installer): harden hosted release publishing

* fix(installer): harden Windows latest pointer parsing

* fix(installer): bound Windows download timeouts

* fix(installer): bound hosted installer probes

* fix(release): make ossutil download configurable

* fix(installer): address hosted release review feedback

* test(installer): keep dist backup on same filesystem

* fix(installer): address remaining review feedback on PR #3828

- Remove REQUIRE_CHECKSUM dead code, always hard-fail on checksum issues
- Add JSDoc to HOSTED_INSTALLER_BEHAVIOR_PATTERNS explaining its purpose
- Add credential cleanup trap for ossutilconfig in release workflow
- Add 3-attempt retry with exponential backoff for OSS uploads
- Tighten findstr SOURCE regex to require leading letter

* fix(release): correct OSS credentials lifetime and mirror probe fallback

- release.yml: remove `trap EXIT` inside the Configure step; it deleted
  ${RUNNER_TEMP}/.ossutilconfig as soon as the configure shell exited,
  so every subsequent step (publish/sync/verify) lost the credentials.
  Move credential cleanup to a final `if: always()` step at the job tail.
- install-qwen-standalone.sh: drop the predictable PID-based mktemp -d
  fallback in race_mirror_head; if mktemp fails, return "github" instead
  of using /tmp/qwen-mirror.$$ which a local attacker could pre-create
  to bias mirror selection.

* fix(installer): address review feedback round 2

Workflow:
- Move 'Publish Aliyun OSS Latest VERSION' to run after the hosted installer
  assets are uploaded and verified, so the latest/VERSION pointer only flips
  once every release artifact is in place. Previously a hosted-sync failure
  could leave the pointer ahead of the actual installer scripts.

upload-aliyun-oss-assets.js:
- Replace `spawnSync('sleep', ...)` retry backoff with an Atomics.wait-based
  cross-platform sleep so retries also work on Windows runners.

install-qwen-standalone.bat:
- :DetectTarget no longer emits TARGET=win-arm64 because RELEASE_TARGETS has
  no win-arm64 archive; ARM64 hosts now fall through to the unsupported-arch
  branch and (in detect mode) get the npm fallback instead of a 404.
- Add QWEN_INSTALL_CURL_EXE to :ValidateRawEnvironmentOptions so this curl
  override is checked for shell metacharacters like every other knob.
- Replace `call echo %%i>>...` with plain `echo %%i>>...` when capturing
  pre-install qwen.cmd paths; `call` triggered an extra parse pass that
  could interpret &/|/<,>/etc. inside a directory name as command separators.
- Add `--retry 2` to curl.exe downloads (`:DownloadFile` / `:DownloadFileQuiet`)
  to match the shell installer.
- Include expected vs actual hash in the checksum-mismatch error message.

install-qwen-standalone.ps1:
- Stage the downloaded installer at a cryptographically random temp path
  (`qwen-installer-<random>.bat`) so a same-user attacker cannot pre-stage a
  malicious .bat at a predictable path and race the verify/execute window.
- Atomically install the current-session cmd shim by writing to a sibling
  `.new` temp file then renaming, so a partial write cannot leave a
  half-written shim on PATH.
- Add `--retry 2` to the curl.exe download path.
- Include expected vs actual hash in the checksum-mismatch error message.

install-qwen-standalone.sh:
- Include expected vs actual hash in the checksum-mismatch error message.

uninstall-qwen-standalone.ps1:
- Accept `-Purge` and `-Help` parameters; previously every CLI flag was
  silently dropped, so users running with `-Purge` got no purge and no error.
  `-Purge` maps to `QWEN_UNINSTALL_PURGE=1`.

uninstall-qwen-standalone.sh:
- `remove_install_wrapper` additionally requires the wrapper file to start
  with a `#!` shebang before it deletes it; a user-authored script that just
  happens to mention the install path now stays untouched.

verify-installation-release.js, build-hosted-installation-assets.js:
- Include expected vs actual hash in the checksum-mismatch error messages.

scripts/tests/install-script.test.js:
- Update assertions for the new error wording, the curl `--retry 2` flag,
  the dropped ARM64 detection, and the new release-step ordering.

* fix(installer): address review feedback round 3

Workflow:
- Configure Aliyun OSS Credentials: write the ossutil config file directly
  with restricted umask instead of invoking `ossutil config -k <secret>`.
  Passing the access-key secret via argv made it visible in /proc/<pid>/cmdline
  for the lifetime of that step; writing the INI file in-process keeps the
  secret out of the process table.

upload-aliyun-oss-assets.js:
- Upload assets in parallel with `Promise.all` + async `spawn` instead of a
  sequential `spawnSync` loop. Each asset keeps its own retry budget; failures
  are aggregated so one flaky upload does not mask a separate failure.
- Replace the bespoke `Atomics.wait` retry sleep with `timers/promises#setTimeout`
  now that the loop is async.

INSTALLATION_GUIDE.md:
- Drop the misleading "instead of overwriting the global installation/
  entrypoint objects" sentence; the workflow has always also refreshed the
  global versionless objects so curl|bash links keep resolving without a
  version segment. Document the rollback story instead.

* test(installer): add parseUploadArgs unit tests and align verify derivation

- scripts/tests/upload-aliyun-oss-assets.test.js: cover --help short-circuit,
  required-option validation (--bucket/--config/--prefix/empty assets),
  unknown options, missing option values, and trailing-slash prefix
  normalization.
- scripts/verify-installation-release.js: switch the win-only zip branch
  from `startsWith('win-')` to the strict `=== 'win-x64'` check used by
  build-standalone-release.js, and add a comment recording that the two
  derivations must stay aligned. Without this the helpers would diverge
  the moment a non-x64 win target gets added.

* test(installer): add uploadAssets integration tests with fake ossutil

Add two integration tests that route a temp-directory ossutil shim onto
PATH so uploadAssets actually spawns the real binary with the real cp
argv:

- happy-path test asserts the destination URI, `-c <config>`, `--acl
  public-read`, and per-asset cp invocations land for both inputs.
- failure-path test asserts non-zero ossutil exits surface as an
  aggregate `asset uploads failed` error after the retry budget runs out.

* revert(installer): drop over-engineered ossutil/upload changes

Roll back two changes from a1ef8697b/0a5d308c9 that were not justified
by the actual threat model or release-pipeline needs:

- .github/workflows/release.yml: restore the supported `ossutil config -k`
  invocation. The earlier switch to writing the .ossutilconfig INI file
  in-process was meant to keep the access-key out of /proc/<pid>/cmdline,
  but GitHub-hosted runners are single-tenant ephemeral VMs where no other
  user can read that namespace. The benefit was theoretical; the cost was
  taking on a brittle dependency on ossutil's undocumented config format.

- scripts/upload-aliyun-oss-assets.js: revert the uploadAssets parallel
  rewrite (Promise.all + spawn + setTimeout) back to the original sync
  spawnSync loop with retry. Release-time uploads of ~6 small files do
  not need parallelism, and the async refactor changed the public
  contract (sync→async) for no real wall-clock win.

Kept from those commits:
- The cleanup `if: always()` step that removes RUNNER_TEMP/.ossutilconfig
  at the end of the publish job.
- The cross-platform sleepSync(ms) helper, since `spawnSync('sleep', ...)`
  still does not work on Windows runners.
- The INSTALLATION_GUIDE.md doc fix.
- All other round-2 fixes.

Test assertions updated for the restored sync uploadAssets contract.

* test(installer): cover Windows release script regressions

* test(release): avoid Windows shim lookup in oss upload tests

* test(installer): use stable fake Aliyun version on Windows

* fix(installer): parse Aliyun latest version in batch

* fix(installer): validate Aliyun latest version without findstr

* fix(installer): normalize Aliyun latest version via PowerShell

* fix(installer): avoid captured PowerShell output in batch latest parsing

* fix(installer): normalize Aliyun latest pointer from file

* test(installer): fix fake Windows curl output parsing

* fix(installer): print checksum path on miss, gate hardcoded version pin in ps1 [skip ci]

Address two narrow follow-ups from PR #3828 review:

- build-hosted-installation-assets.js: add a HOSTED_INSTALLER_FORBIDDEN_PATTERNS guard for install-qwen-standalone.ps1. The ps1 shim has no VERSION variable of its own (it forwards @args to the .bat), so the existing default-version positive-match patterns don't apply. The new guard fails the build if a $env:QWEN_INSTALL_VERSION assignment or a --version flag prepended to the forwarded argument list ever lands in the shim. Patterns are line-anchored with /m so the documented usage examples in the header docstring stay valid. Two vitest cases cover the reject and allow paths.

- install-qwen-standalone.sh / .bat: include the searched checksum-file path in the "SHA256SUMS not found" error. Operators triaging --archive failures could not tell from the prior message whether the fallback path (next to the archive) or the remote URL was being looked up. Existing test assertions updated to match the new wording.

Local validation: npm run test:scripts -> 160 passed | 9 skipped (was 158 | 9).

* fix: stamp release version in hosted installers and add Zip Slip protection [skip ci]

1. The hosted installation asset build now accepts --version and stamps it
   into the copied .sh/.bat installers so they default to the tagged release
   version instead of 'latest'. The release workflow passes the version.

2. install-qwen-with-source.bat now validates archive entries before calling
   Expand-Archive, rejecting paths with '..', leading '/', drive-rooted
   paths, empty names, or control characters — matching the protection
   already present in install-qwen-standalone.bat and the .sh installer.

* fix(installer): add SOURCE to PowerShell unsafe-character validation [skip ci]

The SOURCE variable is user-provided and used in path operations but was
not included in the :ValidateOptions unsafe-character check. Add it
alongside the other validated variables.

* fix: correct copyright year 2025 -> 2026 in new files [skip ci]

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: yiliang114 <effortyiliang@gmail.com>
2026-05-21 11:57:10 +08:00
ChiGao
3cc66f9ae5
ci(deps): bump docker/* actions to Node 24 majors (#4131)
GitHub Actions deprecates the Node 20 runtime; older versions of every
docker/* action run on Node 20 and emit the "Node.js 20 actions are
deprecated" warning in every release / e2e / image-build run today.

Each action shipped a "Node 24 as default runtime" major:

  - docker/setup-buildx-action  v3 → v4 (2026-03-05)
  - docker/setup-qemu-action    v3 → v4
  - docker/metadata-action      v5 → v6
  - docker/login-action         v3 → v4
  - docker/build-push-action    v6 → v7

None of our usages touch the deprecated inputs removed in the bumps —
release.yml / e2e.yml call setup-buildx with no `with:` block, and
build-and-publish-image.yml only passes the universally-supported
`images` / `tags` / `registry` / `username` / `password` / `context` /
`platforms` / `push` / `labels` / `build-args` inputs. ESM internal
refactor of each action is transparent to consumers.

Ratchet-pinned bumps use the v4.0.0 commit SHA
`4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd` (release.yml + e2e.yml).
Other action references in build-and-publish-image.yml use
`# ratchet:exclude` per existing convention, so version-string bumps
suffice there.

Verified runtime hosts (`actions/runner` v2.327.1+) are already in use
on github-hosted runners as of 2026-03; no infra bump required.

Co-authored-by: 秦奇 <gary.gq@alibaba-inc.com>
2026-05-14 10:54:01 +08:00
Salman Chishti
70eecdbdf4
Upgrade GitHub Actions for Node 24 compatibility (#1876)
Signed-off-by: Salman Muin Kayser Chishti <13schishti@gmail.com>
2026-05-12 15:02:33 +08:00
易良
cb7059f54d
feat(installer): add standalone archive installation (#3776)
* feat(installer): add standalone archive installation

* fix(installer): harden standalone archive installs

* fix(installer): address standalone review findings

* chore(installer): clarify review followups

* fix(installer): stabilize standalone script checks

* chore(installer): remove internal planning docs

* chore(installer): simplify standalone release review fixes

* test(installer): add Windows batch install smoke

* test(installer): fix Windows batch smoke quoting

* test(installer): preserve Windows cmd quotes

* fix(installer): use robust Windows checksum hashing

* ci: narrow installer debug matrix

* fix(installer): address standalone review hardening

* fix(installer): avoid Windows validation parse errors

* fix(installer): simplify Windows option validation

* fix(installer): harden standalone review fixes
2026-05-11 13:25:48 +08:00
易良
f43af53a20
ci(release): keep skip-ci out of release PR titles (#3950) 2026-05-08 16:51:16 +08:00
易良
930ce0d550
ci(release): skip CI on the version-bump squash commit on main (#3912)
* ci(release): skip CI on auto-generated version-bump PRs

Append `[skip ci]` to both the bump commit message and the
release-PR title in `release.yml` and `release-sdk.yml`.

The PR title doubles as the squash-merge commit message on `main`,
so adding `[skip ci]` there is required to skip CI when the release
PR is auto-merged into `main`.

Affected flows:
- release.yml      -> chore(release): vX.Y.Z
- release-sdk.yml  -> chore(release): sdk-typescript vX.Y.Z

These PRs only bump `package.json` / `package-lock.json` versions
and do not need the full lint/test/CodeQL matrix to run on PR open,
on the release branch push, or on the post-merge push to `main`.

* ci(release): make skip-ci squash subject explicit

* ci(release): scope skip-ci to the squash commit and bind RELEASE_TAG

Two follow-ups on the release-PR skip-ci change:

- Drop `[skip ci]` from the release-branch commit. Putting it there
  also suppressed `push: tags: [v*]` workflows because the release
  tag points at the release-branch tip, so `Build and Publish Docker
  Image` would silently skip when the release was tagged. Keeping the
  marker only on the squash subject preserves the "do not re-run CI
  on main" goal without affecting tag pushes.
- Export `RELEASE_TAG` to the `Enable auto-merge for release PR` step
  in both workflows. The step runs under `set -euo pipefail`, so the
  new `--subject` referencing `${RELEASE_TAG}` would otherwise crash
  with `unbound variable` and abort the merge.
2026-05-07 22:45:49 +08:00
易良
bc32298528
fix(ci): add merge-back PR for stable releases in release workflow (#3764)
After a stable/patch CLI release, the release branch version bump was
never synced back to main, causing nightly versions to fall behind
stable (e.g. nightly 0.15.3 < stable 0.15.5). Add automated PR
creation and auto-merge steps (matching the existing release-sdk.yml
pattern) so package.json on main stays in sync after each release.

Resolves #3756
2026-04-30 15:25:02 +08:00
jinye
ba8d452ce5
fix(ci): preserve preview version overrides (#3705)
* fix(ci): preserve preview version overrides

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-04-28 20:26:42 +08:00
易良
6af0f37bb8
ci(release): parallelize release validation (#3132)
* ci(release): parallelize release validation

* ci(release): allow publish when tests are skipped

* ci(release): drop planning artifact from workflow PR

* ci(release): address workflow review findings

* ci(release): fix quality job bootstrap

* ci(release): fix docker test and dry-run notify flow
2026-04-13 17:16:53 +08:00
tanzhenxin
d07861ad5c chore(channels): make plugin-example private and remove from release workflow
- Mark @qwen-code/channel-plugin-example as private in package.json
- Remove publish step from release workflow
- Remove file: to semver rewrite logic in version script
- Use file: reference for @qwen-code/channel-base dependency

This change prevents the example plugin from being published to npm, as it's only intended for internal/development use.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-04-01 20:43:45 +08:00
tanzhenxin
b2f04418fa
Merge pull request #2628 from QwenLM/feat/channels-telegram
feat(channels): add extensible Channels platform with plugin system and Telegram/WeChat/DingTalk channels
2026-04-01 16:19:08 +08:00
tanzhenxin
ded89618ec refactor(tests): reorganize integration tests by execution mode
Move non-interactive tests to cli/, interactive tests to interactive/.
Add cron-interactive.test.ts wrapping terminal-capture E2E in vitest.
Update npm scripts and release workflow for new directory layout.
2026-03-29 05:49:17 +00:00
tanzhenxin
a700ce8186 chore(release): add channel packages to release workflow
- Bump channel package versions to 0.13.0
- Add publish steps for @qwen-code/channel-base and @qwen-code/channel-plugin-example
- Update version script to convert file: references to semver for published packages

This enables proper npm publishing of channel packages during the release process.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-03-27 06:16:22 +00:00
mingholy.lmh
8fe304c19b fix(workflows): standardize release notes generation and add prerelease labels
- Fix release-sdk.yml: Use file-based approach with --notes-file instead of
  complex inline string interpolation to avoid shell parsing errors with
  backticks and special characters

- Fix release.yml: Add --prerelease flag for nightly and preview releases
to properly mark them as pre-releases on GitHub

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-02-20 21:57:53 +08:00
mingholy.lmh
00a8c6a924 chore: separate CLI and SDK integration test 2025-12-19 15:44:04 +08:00
pomelo-nwu
87b1ffe017 fix(ci): remove non-existent label from release failure issue creation 2025-11-22 14:23:49 +08:00
tanzhenxin
1577dabf41 fix: release workflow failure 2025-10-27 17:47:03 +08:00
tanzhenxin
be633a80cc
📦 Release qwen-code CLI as a Standalone Bundled Package (#866) 2025-10-24 17:08:59 +08:00
mingholy.lmh
14ea33063f Merge tag 'v0.3.0' into chore/sync-gemini-cli-v0.3.0 2025-09-11 16:26:56 +08:00
tanzhenxin
2572faf726
# 🚀 Sync Gemini CLI v0.2.1 - Major Feature Update (#483)
Some checks are pending
Qwen Code CI / Lint (GitHub Actions) (push) Waiting to run
Qwen Code CI / Lint (Javascript) (push) Waiting to run
Qwen Code CI / Lint (Shell) (push) Waiting to run
Qwen Code CI / Lint (YAML) (push) Waiting to run
Qwen Code CI / Lint (push) Blocked by required conditions
Qwen Code CI / Test (push) Blocked by required conditions
Qwen Code CI / Post Coverage Comment (push) Blocked by required conditions
Qwen Code CI / CodeQL (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:docker (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:none (push) Waiting to run
E2E Tests / E2E Test - macOS (push) Waiting to run
2025-09-01 14:48:55 +08:00
matt korwel
c3cf1c61c1
fix(release): fallback to github.sha when ref is not provided (#6862) 2025-08-22 12:54:08 -07:00
tanzhenxin
af0439165a chore: fix action lint errors 2025-08-22 12:00:10 +08:00
tanzhenxin
0f3db5275f chore: fix lint errors for shell scripts and yaml files 2025-08-22 11:35:35 +08:00
matt korwel
0e24805806
feat(release): update release process for nightly and preview builds (#6643)
Co-authored-by: Bryan Morgan <bryanmorgan@google.com>
2025-08-20 15:50:00 +00:00
mingholy.lmh
c546d86d44 Merge tag 'v0.1.21' of github.com:google-gemini/gemini-cli into chore/sync-gemini-cli-v0.1.21 2025-08-20 22:24:50 +08:00
tanzhenxin
12d43589be
🚀 Enhance Release Notes Generation with Previous Tag Detection (#394)
* feat: add automated release notes generation with previous tag detection

* chore: npm run format
2025-08-20 17:05:39 +08:00
Shreya Keshive
69d666cfaf
Fix release notes generation (#6233) 2025-08-14 18:13:13 +00:00
Seth Vargo
8524cce7b9
chore(ci): Ensure release workflow is consistent and not vulnerable to injection attacks (#6059) 2025-08-12 19:51:50 +00:00
anthony bushong
99f88851fb
fix(actions): swap gha bot for cla allowlisted gemini-cli-robot (#5730) 2025-08-07 00:01:22 +00:00
Yiheng Xu
a09a9f2261
fix release.yml 2025-08-01 17:51:42 +08:00
Yiheng Xu
999f3af098
fix release workflow (#172) 2025-08-01 17:13:07 +08:00
koalazf.99
a9d6965bef pre-release commit 2025-07-22 23:26:01 +08:00
Pascal Birchler
ed00612cf7
chore: pin GitHub Actions to SHAs (#2987)
Co-authored-by: Jack Wotherspoon <jackwoth@google.com>
2025-07-11 16:46:06 +00:00
matt korwel
137ffec3f6
Fix nightly Release (#3511) 2025-07-08 06:41:39 +00:00
matt korwel
20825e4114
Release misc (#3418) 2025-07-07 03:16:42 +00:00
matt korwel
5c9372372c
cleaning up prompts for release (#3335) 2025-07-05 21:20:47 +00:00
matt korwel
a7256f630c
Relase: Clean up and condensing (#3321) 2025-07-05 20:58:59 +00:00