Skip to content

feat: SW-1779 add install-jfrog-npm-package composite action#29

Open
owilliams-tetrascience wants to merge 1 commit into
mainfrom
install-jfrog-npm-package-action
Open

feat: SW-1779 add install-jfrog-npm-package composite action#29
owilliams-tetrascience wants to merge 1 commit into
mainfrom
install-jfrog-npm-package-action

Conversation

@owilliams-tetrascience

Copy link
Copy Markdown
Contributor

Summary

Adds a composite action, install-jfrog-npm-package, that installs a single npm package published only to a private JFrog Artifactory registry — as a leaf tarball extracted into an already-installed node_modules.

Why

Several repos need a private, JFrog-only package but pin the public npm registry, so the package can't go in package.json / yarn.lock (it would break external contributors' yarn install and the public-publish path). Today they each inline the same workaround. The most recent case is ts-lib-ui-kit #161 (SW-1779), which installs ts-lib-zephyr-nodejs in its two Zephyr workflows; the data-app repos do the same ad hoc.

This centralizes the pattern — including two non-obvious gotchas — in one reviewed place:

  • Leaf tarball, not npm install. npm install --no-save <pkg> reconciles the entire dependency tree and corrupts a Yarn-4-managed node_modules (observed: ENOTEMPTY: directory not empty, rmdir node_modules/<pkg>/dist). The action fetches only the one package via npm pack and extracts it in place, touching nothing else.
  • Host normalization. Strips the scheme and any trailing slash so the npmrc auth line is always //<host>/:<field>=…, working whether or not the registry URL ends with a slash.

What's included

  • install-jfrog-npm-package/action.yml — composite action (used as a step uses:, like coverage-check), inputs: package, version, registry-url, auth, auth-type (_auth default | _authToken).
  • README.md — new Actions section documenting usage (must run after yarn install) + inputs, and a TOC entry.

Follow-up (separate PR, not here)

Once merged, ts-lib-ui-kit #161 will replace its two inline "Install ts-lib-zephyr-nodejs (JFrog)" run: steps with:

- uses: tetrascience/ts-ci-cd-lib/install-jfrog-npm-package@main
  with:
    package: ts-lib-zephyr-nodejs
    version: "0.4.0"
    registry-url: https://tetrascience.jfrog.io/artifactory/api/npm/ts-npm-virtual/
    auth: ${{ secrets.JFROG_ARTIFACTORY_READ_NPM_AUTH }}

🤖 Generated with Claude Code

Add a composite action that installs a single npm package published only to
a private JFrog Artifactory registry, as a leaf tarball extracted into an
already-installed node_modules.

This centralizes a pattern otherwise duplicated inline across repos (e.g.
ts-lib-ui-kit's two Zephyr workflows and several data-app repos): packages
that can't be added to package.json/yarn.lock — because the repo pins the
public npm registry and a private dep would break external `yarn install` —
are fetched via `npm pack` and extracted in place. It deliberately avoids
`npm install`, which reconciles the whole tree and corrupts a Yarn-managed
node_modules (ENOTEMPTY rmdir node_modules/<pkg>/dist).

Inputs: package, version, registry-url, auth, auth-type (_auth | _authToken,
default _auth). Host normalization strips scheme + trailing slash so the auth
line is always //<host>/:<field>=... regardless of URL format.

Refs: SW-1779

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

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 adds a reusable composite GitHub Action to install a single private JFrog-hosted npm package into an already-existing node_modules (without running npm install), and documents its usage in the repo README to centralize a repeated workflow pattern used across multiple repositories.

Changes:

  • Adds install-jfrog-npm-package composite action that fetches a package via npm pack and extracts it into node_modules/<package>.
  • Documents the new composite action (usage + inputs) in README.md and adds it to the TOC.

Reviewed changes

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

File Description
README.md Adds an “Actions” section documenting the new composite action and how to use it.
install-jfrog-npm-package/action.yml Implements the composite action to fetch/extract a private JFrog-only npm package as a leaf tarball.

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

Comment on lines +46 to +53
if [ ! -d node_modules ]; then
echo "::error::node_modules not found — run this action AFTER 'yarn install'."
exit 1
fi
case "$AUTH_TYPE" in
_auth | _authToken) ;;
*) echo "::error::auth-type must be '_auth' or '_authToken' (got '$AUTH_TYPE')."; exit 1 ;;
esac
Comment on lines +54 to +68
# Normalize the host: strip scheme and any trailing slash so the auth
# line is always `//<host>/:<field>=...` regardless of whether the
# registry URL ends with a slash (npm requires the `/` before the field).
host="${REGISTRY_URL#https://}"; host="${host#http://}"; host="${host%/}"
npmrc="$RUNNER_TEMP/.npmrc-jfrog"
printf 'registry=%s\n//%s/:%s=%s\nalways-auth=true\n' \
"$REGISTRY_URL" "$host" "$AUTH_TYPE" "$AUTH" > "$npmrc"
tgz=$(npm pack "${PACKAGE}@${VERSION}" --userconfig "$npmrc" --registry "$REGISTRY_URL")
# `mkdir -p node_modules/<package>` also creates the @scope dir for
# scoped packages (node_modules/@scope/name).
rm -rf "node_modules/${PACKAGE}"
mkdir -p "node_modules/${PACKAGE}"
tar -xzf "$tgz" -C "node_modules/${PACKAGE}" --strip-components=1
rm -f "$npmrc" "$tgz"
echo "Installed ${PACKAGE}@${VERSION} into node_modules/${PACKAGE}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants