Skip to content

Support pre-release publishing in npm-publish workflow#1464

Merged
minggangw merged 3 commits into
RobotWebTools:developfrom
minggangw:fix-1459-1
Apr 1, 2026
Merged

Support pre-release publishing in npm-publish workflow#1464
minggangw merged 3 commits into
RobotWebTools:developfrom
minggangw:fix-1459-1

Conversation

@minggangw

Copy link
Copy Markdown
Member

Add automatic dist-tag detection to the publish step. npm requires --tag when publishing pre-release versions to prevent them from becoming the default latest on the registry.

The new Determine dist-tag step reads the version from package.json and extracts the pre-release label (e.g. alpha, beta, rc) if present, otherwise defaults to latest. This tag is passed to npm publish --tag.

Examples:

  • 1.9.0-alpha.0--tag alpha
  • 1.9.0-beta.1--tag beta
  • 1.9.0-rc.0--tag rc
  • 1.9.0--tag latest

Fix: #1459

Copilot AI review requested due to automatic review settings April 1, 2026 07:12

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the npm publish GitHub Actions workflow to automatically choose an npm dist-tag based on the version in package.json, so pre-release versions (alpha/beta/rc) don’t accidentally publish under latest.

Changes:

  • Add a Determine dist-tag step that derives a dist-tag from package.json version prerelease label, defaulting to latest.
  • Pass the computed dist-tag into npm publish --tag for both dry-run and real publish paths.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .github/workflows/npm-publish.yml Outdated
Comment on lines +77 to +83
# Pre-release version (e.g. 1.9.0-alpha.0) — extract pre-release label
TAG=$(echo "$VERSION" | sed 's/.*-\([a-zA-Z]*\).*/\1/')
echo "tag=$TAG" >> $GITHUB_OUTPUT
else
echo "tag=latest" >> $GITHUB_OUTPUT
fi
echo "Version: $VERSION, Tag: $(cat $GITHUB_OUTPUT | grep tag | cut -d= -f2)"

Copilot AI Apr 1, 2026

Copy link

Choose a reason for hiding this comment

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

The dist-tag extraction via sed 's/.*-\([a-zA-Z]*\).*/\1/' is not SemVer-robust: valid prerelease identifiers can include digits/hyphens (e.g. 1.2.3-alpha1.0, 1.2.3-0.3.7), which would yield a truncated or empty TAG. If TAG becomes empty, the publish step may fail or mis-handle subsequent args. Consider parsing the first prerelease identifier more reliably (e.g., take the substring after -, strip build metadata after +, then take up to the first .) and fail the step if the derived tag is empty; also quote $GITHUB_OUTPUT in the redirect to avoid path/word-splitting issues.

