Kaynağa Gözat

Merge pull request #2446 from deepseek-harness/fix/vendor-release-bump-all

Release: vendor@4.0.1-rc.3
imccyu 1 ay önce
ebeveyn
işleme
76be2ef4dc

+ 24 - 54
scripts/release/bump.ts

@@ -5,9 +5,10 @@
  *
  * The dsh family shares one version across its members and the workspace root:
  * `major`, `minor`, `patch`, or an explicit `x.y.z` (including a prerelease such
- * as `0.0.1-rc.1`). The vendored family has one version line per package and
- * publishes only what changed since that package's own `vendor-<package>-v*`
- * tag, which is the record of the commit it last published from.
+ * as `0.0.1-rc.1`). The vendored family has one version line per package, but
+ * every release advances and publishes the complete family so the next release
+ * never reuses an unchanged member's existing version from a different
+ * repository state.
  *
  * The version lands in the manifests, the lockfile follows, and a human creates
  * the tag after the commit merges. CI never writes to the repository.
@@ -17,7 +18,7 @@ import { readFileSync, writeFileSync } from 'node:fs'
 import { join, matchesGlob } from 'node:path'
 import { parseArgs } from 'node:util'
 import { releaseFamily, type ReleaseFamily, type ReleaseMember } from './families.ts'
-import { attempt, capture, isEntry } from './process.ts'
+import { capture, isEntry } from './process.ts'
 
 /** Files npm publishes whether or not `files` lists them. */
 const ALWAYS_PUBLISHED = ['package.json', 'README*', 'LICENSE*', 'LICENCE*'] as const
