Skip to content

feat(ENG-13679): NPM Credential Helper - #367

Merged
tigh-latte merged 21 commits into
masterfrom
tigh/npm-credential-helper
Aug 20, 2026
Merged

feat(ENG-13679): NPM Credential Helper#367
tigh-latte merged 21 commits into
masterfrom
tigh/npm-credential-helper

Conversation

@tigh-latte

Copy link
Copy Markdown
Contributor

Description

Provide a credential helper of npm, which pnpm can use, in order to authenticate without hard coded tokens.

It adds the token as a best attempt, only if a given domain hasn't already had auth configured. Any collisions are reported as errors.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update
  • Refactoring
  • Other (please describe)

Copilot AI lite review requested due to automatic review settings August 20, 2026 09:14
@tigh-latte
tigh-latte requested a review from a team as a code owner August 20, 2026 09:14
@tigh-latte tigh-latte changed the title Tigh/npm credential helper feat(ENG-13679): NPM Credential Helper Aug 20, 2026
Comment thread cloudsmith_cli/cli/tests/commands/test_credential_helper_install.py Fixed

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds an NPM credential-helper integration to Cloudsmith CLI so pnpm/npm can authenticate to Cloudsmith registries without hard-coded tokens, plus installer/uninstaller support and tests.

Changes:

  • Introduces an NPM credential helper runtime and Click command (cloudsmith credential-helper npm).
  • Adds an NPM installer that writes a launcher and configures .npmrc tokenHelper entries (with best-effort custom-domain discovery).
  • Extends the credential-helper management CLI, launcher utilities, and test suite to cover NPM flows.

Reviewed changes

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

Show a summary per file
File Description
cloudsmith_cli/credential_helpers/npm/runtime.py New NPM helper runtime that returns a token for Cloudsmith registries.
cloudsmith_cli/credential_helpers/npm/rc.py New .npmrc parser/mutator for //host/:key=value entries.
cloudsmith_cli/credential_helpers/npm/installer.py New install/uninstall/status implementation for NPM .npmrc + launcher wiring.
cloudsmith_cli/credential_helpers/npm/init.py Exports NPM helper runtime API.
cloudsmith_cli/credential_helpers/launchers.py Adds dry_run support to launcher write/remove helpers.
cloudsmith_cli/credential_helpers/generic.py Adds PartialInstallError for partial-install reporting/exit handling.
cloudsmith_cli/credential_helpers/docker/installer.py Adjusts PATH warning text (but currently incorrect).
cloudsmith_cli/cli/commands/credential_helper/npm.py New Click command entry point for the NPM helper protocol.
cloudsmith_cli/cli/commands/credential_helper/manage.py Registers NPM installer and adds partial-install handling for install.
cloudsmith_cli/cli/commands/credential_helper/init.py Registers the new npm subcommand.
cloudsmith_cli/cli/tests/commands/test_credential_helper_install.py Adds NPM installer/manage command coverage and extends launcher tests.
Suppressed comments (5)

cloudsmith_cli/credential_helpers/npm/rc.py:42

  • Leading whitespace preservation is computed incorrectly: entry[: len(stripped_entry) - len(entry)] produces an unrelated slice (often most of the line) instead of just the leading whitespace. This will corrupt written .npmrc lines that were indented.
            # remove any starting whitespace
            stripped_entry = entry.lstrip()

            # track the starting whitespace
            self._leading = entry[: len(stripped_entry) - len(entry)]
            if not stripped_entry.startswith("/"):
                raise ValueError("invalid url, should start with ``//``")

cloudsmith_cli/credential_helpers/npm/rc.py:93

  • __contains__ uses item._value is not None as the wildcard condition, which means an entry with a specific value is treated as a match as long as the key exists (even if the stored value differs). After making from_values(..., value=None) set _value=None, the wildcard check should be inverted.
    def __contains__(self, item: str | URLEntry) -> bool:
        if isinstance(item, NPMRC.URLEntry):
            return item.id in self._mapping and (
                item._value is not None or self._mapping[item.id] == item._value
            )

