From 99399f9c227487740309036394e597e862bbb0f6 Mon Sep 17 00:00:00 2001 From: Aikins Laryea Date: Sat, 31 Oct 2026 16:12:49 +0000 Subject: [PATCH] ci(sdk): fail npm tarballs with no export or bin targets, and print the counts release-artifact.sh now fails a packed manifest with neither exports nor bin, fails a pattern target with its own message, and prints each package's target count. The CI guard for an empty package list says why it failed. --- .github/scripts/release-artifact.sh | 10 +++++++++- .github/scripts/release_test.sh | 22 ++++++++++++++++++++-- .github/workflows/ci.yml | 5 ++++- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/.github/scripts/release-artifact.sh b/.github/scripts/release-artifact.sh index e57f6136..b77504ea 100755 --- a/.github/scripts/release-artifact.sh +++ b/.github/scripts/release-artifact.sh @@ -66,11 +66,19 @@ if [[ "$release_type" == node ]]; then # pnpm pack writes publishConfig.exports into exports. A missing target fails only on import. packed_files=$(tar -tf "$artifact") targets=$(jq -r '.exports, .bin | .. | strings' <<< "$metadata") + if [[ -z "$targets" ]]; then + echo "Packed $packed_name has no target in its exports or bin" >&2 + exit 1 + fi while IFS= read -r target; do - [[ -n "$target" ]] || continue + if [[ "$target" == *"*"* ]]; then + echo "Packed $packed_name has the pattern target $target, which this check cannot match" >&2 + exit 1 + fi if ! grep -Fxq "package/${target#./}" <<< "$packed_files"; then echo "Packed $packed_name has no $target, a target of its exports or bin" >&2 exit 1 fi done <<< "$targets" + echo "$packed_name: targets in exports and bin: $(wc -l <<< "$targets" | tr -d ' '), all in the tarball" fi diff --git a/.github/scripts/release_test.sh b/.github/scripts/release_test.sh index fd302028..dad0ccc3 100755 --- a/.github/scripts/release_test.sh +++ b/.github/scripts/release_test.sh @@ -275,7 +275,8 @@ expect_failure "Retry commit changes package.json outside packageManager" \ run_source workflow_dispatch refs/heads/main "$package_change_sha" mkdir -p "$tmp/archive/package" -printf '{"name":"@telemetry-dev/mcp","version":"0.1.1"}\n' > "$tmp/archive/package/package.json" +printf '{"name":"@telemetry-dev/mcp","version":"0.1.1","exports":{"./package.json":"./package.json"}}\n' \ + > "$tmp/archive/package/package.json" tar -czf "$tmp/mcp.tgz" -C "$tmp/archive" package printf '{"packages/mcp":"0.1.1"}\n' > "$repo/.release-please-manifest.json" ( @@ -291,7 +292,7 @@ expect_failure "Packed name @telemetry-dev/other does not match release name @te bash -c "cd '$repo' && '$artifact_script' packages/mcp '$tmp/wrong-name.tgz'" printf '{"packages/mcp":"0.1.1"}\n' > "$repo/.release-please-manifest.json" jq -n '{ - name: "@telemetry-dev/mcp", version: "0.1.1", bin: "dist/cli.mjs", + name: "@telemetry-dev/mcp", version: "0.1.1", bin: {mcp: "dist/cli.mjs"}, exports: {".": {types: "./dist/index.d.mts", import: "./dist/index.mjs"}, "./package.json": "./package.json"} }' > "$tmp/archive/package/package.json" for missing in none dist/index.d.mts dist/cli.mjs; do @@ -310,6 +311,23 @@ for missing in none dist/index.d.mts dist/cli.mjs; do bash -c "cd '$repo' && '$artifact_script' packages/mcp '$tmp/exports.tgz'" fi done +# A string bin is the other form of bin. +jq '.bin = "dist/cli.mjs"' "$tmp/archive/package/package.json" > "$tmp/bin.json" +mv "$tmp/bin.json" "$tmp/archive/package/package.json" +tar -czf "$tmp/exports.tgz" -C "$tmp/archive" package +expect_failure "dist/cli.mjs, a target of its exports or bin" \ + bash -c "cd '$repo' && '$artifact_script' packages/mcp '$tmp/exports.tgz'" +# A pattern target names no file, so the check cannot match it. +printf 'export {};\n' > "$tmp/archive/package/dist/cli.mjs" +jq '.exports["./*"] = "./dist/*.mjs"' "$tmp/archive/package/package.json" > "$tmp/pattern.json" +mv "$tmp/pattern.json" "$tmp/archive/package/package.json" +tar -czf "$tmp/exports.tgz" -C "$tmp/archive" package +expect_failure "Packed @telemetry-dev/mcp has the pattern target ./dist/*.mjs" \ + bash -c "cd '$repo' && '$artifact_script' packages/mcp '$tmp/exports.tgz'" +jq -n '{name: "@telemetry-dev/mcp", version: "0.1.1"}' > "$tmp/archive/package/package.json" +tar -czf "$tmp/exports.tgz" -C "$tmp/archive" package +expect_failure "Packed @telemetry-dev/mcp has no target in its exports or bin" \ + bash -c "cd '$repo' && '$artifact_script' packages/mcp '$tmp/exports.tgz'" rm -rf "$tmp/archive/package/dist" mkdir -p "$tmp/publish/npm" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3db575cd..d4855132 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,7 +41,10 @@ jobs: .packages | to_entries[] | select(.value["release-type"] == "node" and $manifest[0][.key] != null) | .key ' release-please-config.json) - [[ -n "$packages" ]] + if [[ -z "$packages" ]]; then + echo "No npm package in release-please-config.json has a release version" >&2 + exit 1 + fi while IFS= read -r package; do metadata=$(pnpm --dir "$package" pack --pack-destination "$output" --json) .github/scripts/release-artifact.sh "$package" "$(jq -r '.filename' <<< "$metadata")"