Skip to content

Support npm publish using native npm client with .npmrc via --use-npmrc flag #2952

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions buildtools/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -934,9 +934,18 @@ func NpmPublishCmd(c *cli.Context) (err error) {
if npmCmd.GetXrayScan() {
commandsUtils.ConditionalUploadScanFunc = scan.ConditionalUploadDefaultScanFunc
}
printDeploymentView, detailedSummary := log.IsStdErrTerminal(), npmCmd.IsDetailedSummary()
if !detailedSummary {
npmCmd.SetDetailedSummary(printDeploymentView)

var printDeploymentView, detailedSummary bool

// we do not support deployment view and detailed summary when using npmrc for publishing since
// TransferDetails is not available to us
Comment on lines +940 to +941
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
// we do not support deployment view and detailed summary when using npmrc for publishing since
// TransferDetails is not available to us
// Deployment view and Detailed summary is not supported when using npmrc for publishing since transfer details are not available.

if npmCmd.ShouldUseNpmRc() {
printDeploymentView, detailedSummary = false, false
} else {
printDeploymentView, detailedSummary = log.IsStdErrTerminal(), npmCmd.IsDetailedSummary()
if !detailedSummary {
npmCmd.SetDetailedSummary(printDeploymentView)
}
}
err = commands.Exec(npmCmd)
result := npmCmd.Result()
Expand Down
10 changes: 5 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ require (
github.com/jfrog/build-info-go v1.10.10
github.com/jfrog/gofrog v1.7.6
github.com/jfrog/jfrog-cli-artifactory v0.2.1
github.com/jfrog/jfrog-cli-core/v2 v2.58.2
github.com/jfrog/jfrog-cli-core/v2 v2.58.3
github.com/jfrog/jfrog-cli-platform-services v1.9.0
github.com/jfrog/jfrog-cli-security v1.16.2
github.com/jfrog/jfrog-client-go v1.51.1
github.com/jfrog/jfrog-client-go v1.52.0
github.com/jszwec/csvutil v1.10.0
github.com/manifoldco/promptui v0.9.0
github.com/stretchr/testify v1.10.0
Expand Down Expand Up @@ -189,10 +189,10 @@ require (
sigs.k8s.io/yaml v1.4.0 // indirect
)

replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20250410085750-f34f5feea93e
replace github.com/jfrog/jfrog-cli-artifactory => github.com/fluxxBot/jfrog-cli-artifactory v0.0.0-20250423112031-a0c4384c6063

replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.28.1-0.20250406105605-ee90d11546f9
replace github.com/jfrog/jfrog-cli-core/v2 => github.com/fluxxBot/jfrog-cli-core/v2 v2.31.1-0.20250420214742-c12c4050641f

replace github.com/jfrog/jfrog-cli-artifactory => github.com/jfrog/jfrog-cli-artifactory v0.2.2-0.20250414045808-41544959f9b9
replace github.com/jfrog/jfrog-client-go => github.com/fluxxBot/jfrog-client-go v1.28.1-0.20250413214704-1b6cdf0520c6

replace github.com/jfrog/jfrog-cli-security => github.com/jfrog/jfrog-cli-security v1.16.3-0.20250402121228-12cce9f88504
12 changes: 6 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,12 @@ github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fluxxBot/jfrog-cli-artifactory v0.0.0-20250423112031-a0c4384c6063 h1:5v/fyOxPnJYGze49V76hP/2sHQgm9I0zxX7pm4E+Gtc=
github.com/fluxxBot/jfrog-cli-artifactory v0.0.0-20250423112031-a0c4384c6063/go.mod h1:uDQCzRFo8n90WXEIYeOKc8ed2TT/pJ3iOQdImw6vgkY=
github.com/fluxxBot/jfrog-cli-core/v2 v2.31.1-0.20250420214742-c12c4050641f h1:SdMa2iO2PqNegvh57uHkWy/00RySEO/CeiZCSa9rT8w=
github.com/fluxxBot/jfrog-cli-core/v2 v2.31.1-0.20250420214742-c12c4050641f/go.mod h1:nrKlwWRT7BT9TqE51WSIpUlO8uQR6qWHlp3UiKqC4nc=
github.com/fluxxBot/jfrog-client-go v1.28.1-0.20250413214704-1b6cdf0520c6 h1:krAN+7hGggGDXfAlcC8eni2QxWfW7I5JVNPvhI3vS4U=
github.com/fluxxBot/jfrog-client-go v1.28.1-0.20250413214704-1b6cdf0520c6/go.mod h1:uRmT8Q1SJymIzId01v0W1o8mGqrRfrwUF53CgEMsH0U=
github.com/forPelevin/gomoji v1.3.0 h1:WPIOLWB1bvRYlKZnSSEevLt3IfKlLs+tK+YA9fFYlkE=
github.com/forPelevin/gomoji v1.3.0/go.mod h1:mM6GtmCgpoQP2usDArc6GjbXrti5+FffolyQfGgPboQ=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
Expand Down Expand Up @@ -186,16 +192,10 @@ github.com/jfrog/gofrog v1.7.6 h1:QmfAiRzVyaI7JYGsB7cxfAJePAZTzFz0gRWZSE27c6s=
github.com/jfrog/gofrog v1.7.6/go.mod h1:ntr1txqNOZtHplmaNd7rS4f8jpA5Apx8em70oYEe7+4=
github.com/jfrog/jfrog-apps-config v1.0.1 h1:mtv6k7g8A8BVhlHGlSveapqf4mJfonwvXYLipdsOFMY=
github.com/jfrog/jfrog-apps-config v1.0.1/go.mod h1:8AIIr1oY9JuH5dylz2S6f8Ym2MaadPLR6noCBO4C22w=
github.com/jfrog/jfrog-cli-artifactory v0.2.2-0.20250414045808-41544959f9b9 h1:j9bepUA23952AdytsBqGbsl4QMScksbCFXulqWvj0eY=
github.com/jfrog/jfrog-cli-artifactory v0.2.2-0.20250414045808-41544959f9b9/go.mod h1:8qrGaRb162a4NWGr7R1rj8P80s8NU8KRTs69NMkQENA=
github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20250410085750-f34f5feea93e h1:N+7gJdZmwggKqrTbrEvAFxxXQziFbJ4zHI/sXa8vR1A=
github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20250410085750-f34f5feea93e/go.mod h1:4S7yztLwWq4yA+k9j9s5gvIqr7xC/6EjJQ+0ENCHTFc=
github.com/jfrog/jfrog-cli-platform-services v1.9.0 h1:r/ETgJuMUOUu12w20ydsF6paqEaj0khH6bxMRsdNz1Y=
github.com/jfrog/jfrog-cli-platform-services v1.9.0/go.mod h1:pMZMSwhj7yA4VKyj0Skr2lObIyGpZUxNJ40DSLKXU38=
github.com/jfrog/jfrog-cli-security v1.16.3-0.20250402121228-12cce9f88504 h1:mnU8PtDaCmU1ZC8Wcy0VKj1gJEZnnyjgAc3rJLCcMjs=
github.com/jfrog/jfrog-cli-security v1.16.3-0.20250402121228-12cce9f88504/go.mod h1:tJyLh4KI4qoF/AVBy0wC9s8DVxV/hoyKK4LIzpxL590=
github.com/jfrog/jfrog-client-go v1.28.1-0.20250406105605-ee90d11546f9 h1:pEBTHYeyuDa+w0oJNCYFq1wD2O2NqWdDTAtDRFy7s3w=
github.com/jfrog/jfrog-client-go v1.28.1-0.20250406105605-ee90d11546f9/go.mod h1:uRmT8Q1SJymIzId01v0W1o8mGqrRfrwUF53CgEMsH0U=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jszwec/csvutil v1.10.0 h1:upMDUxhQKqZ5ZDCs/wy+8Kib8rZR8I8lOR34yJkdqhI=
Expand Down
120 changes: 118 additions & 2 deletions npm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
"fmt"
"github.com/jfrog/jfrog-cli-artifactory/artifactory/commands/generic"
utils2 "github.com/jfrog/jfrog-cli-core/v2/artifactory/commands/utils"
"github.com/jfrog/jfrog-cli-core/v2/artifactory/utils"
"github.com/jfrog/jfrog-client-go/http/httpclient"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -148,12 +149,119 @@ func testNpm(t *testing.T, isLegacy bool) {
inttestutils.DeleteBuild(serverDetails.ArtifactoryUrl, tests.NpmBuildName, artHttpDetails)
}

func TestNpmPublishWithNpmrc(t *testing.T) {
testNpmPublishWithNpmrc(t, validateNpmPublish, "npmpublishrcproject", tests.NpmRepo, false)
}

func TestNpmPublishWithNpmrcScoped(t *testing.T) {
testNpmPublishWithNpmrc(t, validateNpmScopedPublish, "npmpublishrcscopedproject", tests.NpmScopedRepo, true)
}

func testNpmPublishWithNpmrc(t *testing.T, validationFunc func(t *testing.T, npmTest npmTestParams, isNpm7 bool), projectName string, repoName string, isScoped bool) {
initNpmTest(t)
defer cleanNpmTest(t)
wd, err := os.Getwd()
assert.NoError(t, err, "Failed to get current dir")
defer clientTestUtils.ChangeDirAndAssert(t, wd)
buildNumber := strconv.Itoa(1)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
buildNumber := strconv.Itoa(1)
buildNumber := "1"

just wondering why not directly to string?

npmVersion, _, err := buildutils.GetNpmVersionAndExecPath(log.Logger)
if err != nil {
assert.NoError(t, err)
return
}

// Init npm project & npmp command for testing
npmProjectPath := initNpmPublishRcProjectTest(t, projectName)
configFilePath := filepath.Join(npmProjectPath, ".jfrog", "projects", "npm.yaml")

// fetch module id
packageJsonPath := npmProjectPath + "/package.json"
moduleName := readModuleId(t, packageJsonPath, npmVersion)

err = createNpmrcForTesting(configFilePath)
assert.NoError(t, err)

if isScoped {
addNpmScopeRegistryToNpmRc(t, npmProjectPath, packageJsonPath, npmVersion)
}

npmpCmd, err := publishUsingNpmrc(configFilePath, buildNumber)
Copy link
Collaborator

Choose a reason for hiding this comment

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

why is it npmp ?

assert.NoError(t, err)

result := npmpCmd.Result()
assert.NotNil(t, result)

validateNpmLocalBuildInfo(t, tests.NpmBuildName, buildNumber, moduleName)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Are we creating build info as well with --use-npmrc ?

assert.NoError(t, artifactoryCli.Exec("bp", tests.NpmBuildName, buildNumber))

// validation
testParams := npmTestParams{testName: "npm p",
nativeCommand: "npm publish",
legacyCommand: "rt npm-publish",
repo: repoName,
wd: npmProjectPath,
validationFunc: validateNpmPublish,
Copy link
Collaborator

Choose a reason for hiding this comment

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

validateNpmPublish is validating published module using artifact properties but --use-npmrc flag will not fail when it is not able to set properties. Is there any other way to validate the published artifact using --use-npmrc ?

buildNumber: buildNumber,
moduleName: moduleName,
}
validationFunc(t, testParams, false)
}

func createNpmrcForTesting(configFilePath string) (err error) {
//Creation of npmrc - npmCommand.CreateTempNpmrc() function is used to create a npmrc file used for uploading
npmCommand := npm.NewNpmCommand("install", true)
npmCommand.SetConfigFilePath(configFilePath)
npmCommand.SetServerDetails(serverDetails)
err = npmCommand.PreparePrerequisites(tests.NpmRepo)
if err != nil {
return
}
err = npmCommand.CreateTempNpmrc()
return
}

func publishUsingNpmrc(configFilePath string, buildNumber string) (npm.NpmPublishCommand, error) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

How does sample output looks with --use-npmrc ?

args := []string{"--use-npmrc=true", "--build-name=" + tests.NpmBuildName, "--build-number=" + buildNumber}
npmpCmd := npm.NewNpmPublishCommand()
npmpCmd.SetConfigFilePath(configFilePath).SetArgs(args)
err := npmpCmd.Init()
if err != nil {
return *npmpCmd, err
}
err = commands.Exec(npmpCmd)
if err != nil {
return *npmpCmd, err
}
return *npmpCmd, err
}

func readModuleId(t *testing.T, wd string, npmVersion *version.Version) string {
packageInfo, err := buildutils.ReadPackageInfoFromPackageJsonIfExists(filepath.Dir(wd), npmVersion)
assert.NoError(t, err)
return packageInfo.BuildInfoModuleId()
}

func addNpmScopeRegistryToNpmRc(t *testing.T, projectPath string, packageJsonPath string, npmVersion *version.Version) {
scope := getScopeFromPackageJson(t, packageJsonPath, npmVersion)
authConfig, err := serverDetails.CreateArtAuthConfig()
assert.NoError(t, err)
_, registry, err := utils2.GetArtifactoryNpmRepoDetails(tests.NpmScopedRepo, authConfig, false)
assert.NoError(t, err)
scopedRegistry := scope + ":registry=" + registry
npmrcFilePath := filepath.Join(projectPath, ".npmrc")
npmrcFile, err := os.OpenFile(npmrcFilePath, os.O_APPEND|os.O_WRONLY, 0644)
assert.NoError(t, err)
defer npmrcFile.Close()
_, err = npmrcFile.WriteString(scopedRegistry)
assert.NoError(t, err)
}

func getScopeFromPackageJson(t *testing.T, wd string, npmVersion *version.Version) string {
packageInfo, err := buildutils.ReadPackageInfoFromPackageJsonIfExists(filepath.Dir(wd), npmVersion)
assert.NoError(t, err)
return packageInfo.Scope
}

func TestNpmWithGlobalConfig(t *testing.T) {
initNpmTest(t)
defer cleanNpmTest(t)
Expand Down Expand Up @@ -285,6 +393,14 @@ func initNpmProjectTest(t *testing.T) (npmProjectPath string) {
return
}

func initNpmPublishRcProjectTest(t *testing.T, projectName string) (npmProjectPath string) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
func initNpmPublishRcProjectTest(t *testing.T, projectName string) (npmProjectPath string) {
func initNpmPublishviaNPMRCTest(t *testing.T, projectName string) (npmProjectPath string) {

npmProjectPath = filepath.Dir(createNpmProject(t, projectName))
err := createConfigFileForTest([]string{npmProjectPath}, tests.NpmRemoteRepo, tests.NpmRepo, t, project.Npm, false)
assert.NoError(t, err)
prepareArtifactoryForNpmBuild(t, npmProjectPath)
return
}

func initNpmWorkspacesProjectTest(t *testing.T) (npmProjectPath string) {
npmProjectPath = filepath.Dir(createNpmProject(t, "npmworkspaces"))
err := createConfigFileForTest([]string{npmProjectPath}, tests.NpmRemoteRepo, tests.NpmRepo, t, project.Npm, false)
Expand Down Expand Up @@ -361,8 +477,8 @@ func validateNpmPublish(t *testing.T, npmTestParams npmTestParams, isNpm7 bool)
}

func validateNpmScopedPublish(t *testing.T, npmTestParams npmTestParams, isNpm7 bool) {
verifyExistInArtifactoryByProps(tests.GetNpmDeployedScopedArtifacts(isNpm7),
tests.NpmRepo+"/*",
verifyExistInArtifactoryByProps(tests.GetNpmDeployedScopedArtifacts(npmTestParams.repo, isNpm7),
npmTestParams.repo+"/*",
fmt.Sprintf("build.name=%v;build.number=%v;build.timestamp=*", tests.NpmBuildName, npmTestParams.buildNumber), t)
validateNpmCommonPublish(t, npmTestParams, isNpm7, true)
}
Expand Down
17 changes: 17 additions & 0 deletions testdata/npm/npmpublishrcproject/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "jfrog-cli-tests",
"version": "1.0.0",
"description": "test package",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"xml": "1.0.1"
},
"devDependencies": {
"json": "9.0.6"
}
}
17 changes: 17 additions & 0 deletions testdata/npm/npmpublishrcscopedproject/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "@jscope/jfrog-cli-tests",
"version": "1.0.0",
"description": "test package",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"xml": "1.0.1"
},
"devDependencies": {
"json": "9.0.6"
}
}
5 changes: 5 additions & 0 deletions testdata/npm_local_scoped_repository_config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"key": "${NPM_SCOPED_REPO}",
"rclass": "local",
"packageType": "npm"
}
7 changes: 6 additions & 1 deletion utils/cliutils/commandsflags.go
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,7 @@ const (
// Unique npm flags
npmPrefix = "npm-"
npmDetailedSummary = npmPrefix + detailedSummary
useNpmRc = "use-npmrc"

// Unique nuget/dotnet config flags
nugetV2 = "nuget-v2"
Expand Down Expand Up @@ -1704,6 +1705,10 @@ var flagsMap = map[string]cli.Flag{
Name: ApplicationKey,
Usage: "[Optional] JFrog ApplicationKey Key` ` ",
},
useNpmRc: cli.BoolFlag{
Name: useNpmRc,
Usage: "[Default: false] Set to true if you'd like to use the .npmrc file for configurations. Note: This flag would invoke npm native client behind the scenes, has performance implications and does not support deployment view and detailed summary` `",
},
Comment on lines +1708 to +1711
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
useNpmRc: cli.BoolFlag{
Name: useNpmRc,
Usage: "[Default: false] Set to true if you'd like to use the .npmrc file for configurations. Note: This flag would invoke npm native client behind the scenes, has performance implications and does not support deployment view and detailed summary` `",
},
useNpmRc: cli.BoolFlag{
Name: useNPMRC,
Usage: "[Default: false] Set to true to use the .npmrc file for publish. Note: This flag would invoke npm native client behind the scenes, has performance implications and does not support deployment view and detailed summary` `",
},

}

