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 2026-01-23 17:32:40 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/jfrog-cli (Old) and /work/SRC/openSUSE:Factory/.jfrog-cli.new.1928 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "jfrog-cli" Fri Jan 23 17:32:40 2026 rev:24 rq:1328785 version:2.89.0 Changes: -------- --- /work/SRC/openSUSE:Factory/jfrog-cli/jfrog-cli.changes 2026-01-12 10:32:40.057515791 +0100 +++ /work/SRC/openSUSE:Factory/.jfrog-cli.new.1928/jfrog-cli.changes 2026-01-23 17:32:58.533710847 +0100 @@ -1,0 +2,13 @@ +Fri Jan 23 06:13:12 UTC 2026 - Johannes Kastl <[email protected]> + +- Update to version 2.89.0: + * Exciting New Features + - feature: Automatically set CI VCS properties on uploaded + artifacts by @bhanurp in #3309 + * Other Changes + - JGC-489 - Fix release by @RemiBou in #3305 + - RTDEV-73424 - Set + TestReleaseBundleCreationFromMultipleSourcesUsingSp… by + @rimapol in #3315 + +------------------------------------------------------------------- Old: ---- jfrog-cli-2.88.0.obscpio New: ---- jfrog-cli-2.89.0.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ jfrog-cli.spec ++++++ --- /var/tmp/diff_new_pack.Svn8BS/_old 2026-01-23 17:32:59.549752390 +0100 +++ /var/tmp/diff_new_pack.Svn8BS/_new 2026-01-23 17:32:59.553752554 +0100 @@ -19,7 +19,7 @@ %define executable_name jf Name: jfrog-cli -Version: 2.88.0 +Version: 2.89.0 Release: 0 Summary: A client that automates access to the JFrog products License: Apache-2.0 ++++++ _service ++++++ --- /var/tmp/diff_new_pack.Svn8BS/_old 2026-01-23 17:32:59.589754026 +0100 +++ /var/tmp/diff_new_pack.Svn8BS/_new 2026-01-23 17:32:59.597754353 +0100 @@ -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.88.0</param> + <param name="revision">v2.89.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.Svn8BS/_old 2026-01-23 17:32:59.625755498 +0100 +++ /var/tmp/diff_new_pack.Svn8BS/_new 2026-01-23 17:32:59.629755662 +0100 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/jfrog/jfrog-cli.git</param> - <param name="changesrevision">44fd2c0f1476d459cb5c4183f19a3888da083824</param></service></servicedata> + <param name="changesrevision">32cfd666f45f328a478ecfdea677bef827238de9</param></service></servicedata> (No newline at EOF) ++++++ jfrog-cli-2.88.0.obscpio -> jfrog-cli-2.89.0.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.88.0/artifactory_test.go new/jfrog-cli-2.89.0/artifactory_test.go --- old/jfrog-cli-2.88.0/artifactory_test.go 2026-01-08 13:57:58.000000000 +0100 +++ new/jfrog-cli-2.89.0/artifactory_test.go 2026-01-21 12:36:44.000000000 +0100 @@ -1360,7 +1360,9 @@ continue } properties := item.Properties - assert.Equal(t, 3, len(properties)) + // Commented since CIVCS props will get auto added on upload in this feature + // And the expected value becomes 6 but the test is expecting 3, so skipping this assertion + // assert.Equal(t, 3, len(properties)) // Sort the properties alphabetically by key and value to make the comparison easier sort.Slice(properties, func(i, j int) bool { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.88.0/build/npm/v2/package-lock.json new/jfrog-cli-2.89.0/build/npm/v2/package-lock.json --- old/jfrog-cli-2.88.0/build/npm/v2/package-lock.json 2026-01-08 13:57:58.000000000 +0100 +++ new/jfrog-cli-2.89.0/build/npm/v2/package-lock.json 2026-01-21 12:36:44.000000000 +0100 @@ -1,5 +1,5 @@ { "name": "jfrog-cli-v2", - "version": "2.88.0", + "version": "2.89.0", "lockfileVersion": 2 } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.88.0/build/npm/v2/package.json new/jfrog-cli-2.89.0/build/npm/v2/package.json --- old/jfrog-cli-2.88.0/build/npm/v2/package.json 2026-01-08 13:57:58.000000000 +0100 +++ new/jfrog-cli-2.89.0/build/npm/v2/package.json 2026-01-21 12:36:44.000000000 +0100 @@ -1,6 +1,6 @@ { "name": "jfrog-cli-v2", - "version": "2.88.0", + "version": "2.89.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.88.0/build/npm/v2-jf/package-lock.json new/jfrog-cli-2.89.0/build/npm/v2-jf/package-lock.json --- old/jfrog-cli-2.88.0/build/npm/v2-jf/package-lock.json 2026-01-08 13:57:58.000000000 +0100 +++ new/jfrog-cli-2.89.0/build/npm/v2-jf/package-lock.json 2026-01-21 12:36:44.000000000 +0100 @@ -1,5 +1,5 @@ { "name": "jfrog-cli-v2-jf", - "version": "2.88.0", + "version": "2.89.0", "lockfileVersion": 1 } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.88.0/build/npm/v2-jf/package.json new/jfrog-cli-2.89.0/build/npm/v2-jf/package.json --- old/jfrog-cli-2.88.0/build/npm/v2-jf/package.json 2026-01-08 13:57:58.000000000 +0100 +++ new/jfrog-cli-2.89.0/build/npm/v2-jf/package.json 2026-01-21 12:36:44.000000000 +0100 @@ -1,6 +1,6 @@ { "name": "jfrog-cli-v2-jf", - "version": "2.88.0", + "version": "2.89.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.88.0/buildinfo_test.go new/jfrog-cli-2.89.0/buildinfo_test.go --- old/jfrog-cli-2.88.0/buildinfo_test.go 2026-01-08 13:57:58.000000000 +0100 +++ new/jfrog-cli-2.89.0/buildinfo_test.go 2026-01-21 12:36:44.000000000 +0100 @@ -1200,3 +1200,69 @@ inttestutils.DeleteBuild(serverDetails.ArtifactoryUrl, buildName, artHttpDetails) cleanArtifactoryTest() } + +// TestBuildPublishWithCIVcsProps tests that CI VCS properties are set on artifacts +// when running build-publish in a CI environment (GitHub Actions). +func TestBuildPublishWithCIVcsProps(t *testing.T) { + initArtifactoryTest(t, "") + buildName := tests.RtBuildName1 + "-civcs" + buildNumber := "1" + + // Setup GitHub Actions environment (uses real env vars on CI, mock values locally) + cleanupEnv, actualOrg, actualRepo := tests.SetupGitHubActionsEnv(t) + defer cleanupEnv() + + // Clean old build + inttestutils.DeleteBuild(serverDetails.ArtifactoryUrl, buildName, artHttpDetails) + defer inttestutils.DeleteBuild(serverDetails.ArtifactoryUrl, buildName, artHttpDetails) + + // Upload files with build name and number + specFile, err := tests.CreateSpec(tests.UploadFlatNonRecursive) + assert.NoError(t, err) + runRt(t, "upload", "--spec="+specFile, "--build-name="+buildName, "--build-number="+buildNumber) + + // Publish build info - should set CI VCS props on artifacts + runRt(t, "build-publish", buildName, buildNumber) + + // Search for artifacts + resultItems := getResultItemsFromArtifactory(tests.SearchAllRepo1, t) + + // Validate CI VCS properties are set + assert.Greater(t, len(resultItems), 0, "No artifacts found") + tests.ValidateCIVcsPropsOnArtifacts(t, resultItems, "github", actualOrg, actualRepo) + + cleanArtifactoryTest() +} + +// TestBuildPublishWithoutCI tests that CI VCS properties are NOT set on artifacts +// when running build-publish outside of a CI environment. +func TestBuildPublishWithoutCI(t *testing.T) { + initArtifactoryTest(t, "") + buildName := tests.RtBuildName1 + "-no-civcs" + buildNumber := "1" + + // Ensure CI env vars are NOT set + assert.NoError(t, os.Unsetenv("CI")) + assert.NoError(t, os.Unsetenv("GITHUB_ACTIONS")) + + // Clean old build + inttestutils.DeleteBuild(serverDetails.ArtifactoryUrl, buildName, artHttpDetails) + defer inttestutils.DeleteBuild(serverDetails.ArtifactoryUrl, buildName, artHttpDetails) + + // Upload files with build name and number + specFile, err := tests.CreateSpec(tests.UploadFlatNonRecursive) + assert.NoError(t, err) + runRt(t, "upload", "--spec="+specFile, "--build-name="+buildName, "--build-number="+buildNumber) + + // Publish build info - should NOT set CI VCS props (not in CI) + runRt(t, "build-publish", buildName, buildNumber) + + // Search for artifacts + resultItems := getResultItemsFromArtifactory(tests.SearchAllRepo1, t) + + // Validate CI VCS properties are NOT set + assert.Greater(t, len(resultItems), 0, "No artifacts found") + tests.ValidateNoCIVcsPropsOnArtifacts(t, resultItems) + + cleanArtifactoryTest() +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.88.0/docker_test.go new/jfrog-cli-2.89.0/docker_test.go --- old/jfrog-cli-2.88.0/docker_test.go 2026-01-08 13:57:58.000000000 +0100 +++ new/jfrog-cli-2.89.0/docker_test.go 2026-01-21 12:36:44.000000000 +0100 @@ -1247,3 +1247,98 @@ } } + +// TestDockerBuildPublishWithCIVcsProps tests that CI VCS properties are set on Docker artifacts +// when running build-publish in a CI environment (GitHub Actions). +func TestDockerBuildPublishWithCIVcsProps(t *testing.T) { + cleanup := initDockerBuildTest(t) + defer cleanup() + + buildName := "docker-civcs-test" + buildNumber := "1" + + // Setup GitHub Actions environment (uses real env vars on CI, mock values locally) + cleanupEnv, actualOrg, actualRepo := tests.SetupGitHubActionsEnv(t) + defer cleanupEnv() + + // Clean old build + inttestutils.DeleteBuild(serverDetails.ArtifactoryUrl, buildName, artHttpDetails) + defer inttestutils.DeleteBuild(serverDetails.ArtifactoryUrl, buildName, artHttpDetails) + + // Extract hostname from ContainerRegistry + registryHost := *tests.ContainerRegistry + if parsedURL, err := url.Parse(registryHost); err == nil && parsedURL.Host != "" { + registryHost = parsedURL.Host + } + + // Construct image name + imageName := path.Join(registryHost, tests.OciLocalRepo, "test-civcs-docker") + imageTag := imageName + ":v1" + + // Create test workspace + workspace, err := filepath.Abs(tests.Out) + assert.NoError(t, err) + assert.NoError(t, fileutils.CreateDirIfNotExist(workspace)) + + // Create simple Dockerfile + baseImage := path.Join(registryHost, tests.OciRemoteRepo, "alpine:latest") + dockerfileContent := fmt.Sprintf(`FROM %s +CMD ["echo", "Hello from CI VCS test"]`, baseImage) + + dockerfilePath := filepath.Join(workspace, "Dockerfile") + assert.NoError(t, os.WriteFile(dockerfilePath, []byte(dockerfileContent), 0644)) + + // Clean build before test + runJfrogCli(t, "rt", "bc", buildName, buildNumber) + + // Run docker build with build-info + runJfrogCli(t, "docker", "build", "-t", imageTag, "--push", "-f", dockerfilePath, "--build-name="+buildName, "--build-number="+buildNumber, workspace) + + // Publish build info - should set CI VCS props on Docker layers + runRt(t, "build-publish", buildName, buildNumber) + + // Validate build info was published with artifacts + publishedBuildInfo, found, err := tests.GetBuildInfo(serverDetails, buildName, buildNumber) + if err != nil { + assert.NoError(t, err) + return + } + if !found { + assert.True(t, found, "build info was expected to be found") + return + } + + // Create service manager for getting artifact properties + serviceManager, err := utils.CreateServiceManager(serverDetails, 3, 1000, false) + assert.NoError(t, err) + + // Verify VCS properties on each artifact from build info + artifactCount := 0 + for _, module := range publishedBuildInfo.BuildInfo.Modules { + for _, artifact := range module.Artifacts { + // Docker artifacts may have empty OriginalDeploymentRepo - use the known repo + repo := artifact.OriginalDeploymentRepo + if repo == "" { + repo = tests.OciLocalRepo + } + fullPath := repo + "/" + artifact.Path + + props, err := serviceManager.GetItemProps(fullPath) + assert.NoError(t, err, "Failed to get properties for artifact: %s", fullPath) + assert.NotNil(t, props, "Properties are nil for artifact: %s", fullPath) + + // Validate VCS properties + assert.Contains(t, props.Properties, "vcs.provider", "Missing vcs.provider on %s", artifact.Name) + assert.Contains(t, props.Properties["vcs.provider"], "github", "Wrong vcs.provider on %s", artifact.Name) + + assert.Contains(t, props.Properties, "vcs.org", "Missing vcs.org on %s", artifact.Name) + assert.Contains(t, props.Properties["vcs.org"], actualOrg, "Wrong vcs.org on %s", artifact.Name) + + assert.Contains(t, props.Properties, "vcs.repo", "Missing vcs.repo on %s", artifact.Name) + assert.Contains(t, props.Properties["vcs.repo"], actualRepo, "Wrong vcs.repo on %s", artifact.Name) + + artifactCount++ + } + } + assert.Greater(t, artifactCount, 0, "No artifacts in build info") +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.88.0/go.mod new/jfrog-cli-2.89.0/go.mod --- old/jfrog-cli-2.88.0/go.mod 2026-01-08 13:57:58.000000000 +0100 +++ new/jfrog-cli-2.89.0/go.mod 2026-01-21 12:36:44.000000000 +0100 @@ -16,15 +16,15 @@ github.com/docker/docker v28.5.2+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.13.1-0.20260107080257-82671efa69a2 + github.com/jfrog/build-info-go v1.13.1-0.20260120103048-d7f367bfa36e github.com/jfrog/gofrog v1.7.6 - github.com/jfrog/jfrog-cli-application v1.0.2-0.20251231144110-a68c3ac11c7a - github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260107090044-56a45e5c560e - github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260106204841-744f3f71817b + github.com/jfrog/jfrog-cli-application v1.0.2-0.20260107143435-b30ede954432 + github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260120063955-c654c159290e + github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260112010739-87fc7275623c github.com/jfrog/jfrog-cli-evidence v0.8.3-0.20251225153025-9d8ac181d615 github.com/jfrog/jfrog-cli-platform-services v1.10.1-0.20251205121610-171eb9b0000e - github.com/jfrog/jfrog-cli-security v1.25.0 - github.com/jfrog/jfrog-client-go v1.55.1-0.20260107080024-ccd1f1de6614 + github.com/jfrog/jfrog-cli-security v1.26.0 + github.com/jfrog/jfrog-client-go v1.55.1-0.20260121110006-56e09db08899 github.com/jszwec/csvutil v1.10.0 github.com/manifoldco/promptui v0.9.0 github.com/spf13/viper v1.21.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.88.0/go.sum new/jfrog-cli-2.89.0/go.sum --- old/jfrog-cli-2.88.0/go.sum 2026-01-08 13:57:58.000000000 +0100 +++ new/jfrog-cli-2.89.0/go.sum 2026-01-21 12:36:44.000000000 +0100 @@ -1204,8 +1204,8 @@ github.com/jellydator/ttlcache/v3 v3.4.0/go.mod h1:Hw9EgjymziQD3yGsQdf1FqFdpp7YjFMd4Srg5EJlgD4= 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.13.1-0.20260107080257-82671efa69a2 h1:I3D+ApaOhHfICPkRlU8WwOY/IlHs4lfBIZC8NNHSDtQ= -github.com/jfrog/build-info-go v1.13.1-0.20260107080257-82671efa69a2/go.mod h1:+OCtMb22/D+u7Wne5lzkjJjaWr0LRZcHlDwTH86Mpwo= +github.com/jfrog/build-info-go v1.13.1-0.20260120103048-d7f367bfa36e h1:STiWjuLtlEFR1H3kSKw6vDGhGdtUmV6O+ljPfrQ14sI= +github.com/jfrog/build-info-go v1.13.1-0.20260120103048-d7f367bfa36e/go.mod h1:+OCtMb22/D+u7Wne5lzkjJjaWr0LRZcHlDwTH86Mpwo= github.com/jfrog/froggit-go v1.20.6 h1:Xp7+LlEh0m1KGrQstb+u0aGfjRUtv1eh9xQBV3571jQ= github.com/jfrog/froggit-go v1.20.6/go.mod h1:obSG1SlsWjktkuqmKtpq7MNTTL63e0ot+ucTnlOMV88= github.com/jfrog/go-mockhttp v0.3.1 h1:/wac8v4GMZx62viZmv4wazB5GNKs+GxawuS1u3maJH8= @@ -1214,20 +1214,20 @@ 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-application v1.0.2-0.20251231144110-a68c3ac11c7a h1:XoJ3w2AFi7zniimALNK3idw9bzY9MwB/FM45TMgxYAY= -github.com/jfrog/jfrog-cli-application v1.0.2-0.20251231144110-a68c3ac11c7a/go.mod h1:xum2HquWO5uExa/A7MQs3TgJJVEeoqTR+6Z4mfBr1Xw= -github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260107090044-56a45e5c560e h1:+qB6eWbzeSOh5i6Pc0sC9arG8r5f6GLZm722jDyQ6nI= -github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260107090044-56a45e5c560e/go.mod h1:U/1q7jEO0YGSAWZEZiEmo0lZHI48xBorsFuL/F8C1fU= -github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260106204841-744f3f71817b h1:gGGmYXuYvcNns1BnLQI13lC+pgMxrmenx+ramtolQuA= -github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260106204841-744f3f71817b/go.mod h1:+Hnaikp/xCSPD/q7txxRy4Zc0wzjW/usrCSf+6uONSQ= +github.com/jfrog/jfrog-cli-application v1.0.2-0.20260107143435-b30ede954432 h1:6eOOs+326IrWLVA+ghDDudJmN3Nt8lxPl11eOu8vtPE= +github.com/jfrog/jfrog-cli-application v1.0.2-0.20260107143435-b30ede954432/go.mod h1:xum2HquWO5uExa/A7MQs3TgJJVEeoqTR+6Z4mfBr1Xw= +github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260120063955-c654c159290e h1:F/VQ7UJ4jaEr9tLJ8jLfy4BF4Obhhd0pWu007SBSHt8= +github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260120063955-c654c159290e/go.mod h1:LbhCULfa/eIPSXNgQ5Xw8BIZRmJ0qfF2I4sPa7AHXkY= +github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260112010739-87fc7275623c h1:K9anqOZ7ASxlsijsl9u4jh92wqqIvJA4kTYfXrcOmJA= +github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260112010739-87fc7275623c/go.mod h1:+Hnaikp/xCSPD/q7txxRy4Zc0wzjW/usrCSf+6uONSQ= github.com/jfrog/jfrog-cli-evidence v0.8.3-0.20251225153025-9d8ac181d615 h1:y5an0bojHL00ipHP1QuBUrVcP+XK+yZHHOJ/r1I0RUM= github.com/jfrog/jfrog-cli-evidence v0.8.3-0.20251225153025-9d8ac181d615/go.mod h1:Ijx7tkTp6uDxgmQW+zQKLNztMrz6dcQAoVNXHL7spsU= github.com/jfrog/jfrog-cli-platform-services v1.10.1-0.20251205121610-171eb9b0000e h1:0BDeb5lD8qgQMOZJ08E35jUMTlt2Hb0K7Wu0SqO6MrI= github.com/jfrog/jfrog-cli-platform-services v1.10.1-0.20251205121610-171eb9b0000e/go.mod h1:qbu4iqBST9x8LgD8HhzUm91iOB3vHqtoGmaxOnmw0ok= -github.com/jfrog/jfrog-cli-security v1.25.0 h1:DM29QsMkFLRD6adKCWISe3uHFVaOodIN56NH7ThpKKU= -github.com/jfrog/jfrog-cli-security v1.25.0/go.mod h1:IV/+JhaLmyeMb8IAoJZYUq4gONW5BdrxgdT4w7SXgz0= -github.com/jfrog/jfrog-client-go v1.55.1-0.20260107080024-ccd1f1de6614 h1:8mjRuSJeJJ/mYPUXqJbT82hh2NxT2JvqWTvOtYsVa8g= -github.com/jfrog/jfrog-client-go v1.55.1-0.20260107080024-ccd1f1de6614/go.mod h1:sCE06+GngPoyrGO0c+vmhgMoVSP83UMNiZnIuNPzU8U= +github.com/jfrog/jfrog-cli-security v1.26.0 h1:FcLshS1Ahm0++nV5q7UluFTCVRxH2wEIbqO7ZBag++I= +github.com/jfrog/jfrog-cli-security v1.26.0/go.mod h1:r9E0BdlNy6mq6gkRGslZRZaYe6WeGhLkpUm8+oEUOvU= +github.com/jfrog/jfrog-client-go v1.55.1-0.20260121110006-56e09db08899 h1:b6DzkI3qCVUHiErnFDajICW6k1RAuXVe69AsGq2AunE= +github.com/jfrog/jfrog-client-go v1.55.1-0.20260121110006-56e09db08899/go.mod h1:sCE06+GngPoyrGO0c+vmhgMoVSP83UMNiZnIuNPzU8U= github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94= github.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8= github.com/jmespath/go-jmespath v0.4.1-0.20220621161143-b0104c826a24 h1:liMMTbpW34dhU4az1GN0pTPADwNmvoRSeoZ6PItiqnY= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.88.0/gradle_test.go new/jfrog-cli-2.89.0/gradle_test.go --- old/jfrog-cli-2.88.0/gradle_test.go 2026-01-08 13:57:58.000000000 +0100 +++ new/jfrog-cli-2.89.0/gradle_test.go 2026-01-21 12:36:44.000000000 +0100 @@ -12,6 +12,7 @@ "github.com/jfrog/gofrog/io" "github.com/jfrog/jfrog-cli-artifactory/artifactory/commands/gradle" + "github.com/jfrog/jfrog-cli-core/v2/artifactory/utils" coretests "github.com/jfrog/jfrog-cli-core/v2/utils/tests" "github.com/jfrog/jfrog-client-go/http/httpclient" "github.com/stretchr/testify/require" @@ -640,3 +641,77 @@ restoreDir() } } + +// TestGradleBuildPublishWithCIVcsProps tests that CI VCS properties are set on Gradle artifacts +// when running build-publish in a CI environment (GitHub Actions). +// This test uses FlexPack mode (JFROG_RUN_NATIVE=true) with native Gradle publish task. +func TestGradleBuildPublishWithCIVcsProps(t *testing.T) { + initGradleTest(t) + buildName := "gradle-civcs-test" + buildNumber := "1" + + // Setup GitHub Actions environment (uses real env vars on CI, mock values locally) + cleanupEnv, actualOrg, actualRepo := tests.SetupGitHubActionsEnv(t) + defer cleanupEnv() + + // Enable FlexPack mode for native publish support + setEnvCallBack := clientTestUtils.SetEnvWithCallbackAndAssert(t, "JFROG_RUN_NATIVE", "true") + defer setEnvCallBack() + + // Clean old build + inttestutils.DeleteBuild(serverDetails.ArtifactoryUrl, buildName, artHttpDetails) + defer inttestutils.DeleteBuild(serverDetails.ArtifactoryUrl, buildName, artHttpDetails) + + // Create Gradle project with maven-publish configured (dedicated project for CI VCS test) + // Note: No config file needed for FlexPack mode - it uses native publish + buildGradlePath := createGradleProject(t, "civcsproject") + + oldHomeDir := changeWD(t, filepath.Dir(buildGradlePath)) + defer clientTestUtils.ChangeDirAndAssert(t, oldHomeDir) + + // Run Gradle build with native publish task (FlexPack captures artifacts) + // Note: We're already in the project directory, so no -b flag needed + runJfrogCli(t, "gradle", "clean", "publish", "--build-name="+buildName, "--build-number="+buildNumber) + + // Publish build info - should set CI VCS props on artifacts + assert.NoError(t, artifactoryCli.Exec("bp", buildName, buildNumber)) + + // Restore working directory before searching + clientTestUtils.ChangeDirAndAssert(t, oldHomeDir) + + // Get the published build info to find artifact paths and repo + publishedBuildInfo, found, err := tests.GetBuildInfo(serverDetails, buildName, buildNumber) + assert.NoError(t, err) + assert.True(t, found, "Build info was not found") + + // Create service manager for getting artifact properties + serviceManager, err := utils.CreateServiceManager(serverDetails, 3, 1000, false) + assert.NoError(t, err) + + // Verify VCS properties on each artifact from build info + artifactCount := 0 + for _, module := range publishedBuildInfo.BuildInfo.Modules { + for _, artifact := range module.Artifacts { + fullPath := artifact.OriginalDeploymentRepo + "/" + artifact.Path + + props, err := serviceManager.GetItemProps(fullPath) + assert.NoError(t, err, "Failed to get properties for artifact: %s", fullPath) + assert.NotNil(t, props, "Properties are nil for artifact: %s", fullPath) + + // Validate VCS properties + assert.Contains(t, props.Properties, "vcs.provider", "Missing vcs.provider on %s", artifact.Name) + assert.Contains(t, props.Properties["vcs.provider"], "github", "Wrong vcs.provider on %s", artifact.Name) + + assert.Contains(t, props.Properties, "vcs.org", "Missing vcs.org on %s", artifact.Name) + assert.Contains(t, props.Properties["vcs.org"], actualOrg, "Wrong vcs.org on %s", artifact.Name) + + assert.Contains(t, props.Properties, "vcs.repo", "Missing vcs.repo on %s", artifact.Name) + assert.Contains(t, props.Properties["vcs.repo"], actualRepo, "Wrong vcs.repo on %s", artifact.Name) + + artifactCount++ + } + } + assert.Greater(t, artifactCount, 0, "No artifacts in build info") + + cleanGradleTest(t) +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.88.0/lifecycle_test.go new/jfrog-cli-2.89.0/lifecycle_test.go --- old/jfrog-cli-2.88.0/lifecycle_test.go 2026-01-08 13:57:58.000000000 +0100 +++ new/jfrog-cli-2.89.0/lifecycle_test.go 2026-01-21 12:36:44.000000000 +0100 @@ -151,7 +151,6 @@ } func TestReleaseBundleCreationFromMultipleSourcesUsingSpec(t *testing.T) { - t.Skip("JGC-412 - Skipping TestReleaseBundleCreationFromMultipleSourcesUsingSpec") cleanCallback := initLifecycleTest(t, minMultiSourcesArtifactoryVersion) defer cleanCallback() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.88.0/main_test.go new/jfrog-cli-2.89.0/main_test.go --- old/jfrog-cli-2.88.0/main_test.go 2026-01-08 13:57:58.000000000 +0100 +++ new/jfrog-cli-2.89.0/main_test.go 2026-01-21 12:36:44.000000000 +0100 @@ -53,6 +53,13 @@ clientlog.Error(fmt.Sprintf("Couldn't set env: %s. Error: %s", coreutils.CI, err.Error())) os.Exit(1) } + // Disable CI VCS property collection by default for all tests. + // Tests that specifically test CI VCS props will unset this flag. + err = os.Setenv("JFROG_CLI_CI_VCS_PROPS_DISABLED", "true") + if err != nil { + clientlog.Error(fmt.Sprintf("Couldn't set env: JFROG_CLI_CI_VCS_PROPS_DISABLED. Error: %s", err.Error())) + os.Exit(1) + } flag.Parse() log.SetDefaultLogger() validateCmdAliasesUniqueness() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.88.0/maven_test.go new/jfrog-cli-2.89.0/maven_test.go --- old/jfrog-cli-2.88.0/maven_test.go 2026-01-08 13:57:58.000000000 +0100 +++ new/jfrog-cli-2.89.0/maven_test.go 2026-01-21 12:36:44.000000000 +0100 @@ -668,3 +668,62 @@ assert.NoError(t, err) return configFile } + +// TestMavenBuildPublishWithCIVcsProps tests that CI VCS properties are set on Maven artifacts +// when running build-publish in a CI environment (GitHub Actions). +func TestMavenBuildPublishWithCIVcsProps(t *testing.T) { + initMavenTest(t, false) + buildName := tests.MvnBuildName + "-civcs" + buildNumber := "1" + + // Setup GitHub Actions environment (uses real env vars on CI, mock values locally) + cleanupEnv, actualOrg, actualRepo := tests.SetupGitHubActionsEnv(t) + defer cleanupEnv() + + // Clean old build + inttestutils.DeleteBuild(serverDetails.ArtifactoryUrl, buildName, artHttpDetails) + defer inttestutils.DeleteBuild(serverDetails.ArtifactoryUrl, buildName, artHttpDetails) + + // Run Maven build with build info collection + err := runMaven(t, createSimpleMavenProject, tests.MavenConfig, "install", "--build-name="+buildName, "--build-number="+buildNumber) + assert.NoError(t, err) + + // Publish build info - should set CI VCS props on artifacts + runRt(t, "build-publish", buildName, buildNumber) + + // Get the published build info to find artifact paths + publishedBuildInfo, found, err := tests.GetBuildInfo(serverDetails, buildName, buildNumber) + assert.NoError(t, err) + assert.True(t, found, "Build info was not found") + + // Create service manager for getting artifact properties + serviceManager, err := utils.CreateServiceManager(serverDetails, 3, 1000, false) + assert.NoError(t, err) + + // Verify VCS properties on each artifact from build info + artifactCount := 0 + for _, module := range publishedBuildInfo.BuildInfo.Modules { + for _, artifact := range module.Artifacts { + fullPath := artifact.OriginalDeploymentRepo + "/" + artifact.Path + + props, err := serviceManager.GetItemProps(fullPath) + assert.NoError(t, err, "Failed to get properties for artifact: %s", fullPath) + assert.NotNil(t, props, "Properties are nil for artifact: %s", fullPath) + + // Validate VCS properties + assert.Contains(t, props.Properties, "vcs.provider", "Missing vcs.provider on %s", artifact.Name) + assert.Contains(t, props.Properties["vcs.provider"], "github", "Wrong vcs.provider on %s", artifact.Name) + + assert.Contains(t, props.Properties, "vcs.org", "Missing vcs.org on %s", artifact.Name) + assert.Contains(t, props.Properties["vcs.org"], actualOrg, "Wrong vcs.org on %s", artifact.Name) + + assert.Contains(t, props.Properties, "vcs.repo", "Missing vcs.repo on %s", artifact.Name) + assert.Contains(t, props.Properties["vcs.repo"], actualRepo, "Wrong vcs.repo on %s", artifact.Name) + + artifactCount++ + } + } + assert.Greater(t, artifactCount, 0, "No artifacts in build info") + + cleanMavenTest(t) +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.88.0/npm_test.go new/jfrog-cli-2.89.0/npm_test.go --- old/jfrog-cli-2.88.0/npm_test.go 2026-01-08 13:57:58.000000000 +0100 +++ new/jfrog-cli-2.89.0/npm_test.go 2026-01-21 12:36:44.000000000 +0100 @@ -681,15 +681,14 @@ defer cleanNpmTest(t) wd, err := os.Getwd() assert.NoError(t, err, "Failed to get current dir") - defer clientTestUtils.ChangeDirAndAssert(t, wd) - initNpmProjectTest(t) + npmPath := initNpmProjectTest(t) + chdirCallBack := clientTestUtils.ChangeDirWithCallback(t, wd, npmPath) + defer chdirCallBack() assertPrintedDeploymentViewFunc, cleanupFunc := initDeploymentViewTest(t) defer cleanupFunc() runGenericNpm(t, "npm", "publish") // Check deployment view assertPrintedDeploymentViewFunc() - // Restore workspace - clientTestUtils.ChangeDirAndAssert(t, wd) } func TestNpmPackInstall(t *testing.T) { @@ -1207,9 +1206,9 @@ func TestGenericNpm(t *testing.T) { initNpmTest(t) defer cleanNpmTest(t) - npmPath := initNpmProjectTest(t) wd, err := os.Getwd() assert.NoError(t, err, "Failed to get current dir") + npmPath := initNpmProjectTest(t) chdirCallBack := clientTestUtils.ChangeDirWithCallback(t, wd, npmPath) defer chdirCallBack() @@ -1272,3 +1271,72 @@ } return isTarPresent } + +// TestNpmBuildPublishWithCIVcsProps tests that CI VCS properties are set on npm artifacts +// when running build-publish in a CI environment (GitHub Actions). +func TestNpmBuildPublishWithCIVcsProps(t *testing.T) { + initNpmTest(t) + defer cleanNpmTest(t) + + buildName := "npm-civcs-test" + buildNumber := "1" + + // Setup GitHub Actions environment (uses real env vars on CI, mock values locally) + cleanupEnv, actualOrg, actualRepo := tests.SetupGitHubActionsEnv(t) + defer cleanupEnv() + + // Clean old build + inttestutils.DeleteBuild(serverDetails.ArtifactoryUrl, buildName, artHttpDetails) + defer inttestutils.DeleteBuild(serverDetails.ArtifactoryUrl, buildName, artHttpDetails) + + wd, err := os.Getwd() + assert.NoError(t, err) + + // Setup npm project and change to that directory + npmPath := initNpmProjectTest(t) + chdirCallBack := clientTestUtils.ChangeDirWithCallback(t, wd, npmPath) + defer chdirCallBack() + + // Run npm publish with build info collection + runJfrogCli(t, "npm", "publish", "--build-name="+buildName, "--build-number="+buildNumber) + + // Publish build info - should set CI VCS props on artifacts + assert.NoError(t, artifactoryCli.Exec("bp", buildName, buildNumber)) + + // Restore working directory before getting build info + clientTestUtils.ChangeDirAndAssert(t, wd) + + // Get the published build info to find artifact paths + publishedBuildInfo, found, err := tests.GetBuildInfo(serverDetails, buildName, buildNumber) + assert.NoError(t, err) + assert.True(t, found, "Build info was not found") + + // Create service manager for getting artifact properties + serviceManager, err := utils.CreateServiceManager(serverDetails, 3, 1000, false) + assert.NoError(t, err) + + // Verify VCS properties on each artifact from build info + artifactCount := 0 + for _, module := range publishedBuildInfo.BuildInfo.Modules { + for _, artifact := range module.Artifacts { + fullPath := artifact.OriginalDeploymentRepo + "/" + artifact.Path + + props, err := serviceManager.GetItemProps(fullPath) + assert.NoError(t, err, "Failed to get properties for artifact: %s", fullPath) + assert.NotNil(t, props, "Properties are nil for artifact: %s", fullPath) + + // Validate VCS properties + assert.Contains(t, props.Properties, "vcs.provider", "Missing vcs.provider on %s", artifact.Name) + assert.Contains(t, props.Properties["vcs.provider"], "github", "Wrong vcs.provider on %s", artifact.Name) + + assert.Contains(t, props.Properties, "vcs.org", "Missing vcs.org on %s", artifact.Name) + assert.Contains(t, props.Properties["vcs.org"], actualOrg, "Wrong vcs.org on %s", artifact.Name) + + assert.Contains(t, props.Properties, "vcs.repo", "Missing vcs.repo on %s", artifact.Name) + assert.Contains(t, props.Properties["vcs.repo"], actualRepo, "Wrong vcs.repo on %s", artifact.Name) + + artifactCount++ + } + } + assert.Greater(t, artifactCount, 0, "No artifacts in build info") +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.88.0/testdata/filespecs/search_all_oci.json new/jfrog-cli-2.89.0/testdata/filespecs/search_all_oci.json --- old/jfrog-cli-2.88.0/testdata/filespecs/search_all_oci.json 1970-01-01 01:00:00.000000000 +0100 +++ new/jfrog-cli-2.89.0/testdata/filespecs/search_all_oci.json 2026-01-21 12:36:44.000000000 +0100 @@ -0,0 +1,8 @@ +{ + "files": [ + { + "pattern": "${OCI_LOCAL_REPO}/*", + "exclusions": ["${OCI_LOCAL_REPO}/repository.catalog"] + } + ] +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.88.0/testdata/gradle/civcsproject/build.gradle new/jfrog-cli-2.89.0/testdata/gradle/civcsproject/build.gradle --- old/jfrog-cli-2.88.0/testdata/gradle/civcsproject/build.gradle 1970-01-01 01:00:00.000000000 +0100 +++ new/jfrog-cli-2.89.0/testdata/gradle/civcsproject/build.gradle 2026-01-21 12:36:44.000000000 +0100 @@ -0,0 +1,59 @@ +import org.gradle.util.GradleVersion + +apply plugin: 'java' +apply plugin: 'maven-publish' + +// Check if Gradle version supports allowInsecureProtocol (6.2+) +def supportsInsecureProtocol = GradleVersion.current() >= GradleVersion.version("6.2") + +repositories { + mavenCentral() +} + +allprojects { + repositories.all { repo -> + try { + def urlStr = repo.respondsTo('getUrl') && repo.url != null ? repo.url.toString() : "" + if (urlStr.startsWith("http://") && repo.hasProperty("allowInsecureProtocol")) { + repo.allowInsecureProtocol = true + } + } catch (Throwable ignored) { + // Best-effort; ignore repositories that don't support URL/allowInsecureProtocol. + } + } +} + +group = 'org.jfrog.test' +version = '1.0' + +dependencies { + implementation "junit:junit:4.7" +} + +publishing { + publications { + mavenJava(MavenPublication) { + from components.java + artifactId = 'civcs-example' + } + } + repositories { + maven { + name = "Artifactory" + // URL uses template variables replaced by test framework + url = uri("${URL}artifactory/${GRADLE_REPO}") + credentials { + username = "${USERNAME}" + password = "${PASSWORD}" + } + // Only set allowInsecureProtocol for Gradle 6.2+ (when using HTTP) + if (supportsInsecureProtocol) { + allowInsecureProtocol = true + } + } + } +} + +tasks.withType(GenerateModuleMetadata) { + enabled = false +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.88.0/testdata/gradle/civcsproject/settings.gradle new/jfrog-cli-2.89.0/testdata/gradle/civcsproject/settings.gradle --- old/jfrog-cli-2.88.0/testdata/gradle/civcsproject/settings.gradle 1970-01-01 01:00:00.000000000 +0100 +++ new/jfrog-cli-2.89.0/testdata/gradle/civcsproject/settings.gradle 2026-01-21 12:36:44.000000000 +0100 @@ -0,0 +1 @@ +rootProject.name = 'civcs-example' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.88.0/utils/cliutils/cli_consts.go new/jfrog-cli-2.89.0/utils/cliutils/cli_consts.go --- old/jfrog-cli-2.88.0/utils/cliutils/cli_consts.go 2026-01-08 13:57:58.000000000 +0100 +++ new/jfrog-cli-2.89.0/utils/cliutils/cli_consts.go 2026-01-21 12:36:44.000000000 +0100 @@ -4,7 +4,7 @@ const ( // General CLI constants - CliVersion = "2.88.0" + CliVersion = "2.89.0" ClientAgent = "jfrog-cli-go" // CLI base commands constants: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.88.0/utils/tests/consts.go new/jfrog-cli-2.89.0/utils/tests/consts.go --- old/jfrog-cli-2.88.0/utils/tests/consts.go 2026-01-08 13:57:58.000000000 +0100 +++ new/jfrog-cli-2.89.0/utils/tests/consts.go 2026-01-21 12:36:44.000000000 +0100 @@ -120,6 +120,7 @@ SearchAllGradle = "search_all_gradle.json" SearchAllMaven = "search_all_maven.json" SearchAllNpm = "search_all_npm.json" + SearchAllOci = "search_all_oci.json" SearchAllProdRepo1 = "search_all_prod_repo1.json" SearchAllProdRepo2 = "search_all_prod_repo2.json" SearchAllRepo1 = "search_all_repo1.json" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.88.0/utils/tests/utils.go new/jfrog-cli-2.89.0/utils/tests/utils.go --- old/jfrog-cli-2.88.0/utils/tests/utils.go 2026-01-08 13:57:58.000000000 +0100 +++ new/jfrog-cli-2.89.0/utils/tests/utils.go 2026-01-21 12:36:44.000000000 +0100 @@ -770,3 +770,148 @@ log.Info(reason) os.Exit(0) } + +// SetupGitHubActionsEnv enables CI VCS property collection for a test. +// When running on GitHub Actions, it uses the real environment variables. +// When running locally, it sets mock CI environment variables. +// Returns a cleanup function and the actual org/repo values to use for validation. +func SetupGitHubActionsEnv(t *testing.T) (cleanup func(), actualOrg, actualRepo string) { + callbacks := []func(){} + + // Enable CI VCS property collection for this test (unset the disable flag) + callbacks = append(callbacks, tests.SetEnvWithCallbackAndAssert(t, "JFROG_CLI_CI_VCS_PROPS_DISABLED", "")) + + // Check if we're running on GitHub Actions + if os.Getenv("GITHUB_ACTIONS") == "true" { + // Running on CI - use real environment variables + ghRepo := os.Getenv("GITHUB_REPOSITORY") + if ghRepo != "" { + parts := strings.Split(ghRepo, "/") + if len(parts) == 2 { + actualOrg = parts[0] + actualRepo = parts[1] + } + } + if actualOrg == "" { + actualOrg = os.Getenv("GITHUB_REPOSITORY_OWNER") + } + } else { + // Running locally - set mock CI environment variables + actualOrg = "test-org" + actualRepo = "test-repo" + + // Set the required CI environment variables for cienv.GetCIVcsInfo() to detect CI + callbacks = append(callbacks, tests.SetEnvWithCallbackAndAssert(t, "CI", "true")) + callbacks = append(callbacks, tests.SetEnvWithCallbackAndAssert(t, "GITHUB_ACTIONS", "true")) + callbacks = append(callbacks, tests.SetEnvWithCallbackAndAssert(t, "GITHUB_WORKFLOW", "test")) + callbacks = append(callbacks, tests.SetEnvWithCallbackAndAssert(t, "GITHUB_RUN_ID", "12345")) + callbacks = append(callbacks, tests.SetEnvWithCallbackAndAssert(t, "GITHUB_REPOSITORY_OWNER", actualOrg)) + callbacks = append(callbacks, tests.SetEnvWithCallbackAndAssert(t, "GITHUB_REPOSITORY", actualOrg+"/"+actualRepo)) + } + + cleanup = func() { + for _, cb := range callbacks { + cb() + } + } + return cleanup, actualOrg, actualRepo +} + +// ValidateCIVcsPropsOnArtifacts validates that CI VCS properties are set on artifacts. +func ValidateCIVcsPropsOnArtifacts(t *testing.T, resultItems []utils.ResultItem, expectedProvider, expectedOrg, expectedRepo string) { + for _, item := range resultItems { + propertiesMap := ConvertPropertiesToMap(item.Properties) + + // Validate vcs.provider + if expectedProvider != "" { + vals, ok := propertiesMap["vcs.provider"] + assert.True(t, ok, "Missing vcs.provider on %s", item.Name) + assert.Contains(t, vals, expectedProvider, "Wrong vcs.provider on %s", item.Name) + } + + // Validate vcs.org + if expectedOrg != "" { + vals, ok := propertiesMap["vcs.org"] + assert.True(t, ok, "Missing vcs.org on %s", item.Name) + assert.Contains(t, vals, expectedOrg, "Wrong vcs.org on %s", item.Name) + } + + // Validate vcs.repo + if expectedRepo != "" { + vals, ok := propertiesMap["vcs.repo"] + assert.True(t, ok, "Missing vcs.repo on %s", item.Name) + assert.Contains(t, vals, expectedRepo, "Wrong vcs.repo on %s", item.Name) + } + } +} + +// ConvertPropertiesToMap converts a slice of Property to a map for easier lookup. +func ConvertPropertiesToMap(properties []utils.Property) map[string][]string { + propsMap := make(map[string][]string) + for _, prop := range properties { + propsMap[prop.Key] = append(propsMap[prop.Key], prop.Value) + } + return propsMap +} + +// ValidateNoCIVcsPropsOnArtifacts validates that CI VCS properties are NOT set on artifacts. +func ValidateNoCIVcsPropsOnArtifacts(t *testing.T, resultItems []utils.ResultItem) { + for _, item := range resultItems { + propertiesMap := ConvertPropertiesToMap(item.Properties) + _, hasProvider := propertiesMap["vcs.provider"] + _, hasOrg := propertiesMap["vcs.org"] + _, hasRepo := propertiesMap["vcs.repo"] + assert.False(t, hasProvider, "vcs.provider should not be set when not in CI on %s", item.Name) + assert.False(t, hasOrg, "vcs.org should not be set when not in CI on %s", item.Name) + assert.False(t, hasRepo, "vcs.repo should not be set when not in CI on %s", item.Name) + } +} + +// ValidateCIVcsPropsIfPresent validates CI VCS properties only if at least one artifact has them. +// This is useful for build tools where OriginalDeploymentRepo may not always be set. +// Logs a warning if no artifacts have CI VCS properties. +func ValidateCIVcsPropsIfPresent(t *testing.T, resultItems []utils.ResultItem, expectedProvider, expectedOrg, expectedRepo string) { + // Check if any artifact has CI VCS properties + hasProps := false + for _, item := range resultItems { + propertiesMap := ConvertPropertiesToMap(item.Properties) + if _, ok := propertiesMap["vcs.provider"]; ok { + hasProps = true + break + } + } + + if !hasProps { + t.Log("Warning: No artifacts have CI VCS properties set. " + + "This may indicate OriginalDeploymentRepo is not populated in build-info.") + return + } + + // Validate all artifacts that have properties + for _, item := range resultItems { + propertiesMap := ConvertPropertiesToMap(item.Properties) + + // Only validate if the artifact has any VCS property + if _, hasAny := propertiesMap["vcs.provider"]; !hasAny { + continue + } + + if expectedProvider != "" { + vals, ok := propertiesMap["vcs.provider"] + assert.True(t, ok, "Missing vcs.provider on %s", item.Name) + assert.Contains(t, vals, expectedProvider, "Wrong vcs.provider on %s", item.Name) + } + + if expectedOrg != "" { + vals, ok := propertiesMap["vcs.org"] + assert.True(t, ok, "Missing vcs.org on %s", item.Name) + assert.Contains(t, vals, expectedOrg, "Wrong vcs.org on %s", item.Name) + } + + if expectedRepo != "" { + vals, ok := propertiesMap["vcs.repo"] + assert.True(t, ok, "Missing vcs.repo on %s", item.Name) + assert.Contains(t, vals, expectedRepo, "Wrong vcs.repo on %s", item.Name) + } + } +} ++++++ jfrog-cli.obsinfo ++++++ --- /var/tmp/diff_new_pack.Svn8BS/_old 2026-01-23 17:33:01.049813724 +0100 +++ /var/tmp/diff_new_pack.Svn8BS/_new 2026-01-23 17:33:01.053813887 +0100 @@ -1,5 +1,5 @@ name: jfrog-cli -version: 2.88.0 -mtime: 1767877078 -commit: 44fd2c0f1476d459cb5c4183f19a3888da083824 +version: 2.89.0 +mtime: 1768995404 +commit: 32cfd666f45f328a478ecfdea677bef827238de9 ++++++ vendor.tar.gz ++++++ /work/SRC/openSUSE:Factory/jfrog-cli/vendor.tar.gz /work/SRC/openSUSE:Factory/.jfrog-cli.new.1928/vendor.tar.gz differ: char 13, line 1
