Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions .github/workflows/codra-cli-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep partial dry runs from requiring every binary

When publish=false (the default), resolve-matrix sets allow_partial=1, but this now still passes every selected platform into CODRA_EXPECT_PLATFORMS. scripts/pack-dry-run.js treats that variable as a hard required list, so a dry run with any missing/undownloaded artifact fails validation even though the workflow input explicitly says dry runs allow partial binaries by default; the previous expect_all_pack guard avoided that by only requiring the full list for non-partial publish runs.

Useful? React with 👍 / 👎.

run: npm run pack:dry

- name: Build npm tarball (no publish)
Expand All @@ -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
Expand Down
2 changes: 2 additions & 0 deletions packages/codra-npm-cli/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
artifacts/
scripts/
64 changes: 59 additions & 5 deletions packages/codra-npm-cli/scripts/build-platform-binaries.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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) {
Expand All @@ -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();
26 changes: 22 additions & 4 deletions packages/codra-npm-cli/scripts/prepack.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
5 changes: 5 additions & 0 deletions packages/codra-npm-cli/scripts/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
Loading