Skip to content

Commit 3f9de83

Browse files
committed
fix: compare npm tarballs before version bump
1 parent 72b0a46 commit 3f9de83

3 files changed

Lines changed: 25 additions & 20 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ jobs:
9999
| `readme_dest` | Destination path for README | No | `packages/app/README.md` |
100100
| `publish_npm` | Whether to publish to npm registry | No | `true` |
101101
| `publish_github_packages` | Whether to publish to GitHub Packages | No | `true` |
102-
| `skip_if_unchanged` | Skip version bump/publish if local package.json + dist match latest npm package | No | `false` |
102+
| `skip_if_unchanged` | Skip version bump/publish if the local npm tarball matches the latest published tarball (ignoring version/gitHead) | No | `false` |
103103
| `npm_token` | NPM authentication token | No (required if `publish_npm` is true) | - |
104104
| `github_token` | GitHub token for releases and packages | Yes | - |
105105

@@ -117,7 +117,7 @@ jobs:
117117
1. **Checkout**: Checks out the repository at the specified ref
118118
2. **Setup**: Configures pnpm and Node.js environment
119119
3. **Dependencies**: Installs project dependencies
120-
4. **Optional compare**: When `skip_if_unchanged` is true, compares local `package.json` + `dist` with the latest npm package and skips release if identical
120+
4. **Optional compare**: When `skip_if_unchanged` is true, compares the local npm tarball with the latest published tarball (ignoring version/gitHead) and skips release if identical
121121
5. **Changeset**: Creates automatic changeset if none exists
122122
6. **Version**: Bumps package version using changesets
123123
7. **Commit**: Commits version changes back to the branch

SETUP.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ permissions:
9595

9696
### Optional Behavior
9797

98-
- `skip_if_unchanged` - When enabled, the action compares local `package.json` + `dist` with the latest npm package and skips the release if identical. For private npm packages, provide `NPM_TOKEN` so the comparison can fetch the published tarball.
98+
- `skip_if_unchanged` - When enabled, the action compares the local npm tarball with the latest published tarball (ignoring version/gitHead) and skips the release if identical. For private npm packages, provide `NPM_TOKEN` so the comparison can fetch the published tarball.
9999

100100
### Action Permissions Policy
101101

action.yml

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,6 @@ runs:
109109
set -euo pipefail
110110
PKG_PATH="${{ inputs.package_json_path }}"
111111
PKG_DIR="$(dirname "$PKG_PATH")"
112-
LOCAL_PKG="${PKG_PATH}"
113-
LOCAL_DIST="${PKG_DIR}/dist"
114112
PKG_NAME="$(node -p "require('./${PKG_PATH}').name")"
115113
116114
if [ -n "${{ inputs.npm_token }}" ]; then
@@ -123,34 +121,41 @@ runs:
123121
exit 0
124122
fi
125123
126-
if ! TARBALL="$(npm pack "${PKG_NAME}@${LATEST_VERSION}" --silent 2>/dev/null)"; then
124+
TMP_DIR="$(mktemp -d)"
125+
trap 'rm -rf "$TMP_DIR"' EXIT
126+
127+
if ! REMOTE_TARBALL="$(npm pack "${PKG_NAME}@${LATEST_VERSION}" --silent --pack-destination "$TMP_DIR" 2>/dev/null)"; then
127128
echo "Unable to download ${PKG_NAME}@${LATEST_VERSION}; proceeding with release."
128129
echo "should_release=true" >> "$GITHUB_OUTPUT"
129130
exit 0
130131
fi
131132
132-
TMP_DIR="$(mktemp -d)"
133-
trap 'rm -rf "$TMP_DIR"' EXIT
134-
tar -xzf "$TARBALL" -C "$TMP_DIR"
135-
rm -f "$TARBALL"
136-
137-
REMOTE_DIR="${TMP_DIR}/package"
138-
REMOTE_PKG="${REMOTE_DIR}/package.json"
139-
REMOTE_DIST="${REMOTE_DIR}/dist"
140-
141-
if [ ! -f "$REMOTE_PKG" ]; then
142-
echo "Remote package.json missing; proceeding with release."
133+
if ! LOCAL_TARBALL="$(cd "$PKG_DIR" && npm pack --silent --pack-destination "$TMP_DIR")"; then
134+
echo "Unable to pack local ${PKG_NAME}; proceeding with release."
143135
echo "should_release=true" >> "$GITHUB_OUTPUT"
144136
exit 0
145137
fi
146138
147-
if [ ! -d "$LOCAL_DIST" ] || [ ! -d "$REMOTE_DIST" ]; then
148-
echo "Missing dist folder for comparison; proceeding with release."
139+
LOCAL_DIR="${TMP_DIR}/local"
140+
REMOTE_DIR="${TMP_DIR}/remote"
141+
mkdir -p "$LOCAL_DIR" "$REMOTE_DIR"
142+
143+
tar -xzf "${TMP_DIR}/${LOCAL_TARBALL}" -C "$LOCAL_DIR"
144+
tar -xzf "${TMP_DIR}/${REMOTE_TARBALL}" -C "$REMOTE_DIR"
145+
146+
LOCAL_PKG="${LOCAL_DIR}/package/package.json"
147+
REMOTE_PKG="${REMOTE_DIR}/package/package.json"
148+
149+
if [ ! -f "$LOCAL_PKG" ] || [ ! -f "$REMOTE_PKG" ]; then
150+
echo "package.json missing in tarball; proceeding with release."
149151
echo "should_release=true" >> "$GITHUB_OUTPUT"
150152
exit 0
151153
fi
152154
153-
if diff -q "$LOCAL_PKG" "$REMOTE_PKG" >/dev/null 2>&1 && diff -qr "$LOCAL_DIST" "$REMOTE_DIST" >/dev/null 2>&1; then
155+
node -e "const fs=require('fs');const p=process.argv[1];const pkg=JSON.parse(fs.readFileSync(p,'utf8'));delete pkg.gitHead;pkg.version='0.0.0';fs.writeFileSync(p, JSON.stringify(pkg, null, 2)+'\n');" "$LOCAL_PKG"
156+
node -e "const fs=require('fs');const p=process.argv[1];const pkg=JSON.parse(fs.readFileSync(p,'utf8'));delete pkg.gitHead;pkg.version='0.0.0';fs.writeFileSync(p, JSON.stringify(pkg, null, 2)+'\n');" "$REMOTE_PKG"
157+
158+
if diff -qr "$LOCAL_DIR/package" "$REMOTE_DIR/package" >/dev/null 2>&1; then
154159
echo "::notice::No changes compared to ${PKG_NAME}@${LATEST_VERSION}. Skipping release."
155160
echo "should_release=false" >> "$GITHUB_OUTPUT"
156161
else

0 commit comments

Comments
 (0)