@@ -144,30 +145,33 @@ function nextSharedVersion(current: string, request: string): string {
 /**
  * The version a vendored package publishes next.
  *
- * The baseline is the higher of the manifest version and the last published
+ * The baseline is the higher of the manifest version and the last tagged
  * version: a vendor re-sync restores upstream's version, which is lower than
- * what this repository already published, and incrementing that would name a
- * version the registry already carries.
+ * the release version this repository already reserved, and incrementing that
+ * would reuse an existing version.
  *
  * A prerelease does not consume its own release numbers. Publishing
  * `4.0.1-rc.1` leaves `4.0.1` free, so the next stable version is `4.0.1`
  * rather than `4.0.2`, and a second prerelease keeps those numbers too.
  * @param current - the package's manifest version.
- * @param published - the version its newest tag names, when it has one.
+ * @param tagged - the version its newest tag names, when it has one.
  * @param prerelease - prerelease identifier to append, for a rehearsal publication.
  * @returns The target version.
  */
 export function nextVendorVersion(
   current: string,
-  published: string | undefined,
+  tagged: string | undefined,
   prerelease?: string,
 ): string {
-  const ahead = published !== undefined && compareReleaseNumbers(published, current) > 0
-  const baseline = ahead ? published : current
+  const taggedOrder = tagged === undefined ? undefined : compareReleaseNumbers(tagged, current)
+  const ahead = taggedOrder !== undefined && taggedOrder > 0
+  const baseline = ahead ? tagged : current
   const [major, minor, patch] = releaseNumbers(baseline)
-  // Reuse the numbers when the published version that set them is a prerelease
+  // Reuse the numbers when the tagged version that set them is a prerelease
   // of them; increment when a stable release already holds them.
-  const reuse = ahead && published.includes('-')
+  const taggedPrerelease = tagged !== undefined && prereleaseOf(tagged) !== undefined
+  const sameReleasePrereleases = taggedOrder === 0 && prereleaseOf(current) !== undefined
+  const reuse = taggedPrerelease && (ahead || sameReleasePrereleases)
   const numbers = reuse
     ? `${String(major)}.${String(minor)}.${String(patch)}`
     : `${String(major)}.${String(minor)}.${String(patch + 1)}`
@@ -191,12 +195,12 @@ export function reachesPayload(member: ReleaseMember, path: string): boolean {
 }
 
 /**
- * The newest version a member published, read from its tags.
+ * The newest version a member tagged.
  * @param family - the member's family.
  * @param member - the member.
- * @returns The version, or undefined when the member never published.
+ * @returns The version, or undefined when the member has no release tag.
  */
-function lastPublishedVersion(family: ReleaseFamily, member: ReleaseMember): string | undefined {
+function lastTaggedVersion(family: ReleaseFamily, member: ReleaseMember): string | undefined {
   const prefix = family.tagPrefixFor(member)
   const versions = capture('git', ['tag', '--list', `${prefix}*`])
     .split('\n').filter(line => line !== '').map(tag => tag.slice(prefix.length))
@@ -204,33 +208,6 @@ function lastPublishedVersion(family: ReleaseFamily, member: ReleaseMember): str
   return versions.reduce((newest, candidate) => compareVersions(candidate, newest) > 0 ? candidate : newest)
 }
 
-/**
- * Confirm the registry carries the version a tag names.
- *
- * A tag is a commit pointer, not proof of publication: a tag pushed for a
- * publication that then failed would otherwise read as "already published" and
- * skip the package indefinitely. Querying a private package needs credentials,
- * so an unauthenticated machine reports the gap instead of failing.
- * @param name - package name.
- * @param version - the version the tag names.
- */
-function confirmPublished(name: string, version: string): void {
-  const result = attempt('npm', ['view', `${name}@${version}`, 'version'])
-  if (result.status === 0) return
-  const output = `${result.stdout}${result.stderr}`
-  if (output.includes('ENEEDAUTH') || output.includes('E401') || output.includes('E403')) {
-    console.log(`release bump: cannot reach the registry for ${name}@${version}; skipping the tag check`)
-    return
-  }
-  if (output.includes('E404') || output.includes('404 Not Found')) {
-    throw new Error(
-      `${name}@${version} is tagged but absent from the registry.`
-      + '\nThe tag was pushed for a publication that did not complete: re-run that publish, or delete the tag.',
-    )
-  }
-  throw new Error(`npm view ${name}@${version} failed:\n${output}`)
-}
-
 /**
  * Write a version into a manifest, preserving formatting and key order.
  * @param root - repository root.
@@ -293,8 +270,8 @@ function planShared(
 }
 
 /**
- * Plan the vendored family's rewrite: every package whose payload changed since
- * it last published.
+ * Plan the vendored family's rewrite: every package advances together while
+ * retaining its own version line and tag.
  * @param family - the vendored family.
  * @param members - the family's members.
  * @param prerelease - prerelease identifier to append, for a rehearsal publication.
@@ -307,15 +284,8 @@ function planPerPackage(
 ): PlannedVersion[] {
   const planned: PlannedVersion[] = []
   for (const member of members) {
-    const published = lastPublishedVersion(family, member)
-    if (published !== undefined) {
-      confirmPublished(member.name, published)
-      const since = `${family.tagPrefixFor(member)}${published}`
-      const changed = capture('git', ['diff', '--name-only', `${since}..HEAD`, '--', member.directory])
-        .split('\n').filter(line => line !== '')
-      if (!changed.some(path => reachesPayload(member, path))) continue
-    }
-    const to = nextVendorVersion(member.version, published, prerelease)
+    const tagged = lastTaggedVersion(family, member)
+    const to = nextVendorVersion(member.version, tagged, prerelease)
     planned.push({
       manifestPath: join(member.directory, 'package.json'),
       label: member.directory,

+ 1 - 1
vendor/cordis/package.json

@@ -1,7 +1,7 @@
 {
   "name": "@deepseek-ai/cordis",
   "description": "Meta-Framework for Modern JavaScript Applications",
-  "version": "4.0.1-rc.1",
+  "version": "4.0.1-rc.3",
   "publishConfig": {
     "access": "restricted"
   },

+ 1 - 1
vendor/cosmokit/package.json

@@ -1,7 +1,7 @@
 {
   "name": "@deepseek-ai/cosmokit",
   "description": "A collection of common utilities",
-  "version": "1.8.2-rc.1",
+  "version": "1.8.2-rc.3",
   "publishConfig": {
     "access": "restricted"
   },

+ 1 - 1
vendor/group/package.json

@@ -1,7 +1,7 @@
 {
   "name": "@deepseek-ai/cordis-plugin-group",
   "description": "Nested plugin group for cordis",
-  "version": "1.0.1-rc.1",
+  "version": "1.0.1-rc.3",
   "publishConfig": {
     "access": "restricted"
   },

+ 1 - 1
vendor/hmr/package.json

@@ -1,7 +1,7 @@
 {
   "name": "@deepseek-ai/cordis-plugin-hmr",
   "description": "Hot Module Replacement Plugin for Cordis",
-  "version": "1.0.16-rc.1",
+  "version": "1.0.16-rc.3",
   "publishConfig": {
     "access": "restricted"
   },

+ 1 - 1
vendor/include/package.json

@@ -1,7 +1,7 @@
 {
   "name": "@deepseek-ai/cordis-plugin-include",
   "description": "Include files in cordis configurations",
-  "version": "1.0.6-rc.2",
+  "version": "1.0.6-rc.3",
   "publishConfig": {
     "access": "restricted"
   },

+ 1 - 1
vendor/loader/package.json

@@ -1,7 +1,7 @@
 {
   "name": "@deepseek-ai/cordis-plugin-loader",
   "description": "Plugin loader for cordis",
-  "version": "1.0.2-rc.2",
+  "version": "1.0.2-rc.3",
   "publishConfig": {
     "access": "restricted"
   },

+ 1 - 1
vendor/logger-console/package.json

@@ -1,7 +1,7 @@
 {
   "name": "@deepseek-ai/cordis-plugin-logger-console",
   "description": "Console logger exporter for cordis",
-  "version": "1.0.1-rc.1",
+  "version": "1.0.1-rc.3",
   "publishConfig": {
     "access": "restricted"
   },

+ 1 - 1
vendor/schemastery/package.json

@@ -1,7 +1,7 @@
 {
   "name": "@deepseek-ai/schemastery",
   "description": "Type driven schema validator",
-  "version": "3.18.1-rc.1",
+  "version": "3.18.1-rc.3",
   "publishConfig": {
     "access": "restricted"
   },

+ 1 - 1
vendor/timer/package.json

@@ -1,7 +1,7 @@
 {
   "name": "@deepseek-ai/cordis-plugin-timer",
   "description": "Timer service for cordis",
-  "version": "1.1.3-rc.1",
+  "version": "1.1.3-rc.3",
   "publishConfig": {
     "access": "restricted"
   },