cloudsmith_cli/credential_helpers/npm/installer.py:67

  • Typo in docstring: "crednetial" → "credential".
        """Install the NPM crednetial helper.

cloudsmith_cli/credential_helpers/npm/installer.py:180

  • When not running in dry-run mode, successful .npmrc mutations don't add any action strings (unlike DockerInstaller, which reports the keys it set). This makes credential-helper install npm output incomplete and harder to audit.
                if dry_run:
                    if added:
                        actions.append(f"would set {entry} in {config_path}")
                    else:
                        actions.append(

cloudsmith_cli/cli/commands/credential_helper/npm.py:12

  • Avoid import * here; it obscures what the command depends on and differs from the Docker helper command (which imports execute explicitly).
from ....credential_helpers.npm import *
from ...decorators import common_api_auth_options, resolve_credentials

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread cloudsmith_cli/credential_helpers/npm/rc.py Outdated
Comment thread cloudsmith_cli/credential_helpers/npm/runtime.py Outdated
Comment thread cloudsmith_cli/credential_helpers/docker/installer.py
Comment thread cloudsmith_cli/credential_helpers/pnpm/runtime.py
Comment thread cloudsmith_cli/credential_helpers/pnpm/installer.py
Comment thread cloudsmith_cli/credential_helpers/pnpm/rc.py
Comment thread cloudsmith_cli/cli/commands/credential_helper/pnpm.py
Comment thread cloudsmith_cli/credential_helpers/generic.py
Comment thread cloudsmith_cli/cli/tests/commands/test_credential_helper_install.py
Comment thread cloudsmith_cli/cli/commands/credential_helper/manage.py
@tigh-latte
tigh-latte force-pushed the tigh/npm-credential-helper branch from 4883fb7 to 97edd56 Compare August 20, 2026 11:15

@cloudsmith-iduffy cloudsmith-iduffy left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ran it locally and it worked great, few small comments but nothing major.

Comment thread cloudsmith_cli/cli/commands/credential_helper/npm.py Outdated
Comment thread cloudsmith_cli/credential_helpers/pnpm/rc.py
Comment thread cloudsmith_cli/credential_helpers/pnpm/rc.py
Comment thread cloudsmith_cli/credential_helpers/pnpm/installer.py
Comment thread cloudsmith_cli/credential_helpers/npm/installer.py Outdated
Add pattern to exclude test packages at deeper nesting levels (e.g.
cloudsmith_cli.credential_helpers.npm.tests) from the built wheel
distribution. This prevents duplicate __init__.py files in the wheel
and ensures test files are not packaged with the CLI.
… expects an absolute path and therefore doesn't need to be in PATH
* beginning on npm -> pnpm rename
* `resolve_bin_dir` will now resolve dirs as absolute instead of relative
* silently fail handling malformed url entries in npmrc, testing them instead as a
  normal line
* fix typo
* tests where apply for the above
also, add tests around this, and make sure that the dry run reports that a value will be
written
given that tokenHelper is a pnpm config item.
@tigh-latte
tigh-latte force-pushed the tigh/npm-credential-helper branch from 2c9d5b6 to 99bd6f2 Compare August 20, 2026 13:41
@tigh-latte

tigh-latte commented Aug 20, 2026

Copy link
Copy Markdown
Contributor Author

@cloudsmith-iduffy feedback implemented there + tests to cover the cases you found, this is ready for another look

@cloudsmith-iduffy cloudsmith-iduffy left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

One small comment but otherwise good!

Comment thread CHANGELOG.md Outdated
@tigh-latte
tigh-latte merged commit 94f9cfe into master Aug 20, 2026
26 checks passed
@tigh-latte
tigh-latte deleted the tigh/npm-credential-helper branch August 20, 2026 14:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants