mirror of
https://github.com/zhu1090093659/dsh-web.git
synced 2026-09-28 14:24:03 +08:00
Move every family manifest, the plugin scaffold and the shared workspace package onto the 0.1.7-rc.2 cohort, together with the surfaces that state the same fact: - the dsh.engines.dsh floors and the matching @deepseek-ai/dsh host peers - the release-age exclusion ledger and the two packageExtensions keys - the root README badges, the CI/release mount-smoke pins and the docs/publish-prep.md and docs/plugins.md prose Two rc.2 facts were verified against the published artifacts rather than inferred from the version number: - the shell's frozen static module table is unchanged (the same nine specifiers in the dsh-web-frontend rc.2 dist bundle), so shared/web-platform.ts keeps its list and only its provenance comment moves; the new dsh-client-shortcuts is an ordinary client plugin, not a static module - @deepseek-ai/dsh-client-ui-primitives@0.1.7-rc.2 imports a further undeclared face, @deepseek-ai/dsh-util-code-language, so the primitives packageExtensions patch gains that pin The satellite peer floors in pnpm-lock.yaml still read >=0.1.7-rc.1: they belong to the satellite packages and move when those repositories release the aligned version.
232 lines
8.6 KiB
YAML
232 lines
8.6 KiB
YAML
name: Release
|
|
|
|
# Tag-triggered release pipeline: pushing a vX.Y.Z tag is the single release
|
|
# switch. The workflow verifies every package version equals the tag version
|
|
# (the tag is the version source of truth) and runs the full gate. The npm
|
|
# publish lane sits behind the NPM_PUBLISH_ENABLED switch (workflow env
|
|
# below): while it is 'false', a tag push stops at the mount smoke plus the
|
|
# GitHub Release and nothing reaches npm.
|
|
#
|
|
# The lane is enabled: the @deepseek-ai/* alpha.2 cohort the family tracks
|
|
# is published to npm (alpha dist-tag), so the family's @deepseek-ai/*
|
|
# dependency ranges resolve from the registry. With NPM_PUBLISH_ENABLED
|
|
# 'true', a tag push publishes every family package in dependency order and
|
|
# runs the post-publish strict-registry smoke assertion.
|
|
#
|
|
# Publishing requires the repository secret NPM_TOKEN (npm automation token
|
|
# for the @linxin666 scope).
|
|
|
|
on:
|
|
push:
|
|
tags:
|
|
- 'v*'
|
|
|
|
env:
|
|
# Single switch for the npm publish lane. Decision record:
|
|
# .agents/notes/implemented/process/2026-08-28-pause-release-npm-publish-unstable-dsh-alpha.md
|
|
NPM_PUBLISH_ENABLED: 'true'
|
|
|
|
permissions:
|
|
contents: write
|
|
|
|
concurrency:
|
|
group: release-${{ github.ref }}
|
|
cancel-in-progress: false
|
|
|
|
jobs:
|
|
publish:
|
|
name: Build, test, gated npm publish
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 45
|
|
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v5
|
|
with:
|
|
# Full history so scripts/release-notes.mjs can walk back to the
|
|
# previous v* tag and build the release notes commit range.
|
|
fetch-depth: 0
|
|
|
|
- name: Lint GitHub Actions workflows
|
|
uses: docker://rhysd/actionlint:latest
|
|
|
|
- name: Setup pnpm
|
|
uses: pnpm/action-setup@v5
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@v5
|
|
with:
|
|
node-version: 22
|
|
cache: pnpm
|
|
|
|
# --ignore-scripts: the consistency checks compare COMMITTED bundle
|
|
# artifacts against the committed sources; a fresh build embeds the
|
|
# checkout's absolute path into every bundle (CSS-module hashes and
|
|
# \0dsh-css region markers), so rebuilt bytes differ per machine. The
|
|
# explicit Build step still verifies everything builds.
|
|
|
|
- name: Install dependencies
|
|
run: pnpm install --frozen-lockfile --ignore-scripts
|
|
|
|
- name: Typecheck
|
|
run: pnpm typecheck
|
|
|
|
- name: Build
|
|
run: pnpm build
|
|
|
|
- name: Tests
|
|
run: pnpm test
|
|
|
|
- name: Script tests
|
|
run: pnpm test:scripts
|
|
|
|
- name: Aggregate package consistency
|
|
run: pnpm aggregate:check
|
|
|
|
# Publish-safety gate (issue #70 class): no published lib bundle may
|
|
# import a devDependencies-only package. Runs in CI on every PR; the
|
|
# tag pipeline must enforce it too, before anything reaches npm.
|
|
- name: Runtime dependency guard
|
|
run: pnpm runtime-deps:check
|
|
|
|
- name: Extract tag version
|
|
id: tag
|
|
run: echo "version=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Verify package versions match the tag
|
|
run: node scripts/verify-version.mjs "${{ steps.tag.outputs.version }}"
|
|
|
|
# Generated before publish: a notes failure must abort the run
|
|
# before anything reaches npm (a failed publish cannot be re-run
|
|
# for an already-published version).
|
|
#
|
|
# Bilingual convention (v0.2.6+): the maintainer commits the split-view
|
|
# notes at docs/release-notes/<tag>.md together with the release
|
|
# commit; the pipeline prefers that file. The notes show Chinese by
|
|
# default with the English version behind a <details> toggle. The
|
|
# scripts/release-notes.mjs draft (authored subjects in both views) is
|
|
# only a fallback when the committed file is missing.
|
|
- name: Generate release notes
|
|
run: |
|
|
NOTES_FILE="docs/release-notes/${GITHUB_REF_NAME}.md"
|
|
if [ -f "$NOTES_FILE" ]; then
|
|
cp "$NOTES_FILE" "$RUNNER_TEMP/release-notes.md"
|
|
else
|
|
node scripts/release-notes.mjs "$GITHUB_REF_NAME" > "$RUNNER_TEMP/release-notes.md"
|
|
fi
|
|
|
|
# Hand the notes to the release job (job 2): they must exist before
|
|
# anything downstream runs (a notes failure aborts the run), and the
|
|
# release job consumes them after the mount smoke.
|
|
- name: Upload release notes artifact
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: release-notes
|
|
path: ${{ runner.temp }}/release-notes.md
|
|
if-no-files-found: error
|
|
|
|
# Publish with the explicit "latest" dist-tag so that installing the
|
|
# package without a version (or with @latest) always resolves to the
|
|
# newest release, never a stale earlier one. Gated on the
|
|
# NPM_PUBLISH_ENABLED switch.
|
|
- name: Publish packages to npm
|
|
if: env.NPM_PUBLISH_ENABLED == 'true'
|
|
env:
|
|
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
run: |
|
|
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > ~/.npmrc
|
|
pnpm -r publish --no-git-checks --access public --registry=https://registry.npmjs.org/ --tag latest
|
|
|
|
# pnpm's per-package success lines are not a trust boundary: the
|
|
# registry can lag minutes behind a publish (v0.3.18) or lose a version
|
|
# silently, and the mount smoke's auto rewrite would paper over a
|
|
# missing family dependency with a workspace tarball. Assert every
|
|
# family version resolves from the registry, retrying propagation lag,
|
|
# before the mount smoke and the GitHub Release run.
|
|
- name: Verify published versions on the registry
|
|
if: env.NPM_PUBLISH_ENABLED == 'true'
|
|
run: node scripts/verify-registry.mjs "${{ steps.tag.outputs.version }}"
|
|
|
|
# Dual-publish the final legacy aggregate name for the transition
|
|
# window. The legacy tarball is derived from the fresh current package,
|
|
# carries the old browser loader id, and announces dsh.migrate so the
|
|
# plugin-manager and Doctor can migrate existing profiles automatically.
|
|
- name: Publish legacy aggregate package
|
|
if: env.NPM_PUBLISH_ENABLED == 'true'
|
|
env:
|
|
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
run: |
|
|
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > ~/.npmrc
|
|
node scripts/publish-legacy-aggregate.mjs "${{ steps.tag.outputs.version }}"
|
|
|
|
# The GitHub Release is created by the verify-release job only after
|
|
# the mount smoke passes; a failed smoke leaves the tag without a
|
|
# release for inspection instead of shipping a bad consumer path
|
|
# silently.
|
|
|
|
verify-release:
|
|
name: Mount smoke + GitHub Release
|
|
needs: publish
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 30
|
|
env:
|
|
DSH_TELEMETRY_DISABLED: '1'
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v5
|
|
|
|
- name: Setup pnpm
|
|
uses: pnpm/action-setup@v5
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@v5
|
|
with:
|
|
node-version: 22
|
|
cache: pnpm
|
|
|
|
- name: Install dependencies
|
|
run: pnpm install --frozen-lockfile --ignore-scripts
|
|
|
|
# Pin the DSH CLI the lane mounts into (same pin as ci.yml's
|
|
# plugin-mount lane).
|
|
- name: Install dsh CLI (pinned)
|
|
run: npm install -g @deepseek-ai/dsh@0.1.7-rc.2
|
|
|
|
# The aggregate tarball must be produced from a fresh build.
|
|
- name: Build
|
|
run: pnpm build
|
|
|
|
- name: Cache Playwright browsers
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: ~/.cache/ms-playwright
|
|
key: ${{ runner.os }}-playwright-${{ hashFiles('pnpm-lock.yaml') }}
|
|
|
|
- name: Install Playwright Chromium
|
|
timeout-minutes: 10
|
|
run: pnpm exec playwright install chromium
|
|
|
|
# The auto rewrite in scripts/e2e-mount-rewrite keeps the consumer
|
|
# assertion honest in both states: with the npm lane enabled every
|
|
# family dependency is published, so the tarball stays on the registry
|
|
# path (npm-strict consumer install); with the lane paused every packed
|
|
# version is unpublished, so each family dependency is packed from the
|
|
# workspace and installed as a file: tarball — the smoke then validates
|
|
# this tag's own builds.
|
|
- name: Mount + headless-render smoke
|
|
run: bash scripts/e2e-mount.sh
|
|
|
|
- name: Download release notes artifact
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
name: release-notes
|
|
path: ${{ runner.temp }}
|
|
|
|
- name: Create GitHub Release
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
run: |
|
|
gh release create "$GITHUB_REF_NAME" \
|
|
--notes-file "$RUNNER_TEMP/release-notes.md" \
|
|
--title "dsh-web $GITHUB_REF_NAME"
|