Files
workdsh/.github/workflows/ci.yml
T

328 lines
13 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
name: CI
on:
pull_request:
branches: [main]
push:
branches: [main]
tags: ['desktop-v*']
workflow_dispatch:
permissions:
contents: read
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
DSH_TELEMETRY_DISABLED: '1'
jobs:
# Keep required checks conclusive for documentation-only changes. Workflow
# path filters can leave required checks pending, so classify inside the run.
changes:
runs-on: ubuntu-latest
outputs:
product: ${{ steps.scope.outputs.product }}
desktop: ${{ steps.scope.outputs.desktop }}
web: ${{ steps.scope.outputs.web }}
steps:
- uses: actions/checkout@v6
with:
# GitHub's pull-request merge ref can retain the base branch's
# submodule gitlink when the PR advances it to a descendant. Check
# out the actual PR head so pinned submodules match upstream.json.
ref: ${{ github.event.pull_request.head.sha || github.sha }}
fetch-depth: 0
persist-credentials: false
- uses: actions/setup-node@v6
with:
node-version: 22.23.2
- name: Classify changed paths
id: scope
shell: bash
env:
EVENT_NAME: ${{ github.event_name }}
REF_TYPE: ${{ github.ref_type }}
BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.before }}
HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
run: |
set -euo pipefail
node --test scripts/bilingual-docs.test.mjs
node scripts/verify-bilingual-docs.mjs
if [[ "$EVENT_NAME" == "workflow_dispatch" || "$REF_TYPE" == "tag" ]]; then
product=true
desktop=true
web=false
elif [[ -z "$BASE_SHA" || "$BASE_SHA" =~ ^0+$ ]]; then
product=true
desktop=true
web=true
else
git diff --check "$BASE_SHA" "$HEAD_SHA"
product="$(git diff --name-only -z "$BASE_SHA" "$HEAD_SHA" | node scripts/classify-ci-changes.mjs)"
changed_paths="$(git diff --name-only "$BASE_SHA" "$HEAD_SHA")"
if [[ -n "$changed_paths" ]] && grep -q '^workdsh-web/' <<< "$changed_paths"; then web=true; else web=false; fi
if [[ -n "$changed_paths" ]] && grep -qv '^workdsh-web/' <<< "$changed_paths"; then desktop=true; else desktop=false; fi
fi
echo "product=$product" >> "$GITHUB_OUTPUT"
echo "desktop=$desktop" >> "$GITHUB_OUTPUT"
echo "web=$web" >> "$GITHUB_OUTPUT"
# Full product gate: build, typecheck, unit tests, and every headless smoke.
# A documentation-only change already passed diff validation in `changes`.
check:
needs: changes
runs-on: ubuntu-latest
steps:
- name: Documentation-only gate
if: needs.changes.outputs.product == 'false'
run: echo "Documentation-only change; product build and tests are not required."
- uses: actions/checkout@v6
if: needs.changes.outputs.product == 'true'
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
persist-credentials: false
submodules: recursive
- uses: actions/setup-node@v6
if: needs.changes.outputs.product == 'true'
with:
node-version: 22.23.2
- if: needs.changes.outputs.product == 'true'
run: corepack enable
- name: Resolve Yarn cache folder
if: needs.changes.outputs.product == 'true'
id: yarn-cache
run: echo "dir=$(yarn config get cacheFolder)" >> "$GITHUB_OUTPUT"
- uses: actions/cache@v6
if: needs.changes.outputs.product == 'true'
with:
path: ${{ steps.yarn-cache.outputs.dir }}
key: yarn-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('yarn.lock', '.yarnrc.yml') }}
- if: needs.changes.outputs.product == 'true'
run: yarn install --immutable
- if: needs.changes.outputs.product == 'true'
run: yarn check
web-source-check:
name: Web source checks (no installer)
needs: changes
if: needs.changes.outputs.web == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
persist-credentials: false
- uses: actions/setup-node@v6
with:
node-version: 22.23.2
- run: corepack enable
- working-directory: workdsh-web
run: pnpm install --frozen-lockfile
- working-directory: workdsh-web
run: pnpm build
- working-directory: workdsh-web
run: pnpm typecheck
- working-directory: workdsh-web
run: pnpm check:versions
- name: Install browser for Web integration tests
working-directory: workdsh-web
run: pnpm exec playwright install --with-deps chromium
- working-directory: workdsh-web
run: pnpm test:integration
# Windows-only logic and unsigned NSIS build on a real Windows runner:
# updates, window options, pwsh sandbox, volume diagnostics, and packaging.
# The package gate runs once before packaging.
desktop-windows:
needs: changes
if: needs.changes.outputs.desktop == 'true'
runs-on: windows-latest
steps:
- uses: actions/checkout@v6
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
persist-credentials: false
submodules: recursive
- uses: actions/setup-node@v6
with:
node-version: 22.23.2
- run: corepack enable
- name: Resolve Yarn cache folder
id: yarn-cache
run: echo "dir=$(yarn config get cacheFolder)" >> "$env:GITHUB_OUTPUT"
- uses: actions/cache@v6
with:
path: ${{ steps.yarn-cache.outputs.dir }}
key: yarn-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('yarn.lock', '.yarnrc.yml') }}
- run: yarn install --immutable
- run: yarn upstream:install
- run: yarn workspace dsh-plugin-desktop check:win-package
- name: Prepare WorkDSH release profile
timeout-minutes: 15
run: yarn workspace dsh-plugin-desktop prepare:workdsh-runtime
- name: Prepare official Python and Node runtime
timeout-minutes: 15
run: yarn workspace dsh-plugin-desktop prepare:workdsh-primary-runtime
- name: Build Windows installer
timeout-minutes: 30
env:
DSH_PACKAGE_CHECK_ALREADY_RAN: '1'
run: node dsh-plugin-desktop/scripts/package-win.ts
- name: Report unpacked Windows footprint
run: node dsh-plugin-desktop/scripts/report-package-footprint.mjs dsh-plugin-desktop/dist/win-unpacked dsh-plugin-desktop/dist/windows-footprint.json
- name: Upload Windows footprint report
uses: actions/upload-artifact@v4
with:
name: desktop-footprint-windows-x64
path: dsh-plugin-desktop/dist/windows-footprint.json
if-no-files-found: error
retention-days: 14
- name: Upload Windows installer
uses: actions/upload-artifact@v4
with:
name: dsh-plugin-desktop-windows-x64
path: |
dsh-plugin-desktop/dist/*.exe
dsh-plugin-desktop/dist/*.blockmap
if-no-files-found: error
retention-days: 14
# Per-architecture macOS packaging smoke on a real macOS runner: the signed
# release is built manually on a credentialed machine, so an unsigned DMG
# here catches Intel and Apple Silicon packaging regressions before a manual
# release. No signing secrets ever reach this job.
desktop-macos:
needs: changes
if: needs.changes.outputs.desktop == 'true'
runs-on: macos-latest
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
arch: [x64, arm64]
steps:
- uses: actions/checkout@v6
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
persist-credentials: false
submodules: recursive
- uses: actions/setup-node@v6
with:
node-version: 22.23.2
- run: corepack enable
- name: Resolve Yarn cache folder
id: yarn-cache
run: echo "dir=$(yarn config get cacheFolder)" >> "$GITHUB_OUTPUT"
- uses: actions/cache@v6
with:
path: ${{ steps.yarn-cache.outputs.dir }}
key: yarn-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('yarn.lock', '.yarnrc.yml') }}
- run: yarn install --immutable
- run: yarn upstream:install
- run: yarn workspace dsh-plugin-desktop check:mac-package
- name: Prepare WorkDSH release profile
timeout-minutes: 15
env:
WORKDSH_MAC_ARCH: ${{ matrix.arch }}
run: yarn workspace dsh-plugin-desktop prepare:workdsh-runtime
- name: Prepare official Python and Node runtime
timeout-minutes: 15
env:
WORKDSH_MAC_ARCH: ${{ matrix.arch }}
run: yarn workspace dsh-plugin-desktop prepare:workdsh-primary-runtime
- name: Build macOS smoke artifact
timeout-minutes: 25
env:
DSH_PACKAGE_CHECK_ALREADY_RAN: '1'
WORKDSH_MAC_ARCH: ${{ matrix.arch }}
run: node dsh-plugin-desktop/scripts/package-mac.ts
- name: Upload macOS architecture DMG
uses: actions/upload-artifact@v4
with:
name: dsh-plugin-desktop-macos-${{ matrix.arch }}
path: |
dsh-plugin-desktop/dist/mac-smoke/${{ matrix.arch }}/*.dmg
dsh-plugin-desktop/dist/mac-smoke/${{ matrix.arch }}/*.dmg.blockmap
if-no-files-found: error
retention-days: 14
# Upstream toolchain smoke: the portable-shell scripts must resolve the
# pinned submodule's own Yarn/pnpm release on Windows.
upstream-command-windows:
needs: changes
if: needs.changes.outputs.desktop == 'true'
runs-on: windows-latest
steps:
- uses: actions/checkout@v6
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
persist-credentials: false
submodules: recursive
- uses: actions/setup-node@v6
with:
node-version: 22.23.2
- run: corepack enable
- run: yarn check:layout
- run: yarn upstream:version
publish-desktop-release:
if: github.ref_type == 'tag' && startsWith(github.ref_name, 'desktop-v')
needs: [check, desktop-windows, desktop-macos, upstream-command-windows]
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v6
with:
submodules: recursive
persist-credentials: false
- uses: actions/setup-node@v6
with:
node-version: 22.23.2
- name: Require one DSH version before publication
run: node scripts/verify-desktop-dsh-alignment.mjs
- name: Download desktop packages
uses: actions/download-artifact@v5
with:
pattern: dsh-plugin-desktop-*
path: staging
- name: Prepare uniquely named release assets
shell: bash
run: |
set -euo pipefail
mkdir release-assets
while IFS= read -r -d '' file; do
artifact="$(basename "$(dirname "$file")")"
name="$(basename "$file")"
cp "$file" "release-assets/${artifact}--${name}"
done < <(find staging -type f -print0)
(cd release-assets && sha256sum -- * > SHA256SUMS)
- name: Publish GitHub prerelease
env:
GH_TOKEN: ${{ github.token }}
TAG: ${{ github.ref_name }}
shell: bash
run: |
VERSION="${TAG#desktop-v}"
cat > release-notes.md <<'EOF'
WorkDSH Desktop 提供 Windows x64 安装版和 macOS Intel x64 与 Apple Silicon arm64 独立 DMG。
- 桌面产品名称统一为 WorkDSH
- 安装包内置完整 WorkDSH 运行时,启动后可直接使用项目、资料库、专家、技能和连接器
- 内置 Node 和 Python;Agent 使用 Playwright 浏览网页时,可在同一会话的右侧栏查看并操作页面
- 应用、Dock、托盘和安装包图标统一为 WorkDSH 蓝色 W 标识
- README 包含项目、资料库和桌面端下载说明
- Windows 包在原生 Windows Runner 构建和验证
- macOS 分别提供 Intel x64 和 Apple Silicon arm64 未签名预览包
这是 Alpha 预发布。请在升级前备份本地配置和数据;未签名包可能触发系统安全提示。所有文件的 SHA-256 见 `SHA256SUMS`。
EOF
gh release create "$TAG" release-assets/* \
--repo "$GITHUB_REPOSITORY" \
--title "WorkDSH Desktop ${VERSION}" \
--notes-file release-notes.md \
--prerelease