var commandFlags = map[string][]string{
Expand Down Expand Up @@ -1853,7 +1858,7 @@ var commandFlags = map[string][]string{
BuildName, BuildNumber, module, Project,
},
NpmPublish: {
BuildName, BuildNumber, module, Project, npmDetailedSummary, xrayScan, xrOutput,
BuildName, BuildNumber, module, Project, npmDetailedSummary, xrayScan, xrOutput, useNpmRc,
},
PnpmConfig: {
global, serverIdResolve, repoResolve,
Expand Down
7 changes: 5 additions & 2 deletions utils/tests/consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ const (
MavenWithoutDeployerConfig = "maven_without_deployer.yaml"
MoveCopySpecExclusions = "move_copy_spec_exclusions.json"
NpmLocalRepositoryConfig = "npm_local_repository_config.json"
NpmLocalScopedRespositoryConfig = "npm_local_scoped_repository_config.json"
NpmRemoteRepositoryConfig = "npm_remote_repository_config.json"
NugetRemoteRepositoryConfig = "nuget_remote_repository_config.json"
Out = "out"
Expand Down Expand Up @@ -165,6 +166,7 @@ const (
XrayEndpoint = "xray/"
YarnRemoteRepositoryConfig = "yarn_remote_repository_config.json"
ReleaseLifecycleImportDependencySpec = "import_bundle_repo_dependency.json"
UseNpmRcFlag = "--use-npmrc"
)

var (
Expand All @@ -181,6 +183,7 @@ var (
MvnRepo1 = "cli-mvn1"
MvnRepo2 = "cli-mvn2"
NpmRepo = "cli-npm"
NpmScopedRepo = "cli-npm-scoped"
NpmRemoteRepo = "cli-npm-remote"
NugetRemoteRepo = "cli-nuget-remote"
YarnRemoteRepo = "cli-yarn-remote"
Expand Down Expand Up @@ -1797,8 +1800,8 @@ func GetGradleDeployedArtifacts() []string {
}
}

func GetNpmDeployedScopedArtifacts(isNpm7 bool) []string {
path := NpmRepo + "/@jscope/jfrog-cli-tests/-/@jscope/"
func GetNpmDeployedScopedArtifacts(npmRepo string, isNpm7 bool) []string {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why is this change required?

path := npmRepo + "/@jscope/jfrog-cli-tests/-/@jscope/"
path += GetNpmArtifactName(isNpm7, true)
return []string{
path,
Expand Down
5 changes: 4 additions & 1 deletion utils/tests/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ var reposConfigMap = map[*string]string{
&MvnRemoteRepo: MavenRemoteRepositoryConfig,
&GradleRemoteRepo: GradleRemoteRepositoryConfig,
&NpmRepo: NpmLocalRepositoryConfig,
&NpmScopedRepo: NpmLocalScopedRespositoryConfig,
&NpmRemoteRepo: NpmRemoteRepositoryConfig,
&NugetRemoteRepo: NugetRemoteRepositoryConfig,
&YarnRemoteRepo: YarnRemoteRepositoryConfig,
Expand Down Expand Up @@ -325,7 +326,7 @@ func GetNonVirtualRepositories() map[*string]string {
TestGo: {&GoRepo, &GoRemoteRepo},
TestGradle: {&GradleRepo, &GradleRemoteRepo},
TestMaven: {&MvnRepo1, &MvnRepo2, &MvnRemoteRepo},
TestNpm: {&NpmRepo, &NpmRemoteRepo},
TestNpm: {&NpmRepo, &NpmScopedRepo, &NpmRemoteRepo},
TestNuget: {&NugetRemoteRepo},
TestPip: {&PypiLocalRepo, &PypiRemoteRepo},
TestPipenv: {&PipenvRemoteRepo},
Expand Down Expand Up @@ -419,6 +420,7 @@ func getSubstitutionMap() map[string]string {
"${GRADLE_REMOTE_REPO}": GradleRemoteRepo,
"${GRADLE_REPO}": GradleRepo,
"${NPM_REPO}": NpmRepo,
"${NPM_SCOPED_REPO}": NpmScopedRepo,
"${NPM_REMOTE_REPO}": NpmRemoteRepo,
"${NUGET_REMOTE_REPO}": NugetRemoteRepo,
"${YARN_REMOTE_REPO}": YarnRemoteRepo,
Expand Down Expand Up @@ -488,6 +490,7 @@ func AddTimestampToGlobalVars() {
MvnRepo1 += uniqueSuffix
MvnRepo2 += uniqueSuffix
NpmRepo += uniqueSuffix
NpmScopedRepo += uniqueSuffix
NpmRemoteRepo += uniqueSuffix
NugetRemoteRepo += uniqueSuffix
YarnRemoteRepo += uniqueSuffix
Expand Down