Skip to content

Commit 167156f

Browse files
committed
feat: enhance version bump logic in npm publish workflow
1 parent 7a1eee6 commit 167156f

1 file changed

Lines changed: 85 additions & 1 deletion

File tree

.github/workflows/npm-publish-manual.yml

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,16 +181,100 @@ jobs:
181181
182182
echo "type=$VERSION_TYPE" >> $GITHUB_OUTPUT
183183
184+
- name: 🧮 Resolve next release version
185+
id: release_version
186+
env:
187+
VERSION_TYPE: ${{ steps.version.outputs.type }}
188+
run: |
189+
PACKAGE_VERSION=$(node -p "require('./package.json').version")
190+
LATEST_TAG=$(git tag --list 'v*' --sort=-version:refname | head -n 1 | sed 's/^v//')
191+
LATEST_NPM=$(npm view "$PACKAGE_NAME" version 2>/dev/null || true)
192+
193+
BASE_VERSION=$(node -e '
194+
const versions = process.argv.slice(1).filter(Boolean);
195+
196+
function parse(version) {
197+
const match = /^(\d+)\.(\d+)\.(\d+)$/.exec(version || "");
198+
return match ? match.slice(1).map(Number) : null;
199+
}
200+
201+
function compare(left, right) {
202+
for (let index = 0; index < 3; index += 1) {
203+
if (left[index] !== right[index]) {
204+
return left[index] - right[index];
205+
}
206+
}
207+
208+
return 0;
209+
}
210+
211+
let highestVersion = "0.0.0";
212+
let highestParsed = [0, 0, 0];
213+
214+
for (const version of versions) {
215+
const parsed = parse(version);
216+
217+
if (!parsed) {
218+
continue;
219+
}
220+
221+
if (compare(parsed, highestParsed) > 0) {
222+
highestVersion = version;
223+
highestParsed = parsed;
224+
}
225+
}
226+
227+
process.stdout.write(highestVersion);
228+
' "$PACKAGE_VERSION" "$LATEST_TAG" "$LATEST_NPM")
229+
230+
NEXT_VERSION=$(node -e '
231+
const [baseVersion, bumpType] = process.argv.slice(1);
232+
const [major, minor, patch] = baseVersion.split(".").map(Number);
233+
234+
if ([major, minor, patch].some(Number.isNaN)) {
235+
throw new Error(`Invalid base version: ${baseVersion}`);
236+
}
237+
238+
const nextVersion =
239+
bumpType === "major"
240+
? [major + 1, 0, 0]
241+
: bumpType === "minor"
242+
? [major, minor + 1, 0]
243+
: [major, minor, patch + 1];
244+
245+
process.stdout.write(nextVersion.join("."));
246+
' "$BASE_VERSION" "$VERSION_TYPE")
247+
248+
echo "📦 package.json version: $PACKAGE_VERSION"
249+
echo "🏷️ latest git tag: ${LATEST_TAG:-none}"
250+
echo "📡 latest npm version: ${LATEST_NPM:-none}"
251+
echo "🔢 base version selected: $BASE_VERSION"
252+
echo "🚀 next version selected: $NEXT_VERSION"
253+
254+
echo "base=$BASE_VERSION" >> "$GITHUB_OUTPUT"
255+
echo "next=$NEXT_VERSION" >> "$GITHUB_OUTPUT"
256+
184257
- name: 📈 Bump version (local only)
185258
run: |
186259
git config user.name "github-actions[bot]"
187260
git config user.email "github-actions[bot]@users.noreply.github.com"
188-
pnpm version ${{ steps.version.outputs.type }} --no-git-tag-version
261+
npm version "${{ steps.release_version.outputs.next }}" --no-git-tag-version
189262
190263
- name: 🔎 Check version doesn't already exist on npm
191264
run: |
192265
NEW_VERSION=$(node -p "require('./package.json').version")
193266
echo "NEW_VERSION=$NEW_VERSION" >> $GITHUB_ENV
267+
268+
if git rev-parse "v$NEW_VERSION" >/dev/null 2>&1; then
269+
echo "❌ Tag v$NEW_VERSION already exists locally."
270+
exit 1
271+
fi
272+
273+
if git ls-remote --exit-code --tags origin "refs/tags/v$NEW_VERSION" >/dev/null 2>&1; then
274+
echo "❌ Tag v$NEW_VERSION already exists on origin."
275+
exit 1
276+
fi
277+
194278
if npm view "$PACKAGE_NAME@$NEW_VERSION" version 2>/dev/null | grep -q "$NEW_VERSION"; then
195279
echo "❌ Version $NEW_VERSION already exists on npm. Aborting to avoid duplicate publish."
196280
exit 1

0 commit comments

Comments
 (0)