Sign inSign up

signiant/npm-toolkit

By signiant

Updated 3 months ago

http://bitbucket.org/signiant/npm-toolkit

Image
0

7.2K

signiant/npm-toolkit repository overview

Automatically updated from commit d00ad2b by bb-pipe-build at 2026-06-23 18:44:38 UTC

npm-toolkit

This BitBucket Pipe will create an .npmrc file for use outside the pipe, and publish packages to NPM repositories or run a short script.

Why is this necessary?

AWS CodeArtifact credentials are only valid for a limited time, so they must be generated dynamically. This script will log into AWS, generate codeartifact credentials, and use them to populate an .npmrc file for you.

Additionally, if every project uses the same tool to create this file then it will be much easier to perform failover or other repository changes in the future, since changes can be made in one place.

Variables

VariableUsageDefault
FAIL_ON_INTEGRITY_MISMATCHFails publish if package version already exists but doesn't match (see Node 20.10.0 issue)'0'
PUBLISHPublish your package to the Signiant repo. Accepts 1, '1', 'true', and 'yes''0'
PUBLISH_COMMANDOverride publish command (e.g. lerna publish from-package). Implies PUBLISH=1'npm publish --scope @signiant'
SCRIPTShell script to execute before publish. Must be successful to publish. See examples below'' or 'npm ci' (on publish)
WORK_DIRIf exists, change to this directory before doing work. Skipped if directory does not exist.'app'

Other variables exist, but they are not for you to use.

Public Docker Image

The script pulls all sensitive data from environment variables so that the docker image can be made public. Public images mean pipelines don't need to authenticate to the docker registry first to use the pipe.

Multi-repo madness!

When creating the .npmrc file, this pipe will search your package-lock.json file for the JFrog Artifactory URL (SIGNIANT_NPM_CONFIG_REGISTRY). If found, it will set up that as the @signiant scoped repo. If it is not found, then the AWS CodeArtifact repo is configured instead.

When publishing a package, this pipe will first publish to JFrog and then to AWS. If there is a failure, the script immediately exits.

Publishing success/failure conditions

The publish logic works as follows:

  • If the package version does not exist in the repository, publish it.
  • If the package version already exists in the repository, compare SHA sum.
    • Succeed pipeline on SHA match.
    • Fail pipeline on SHA mismatch.

Usage

Generating a .npmrc file
  - step:
      name: Validate
      image: node:20-bullseye # Make sure node is installed if you're running `npm` commands outside the pipe
      script:
        - pipe: signiant/npm-toolkit:prod # By default, it only generates the .npmrc file
        - unset NPM_CONFIG_REGISTRY # Only necessary until SRE removes this workspace variable
        - npm ci
        - npm audit --production
        - npm ls --production
Run a script inside the pipe
- step:
    name: Validate with script
    script:
      - pipe: signiant/npm-toolkit:prod
        variables:
          SCRIPT: |
            printf "\n\n~~~~~ npm ci ~~~~~\n"
            npm ci
            printf "\n\n~~~~~ npm audit ~~~~~\n"
            npm audit --production
            printf "\n\n~~~~~ npm ls ~~~~~\n"
            npm ls --production
Publishing a package
- step: 
    name: Publish
    script:
      - pipe: signiant/npm-toolkit:prod
        variables:
          PUBLISH: 'true'
Combining PUBLISH with SCRIPT

One step will publish only if the audit passes.

- step: 
    name: Publish
    script:
      - pipe: signiant/npm-toolkit:prod
        variables:
          PUBLISH: 'true'
          SCRIPT: npm audit --production --registry=https://registry.npmjs.org
          WORK_DIR: 'path/to/the/code/'
Publishing a package with alternate command
- step: 
    name: Publish
    script:
      - pipe: signiant/npm-toolkit:prod
        variables:
          PUBLISH_COMMAND: 'lerna publish from-package'

Troubleshooting

Why do my pipelines keep warning of SHA mismatch with a previously published package?

When npm creates a package (i.e. npm pack or npm publish), the created archive contains most of the working directory. This includes common files like bitbucket-pipelines.yml. Exceptions are defined in .npmignore. If .npmignore does not exist, it will look at .gitignore.

If you update ANY file in the archive and try to re-publish the same version, you WILL get a SHA mismatch.

Unless you plan to bump your package version for every minor non-code update, add your pipeline and other non-code files to .npmignore.

Running npm pack puts the archive in the current directory. If you run npm pack again, the first package will get added inside the second package and change the SHA. For this reason, add *.tgz to your .npmignore, or alternatively use npm pack --dry-run to troubleshoot package content issues

Another possible reason is that packages built with Node 20.10.0 (npm 10.2.3) or later have a different hash than those built with Node 20.9.0 (npm 10.1.0) or earlier. I opened a case: https://github.com/npm/cli/issues/7610

The build step that failed is probably telling npm-toolkit to run something like npm ci, but the step is also using the node cache like this:

caches:
  - node

The problem is that when BitBucket extracts the cached node_modules folder, it sets the permissions to drwxr-xr-x so that only the root user can write to it. BitBucket squashes permissions for the npm-toolkit pipe so that everything is being done as a non-root user.

Possible solutions:

  1. Don't use the node cache in the BitBucket pipeline. Running npm ci deletes and recreates all that stuff, so it's not saving you any time.
  2. Add chmod a+w node_modules before calling pipe: signiant/npm-toolkit, if you really need it.
What about permission issues for artifacts from other steps?

For the same reason as above, artifacts get extracted with permissions such that the npm-toolkit pipe cannot write to them. If you're writing to a folder, why carry it over from a previous step?

Possible solutions:

  1. Add chmod a+x before calling pipe: signiant/npm-toolkit
  2. Don't download those artifacts for the npm-toolkit step, which can be achieved with artifacts\n download: false used as shown here:
- step: &publish
    name: Publish
    script:
      - pipe: signiant/npm-toolkit:prod
        variables:
          PUBLISH: 'true'
    artifacts:
      download: false # Don't download artifacts, as they will cause permission issues
How does it know what Node version to use?

This repo uses n auto to install a compatible Node version. This tool references the engines section of your package.json file. Some developers will think it's a good idea to use minimum-only versioning like this:

"engines": {
  "node": ">=18"
},

However, modern mathemagical engineers have uncovered that 22 is greater than or equal to 18! Consider using something like "node": "^18" or "node": ">=18 <22" instead. Unless engines-strict is set, this field is only advisory so you might as well populate it with a maximum.

What version of n is used?

This pipe uses a custom fork of n from https://raw.githubusercontent.com/sigJoe/n with the --if-needed flag for lazy installation of Node. If package.json engines says >=16 and Node 20 is installed, --if-needed will decide that the current version is "good enough" rather than the previous behaviour of updating to absolute latest since 25>=16.

Tag summary

Content type

Image

Digest

sha256:e77b85e95

Size

202.5 MB

Last updated

3 months ago

docker pull signiant/npm-toolkit