name: v8 Release on: push: tags: ['scriptor-v*'] permissions: contents: read concurrency: group: v8-release-${{ github.ref }} cancel-in-progress: false jobs: release: runs-on: windows-latest timeout-minutes: 50 permissions: contents: write env: RELEASE_TAG: ${{ github.ref_name }} steps: - name: Check out with repository line endings only run: git config --global core.autocrlf false - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 with: fetch-depth: 0 persist-credentials: false - name: Tag belongs to accepted public v8 shell: bash run: git merge-base --is-ancestor HEAD origin/v8 - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4 with: version: 11.27.1 - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: '24.15.0' cache: pnpm - run: pnpm install --frozen-lockfile - run: pnpm check:version - run: pnpm audit --audit-level=high - run: pnpm lint - run: pnpm test:release - run: pnpm test - run: pnpm -r --workspace-concurrency=1 test - run: pnpm release:build -- --out .tmp/release - name: Install the exact release assets into a clean host run: | # 以构建清单为准定位主包与可选包;glob 会把 *-full-*.tgz 误并入主包位置。 $manifest = Get-Content .tmp/release/release-manifest.json -Raw | ConvertFrom-Json $mainPackage = Join-Path .tmp/release $manifest.filename $embeddingTarball = ($manifest.optionalPackages | Where-Object { $_.name -eq 'webnovel-embedding-provider' }).tarball if (-not $embeddingTarball) { throw 'Embedding package missing from release manifest' } $embeddingPackage = Join-Path .tmp/release $embeddingTarball $metaTarball = ($manifest.optionalPackages | Where-Object { $_.name -eq '@linfengqaqtat/dsh-scriptor-full' }).tarball if (-not $metaTarball) { throw 'Full package missing from release manifest' } $metaPackage = Join-Path .tmp/release $metaTarball pnpm release:smoke -- $mainPackage $embeddingPackage $metaPackage if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } - name: Validate npm publish inputs without publishing run: node scripts/release/publish-npm.mjs --assets .tmp/release - name: Create a draft; never replace an existing release env: GH_TOKEN: ${{ github.token }} run: | gh release view $env:RELEASE_TAG *> $null if ($LASTEXITCODE -eq 0) { throw 'Release already exists; inspect it without overwriting its assets.' } $manifest = Get-Content .tmp/release/release-manifest.json -Raw | ConvertFrom-Json $releaseArgs = @('release', 'create', $env:RELEASE_TAG, '--verify-tag', '--draft', '--latest=false', '--title', "DSH Scriptor · v8 · $($manifest.version)", '--notes-file', '.tmp/release/release-notes.md') if ($manifest.prerelease) { $releaseArgs += '--prerelease' } $releaseArgs += Get-ChildItem .tmp/release -File | Where-Object Name -ne 'release-notes.md' | Select-Object -ExpandProperty FullName & gh @releaseArgs if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }