NPM Builds with Artifactory - Declarative Pipeline Syntax

JFrog Integrations Documentation

ft:sourceType
Paligo

NPM builds can resolve dependencies, deploy artifacts and publish build-info to Artifactory. To run NPM builds with Artifactory from your Pipeline script, you first need to create an Artifactory server instance, as described in the Creating an Artifactory Server Instance section.

The next step is to define an rtNpmResolver closure, which defines the dependencies resolution details, and an rtNpmDeployer closure, which defines the artifacts deployment details. Here's an example:

rtNpmResolver (
    id: 'resolver-unique-id',
    serverId: 'Artifactory-1',
    repo: 'libs-npm'
)
      
rtNpmDeployer (
    id: 'deployer-unique-id',
    serverId: 'Artifactory-1',
    repo: 'libs-npm-local',
    // Attach custom properties to the published artifacts:
    properties: ['key1=value1', 'key2=value2']
)

As you can see in the example above, the resolver and deployer should have a unique ID, so that they can be referenced later in the script, In addition, they include an Artifactory server ID and the name of the repository.

Now we can use the rtNpmInstall or rtNpmCi closures, to resolve the NPM dependencies. Notice that the closure references the resolver we defined above.

rtNpmInstall (
    // Optional tool name from Jenkins configuration
    tool: NPM_TOOL,
    // Optional path to the project root. If not set, the root of the workspace is assumed as the root project path.
    path: 'npm-example',
    // Optional npm flags or arguments.
    args: '--verbose',
    resolverId: 'resolver-unique-id',
        // Jenkins spawns a new java process during this step's execution.
        // You have the option of passing any java args to this new process.
        javaArgs: '-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005'
    // If the build name and build number are not set here, the current job name and number will be used:
    buildName: 'my-build-name',
    buildNumber: '17',
    // Optional - Only if this build is associated with a project in Artifactory, set the project key as follows.
    project: 'my-project-key'
)

Note

The rtNpmInstall step invokes the npm install command behind the scenes. If you'd like to use the npm ci command instead, simply replace the step name with rtNpmCi.

And to pack and publish the npm package out project creates, we use the rtNpmPublish closure with a reference to the deployer we defined.

rtNpmPublish (
    // Optional tool name from Jenkins configuration
    tool: 'npm-tool-name',
    // Optional path to the project root. If not set, the root of the workspace is assumed as the root project path.
    path: 'npm-example',
    deployerId: 'deployer-unique-id',
        // Jenkins spawns a new java process during this step's execution.
        // You have the option of passing any java args to this new process.
        javaArgs: '-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005'
    // If the build name and build number are not set here, the current job name and number will be used:
    buildName: 'my-build-name',
    buildNumber: '17',
    // Optional - Only if this build is associated with a project in Artifactory, set the project key as follows.
    project: 'my-project-key'
)

The build uses the npm executable to install (download the dependencies) and also to pack the resulting npm package before publishing it. By default, Jenkins uses the npm executable, which is present in the agent’s PATH. You can also reference a tool defined in Jenkins configuration. Here's how:

environment {
    // Path to the NodeJS home directory (not to the npm executable)
    NODEJS_HOME = 'path/to/the/nodeJS/home'
}
// or
environment {
    // If a tool named 'nodejs-tool-name' is defined in Jenkins configuration.
    NODEJS_HOME = "${tool 'nodejs-tool-name'}"
}
// or
nodejs(nodeJSInstallationName: 'nodejs-tool-name') {
    // Only in this code scope, the npm defined by 'nodejs-tool-name' is used.
}

If the npm installation is not set, the npm executable which is found in the agent's PATH is used.

The last thing you might want to do, is to publish the build-info for this build. See the Publishing Build Info to Artifactory section for how to do it.

More about build-info: You also have the option of customising the build-info module names. You do this by adding the module property to the rtNpmInstall or rtNpmPublish closures as follows:

rtNpmInstall (
    tool: 'npm-tool-name',
    path: 'npm-example',
    resolverId: 'resolver-unique-id',
    module: 'my-custom-build-info-module-name'
)

rtNpmPublish (
    tool: 'npm-tool-name',
    path: 'npm-example',
    deployerId: 'deployer-unique-id'
    module: 'my-custom-build-info-module-name'
)