From 3e5f622e7ffe41cdc6f5e9acd0e8ed295ae18607 Mon Sep 17 00:00:00 2001 From: Chidi Williams Date: Thu, 6 Aug 2026 23:18:27 -0400 Subject: [PATCH] Read the tarball instead of parsing npm pack --json MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The v0.1.1 release has failed twice at this step. The second run took 23s and ended with "Cannot read properties of undefined (reading 'files')": the step above installs npm@latest, and npm no longer returns an array whose [0] holds the file list, so indexing it yields undefined. Nothing was ever wrong with the package — every required file was present at that tag, and the same check passes under npm 10 locally. tar -tzf reads the artifact itself and does not depend on a JSON shape npm is free to change. --- .github/workflows/release.yml | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b55f12f..8450f60 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -89,20 +89,30 @@ jobs: # A package whose executable was excluded by `files` installs cleanly and # then does nothing, so assert the bin is actually in the tarball. + # Reads the tarball rather than parsing `npm pack --json`. That JSON shape is + # not stable across npm majors — the previous version of this step indexed + # [0] of the output and started failing with "Cannot read properties of + # undefined" once the step above began installing npm@latest. `tar -tzf` is. - name: Pack and check the tarball run: | set -euo pipefail - npm pack --json | node -e " - const p = JSON.parse(require('fs').readFileSync(0, 'utf8'))[0]; - const files = p.files.map((f) => f.path); - for (const required of ['bin/rulebase-skills.js', 'package.json', 'README.md', 'LICENSE']) { - if (!files.includes(required)) { - console.error('::error::' + required + ' is missing from the tarball'); - process.exit(1); - } - } - console.error('tarball ok: ' + files.length + ' files, ' + (p.size / 1024).toFixed(1) + ' kB'); - " + mkdir -p /tmp/pack + npm pack --pack-destination /tmp/pack > /dev/null + TARBALL=$(find /tmp/pack -name '*.tgz' | head -1) + if [ -z "$TARBALL" ]; then + echo "::error::npm pack produced no tarball" + exit 1 + fi + # Entries are prefixed with `package/`, and directories end in a slash. + tar -tzf "$TARBALL" | sed 's|^package/||' | grep -v '/$' | sort > /tmp/pack/files.txt + echo "tarball contains $(wc -l < /tmp/pack/files.txt) files" + for required in bin/rulebase-skills.js package.json README.md LICENSE; do + if ! grep -qxF "$required" /tmp/pack/files.txt; then + echo "::error::$required is missing from the tarball" + cat /tmp/pack/files.txt + exit 1 + fi + done - name: Publish if: startsWith(github.ref, 'refs/tags/v')