Suggested change
# Pre-release version (e.g. 1.9.0-alpha.0) — extract pre-release label
TAG=$(echo "$VERSION" | sed 's/.*-\([a-zA-Z]*\).*/\1/')
echo "tag=$TAG" >> $GITHUB_OUTPUT
else
echo "tag=latest" >> $GITHUB_OUTPUT
fi
echo "Version: $VERSION, Tag: $(cat $GITHUB_OUTPUT | grep tag | cut -d= -f2)"
# Pre-release version (e.g. 1.9.0-alpha.0, 1.2.3-0.3.7) — extract first pre-release identifier
PRERELEASE=${VERSION#*-} # remove everything up to and including the first '-'
PRERELEASE=${PRERELEASE%%+*} # strip build metadata (anything after '+')
TAG=${PRERELEASE%%.*} # take the first identifier before any '.'
if [[ -z "$TAG" ]]; then
echo "Error: failed to derive dist-tag from version '$VERSION'" >&2
exit 1
fi
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
else
echo "tag=latest" >> "$GITHUB_OUTPUT"
fi
echo "Version: $VERSION, Tag: $(grep '^tag=' "$GITHUB_OUTPUT" | tail -n1 | cut -d= -f2)"

Copilot uses AI. Check for mistakes.
Comment thread .github/workflows/npm-publish.yml Outdated
Comment on lines +81 to +83
echo "tag=latest" >> $GITHUB_OUTPUT
fi
echo "Version: $VERSION, Tag: $(cat $GITHUB_OUTPUT | grep tag | cut -d= -f2)"

Copilot AI Apr 1, 2026

Copy link

Choose a reason for hiding this comment

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

This log line reads back from $GITHUB_OUTPUT using cat | grep | cut. That file can contain multiple outputs and grep tag is not anchored, so it could log the wrong value if more outputs are ever added. Also, if grep finds no match it will exit non-zero, which could fail the step depending on shell settings. Prefer setting a TAG variable in both branches and logging that directly (or anchor the match to ^tag= if you keep this approach).

Suggested change
echo "tag=latest" >> $GITHUB_OUTPUT
fi
echo "Version: $VERSION, Tag: $(cat $GITHUB_OUTPUT | grep tag | cut -d= -f2)"
TAG=latest
echo "tag=$TAG" >> $GITHUB_OUTPUT
fi
echo "Version: $VERSION, Tag: $TAG"

Copilot uses AI. Check for mistakes.
Comment thread .github/workflows/npm-publish.yml Outdated
Comment on lines +89 to +91
npm publish --provenance --access public --tag ${{ steps.dist-tag.outputs.tag }} --dry-run ./dist/rclnodejs-*.tgz
else
npm publish --provenance --access public ./dist/rclnodejs-*.tgz
npm publish --provenance --access public --tag ${{ steps.dist-tag.outputs.tag }} ./dist/rclnodejs-*.tgz

Copilot AI Apr 1, 2026

Copy link

Choose a reason for hiding this comment

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

--tag ${{ steps.dist-tag.outputs.tag }} is unquoted. If the output is unexpectedly empty, the next token (e.g., --dry-run or the tarball path) can be consumed as the tag value, producing a confusing failure mode. Quote the substitution and consider guarding against an empty tag before invoking npm publish.

Copilot uses AI. Check for mistakes.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +72 to +74
- name: Determine dist-tag
id: dist-tag
run: |

Copilot AI Apr 1, 2026

Copy link

Choose a reason for hiding this comment

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

id: dist-tag is referenced as ${{ steps.dist-tag.outputs.tag }}. In GitHub Actions expressions, step IDs containing - generally can’t be accessed via dot notation (the - is treated as an operator). Rename the step id to something like dist_tag (or distTag) or use bracket syntax: steps['dist-tag'].outputs.tag.

Copilot uses AI. Check for mistakes.
Comment thread .github/workflows/npm-publish.yml Outdated
Comment on lines +76 to +79
const v = require('./package.json').version;
const pre = v.split('-')[1];
if (!pre) { 'latest' }
else { pre.split('.')[0].replace(/[0-9]+$/, '') || 'next' }

Copilot AI Apr 1, 2026

Copy link

Choose a reason for hiding this comment

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

The node -p snippet doesn’t actually return a value: if (!pre) { 'latest' } else { ... } is a statement, so node -p will print undefined (or an empty/incorrect value), which can lead to publishing with an invalid dist-tag. Make the last evaluated expression a string (e.g., a ternary), or wrap the logic in an IIFE that returns the tag, and consider validating that the computed tag is not undefined/null and matches npm’s dist-tag rules.

Suggested change
const v = require('./package.json').version;
const pre = v.split('-')[1];
if (!pre) { 'latest' }
else { pre.split('.')[0].replace(/[0-9]+$/, '') || 'next' }
(() => {
const v = require('./package.json').version;
const pre = v.split('-')[1];
const tag = !pre
? 'latest'
: (pre.split('.')[0].replace(/[0-9]+$/, '') || 'next');
if (!tag || !/^[a-z0-9][a-z0-9._-]*$/.test(tag)) {
throw new Error('Invalid dist-tag: ' + tag);
}
return tag;
})()

Copilot uses AI. Check for mistakes.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

echo "::error::Failed to determine dist-tag"
exit 1
fi
echo "tag=$TAG" >> "$GITHUB_OUTPUT"

Copilot AI Apr 1, 2026

Copy link

Choose a reason for hiding this comment

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

echo "tag=$TAG" >> "$GITHUB_OUTPUT" can behave unexpectedly if the value ever starts with - or contains characters that echo interprets; using printf 'tag=%s\n' "$TAG" >> "$GITHUB_OUTPUT" is more robust for writing outputs in bash.

Suggested change
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
printf 'tag=%s\n' "$TAG" >> "$GITHUB_OUTPUT"

Copilot uses AI. Check for mistakes.
@minggangw minggangw merged commit d07d21e into RobotWebTools:develop Apr 1, 2026
17 of 19 checks passed
minggangw added a commit that referenced this pull request Apr 1, 2026
Add automatic dist-tag detection to the publish step. npm requires `--tag` when publishing pre-release versions to prevent them from becoming the default `latest` on the registry.

The new `Determine dist-tag` step reads the version from `package.json` and extracts the pre-release label (e.g. `alpha`, `beta`, `rc`) if present, otherwise defaults to `latest`. This tag is passed to `npm publish --tag`.

Examples:
- `1.9.0-alpha.0` → `--tag alpha`
- `1.9.0-beta.1` → `--tag beta`
- `1.9.0-rc.0` → `--tag rc`
- `1.9.0` → `--tag latest`

Fix: #1459
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enable npm publishing via GitHub Actions

2 participants