From f809f3213f0cbfcfaf858314ca4dd43c28448e9c Mon Sep 17 00:00:00 2001 From: root Date: Tue, 2 Jun 2026 21:05:46 +0000 Subject: [PATCH] fix(release): include all selected platform binaries in npm tarball --- .github/workflows/codra-cli-release.yml | 14 +++- packages/codra-npm-cli/.npmignore | 2 + .../scripts/build-platform-binaries.js | 64 +++++++++++++++++-- packages/codra-npm-cli/scripts/prepack.js | 26 ++++++-- packages/codra-npm-cli/scripts/test.js | 5 ++ 5 files changed, 100 insertions(+), 11 deletions(-) create mode 100644 packages/codra-npm-cli/.npmignore diff --git a/.github/workflows/codra-cli-release.yml b/.github/workflows/codra-cli-release.yml index 0b1ff83..896869f 100644 --- a/.github/workflows/codra-cli-release.yml +++ b/.github/workflows/codra-cli-release.yml @@ -134,19 +134,29 @@ jobs: CODRA_USE_ARTIFACTS: '1' CODRA_ARTIFACTS_DIR: ${{ github.workspace }}/packages/codra-npm-cli/artifacts CODRA_ALLOW_PARTIAL_BINARIES: ${{ needs.resolve-matrix.outputs.allow_partial }} + CODRA_EXPECT_PLATFORMS: ${{ needs.resolve-matrix.outputs.expected_platforms }} run: npm run build:from-artifacts - name: Test npm wrapper working-directory: packages/codra-npm-cli + env: + CODRA_USE_ARTIFACTS: '1' run: npm test + - name: List release packaging inputs + run: | + echo "artifacts download path:" + find packages/codra-npm-cli/artifacts -maxdepth 3 -type f -print || true + echo "bin/native before pack:" + find packages/codra-npm-cli/bin/native -maxdepth 3 -type f -print || true + - name: Validate npm pack contents working-directory: packages/codra-npm-cli env: CODRA_USE_ARTIFACTS: '1' CODRA_ARTIFACTS_DIR: ${{ github.workspace }}/packages/codra-npm-cli/artifacts CODRA_ALLOW_PARTIAL_BINARIES: ${{ needs.resolve-matrix.outputs.allow_partial }} - CODRA_EXPECT_PLATFORMS: ${{ needs.resolve-matrix.outputs.expect_all_pack == '1' && needs.resolve-matrix.outputs.expected_platforms || '' }} + CODRA_EXPECT_PLATFORMS: ${{ needs.resolve-matrix.outputs.expected_platforms }} run: npm run pack:dry - name: Build npm tarball (no publish) @@ -155,7 +165,7 @@ jobs: CODRA_USE_ARTIFACTS: '1' CODRA_ARTIFACTS_DIR: ${{ github.workspace }}/packages/codra-npm-cli/artifacts CODRA_ALLOW_PARTIAL_BINARIES: ${{ needs.resolve-matrix.outputs.allow_partial }} - CODRA_EXPECT_PLATFORMS: ${{ needs.resolve-matrix.outputs.expect_all_pack == '1' && needs.resolve-matrix.outputs.expected_platforms || '' }} + CODRA_EXPECT_PLATFORMS: ${{ needs.resolve-matrix.outputs.expected_platforms }} run: npm pack - name: Upload npm tarball artifact diff --git a/packages/codra-npm-cli/.npmignore b/packages/codra-npm-cli/.npmignore new file mode 100644 index 0000000..d23c823 --- /dev/null +++ b/packages/codra-npm-cli/.npmignore @@ -0,0 +1,2 @@ +artifacts/ +scripts/ \ No newline at end of file diff --git a/packages/codra-npm-cli/scripts/build-platform-binaries.js b/packages/codra-npm-cli/scripts/build-platform-binaries.js index 015c240..d8dce0f 100644 --- a/packages/codra-npm-cli/scripts/build-platform-binaries.js +++ b/packages/codra-npm-cli/scripts/build-platform-binaries.js @@ -23,26 +23,70 @@ function allowPartial() { return process.env.CODRA_ALLOW_PARTIAL_BINARIES === '1'; } +function selectedTargets() { + const expect = process.env.CODRA_EXPECT_PLATFORMS; + if (!expect) { + return TARGETS; + } + + const keys = expect + .split(',') + .map((key) => key.trim()) + .filter(Boolean); + const selected = TARGETS.filter((target) => keys.includes(target.key)); + if (selected.length === 0) { + console.error('[build:from-artifacts] CODRA_EXPECT_PLATFORMS did not match any known targets'); + process.exit(1); + } + return selected; +} + +function resolveArtifactPath(srcDir, artifactName) { + const direct = path.join(srcDir, artifactName); + if (fs.existsSync(direct)) { + const stat = fs.statSync(direct); + if (stat.isFile()) { + return direct; + } + if (stat.isDirectory()) { + const nested = path.join(direct, artifactName); + if (fs.existsSync(nested) && fs.statSync(nested).isFile()) { + return nested; + } + const nestedBin = path.join(direct, path.basename(artifactName, path.extname(artifactName))); + if (fs.existsSync(nestedBin) && fs.statSync(nestedBin).isFile()) { + return nestedBin; + } + } + } + + return null; +} + function main() { const srcDir = artifactsDir(); const partial = allowPartial(); + const targets = selectedTargets(); const missing = []; const packaged = []; console.log(`[build:from-artifacts] artifacts dir: ${srcDir}`); console.log(`[build:from-artifacts] partial packaging: ${partial ? 'yes' : 'no'}`); + console.log( + `[build:from-artifacts] selected targets: ${targets.map((target) => target.key).join(', ')}`, + ); if (!fs.existsSync(srcDir)) { console.error(`[build:from-artifacts] artifacts directory not found: ${srcDir}`); process.exit(1); } - for (const target of TARGETS) { - const src = path.join(srcDir, target.artifact); + for (const target of targets) { + const src = resolveArtifactPath(srcDir, target.artifact); const destDir = path.join(packageRoot, 'bin', 'native', target.key); const dest = path.join(destDir, target.destName); - if (!fs.existsSync(src)) { + if (!src) { missing.push(target.artifact); continue; } @@ -64,7 +108,7 @@ function main() { if (missing.length > 0) { console.error('[build:from-artifacts] missing artifacts:'); for (const name of missing) { - console.error(` - ${path.join(srcDir, name)}`); + console.error(` - ${name}`); } if (!partial) { @@ -80,7 +124,17 @@ function main() { process.exit(1); } - console.log(`[build:from-artifacts] packaged ${packaged.length}/${TARGETS.length} targets`); + const requiredCount = partial ? packaged.length : targets.length; + if (!partial && packaged.length !== targets.length) { + console.error( + `[build:from-artifacts] expected ${targets.length} binaries, packaged ${packaged.length}`, + ); + process.exit(1); + } + + console.log( + `[build:from-artifacts] packaged ${packaged.length}/${targets.length} selected targets (required ${requiredCount})`, + ); } main(); \ No newline at end of file diff --git a/packages/codra-npm-cli/scripts/prepack.js b/packages/codra-npm-cli/scripts/prepack.js index 06517e1..0e79d64 100644 --- a/packages/codra-npm-cli/scripts/prepack.js +++ b/packages/codra-npm-cli/scripts/prepack.js @@ -45,18 +45,36 @@ function installedNativePlatformKeys() { }); } +function expectedPlatformKeys() { + if (!process.env.CODRA_EXPECT_PLATFORMS) { + return []; + } + + return process.env.CODRA_EXPECT_PLATFORMS.split(',') + .map((key) => key.trim()) + .filter(Boolean); +} + +function hasExpectedNativeBinaries() { + const expected = expectedPlatformKeys(); + const installed = installedNativePlatformKeys(); + if (expected.length === 0) { + return installed.length > 0; + } + return expected.every((key) => installed.includes(key)); +} + function shouldSkipArtifactRebuild() { if (!shouldUseArtifacts()) { return false; } - const installed = installedNativePlatformKeys(); - if (installed.length === 0) { + if (installedNativePlatformKeys().length === 0) { return false; } - // CI already ran build:from-artifacts; avoid a strict second pass during partial dry runs. - if (process.env.CODRA_ALLOW_PARTIAL_BINARIES === '1') { + // CI already ran build:from-artifacts; skip only when every expected selected platform is present. + if (process.env.CODRA_ALLOW_PARTIAL_BINARIES === '1' && hasExpectedNativeBinaries()) { return true; } diff --git a/packages/codra-npm-cli/scripts/test.js b/packages/codra-npm-cli/scripts/test.js index a15bef1..708db6f 100644 --- a/packages/codra-npm-cli/scripts/test.js +++ b/packages/codra-npm-cli/scripts/test.js @@ -82,6 +82,11 @@ function testPlatformHelpers() { } function testArtifactPackaging() { + if (process.env.CODRA_USE_ARTIFACTS === '1') { + console.log('[test] skip artifact packaging layout test (release artifact mode)'); + return; + } + const tmpArtifacts = fs.mkdtempSync(path.join(os.tmpdir(), 'codra-artifacts-')); const hostBinary = lib.resolveNativeBinary();