fix: harden lazycodex platform publishing

This commit is contained in:
YeonGyu-Kim
2026-05-31 00:42:14 +09:00
parent 3fed03d047
commit bcd9ae9901
6 changed files with 53 additions and 14 deletions
+2 -1
View File
@@ -368,6 +368,7 @@ jobs:
- name: Publish oh-my-opencode-${{ matrix.platform }} - name: Publish oh-my-opencode-${{ matrix.platform }}
if: steps.check.outputs.skip_opencode != 'true' && steps.download.outcome == 'success' if: steps.check.outputs.skip_opencode != 'true' && steps.download.outcome == 'success'
continue-on-error: true
env: env:
DIST_TAG: ${{ steps.validate.outputs.dist_tag }} DIST_TAG: ${{ steps.validate.outputs.dist_tag }}
NPM_CONFIG_PROVENANCE: true NPM_CONFIG_PROVENANCE: true
@@ -382,7 +383,7 @@ jobs:
timeout-minutes: 15 timeout-minutes: 15
- name: Publish oh-my-openagent-${{ matrix.platform }} - name: Publish oh-my-openagent-${{ matrix.platform }}
if: steps.check.outputs.skip_openagent != 'true' && steps.download.outcome == 'success' if: always() && steps.check.outputs.skip_openagent != 'true' && steps.download.outcome == 'success'
env: env:
DIST_TAG: ${{ steps.validate.outputs.dist_tag }} DIST_TAG: ${{ steps.validate.outputs.dist_tag }}
NPM_CONFIG_PROVENANCE: true NPM_CONFIG_PROVENANCE: true
+5 -1
View File
@@ -383,7 +383,11 @@ jobs:
jq --arg omo_version "$OMO_VERSION" ' jq --arg omo_version "$OMO_VERSION" '
.name = "lazycodex" | .name = "lazycodex" |
.version = $omo_version | .version = $omo_version |
.optionalDependencies = (.optionalDependencies | to_entries | map(.value = $omo_version) | from_entries) .optionalDependencies = (
.optionalDependencies | to_entries |
map(.key = (.key | sub("^oh-my-opencode-"; "oh-my-openagent-")) | .value = $omo_version) |
from_entries
)
' package.json > tmp.json && mv tmp.json package.json ' package.json > tmp.json && mv tmp.json package.json
if [ -n "$DIST_TAG" ]; then if [ -n "$DIST_TAG" ]; then
+1 -1
View File
@@ -147,7 +147,7 @@ async function writePlatformPackages(root: string): Promise<void> {
platform: process.platform, platform: process.platform,
arch: process.arch, arch: process.arch,
libcFamily: process.platform === "linux" ? "glibc" : undefined, libcFamily: process.platform === "linux" ? "glibc" : undefined,
packageBaseName: "oh-my-opencode", packageBaseName: "oh-my-openagent",
}); });
for (const packageName of packages) { for (const packageName of packages) {
const binaryPath = join(root, "node_modules", packageName, "bin", process.platform === "win32" ? "oh-my-opencode.exe" : "oh-my-opencode"); const binaryPath = join(root, "node_modules", packageName, "bin", process.platform === "win32" ? "oh-my-opencode.exe" : "oh-my-opencode");
+1 -1
View File
@@ -2,7 +2,7 @@
// Shared platform detection module - used by wrapper and postinstall // Shared platform detection module - used by wrapper and postinstall
const PLATFORM_PACKAGE_BASE_BY_WRAPPER_NAME = { const PLATFORM_PACKAGE_BASE_BY_WRAPPER_NAME = {
lazycodex: "oh-my-opencode", lazycodex: "oh-my-openagent",
}; };
export function getPackageBareName(packageName) { export function getPackageBareName(packageName) {
+4 -4
View File
@@ -22,7 +22,7 @@ describe("getPackageBareName", () => {
}); });
describe("resolvePlatformPackageBaseName", () => { describe("resolvePlatformPackageBaseName", () => {
test("maps lazycodex wrapper to oh-my-opencode platform package family", () => { test("maps lazycodex wrapper to oh-my-openagent platform package family", () => {
// #given // #given
const wrapperPackageName = "lazycodex"; const wrapperPackageName = "lazycodex";
@@ -30,10 +30,10 @@ describe("resolvePlatformPackageBaseName", () => {
const resolvedPlatformBase = resolvePlatformPackageBaseName(wrapperPackageName); const resolvedPlatformBase = resolvePlatformPackageBaseName(wrapperPackageName);
// #then // #then
expect(resolvedPlatformBase).toBe("oh-my-opencode"); expect(resolvedPlatformBase).toBe("oh-my-openagent");
}); });
test("maps scoped lazycodex wrapper to oh-my-opencode platform package family", () => { test("maps scoped lazycodex wrapper to oh-my-openagent platform package family", () => {
// #given // #given
const wrapperPackageName = "@code-yeongyu/lazycodex"; const wrapperPackageName = "@code-yeongyu/lazycodex";
@@ -41,7 +41,7 @@ describe("resolvePlatformPackageBaseName", () => {
const resolvedPlatformBase = resolvePlatformPackageBaseName(wrapperPackageName); const resolvedPlatformBase = resolvePlatformPackageBaseName(wrapperPackageName);
// #then // #then
expect(resolvedPlatformBase).toBe("oh-my-opencode"); expect(resolvedPlatformBase).toBe("oh-my-openagent");
}); });
test("keeps oh-my-opencode wrapper mapped to oh-my-opencode platform package family", () => { test("keeps oh-my-opencode wrapper mapped to oh-my-opencode platform package family", () => {
+40 -6
View File
@@ -134,6 +134,40 @@ describe("test workflows", () => {
expect(suppressesDownloadFailure, "missing required artifacts must fail the reusable publish workflow").toBe(false) expect(suppressesDownloadFailure, "missing required artifacts must fail the reusable publish workflow").toBe(false)
}) })
test("publishes openagent platform packages even when legacy opencode publish is unavailable", () => {
// #given
const workflow = readFileSync(publishPlatformWorkflowPath, "utf8")
// #when
const opencodePublishStep = sliceWorkflowSection(
workflow,
" - name: Publish oh-my-opencode-${{ matrix.platform }}",
" - name: Publish oh-my-openagent-${{ matrix.platform }}",
)
const openagentPublishStep = sliceWorkflowSection(
workflow,
" - name: Publish oh-my-openagent-${{ matrix.platform }}",
" timeout-minutes: 15",
)
// #then
expect(opencodePublishStep.includes("continue-on-error: true"), "legacy opencode package publish must not block renamed platform publish").toBe(true)
expect(openagentPublishStep.includes("if: always() && steps.check.outputs.skip_openagent != 'true' && steps.download.outcome == 'success'"), "renamed platform publish must run after legacy publish failures").toBe(true)
})
test("keeps the platform publish workflow step syntax valid around version updates", () => {
// #given
const workflow = readFileSync(publishPlatformWorkflowPath, "utf8")
// #when
const duplicateVersionStep = workflow.includes(
" - name: Update version in package.json\n - name: Update version in package.json",
)
// #then
expect(duplicateVersionStep, "platform publish workflow must not contain adjacent duplicate step names").toBe(false)
})
test("keeps the release tail safe to rerun after a tag exists", () => { test("keeps the release tail safe to rerun after a tag exists", () => {
// #given // #given
const workflow = readFileSync(publishWorkflowPath, "utf8") const workflow = readFileSync(publishWorkflowPath, "utf8")
@@ -216,17 +250,17 @@ describe("test workflows", () => {
!workflow.includes('LAZYCODEX_VERSION: "0.1.0"') && !workflow.includes('LAZYCODEX_VERSION: "0.1.0"') &&
workflow.includes(".name = \"lazycodex\" |") && workflow.includes(".name = \"lazycodex\" |") &&
workflow.includes(".version = $omo_version |") workflow.includes(".version = $omo_version |")
const lazycodexStepUsesOmoPlatformVersion = workflow.includes( const lazycodexStepUsesOpenagentPlatformVersion =
".optionalDependencies = (.optionalDependencies | to_entries | map(.value = $omo_version) | from_entries)", workflow.includes('sub("^oh-my-opencode-"; "oh-my-openagent-")') &&
) workflow.includes("map(.key = (.key | sub")
const lazycodexStepDoesNotRenameOptionalDeps = !workflow.includes('sub("^oh-my-opencode-"; "lazycodex-")') const lazycodexStepDoesNotRenameOptionalDeps = !workflow.includes('sub("^oh-my-opencode-"; "lazycodex-")')
const shimMapsLazycodexToPublishedPlatformFamily = const shimMapsLazycodexToPublishedPlatformFamily =
platformResolver.includes("lazycodex") && platformResolver.includes("oh-my-opencode") platformResolver.includes("lazycodex: \"oh-my-openagent\"")
// #then // #then
expect(lazycodexStepUsesReleaseVersion, "lazycodex publish step must use the release version so unpublished versions are not reused").toBe(true) expect(lazycodexStepUsesReleaseVersion, "lazycodex publish step must use the release version so unpublished versions are not reused").toBe(true)
expect(lazycodexStepUsesOmoPlatformVersion, "lazycodex must depend on the matching OMO platform packages").toBe(true) expect(lazycodexStepUsesOpenagentPlatformVersion, "lazycodex must depend on the matching oh-my-openagent platform packages").toBe(true)
expect(lazycodexStepDoesNotRenameOptionalDeps, "lazycodex publish step must keep optionalDependencies on published platform packages").toBe(true) expect(lazycodexStepDoesNotRenameOptionalDeps, "lazycodex publish step must keep optionalDependencies on published platform packages").toBe(true)
expect(shimMapsLazycodexToPublishedPlatformFamily, "platform resolver must map lazycodex to the real published platform package family").toBe(true) expect(shimMapsLazycodexToPublishedPlatformFamily, "platform resolver must map lazycodex to the oh-my-openagent platform package family").toBe(true)
}) })
}) })