Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package jfrog-cli for openSUSE:Factory checked in at 2025-05-20 09:37:50 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/jfrog-cli (Old) and /work/SRC/openSUSE:Factory/.jfrog-cli.new.30101 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "jfrog-cli" Tue May 20 09:37:50 2025 rev:2 rq:1278305 version:2.76.0 Changes: -------- --- /work/SRC/openSUSE:Factory/jfrog-cli/jfrog-cli.changes 2025-05-02 15:07:40.442857531 +0200 +++ /work/SRC/openSUSE:Factory/.jfrog-cli.new.30101/jfrog-cli.changes 2025-05-20 09:39:46.729908118 +0200 @@ -1,0 +2,25 @@ +Mon May 19 04:35:45 UTC 2025 - Johannes Kastl <opensuse_buildserv...@ojkastl.de> + +- Update to version 2.76.0: + * Exciting New Features + - Introduced new lifecycle annotate command by @rimapol in + #2964 + * Bug Fixes + - Fix bug to use Maven wrapper when DepTreeParams.UseWrapper is + true by @ranma2913 in jfrog/jfrog-cli-security#420 + - BuildScan - Fix parse violations if requested to show by + @attiasas in jfrog/jfrog-cli-security#422 + +------------------------------------------------------------------- +Thu May 08 08:36:47 UTC 2025 - Johannes Kastl <opensuse_buildserv...@ojkastl.de> + +- Update to version 2.75.1: + * Improvements + - Update Analyzer Manager to v1.17.0 by @attiasas in + jfrog/jfrog-cli-security#411 + * Bug Fixes + - Fix jf eot command output by @EyalDelarea in #2961 + - Added no cache flag to gradle dep tree by @eyalk007 in + jfrog/jfrog-cli-security#413 + +------------------------------------------------------------------- Old: ---- jfrog-cli-2.75.0.obscpio New: ---- jfrog-cli-2.76.0.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ jfrog-cli.spec ++++++ --- /var/tmp/diff_new_pack.lAef66/_old 2025-05-20 09:39:47.601948305 +0200 +++ /var/tmp/diff_new_pack.lAef66/_new 2025-05-20 09:39:47.601948305 +0200 @@ -19,7 +19,7 @@ %define executable_name jf Name: jfrog-cli -Version: 2.75.0 +Version: 2.76.0 Release: 0 Summary: A client that automates access to the JFrog products License: Apache-2.0 ++++++ _service ++++++ --- /var/tmp/diff_new_pack.lAef66/_old 2025-05-20 09:39:47.637949964 +0200 +++ /var/tmp/diff_new_pack.lAef66/_new 2025-05-20 09:39:47.641950148 +0200 @@ -3,7 +3,7 @@ <param name="url">https://github.com/jfrog/jfrog-cli.git</param> <param name="scm">git</param> <param name="exclude">.git</param> - <param name="revision">v2.75.0</param> + <param name="revision">v2.76.0</param> <param name="versionformat">@PARENT_TAG@</param> <param name="versionrewrite-pattern">v(.*)</param> <param name="changesgenerate">enable</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.lAef66/_old 2025-05-20 09:39:47.661951070 +0200 +++ /var/tmp/diff_new_pack.lAef66/_new 2025-05-20 09:39:47.661951070 +0200 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/jfrog/jfrog-cli.git</param> - <param name="changesrevision">5c16b02dcdebe2cb31e016efa16703ff11fcd500</param></service></servicedata> + <param name="changesrevision">b0eb1d7432d7a7ce6cafcfc12b51d52f862dfee1</param></service></servicedata> (No newline at EOF) ++++++ jfrog-cli-2.75.0.obscpio -> jfrog-cli-2.76.0.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.75.0/Jenkinsfile new/jfrog-cli-2.76.0/Jenkinsfile --- old/jfrog-cli-2.75.0/Jenkinsfile 2025-04-16 14:18:06.000000000 +0200 +++ new/jfrog-cli-2.76.0/Jenkinsfile 2025-05-18 11:14:11.000000000 +0200 @@ -31,7 +31,7 @@ repo = 'jfrog-cli' sh 'rm -rf temp' sh 'mkdir temp' - def goRoot = tool 'go-1.23.7' + def goRoot = tool 'go-1.23.9' env.GOROOT="$goRoot" env.PATH+=":${goRoot}/bin:/tmp/node-${nodeVersion}-linux-x64/bin" env.GO111MODULE="on" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.75.0/access_test.go new/jfrog-cli-2.76.0/access_test.go --- old/jfrog-cli-2.75.0/access_test.go 2025-04-16 14:18:06.000000000 +0200 +++ new/jfrog-cli-2.76.0/access_test.go 2025-05-18 11:14:11.000000000 +0200 @@ -3,9 +3,9 @@ import ( "encoding/json" "fmt" + "github.com/jfrog/jfrog-cli-core/v2/general/token" "net/http" "os" - "regexp" "testing" "github.com/jfrog/jfrog-cli-core/v2/artifactory/utils" @@ -274,30 +274,18 @@ func TestOidcExchangeToken(t *testing.T) { // If token ID was not provided by the CI, skip this test if os.Getenv(coreutils.OidcExchangeTokenId) == "" { - t.Skip("No token ID available in environment,skipping test") + t.Skip("No token ID available in environment, skipping test") return } accessCli = coreTests.NewJfrogCli(execMain, "jfrog", "") - var testCases = []struct { - name string - args []string - expectedOutput string - }{ - { - name: "Successful exchange", - args: []string{"eot", "setup-jfrog-cli-test", "--url=https://ecosysjfrog.jfrog.io"}, - expectedOutput: `\{ AccessToken: [^\s]+ Username: [^\s]+ \}`, - }, - } - for _, testCase := range testCases { - t.Run(testCase.name, func(t *testing.T) { - output := accessCli.RunCliCmdWithOutput(t, testCase.args...) - matched, err := regexp.MatchString(testCase.expectedOutput, output) - assert.NoError(t, err) - assert.True(t, matched, "Output did not match expected pattern") - }) - } + output := accessCli.RunCliCmdWithOutput(t, "eot", "setup-jfrog-cli-test", "--url=https://ecosysjfrog.jfrog.io") + var result token.ExchangeCommandOutputStruct + err := json.Unmarshal([]byte(output), &result) + assert.NoError(t, err, "Output should be valid JSON") + assert.NotEmpty(t, result.AccessToken, "AccessToken should not be empty") + assert.NotEmpty(t, result.Username, "Username should not be empty") + } func assertNotEmptyIfExpected(t *testing.T, expected bool, output string) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.75.0/build/docker/slim/Dockerfile new/jfrog-cli-2.76.0/build/docker/slim/Dockerfile --- old/jfrog-cli-2.75.0/build/docker/slim/Dockerfile 2025-04-16 14:18:06.000000000 +0200 +++ new/jfrog-cli-2.76.0/build/docker/slim/Dockerfile 2025-05-18 11:14:11.000000000 +0200 @@ -1,6 +1,6 @@ ARG repo_name_21 # Remove ${repo_name_21} to pull from Docker Hub. -FROM ${repo_name_21}/jfrog-docker/golang:1.23.7-alpine as builder +FROM ${repo_name_21}/jfrog-docker/golang:1.23.9-alpine as builder ARG image_name=jfrog-cli ARG cli_executable_name WORKDIR /${image_name} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.75.0/build/npm/v2/package-lock.json new/jfrog-cli-2.76.0/build/npm/v2/package-lock.json --- old/jfrog-cli-2.75.0/build/npm/v2/package-lock.json 2025-04-16 14:18:06.000000000 +0200 +++ new/jfrog-cli-2.76.0/build/npm/v2/package-lock.json 2025-05-18 11:14:11.000000000 +0200 @@ -1,5 +1,5 @@ { "name": "jfrog-cli-v2", - "version": "2.75.0", + "version": "2.76.0", "lockfileVersion": 2 } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.75.0/build/npm/v2/package.json new/jfrog-cli-2.76.0/build/npm/v2/package.json --- old/jfrog-cli-2.75.0/build/npm/v2/package.json 2025-04-16 14:18:06.000000000 +0200 +++ new/jfrog-cli-2.76.0/build/npm/v2/package.json 2025-05-18 11:14:11.000000000 +0200 @@ -1,6 +1,6 @@ { "name": "jfrog-cli-v2", - "version": "2.75.0", + "version": "2.76.0", "description": "🐸 Command-line interface for JFrog Artifactory, Xray, Distribution, Pipelines and Mission Control 🐸", "homepage": "https://github.com/jfrog/jfrog-cli", "preferGlobal": true, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.75.0/build/npm/v2-jf/package-lock.json new/jfrog-cli-2.76.0/build/npm/v2-jf/package-lock.json --- old/jfrog-cli-2.75.0/build/npm/v2-jf/package-lock.json 2025-04-16 14:18:06.000000000 +0200 +++ new/jfrog-cli-2.76.0/build/npm/v2-jf/package-lock.json 2025-05-18 11:14:11.000000000 +0200 @@ -1,5 +1,5 @@ { "name": "jfrog-cli-v2-jf", - "version": "2.75.0", + "version": "2.76.0", "lockfileVersion": 1 } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.75.0/build/npm/v2-jf/package.json new/jfrog-cli-2.76.0/build/npm/v2-jf/package.json --- old/jfrog-cli-2.75.0/build/npm/v2-jf/package.json 2025-04-16 14:18:06.000000000 +0200 +++ new/jfrog-cli-2.76.0/build/npm/v2-jf/package.json 2025-05-18 11:14:11.000000000 +0200 @@ -1,6 +1,6 @@ { "name": "jfrog-cli-v2-jf", - "version": "2.75.0", + "version": "2.76.0", "description": "🐸 Command-line interface for JFrog Artifactory, Xray, Distribution, Pipelines and Mission Control 🐸", "homepage": "https://github.com/jfrog/jfrog-cli", "preferGlobal": true, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.75.0/buildtools/cli.go new/jfrog-cli-2.76.0/buildtools/cli.go --- old/jfrog-cli-2.75.0/buildtools/cli.go 2025-04-16 14:18:06.000000000 +0200 +++ new/jfrog-cli-2.76.0/buildtools/cli.go 2025-05-18 11:14:11.000000000 +0200 @@ -934,9 +934,17 @@ if npmCmd.GetXrayScan() { commandsUtils.ConditionalUploadScanFunc = scan.ConditionalUploadDefaultScanFunc } - printDeploymentView, detailedSummary := log.IsStdErrTerminal(), npmCmd.IsDetailedSummary() - if !detailedSummary { - npmCmd.SetDetailedSummary(printDeploymentView) + + var printDeploymentView, detailedSummary bool + + // Deployment view and Detailed summary is not supported when using npmrc for publishing since transfer details are not available. + if npmCmd.UseNative() { + printDeploymentView, detailedSummary = false, false + } else { + printDeploymentView, detailedSummary = log.IsStdErrTerminal(), npmCmd.IsDetailedSummary() + if !detailedSummary { + npmCmd.SetDetailedSummary(printDeploymentView) + } } err = commands.Exec(npmCmd) result := npmCmd.Result() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.75.0/docker_test.go new/jfrog-cli-2.76.0/docker_test.go --- old/jfrog-cli-2.75.0/docker_test.go 2025-04-16 14:18:06.000000000 +0200 +++ new/jfrog-cli-2.76.0/docker_test.go 2025-05-18 11:14:11.000000000 +0200 @@ -179,6 +179,39 @@ validateContainerBuild(tests.DockerBuildName, buildNumber, imagePath, module, 7, 5, 7, t) } +func loginToArtifactory(t *testing.T, container *tests.TestContainer) { + password := *tests.JfrogPassword + user := *tests.JfrogUser + if *tests.JfrogAccessToken != "" { + user = auth.ExtractUsernameFromAccessToken(*tests.JfrogAccessToken) + password = *tests.JfrogAccessToken + } + assert.NoError(t, container.Exec( + context.Background(), + "docker", + "login", + tests.RtContainerHostName, + "--username="+user, + "--password="+password, + )) +} + +func buildBuilderImage(t *testing.T, workspace, dockerfile, containerName string) *tests.TestContainer { + ctx := context.Background() + testContainer, err := tests.NewContainerRequest(). + SetDockerfile(workspace, dockerfile, nil). + Privileged(). + Networks(rtNetwork). + Name(containerName). + Mount(mount.Mount{Type: mount.TypeBind, Source: workspace, Target: "/workspace", ReadOnly: false}). + Cmd("--insecure-registry", tests.RtContainerHostName). + WaitFor(wait.ForLog("API listen on /var/run/docker.sock").WithStartupTimeout(5*time.Minute)). + Remove(). + Build(ctx, true) + assert.NoError(t, err, "Couldn't create builder image.") + return testContainer +} + // This test validate the collect build-info flow for fat-manifest images. // The way we build the fat manifest and push it to Artifactory is not important. // Therefore, this test runs only with docker. @@ -194,7 +227,6 @@ assert.NoError(t, fileutils.CreateDirIfNotExist(workspace)) testDataDir := filepath.Join(filepath.FromSlash(tests.GetTestResourcesPath()), "docker") files, err := os.ReadDir(testDataDir) - assert.NoError(t, err) for _, file := range files { if !file.IsDir() { @@ -202,45 +234,23 @@ assert.NoError(t, err) } } + // Build the builder image locally. - ctx := context.Background() - testContainer, err := tests.NewContainerRequest(). - SetDockerfile(workspace, "Dockerfile.Buildx.Fatmanifest", nil). - Privileged(). - Networks(rtNetwork). - Name("buildx_container"). - Mount(mount.Mount{Type: mount.TypeBind, Source: workspace, Target: "/workspace", ReadOnly: false}). - Cmd("--insecure-registry", tests.RtContainerHostName). - // Docker daemon take times to load. In order to check if it's available we wait for a log message to indications that the Docker daemon has finished initializing. - WaitFor(wait.ForLog("API listen on /var/run/docker.sock").WithStartupTimeout(5*time.Minute)). - Remove(). - Build(ctx, true) - assert.NoError(t, err, "Couldn't run create buildx image.") - defer func() { assert.NoError(t, testContainer.Terminate(ctx)) }() + testContainer := buildBuilderImage(t, workspace, "Dockerfile.Buildx.Fatmanifest", "buildx_container") + defer func() { assert.NoError(t, testContainer.Terminate(context.Background())) }() // Enable the builder util in the container. - err = testContainer.Exec(ctx, "sh", "script.sh") + err = testContainer.Exec(context.Background(), "sh", "script.sh") assert.NoError(t, err) - // login from the builder container toward the Artifactory. - password := *tests.JfrogPassword - user := *tests.JfrogUser - if *tests.JfrogAccessToken != "" { - user = auth.ExtractUsernameFromAccessToken(*tests.JfrogAccessToken) - password = *tests.JfrogAccessToken - } - assert.NoError(t, testContainer.Exec( - ctx, - "docker", - "login", - tests.RtContainerHostName, - "--username="+user, - "--password="+password)) + // Login to Artifactory + loginToArtifactory(t, testContainer) + buildxOutputFile := "buildmetadata" - // Run the builder in the container and push the fat-manifest image to artifactory + // Run the builder in the container and push the fat-manifest image to Artifactory assert.NoError(t, testContainer.Exec( - ctx, + context.Background(), "docker", "buildx", "build", @@ -263,20 +273,83 @@ assert.NoError(t, artifactoryCli.Exec("build-docker-create", tests.DockerLocalRepo, "--image-file="+buildxOutput, "--build-name="+buildName, "--build-number="+buildNumber)) assert.NoError(t, artifactoryCli.Exec("build-publish", buildName, buildNumber)) - // Validate the published build-info exits + // Validate the published build-info exists publishedBuildInfo, found, err := tests.GetBuildInfo(serverDetails, buildName, buildNumber) - if err != nil { - assert.NoError(t, err) - return + assert.NoError(t, err) + assert.True(t, found, "build info was expected to be found") + assert.True(t, len(publishedBuildInfo.BuildInfo.Modules) > 1) + + // Validate build-name & build-number properties in all image layers + searchSpec := spec.NewBuilder().Pattern(tests.DockerLocalRepo + "/*").Build(buildName).Recursive(true).BuildSpec() + searchCmd := generic.NewSearchCommand() + searchCmd.SetServerDetails(serverDetails).SetSpec(searchSpec) + reader, err := searchCmd.Search() + assert.NoError(t, err) + totalResults, err := reader.Length() + assert.NoError(t, err) + assert.True(t, totalResults > 1) +} + +func TestPushMultiTaggedImage(t *testing.T) { + if !*tests.TestDocker { + t.Skip("Skipping test. To run it, add the '-test.docker=true' option.") } - if !found { - assert.True(t, found, "build info was expected to be found") - return + + buildName := "push-multi-tagged" + tests.DockerBuildName + buildNumber := "1" + + // Setup workspace + workspace, err := filepath.Abs(tests.Out) + assert.NoError(t, err) + assert.NoError(t, fileutils.CreateDirIfNotExist(workspace)) + testDataDir := filepath.Join(filepath.FromSlash(tests.GetTestResourcesPath()), "docker") + files, err := os.ReadDir(testDataDir) + assert.NoError(t, err) + for _, file := range files { + if !file.IsDir() { + _, err := tests.ReplaceTemplateVariables(filepath.Join(testDataDir, file.Name()), tests.Out) + assert.NoError(t, err) + } } - assert.True(t, len(publishedBuildInfo.BuildInfo.Modules) > 1) + // Build the builder image locally + testContainer := buildBuilderImage(t, workspace, "Dockerfile.Buildx.Fatmanifest", "buildx_multi_tag_container") + defer func() { assert.NoError(t, testContainer.Terminate(context.Background())) }() + + // Enable builder + assert.NoError(t, testContainer.Exec(context.Background(), "sh", "script.sh")) + + // Login to Artifactory + loginToArtifactory(t, testContainer) + + // Build & push image with multiple tags + imageName1 := path.Join(tests.RtContainerHostName, tests.DockerLocalRepo, tests.DockerImageName+"-multi:v1") + imageName2 := path.Join(tests.RtContainerHostName, tests.DockerLocalRepo, tests.DockerImageName+"-multi:latest") + buildxOutputFile := "multi-build-metadata" - // Validate build-name & build-number properties in all image layers + assert.NoError(t, testContainer.Exec( + context.Background(), + "docker", "buildx", "build", + "--platform", "linux/amd64,linux/arm64", + "-t", imageName1, + "-t", imageName2, + "-f", "Dockerfile.Fatmanifest", + "--metadata-file", "/workspace/"+buildxOutputFile, + "--push", ".", + )) + + // Run build-docker-create & publish + buildxOutput := filepath.Join(workspace, buildxOutputFile) + assert.NoError(t, artifactoryCli.Exec("build-docker-create", tests.DockerLocalRepo, "--image-file="+buildxOutput, "--build-name="+buildName, "--build-number="+buildNumber)) + assert.NoError(t, artifactoryCli.Exec("build-publish", buildName, buildNumber)) + + // Validate build-info is published + publishedBuildInfo, found, err := tests.GetBuildInfo(serverDetails, buildName, buildNumber) + assert.NoError(t, err) + assert.True(t, found, "build info was expected to be found") + assert.True(t, len(publishedBuildInfo.BuildInfo.Modules) >= 1) + + // Validate build-name & build-number properties in all layers searchSpec := spec.NewBuilder().Pattern(tests.DockerLocalRepo + "/*").Build(buildName).Recursive(true).BuildSpec() searchCmd := generic.NewSearchCommand() searchCmd.SetServerDetails(serverDetails).SetSpec(searchSpec) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.75.0/go.mod new/jfrog-cli-2.76.0/go.mod --- old/jfrog-cli-2.75.0/go.mod 2025-04-16 14:18:06.000000000 +0200 +++ new/jfrog-cli-2.76.0/go.mod 2025-05-18 11:14:11.000000000 +0200 @@ -1,6 +1,6 @@ module github.com/jfrog/jfrog-cli -go 1.23.7 +go 1.23.9 replace ( // Should not be updated to 0.2.6 due to a bug (https://github.com/jfrog/jfrog-cli-core/pull/372) @@ -16,13 +16,13 @@ github.com/docker/docker v27.5.1+incompatible github.com/gocarina/gocsv v0.0.0-20240520201108-78e41c74b4b1 github.com/jfrog/archiver/v3 v3.6.1 - github.com/jfrog/build-info-go v1.10.10 + github.com/jfrog/build-info-go v1.10.12 github.com/jfrog/gofrog v1.7.6 - github.com/jfrog/jfrog-cli-artifactory v0.2.4 - github.com/jfrog/jfrog-cli-core/v2 v2.58.4 + github.com/jfrog/jfrog-cli-artifactory v0.3.0 + github.com/jfrog/jfrog-cli-core/v2 v2.58.6 github.com/jfrog/jfrog-cli-platform-services v1.9.0 - github.com/jfrog/jfrog-cli-security v1.17.0 - github.com/jfrog/jfrog-client-go v1.52.0 + github.com/jfrog/jfrog-cli-security v1.17.2 + github.com/jfrog/jfrog-client-go v1.53.0 github.com/jszwec/csvutil v1.10.0 github.com/manifoldco/promptui v0.9.0 github.com/stretchr/testify v1.10.0 @@ -189,10 +189,10 @@ 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/jfrog/jfrog-cli-artifactory v0.2.5-0.20250514065555-2ad0e403ae04 -// 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/jfrog/jfrog-cli-core/v2 v2.31.1-0.20250514055103-d3d0d25f7c85 -// 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/jfrog/jfrog-client-go v1.28.1-0.20250508130334-f159cff9b11a -// replace github.com/jfrog/jfrog-cli-security => github.com/jfrog/jfrog-cli-security v1.16.3-0.20250402121228-12cce9f88504 +//replace github.com/jfrog/jfrog-cli-security => github.com/jfrog/jfrog-cli-security v1.17.2-0.20250511132918-d9cc4cd50020 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.75.0/go.sum new/jfrog-cli-2.76.0/go.sum --- old/jfrog-cli-2.75.0/go.sum 2025-04-16 14:18:06.000000000 +0200 +++ new/jfrog-cli-2.76.0/go.sum 2025-05-18 11:14:11.000000000 +0200 @@ -176,8 +176,8 @@ github.com/jedib0t/go-pretty/v6 v6.6.5/go.mod h1:Uq/HrbhuFty5WSVNfjpQQe47x16RwVGXIveNGEyGtHs= github.com/jfrog/archiver/v3 v3.6.1 h1:LOxnkw9pOn45DzCbZNFV6K0+6dCsQ0L8mR3ZcujO5eI= github.com/jfrog/archiver/v3 v3.6.1/go.mod h1:VgR+3WZS4N+i9FaDwLZbq+jeU4B4zctXL+gL4EMzfLw= -github.com/jfrog/build-info-go v1.10.10 h1:2nOFjV7SX1uisi2rQK7fb4Evm7YkSOdmssrm6Tf4ipc= -github.com/jfrog/build-info-go v1.10.10/go.mod h1:JcISnovFXKx3wWf3p1fcMmlPdt6adxScXvoJN4WXqIE= +github.com/jfrog/build-info-go v1.10.12 h1:KO/YUeKYtDrnpcmsXmwqr6akjzrwA0hSTUB+Op/HF88= +github.com/jfrog/build-info-go v1.10.12/go.mod h1:JcISnovFXKx3wWf3p1fcMmlPdt6adxScXvoJN4WXqIE= github.com/jfrog/froggit-go v1.17.0 h1:20Ie787WO27SwB2MOHDvsR6yN7fA5WfRnuAbmUqz1Zs= github.com/jfrog/froggit-go v1.17.0/go.mod h1:HvDkfFfJwIdsXFdqaB+utvD2cLDRmaC3kF8otYb6Chw= github.com/jfrog/go-mockhttp v0.3.1 h1:/wac8v4GMZx62viZmv4wazB5GNKs+GxawuS1u3maJH8= @@ -186,16 +186,16 @@ 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.4 h1:n/BlqkH20jW8T1JPr/QHw+D+wsPZsDU0Qq/+eSGzgAg= -github.com/jfrog/jfrog-cli-artifactory v0.2.4/go.mod h1:tXlrvTtG4l0dPdKFG7nlteuSv7vggF/OVwsq44sgVgA= -github.com/jfrog/jfrog-cli-core/v2 v2.58.4 h1:ywpq2UMOPtp9WcELR54HSJJS0PSgin9plM4If9sDks0= -github.com/jfrog/jfrog-cli-core/v2 v2.58.4/go.mod h1:JbLdMCWL0xVZZ0FY7jd+iTi/gKYqRmRpeLBhAFtldfQ= +github.com/jfrog/jfrog-cli-artifactory v0.3.0 h1:nodmuOauNSx2OKwQChQ1fLcnhNs+tgWpOk9caMdAuoI= +github.com/jfrog/jfrog-cli-artifactory v0.3.0/go.mod h1:BliRZeMdqVEKHOtREuowYBgNqwVAFcKY0/veOxQDjwo= +github.com/jfrog/jfrog-cli-core/v2 v2.58.6 h1:cCg9o0M2p52qCnO0Y+Ry8lxbVIJDJy4s948li2UIYaM= +github.com/jfrog/jfrog-cli-core/v2 v2.58.6/go.mod h1:VjXJpjapnKA0eBoCH9+5+nWQOxQJ+uzADMY2DQPkCzE= 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.17.0 h1:K+jtXmT/tNyCYfcbiJUfSgKpHXGrpM1J507Pbi2DXGE= -github.com/jfrog/jfrog-cli-security v1.17.0/go.mod h1:655eM28gQHUdT6IC6uQf677tqrN1wEcPRzc+8vcM/vA= -github.com/jfrog/jfrog-client-go v1.52.0 h1:MCmHviUqj3X7iqyOokTkyvV5yBWFwZYDPVXYikl4nf0= -github.com/jfrog/jfrog-client-go v1.52.0/go.mod h1:uRmT8Q1SJymIzId01v0W1o8mGqrRfrwUF53CgEMsH0U= +github.com/jfrog/jfrog-cli-security v1.17.2 h1:368C9S11uiPffYUyy1Q076XmUh7+XrSuIqfqc4izIig= +github.com/jfrog/jfrog-cli-security v1.17.2/go.mod h1:IkjG18ZIe9oHnZIHRlSs6L7Ddlbreiiwtq1BqQiEe70= +github.com/jfrog/jfrog-client-go v1.53.0 h1:oCNuxEtN2VWcbqGdIp1tdYupm7PJZP53etX1Pr24kxY= +github.com/jfrog/jfrog-client-go v1.53.0/go.mod h1:IKmGx4sYeaiSKBnVzp/j6lVrmyRAXTABfo3B02SPxXI= 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= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.75.0/lifecycle_test.go new/jfrog-cli-2.76.0/lifecycle_test.go --- old/jfrog-cli-2.75.0/lifecycle_test.go 2025-04-16 14:18:06.000000000 +0200 +++ new/jfrog-cli-2.76.0/lifecycle_test.go 2025-05-18 11:14:11.000000000 +0200 @@ -12,12 +12,14 @@ "github.com/jfrog/jfrog-cli/inttestutils" "github.com/jfrog/jfrog-cli/utils/cliutils" "github.com/jfrog/jfrog-cli/utils/tests" + artifactoryclientUtils "github.com/jfrog/jfrog-client-go/artifactory/services/utils" "github.com/jfrog/jfrog-client-go/http/httpclient" "github.com/jfrog/jfrog-client-go/lifecycle" "github.com/jfrog/jfrog-client-go/lifecycle/services" clientUtils "github.com/jfrog/jfrog-client-go/utils" "github.com/jfrog/jfrog-client-go/utils/errorutils" "github.com/jfrog/jfrog-client-go/utils/io/fileutils" + "github.com/jfrog/jfrog-client-go/utils/log" clientTestUtils "github.com/jfrog/jfrog-client-go/utils/tests" "github.com/stretchr/testify/assert" "net/http" @@ -40,6 +42,9 @@ prodEnvironment = "PROD" number1, number2, number3 = "111", "222", "333" withoutSigningKey = true + artifactoryLifecycleSetTagMinVersion = "7.111.0" + rbManifestName = "release-bundle.json.evd" + releaseBundlesV2 = "release-bundles-v2" ) var ( @@ -456,6 +461,174 @@ time.Sleep(5 * time.Second) } +func TestSetReleaseBundleTag(t *testing.T) { + cleanCallback := initLifecycleTest(t, artifactoryLifecycleSetTagMinVersion) + defer cleanCallback() + lcManager := getLcServiceManager(t) + + deleteBuilds := uploadBuilds(t) + defer deleteBuilds() + + // set tag + createRbFromSpec(t, tests.LifecycleBuilds12, tests.LcRbName1, number1, true, true) + defer deleteReleaseBundle(t, lcManager, tests.LcRbName1, number1) + + assertStatusCompleted(t, lcManager, tests.LcRbName1, number1, "") + setReleaseBundleTag(t, lcManager, tests.LcRbName1, number1, "", "bundle-tag") + + // unset tag + createRbFromSpec(t, tests.LifecycleBuilds12, tests.LcRbName2, number1, true, true) + defer deleteReleaseBundle(t, lcManager, tests.LcRbName2, number1) + assertStatusCompleted(t, lcManager, tests.LcRbName2, number1, "") + setReleaseBundleTag(t, lcManager, tests.LcRbName1, number1, "", "bundle-tag") + unsetReleaseBundleTag(t, lcManager, tests.LcRbName1, number1) +} + +func unsetReleaseBundleTag(t *testing.T, lcManager *lifecycle.LifecycleServicesManager, rbName, version string) { + setReleaseBundleTag(t, lcManager, rbName, version, "", "") +} + +func TestReleaseBundleCreateOrUpdateProperties(t *testing.T) { + cleanCallback := initLifecycleTest(t, artifactoryLifecycleSetTagMinVersion) + defer cleanCallback() + lcManager := getLcServiceManager(t) + + deleteBuilds := uploadBuilds(t) + defer deleteBuilds() + + // set properties + createRbFromSpec(t, tests.LifecycleBuilds12, tests.LcRbName1, number1, true, true) + defer deleteReleaseBundle(t, lcManager, tests.LcRbName1, number1) + assertStatusCompleted(t, lcManager, tests.LcRbName1, number1, "") + setReleaseBundleProperties(t, lcManager, tests.LcRbName1, number1, "default", + "key1=value1;key2=value2") + setReleaseBundleProperties(t, lcManager, tests.LcRbName1, number1, "default", + "key1=value1;key2=''") +} + +func TestReleaseBundleDeleteProperties(t *testing.T) { + cleanCallback := initLifecycleTest(t, artifactoryLifecycleSetTagMinVersion) + defer cleanCallback() + lcManager := getLcServiceManager(t) + + deleteBuilds := uploadBuilds(t) + defer deleteBuilds() + + // set and delete properties + createRbFromSpec(t, tests.LifecycleBuilds12, tests.LcRbName1, number1, true, true) + defer deleteReleaseBundle(t, lcManager, tests.LcRbName1, number1) + assertStatusCompleted(t, lcManager, tests.LcRbName1, number1, "") + setReleaseBundleProperties(t, lcManager, tests.LcRbName1, number1, "default", + "key1=value1;key2=value2") + deleteReleaseBundleProperties(t, lcManager, tests.LcRbName1, number1, "default", "key1,key2") +} + +func deleteReleaseBundleProperties(t *testing.T, lcManager *lifecycle.LifecycleServicesManager, rbName, + rbVersion, projectKey, delProps string) { + rbDetails := services.ReleaseBundleDetails{ + ReleaseBundleName: rbName, + ReleaseBundleVersion: rbVersion, + } + queryParams := services.CommonOptionalQueryParams{ + Async: false, + ProjectKey: projectKey, + } + + annotateParams := buildAnnotateParams("", "", delProps, false, false, + true, rbDetails, queryParams) + assert.NoError(t, lcManager.AnnotateReleaseBundle(annotateParams)) + // Wait after remote deleting. Can be removed once remote deleting supports sync. + time.Sleep(5 * time.Second) +} + +func setReleaseBundleTag(t *testing.T, lcManager *lifecycle.LifecycleServicesManager, rbName, rbVersion, + projectKey, tag string) { + log.Info(fmt.Sprintf("Setting release bundle tag=%s to: %s/%s", tag, rbName, rbVersion)) + rbDetails := services.ReleaseBundleDetails{ + ReleaseBundleName: rbName, + ReleaseBundleVersion: rbVersion, + } + queryParams := services.CommonOptionalQueryParams{ + Async: false, + ProjectKey: projectKey, + } + + annotateParams := buildAnnotateParams(tag, "", "", true, false, false, + rbDetails, queryParams) + assert.NoError(t, lcManager.AnnotateReleaseBundle(annotateParams)) + // Wait after remote deleting. Can be removed once remote deleting supports sync. + time.Sleep(5 * time.Second) +} + +func setReleaseBundleProperties(t *testing.T, lcManager *lifecycle.LifecycleServicesManager, rbName, rbVersion, + projectKey, properties string) { + rbDetails := services.ReleaseBundleDetails{ + ReleaseBundleName: rbName, + ReleaseBundleVersion: rbVersion, + } + queryParams := services.CommonOptionalQueryParams{ + Async: false, + ProjectKey: projectKey, + } + + annotateParams := buildAnnotateParams("", properties, "", false, true, + false, rbDetails, queryParams) + assert.NoError(t, lcManager.AnnotateReleaseBundle(annotateParams)) + // Wait after remote deleting. Can be removed once remote deleting supports sync. + time.Sleep(5 * time.Second) +} + +func buildAnnotateParams(tag, properties, keysToDelete string, tagExists, propsExist, delExist bool, rbDetails services.ReleaseBundleDetails, + queryParams services.CommonOptionalQueryParams) services.AnnotateOperationParams { + return services.AnnotateOperationParams{ + RbTag: services.RbAnnotationTag{ + Tag: tag, + Exist: tagExists, + }, + RbProps: services.RbAnnotationProps{ + Properties: resolveProps(properties), + Exist: propsExist, + }, + RbDelProps: services.RbDelProps{ + Keys: keysToDelete, + Exist: delExist, + }, + RbDetails: rbDetails, + QueryParams: queryParams, + PropertyParams: services.CommonPropParams{ + Path: buildManifestPath(queryParams.ProjectKey, rbDetails.ReleaseBundleName, rbDetails.ReleaseBundleVersion), + Recursive: false, + }, + ArtifactoryUrl: services.ArtCommonParams{ + Url: serverDetails.ArtifactoryUrl, + }, + } +} + +func buildManifestPath(projectKey, bundleName, bundleVersion string) string { + return fmt.Sprintf("%s/%s/%s/%s", buildRepoKey(projectKey), bundleName, bundleVersion, rbManifestName) +} + +func buildRepoKey(project string) string { + if project == "" || project == "default" { + return releaseBundlesV2 + } + return fmt.Sprintf("%s-%s", project, releaseBundlesV2) +} + +func resolveProps(properties string) map[string][]string { + if properties == "" { + return make(map[string][]string) + } + + props, err := artifactoryclientUtils.ParseProperties(properties) + if err != nil { + return make(map[string][]string) + } + + return props.ToMap() +} + /* func remoteDeleteReleaseBundle(t *testing.T, lcManager *lifecycle.LifecycleServicesManager, rbName, rbVersion string) { params := distribution.NewDistributeReleaseBundleParams(rbName, rbVersion) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.75.0/npm_test.go new/jfrog-cli-2.76.0/npm_test.go --- old/jfrog-cli-2.75.0/npm_test.go 2025-04-16 14:18:06.000000000 +0200 +++ new/jfrog-cli-2.76.0/npm_test.go 2025-05-18 11:14:11.000000000 +0200 @@ -3,6 +3,7 @@ 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" @@ -148,12 +149,162 @@ 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 := "1" + 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(t, configFilePath) + assert.NoError(t, err) + + if isScoped { + addNpmScopeRegistryToNpmRc(t, npmProjectPath, packageJsonPath, npmVersion) + } + + npmpCmd, err := publishUsingNpmrc(configFilePath, buildNumber) + assert.NoError(t, err) + + result := npmpCmd.Result() + assert.NotNil(t, result) + + validateNpmLocalBuildInfo(t, tests.NpmBuildName, buildNumber, moduleName) + 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, + buildNumber: buildNumber, + moduleName: moduleName, + } + validationFunc(t, testParams, false) +} + +func TestNpmInstallClientNative(t *testing.T) { + initNpmTest(t) + defer cleanNpmTest(t) + wd, err := os.Getwd() + assert.NoError(t, err, "Failed to get current dir") + defer clientTestUtils.ChangeDirAndAssert(t, wd) + + npmVersion, _, err := buildutils.GetNpmVersionAndExecPath(log.Logger) + if err != nil { + assert.NoError(t, err) + return + } + buildNumber := "1" + + npmProjectDirectory := initNpmProjectTest(t) + configFilePath := filepath.Join(npmProjectDirectory, ".jfrog", "projects", "npm.yaml") + err = createNpmrcForTesting(t, configFilePath) + assert.NoError(t, err) + + clientTestUtils.ChangeDirAndAssert(t, npmProjectDirectory) + npmrcFileInfo, err := os.Stat(".npmrc") + if err != nil && os.IsNotExist(err) { + assert.Fail(t, err.Error()) + } + + packageJsonPath := npmProjectDirectory + "/package.json" + moduleName := readModuleId(t, packageJsonPath, npmVersion) + runJfrogCli(t, "npm", "i", "--run-native=true", "--build-name="+tests.NpmBuildName, "--build-number="+buildNumber) + validateNpmLocalBuildInfo(t, tests.NpmBuildName, buildNumber, moduleName) + assert.NoError(t, artifactoryCli.Exec("bp", tests.NpmBuildName, buildNumber)) + + npmTest := npmTestParams{ + testName: "npm with run-native", + buildNumber: buildNumber, + npmArgs: "--run-native=true", + } + + validateNpmInstall(t, npmTest, isNpm7(npmVersion)) + postTestFileInfo, postTestFileInfoErr := os.Stat(".npmrc") + validateNpmrcFileInfo(t, npmTest, npmrcFileInfo, postTestFileInfo, err, postTestFileInfoErr) + validateIfFileWasEverModified(t, npmrcFileInfo, postTestFileInfo) +} + +func createNpmrcForTesting(t *testing.T, configFilePath string) (err error) { + // Creation of npmrc - npmCommand.CreateTempNpmrc() function is used to create a npmrc file + npmCommand := npm.NewNpmCommand("install", true) + npmCommand.SetConfigFilePath(configFilePath) + npmCommand.SetServerDetails(serverDetails) + err = npmCommand.Init() + assert.NoError(t, err) + err = npmCommand.PreparePrerequisites(tests.NpmRepo) + assert.NoError(t, err) + err = npmCommand.CreateTempNpmrc() + return +} + +func publishUsingNpmrc(configFilePath string, buildNumber string) (npm.NpmPublishCommand, error) { + args := []string{"--run-native=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) @@ -261,6 +412,11 @@ assert.Nil(t, bcpNpmrc, "The file 'jfrog.npmrc.backup' was supposed to be deleted but it was not when running the configuration:\n%v", npmTest) } +// if file was backed up then it's mod time should be changed +func validateIfFileWasEverModified(t *testing.T, fileInfo, postTestFileInfo os.FileInfo) { + assert.Equal(t, fileInfo.ModTime(), postTestFileInfo.ModTime()) +} + func initNpmFilesTest(t *testing.T) (npmProjectPath, npmScopedProjectPath, npmNpmrcProjectPath, npmProjectCi, npmPostInstallProjectPath string) { npmProjectPath = createNpmProject(t, "npmproject") npmScopedProjectPath = createNpmProject(t, "npmscopedproject") @@ -285,6 +441,14 @@ return } +func initNpmPublishRcProjectTest(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) @@ -361,8 +525,8 @@ } 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) } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.75.0/testdata/npm/npmpublishrcproject/package.json new/jfrog-cli-2.76.0/testdata/npm/npmpublishrcproject/package.json --- old/jfrog-cli-2.75.0/testdata/npm/npmpublishrcproject/package.json 1970-01-01 01:00:00.000000000 +0100 +++ new/jfrog-cli-2.76.0/testdata/npm/npmpublishrcproject/package.json 2025-05-18 11:14:11.000000000 +0200 @@ -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" + } +} \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.75.0/testdata/npm/npmpublishrcscopedproject/package.json new/jfrog-cli-2.76.0/testdata/npm/npmpublishrcscopedproject/package.json --- old/jfrog-cli-2.75.0/testdata/npm/npmpublishrcscopedproject/package.json 1970-01-01 01:00:00.000000000 +0100 +++ new/jfrog-cli-2.76.0/testdata/npm/npmpublishrcscopedproject/package.json 2025-05-18 11:14:11.000000000 +0200 @@ -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" + } +} \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.75.0/testdata/npm_local_scoped_repository_config.json new/jfrog-cli-2.76.0/testdata/npm_local_scoped_repository_config.json --- old/jfrog-cli-2.75.0/testdata/npm_local_scoped_repository_config.json 1970-01-01 01:00:00.000000000 +0100 +++ new/jfrog-cli-2.76.0/testdata/npm_local_scoped_repository_config.json 2025-05-18 11:14:11.000000000 +0200 @@ -0,0 +1,5 @@ +{ + "key": "${NPM_SCOPED_REPO}", + "rclass": "local", + "packageType": "npm" +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.75.0/utils/cliutils/cli_consts.go new/jfrog-cli-2.76.0/utils/cliutils/cli_consts.go --- old/jfrog-cli-2.75.0/utils/cliutils/cli_consts.go 2025-04-16 14:18:06.000000000 +0200 +++ new/jfrog-cli-2.76.0/utils/cliutils/cli_consts.go 2025-05-18 11:14:11.000000000 +0200 @@ -4,7 +4,7 @@ const ( // General CLI constants - CliVersion = "2.75.0" + CliVersion = "2.76.0" ClientAgent = "jfrog-cli-go" // CLI base commands constants: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.75.0/utils/cliutils/commandsflags.go new/jfrog-cli-2.76.0/utils/cliutils/commandsflags.go --- old/jfrog-cli-2.75.0/utils/cliutils/commandsflags.go 2025-04-16 14:18:06.000000000 +0200 +++ new/jfrog-cli-2.76.0/utils/cliutils/commandsflags.go 2025-05-18 11:14:11.000000000 +0200 @@ -363,6 +363,7 @@ // Unique npm flags npmPrefix = "npm-" npmDetailedSummary = npmPrefix + detailedSummary + runNative = "run-native" // Unique nuget/dotnet config flags nugetV2 = "nuget-v2" @@ -1704,6 +1705,10 @@ Name: ApplicationKey, Usage: "[Optional] JFrog ApplicationKey Key` ` ", }, + runNative: cli.BoolFlag{ + Name: runNative, + Usage: "[Default: false] Set to true if you'd like to use the native client configurations. Note: This flag would invoke native client behind the scenes, has performance implications and does not support deployment view and detailed summary` `", + }, } var commandFlags = map[string][]string{ @@ -1850,10 +1855,10 @@ global, serverIdResolve, serverIdDeploy, repoResolve, repoDeploy, }, NpmInstallCi: { - BuildName, BuildNumber, module, Project, + BuildName, BuildNumber, module, Project, runNative, }, NpmPublish: { - BuildName, BuildNumber, module, Project, npmDetailedSummary, xrayScan, xrOutput, + BuildName, BuildNumber, module, Project, npmDetailedSummary, xrayScan, xrOutput, runNative, }, PnpmConfig: { global, serverIdResolve, repoResolve, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.75.0/utils/tests/consts.go new/jfrog-cli-2.76.0/utils/tests/consts.go --- old/jfrog-cli-2.75.0/utils/tests/consts.go 2025-04-16 14:18:06.000000000 +0200 +++ new/jfrog-cli-2.76.0/utils/tests/consts.go 2025-05-18 11:14:11.000000000 +0200 @@ -88,6 +88,7 @@ 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" @@ -165,6 +166,7 @@ XrayEndpoint = "xray/" YarnRemoteRepositoryConfig = "yarn_remote_repository_config.json" ReleaseLifecycleImportDependencySpec = "import_bundle_repo_dependency.json" + UseNpmRcFlag = "--use-npmrc" ) var ( @@ -181,6 +183,7 @@ 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" @@ -1797,8 +1800,8 @@ } } -func GetNpmDeployedScopedArtifacts(isNpm7 bool) []string { - path := NpmRepo + "/@jscope/jfrog-cli-tests/-/@jscope/" +func GetNpmDeployedScopedArtifacts(npmRepo string, isNpm7 bool) []string { + path := npmRepo + "/@jscope/jfrog-cli-tests/-/@jscope/" path += GetNpmArtifactName(isNpm7, true) return []string{ path, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.75.0/utils/tests/utils.go new/jfrog-cli-2.76.0/utils/tests/utils.go --- old/jfrog-cli-2.75.0/utils/tests/utils.go 2025-04-16 14:18:06.000000000 +0200 +++ new/jfrog-cli-2.76.0/utils/tests/utils.go 2025-05-18 11:14:11.000000000 +0200 @@ -262,6 +262,7 @@ &MvnRemoteRepo: MavenRemoteRepositoryConfig, &GradleRemoteRepo: GradleRemoteRepositoryConfig, &NpmRepo: NpmLocalRepositoryConfig, + &NpmScopedRepo: NpmLocalScopedRespositoryConfig, &NpmRemoteRepo: NpmRemoteRepositoryConfig, &NugetRemoteRepo: NugetRemoteRepositoryConfig, &YarnRemoteRepo: YarnRemoteRepositoryConfig, @@ -325,7 +326,7 @@ TestGo: {&GoRepo, &GoRemoteRepo}, TestGradle: {&GradleRepo, &GradleRemoteRepo}, TestMaven: {&MvnRepo1, &MvnRepo2, &MvnRemoteRepo}, - TestNpm: {&NpmRepo, &NpmRemoteRepo}, + TestNpm: {&NpmRepo, &NpmScopedRepo, &NpmRemoteRepo}, TestNuget: {&NugetRemoteRepo}, TestPip: {&PypiLocalRepo, &PypiRemoteRepo}, TestPipenv: {&PipenvRemoteRepo}, @@ -419,6 +420,7 @@ "${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, @@ -488,6 +490,7 @@ MvnRepo1 += uniqueSuffix MvnRepo2 += uniqueSuffix NpmRepo += uniqueSuffix + NpmScopedRepo += uniqueSuffix NpmRemoteRepo += uniqueSuffix NugetRemoteRepo += uniqueSuffix YarnRemoteRepo += uniqueSuffix ++++++ jfrog-cli.obsinfo ++++++ --- /var/tmp/diff_new_pack.lAef66/_old 2025-05-20 09:39:48.509990151 +0200 +++ /var/tmp/diff_new_pack.lAef66/_new 2025-05-20 09:39:48.513990335 +0200 @@ -1,5 +1,5 @@ name: jfrog-cli -version: 2.75.0 -mtime: 1744805886 -commit: 5c16b02dcdebe2cb31e016efa16703ff11fcd500 +version: 2.76.0 +mtime: 1747559651 +commit: b0eb1d7432d7a7ce6cafcfc12b51d52f862dfee1 ++++++ vendor.tar.gz ++++++ /work/SRC/openSUSE:Factory/jfrog-cli/vendor.tar.gz /work/SRC/openSUSE:Factory/.jfrog-cli.new.30101/vendor.tar.gz differ: char 28, line 1