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-03-09 16:15:22 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/jfrog-cli (Old) and /work/SRC/openSUSE:Factory/.jfrog-cli.new.8177 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "jfrog-cli" Mon Mar 9 16:15:22 2026 rev:30 rq:1337582 version:2.95.0 Changes: -------- --- /work/SRC/openSUSE:Factory/jfrog-cli/jfrog-cli.changes 2026-03-05 17:24:03.484841414 +0100 +++ /work/SRC/openSUSE:Factory/.jfrog-cli.new.8177/jfrog-cli.changes 2026-03-09 16:15:25.146957806 +0100 @@ -1,0 +2,10 @@ +Mon Mar 09 07:39:21 UTC 2026 - Johannes Kastl <[email protected]> + +- Update to version 2.95.0: + * Other Changes + - Added logic for updating HF_ENDPOINT and HF_TOKEN from + default or spe… by @naveenku-jfrog in #3379 + - Added the huggingface command name by @naveenku-jfrog in + #3383 + +------------------------------------------------------------------- Old: ---- jfrog-cli-2.94.0.obscpio New: ---- jfrog-cli-2.95.0.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ jfrog-cli.spec ++++++ --- /var/tmp/diff_new_pack.Eh4tMV/_old 2026-03-09 16:15:28.907112009 +0100 +++ /var/tmp/diff_new_pack.Eh4tMV/_new 2026-03-09 16:15:28.927112818 +0100 @@ -19,7 +19,7 @@ %define executable_name jf Name: jfrog-cli -Version: 2.94.0 +Version: 2.95.0 Release: 0 Summary: A client that automates access to the JFrog products License: Apache-2.0 ++++++ _service ++++++ --- /var/tmp/diff_new_pack.Eh4tMV/_old 2026-03-09 16:15:29.159122201 +0100 +++ /var/tmp/diff_new_pack.Eh4tMV/_new 2026-03-09 16:15:29.207124142 +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.94.0</param> + <param name="revision">v2.95.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.Eh4tMV/_old 2026-03-09 16:15:29.359130290 +0100 +++ /var/tmp/diff_new_pack.Eh4tMV/_new 2026-03-09 16:15:29.403132070 +0100 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/jfrog/jfrog-cli.git</param> - <param name="changesrevision">b63aa5d2180c5a039e5e548d513bfc04e89c9e13</param></service></servicedata> + <param name="changesrevision">1c728785312c6e01baaf86e6d689a7efd4d7ec9d</param></service></servicedata> (No newline at EOF) ++++++ jfrog-cli-2.94.0.obscpio -> jfrog-cli-2.95.0.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.94.0/build/npm/v2/package-lock.json new/jfrog-cli-2.95.0/build/npm/v2/package-lock.json --- old/jfrog-cli-2.94.0/build/npm/v2/package-lock.json 2026-03-04 11:40:08.000000000 +0100 +++ new/jfrog-cli-2.95.0/build/npm/v2/package-lock.json 2026-03-06 12:07:30.000000000 +0100 @@ -1,5 +1,5 @@ { "name": "jfrog-cli-v2", - "version": "2.94.0", + "version": "2.95.0", "lockfileVersion": 2 } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.94.0/build/npm/v2/package.json new/jfrog-cli-2.95.0/build/npm/v2/package.json --- old/jfrog-cli-2.94.0/build/npm/v2/package.json 2026-03-04 11:40:08.000000000 +0100 +++ new/jfrog-cli-2.95.0/build/npm/v2/package.json 2026-03-06 12:07:30.000000000 +0100 @@ -1,6 +1,6 @@ { "name": "jfrog-cli-v2", - "version": "2.94.0", + "version": "2.95.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.94.0/build/npm/v2-jf/package-lock.json new/jfrog-cli-2.95.0/build/npm/v2-jf/package-lock.json --- old/jfrog-cli-2.94.0/build/npm/v2-jf/package-lock.json 2026-03-04 11:40:08.000000000 +0100 +++ new/jfrog-cli-2.95.0/build/npm/v2-jf/package-lock.json 2026-03-06 12:07:30.000000000 +0100 @@ -1,5 +1,5 @@ { "name": "jfrog-cli-v2-jf", - "version": "2.94.0", + "version": "2.95.0", "lockfileVersion": 1 } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.94.0/build/npm/v2-jf/package.json new/jfrog-cli-2.95.0/build/npm/v2-jf/package.json --- old/jfrog-cli-2.94.0/build/npm/v2-jf/package.json 2026-03-04 11:40:08.000000000 +0100 +++ new/jfrog-cli-2.95.0/build/npm/v2-jf/package.json 2026-03-06 12:07:30.000000000 +0100 @@ -1,6 +1,6 @@ { "name": "jfrog-cli-v2-jf", - "version": "2.94.0", + "version": "2.95.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.94.0/buildtools/cli.go new/jfrog-cli-2.95.0/buildtools/cli.go --- old/jfrog-cli-2.94.0/buildtools/cli.go 2026-03-04 11:40:08.000000000 +0100 +++ new/jfrog-cli-2.95.0/buildtools/cli.go 2026-03-06 12:07:30.000000000 +0100 @@ -85,6 +85,9 @@ const ( buildToolsCategory = "Package Managers:" + huggingfaceAPI = "api/huggingfaceml" + HF_ENDPOINT = "HF_ENDPOINT" + HF_TOKEN = "HF_TOKEN" ) func GetCommands() []cli.Command { @@ -1139,15 +1142,15 @@ cmdName, hfArgs := getCommandName(args) switch cmdName { case "u", "upload": - return huggingFaceUploadCmd(c, hfArgs) + return huggingFaceUploadCmd(c, "upload", hfArgs) case "d", "download": - return huggingFaceDownloadCmd(c, hfArgs) + return huggingFaceDownloadCmd(c, "download", hfArgs) default: return errorutils.CheckErrorf("unknown HuggingFace command: '%s'. Valid commands are: upload (u), download (d)", cmdName) } } -func huggingFaceUploadCmd(c *cli.Context, hfArgs []string) error { +func huggingFaceUploadCmd(c *cli.Context, cmdName string, hfArgs []string) error { // Upload requires folderPath and repoID if len(hfArgs) < 2 { return cliutils.PrintHelpAndReturnError("Folder path and repository ID are required.", c) @@ -1160,12 +1163,13 @@ if repoID == "" { return cliutils.PrintHelpAndReturnError("Repository ID cannot be empty.", c) } - serverDetails, err := coreConfig.GetDefaultServerConf() + serverDetails, err := getHuggingFaceServerDetails(hfArgs) if err != nil { return err } - if serverDetails == nil { - return fmt.Errorf("no default server configuration found. Please configure a server using 'jfrog config add' or specify a server using --server-id") + err = updateHuggingFaceEnv(c, serverDetails) + if err != nil { + return err } buildConfiguration, err := cliutils.CreateBuildConfigurationWithModule(c) if err != nil { @@ -1180,6 +1184,7 @@ repoType = "model" } huggingFaceUploadCmd := huggingfaceCommands.NewHuggingFaceUpload(). + SetCommandName(cmdName). SetFolderPath(folderPath). SetRepoId(repoID). SetRepoType(repoType). @@ -1189,7 +1194,7 @@ return commands.Exec(huggingFaceUploadCmd) } -func huggingFaceDownloadCmd(c *cli.Context, hfArgs []string) error { +func huggingFaceDownloadCmd(c *cli.Context, cmdName string, hfArgs []string) error { // Download requires repoID if len(hfArgs) < 1 { return cliutils.PrintHelpAndReturnError("Model/Dataset name is required.", c) @@ -1199,12 +1204,13 @@ if repoID == "" { return cliutils.PrintHelpAndReturnError("Model/Dataset name cannot be empty.", c) } - serverDetails, err := coreConfig.GetDefaultServerConf() + serverDetails, err := getHuggingFaceServerDetails(hfArgs) if err != nil { return err } - if serverDetails == nil { - return fmt.Errorf("no default server configuration found. Please configure a server using 'jfrog config add' or specify a server using --server-id") + err = updateHuggingFaceEnv(c, serverDetails) + if err != nil { + return err } buildConfiguration, err := cliutils.CreateBuildConfigurationWithModule(c) if err != nil { @@ -1226,6 +1232,7 @@ revision = "main" } huggingFaceDownloadCmd := huggingfaceCommands.NewHuggingFaceDownload(). + SetCommandName(cmdName). SetRepoId(repoID). SetRepoType(repoType). SetRevision(revision). @@ -1235,6 +1242,53 @@ return commands.Exec(huggingFaceDownloadCmd) } +func getHuggingFaceServerDetails(args []string) (*coreConfig.ServerDetails, error) { + _, serverID, err := coreutils.ExtractServerIdFromCommand(args) + if err != nil { + return nil, fmt.Errorf("failed to extract server ID: %w", err) + } + if serverID == "" { + serverDetails, err := coreConfig.GetDefaultServerConf() + if err != nil { + return nil, err + } + if serverDetails == nil { + return nil, fmt.Errorf("no default server configuration found. Please configure a server using 'jfrog config add' or specify a server using --server-id") + } + return serverDetails, nil + } + serverDetails, err := coreConfig.GetSpecificConfig(serverID, true, true) + if err != nil { + return nil, fmt.Errorf("failed to get server configuration for ID '%s': %w", serverID, err) + } + return serverDetails, nil +} + +func updateHuggingFaceEnv(c *cli.Context, serverDetails *coreConfig.ServerDetails) error { + if os.Getenv(HF_ENDPOINT) == "" { + repoKey := c.String("repo-key") + if repoKey == "" { + return cliutils.PrintHelpAndReturnError("Please specify a repository key.", c) + } + hfEndpoint := serverDetails.GetArtifactoryUrl() + huggingfaceAPI + "/" + repoKey + err := os.Setenv(HF_ENDPOINT, hfEndpoint) + if err != nil { + return err + } + } + if os.Getenv(HF_TOKEN) == "" { + accessToken := serverDetails.GetAccessToken() + if accessToken == "" { + return cliutils.PrintHelpAndReturnError("You need to specify an access token.", c) + } + err := os.Setenv(HF_TOKEN, accessToken) + if err != nil { + return err + } + } + return nil +} + func dockerScanCmd(c *cli.Context, imageTag string) error { if show, err := cliutils.ShowGenericCmdHelpIfNeeded(c, c.Args(), securityCLI.DockerScanCmdHiddenName); show || err != nil { return err diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.94.0/go.mod new/jfrog-cli-2.95.0/go.mod --- old/jfrog-cli-2.94.0/go.mod 2026-03-04 11:40:08.000000000 +0100 +++ new/jfrog-cli-2.95.0/go.mod 2026-03-06 12:07:30.000000000 +0100 @@ -19,12 +19,12 @@ github.com/jfrog/build-info-go v1.13.1-0.20260216093441-40a4dc563294 github.com/jfrog/gofrog v1.7.6 github.com/jfrog/jfrog-cli-application v1.0.2-0.20260216085810-1ade6c26b3df - github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260303101540-67cc7f55724b + github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260306094346-2089d7332e94 github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260225195817-bc599cec3973 github.com/jfrog/jfrog-cli-evidence v0.8.3-0.20260202100913-d9ee9476845a github.com/jfrog/jfrog-cli-platform-services v1.10.1-0.20260213131956-d1d39bf3a042 github.com/jfrog/jfrog-cli-security v1.26.3 - github.com/jfrog/jfrog-client-go v1.55.1-0.20260225080504-17057750d47b + github.com/jfrog/jfrog-client-go v1.55.1-0.20260305132144-f99feaed3f18 github.com/jszwec/csvutil v1.10.0 github.com/manifoldco/promptui v0.9.0 github.com/spf13/viper v1.21.0 @@ -38,7 +38,6 @@ ) require ( - cloud.google.com/go/auth v0.18.1 // indirect dario.cat/mergo v1.0.2 // indirect github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect github.com/CycloneDX/cyclonedx-go v0.10.0 // indirect @@ -123,7 +122,6 @@ github.com/google/go-github/v74 v74.0.0 // indirect github.com/google/go-querystring v1.2.0 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.3.11 // indirect github.com/gookit/color v1.6.0 // indirect github.com/grokify/mogo v0.72.6 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.5 // indirect @@ -198,7 +196,7 @@ github.com/spf13/pflag v1.0.10 // indirect github.com/stretchr/objx v0.5.3 // indirect github.com/subosito/gotenv v1.6.0 // indirect - github.com/theupdateframework/go-tuf/v2 v2.4.0 // indirect + github.com/theupdateframework/go-tuf/v2 v2.4.1 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect github.com/transparency-dev/formats v0.0.0-20260119090622-e70c80e9488a // indirect @@ -218,14 +216,9 @@ go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0 // indirect go.opentelemetry.io/otel v1.39.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.39.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.38.0 // indirect go.opentelemetry.io/otel/metric v1.39.0 // indirect go.opentelemetry.io/otel/trace v1.39.0 // indirect - go.opentelemetry.io/proto/otlp v1.9.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/crypto v0.48.0 // indirect diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.94.0/go.sum new/jfrog-cli-2.95.0/go.sum --- old/jfrog-cli-2.94.0/go.sum 2026-03-04 11:40:08.000000000 +0100 +++ new/jfrog-cli-2.95.0/go.sum 2026-03-06 12:07:30.000000000 +0100 @@ -419,8 +419,8 @@ github.com/jfrog/jfrog-apps-config v1.0.1/go.mod h1:8AIIr1oY9JuH5dylz2S6f8Ym2MaadPLR6noCBO4C22w= github.com/jfrog/jfrog-cli-application v1.0.2-0.20260216085810-1ade6c26b3df h1:raSyae8/h1y8HtzFLf7vZZj91fP/qD94AX+biwBJiqs= github.com/jfrog/jfrog-cli-application v1.0.2-0.20260216085810-1ade6c26b3df/go.mod h1:xum2HquWO5uExa/A7MQs3TgJJVEeoqTR+6Z4mfBr1Xw= -github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260303101540-67cc7f55724b h1:RFVA0SoRC1Hf54BdDkt3mv4x5t3600AqUcpA5Fy3n3E= -github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260303101540-67cc7f55724b/go.mod h1:IRUe9nYwCUq8V2WRDUd4bddwiXXdkxvNQ36+0U0uHqI= +github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260306094346-2089d7332e94 h1:A2BxRjC0Zwnn7pEEFQOPl/0BSCw/SvtThS0cY2jsP8Y= +github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260306094346-2089d7332e94/go.mod h1:zjbDerW+Pin6VExtlgwRtpnvtI/ySJTnmqnOwXbsrmc= github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260225195817-bc599cec3973 h1:awB01Y4m0cWzmXuR3waf5IQnoQxDlbUmqT+FMWOpjbs= github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260225195817-bc599cec3973/go.mod h1:yhi+XpiEx18a3t8CZ6M2VpAf3EGqKpBhTzoPBTFe0dk= github.com/jfrog/jfrog-cli-evidence v0.8.3-0.20260202100913-d9ee9476845a h1:lTOAhUjKcOmM/0Kbj4V+I/VHPlW7YNAhIEVpGnCM5mI= @@ -429,8 +429,8 @@ github.com/jfrog/jfrog-cli-platform-services v1.10.1-0.20260213131956-d1d39bf3a042/go.mod h1:n18milUWaaWv6o0bWeEDuoweACoZHRTtQPZpyXBPjEs= github.com/jfrog/jfrog-cli-security v1.26.3 h1:991m5HZrFxR8GOg5ALxTGxih73+wTPmLvlLG0VaXDxk= github.com/jfrog/jfrog-cli-security v1.26.3/go.mod h1:eZLjW37Z6f1DbeKCsL+NnYSm41hQnV1wV6NpLfIOwLw= -github.com/jfrog/jfrog-client-go v1.55.1-0.20260225080504-17057750d47b h1:mSxcMTXtnrYMVhCGk7ui2ERh6yLoUVUQhXaNwd3FhL8= -github.com/jfrog/jfrog-client-go v1.55.1-0.20260225080504-17057750d47b/go.mod h1:sCE06+GngPoyrGO0c+vmhgMoVSP83UMNiZnIuNPzU8U= +github.com/jfrog/jfrog-client-go v1.55.1-0.20260305132144-f99feaed3f18 h1:uyVe+k7c7GzMuKzO3EGUU7ZcG+0cOYFZObI+OUZsHLs= +github.com/jfrog/jfrog-client-go v1.55.1-0.20260305132144-f99feaed3f18/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= @@ -493,8 +493,8 @@ github.com/mattn/go-tty v0.0.7/go.mod h1:f2i5ZOvXBU/tCABmLmOfzLz9azMo5wdAaElRNnJKr+k= github.com/microsoft/azure-devops-go-api/azuredevops/v7 v7.1.0 h1:mmJCWLe63QvybxhW1iBmQWEaCKdc4SKgALfTNZ+OphU= github.com/microsoft/azure-devops-go-api/azuredevops/v7 v7.1.0/go.mod h1:mDunUZ1IUJdJIRHvFb+LPBUtxe3AYB5MI6BMXNg8194= -github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM= -github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk= +github.com/miekg/dns v1.1.61 h1:nLxbwF3XxhwVSm8g9Dghm9MHPaUZuqhPiGL+675ZmEs= +github.com/miekg/dns v1.1.61/go.mod h1:mnAarhS3nWaW+NVP2wTkYVIZyHNJ098SJZUki3eykwQ= github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= @@ -663,8 +663,8 @@ github.com/testcontainers/testcontainers-go v0.40.0/go.mod h1:FSXV5KQtX2HAMlm7U3APNyLkkap35zNLxukw9oBi/MY= github.com/theupdateframework/go-tuf v0.7.0 h1:CqbQFrWo1ae3/I0UCblSbczevCCbS31Qvs5LdxRWqRI= github.com/theupdateframework/go-tuf v0.7.0/go.mod h1:uEB7WSY+7ZIugK6R1hiBMBjQftaFzn7ZCDJcp1tCUug= -github.com/theupdateframework/go-tuf/v2 v2.4.0 h1:3HGxV0lq91/RJ7YycqCKuKBuLfo4rLRut4lh9XqIEP4= -github.com/theupdateframework/go-tuf/v2 v2.4.0/go.mod h1:9S0Srkf3c13FelsOyt5OyG3ZZDq9OJDA4IILavrt72Y= +github.com/theupdateframework/go-tuf/v2 v2.4.1 h1:K6ewW064rKZCPkRo1W/CTbTtm/+IB4+coG1iNURAGCw= +github.com/theupdateframework/go-tuf/v2 v2.4.1/go.mod h1:Nex2enPVYDFCklrnbTzl3OVwD7fgIAj0J5++z/rvCj8= github.com/tink-crypto/tink-go-awskms/v2 v2.1.0 h1:N9UxlsOzu5mttdjhxkDLbzwtEecuXmlxZVo/ds7JKJI= github.com/tink-crypto/tink-go-awskms/v2 v2.1.0/go.mod h1:PxSp9GlOkKL9rlybW804uspnHuO9nbD98V/fDX4uSis= github.com/tink-crypto/tink-go-gcpkms/v2 v2.2.0 h1:3B9i6XBXNTRspfkTC0asN5W0K6GhOSgcujNiECNRNb0= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.94.0/huggingface_test.go new/jfrog-cli-2.95.0/huggingface_test.go --- old/jfrog-cli-2.94.0/huggingface_test.go 2026-03-04 11:40:08.000000000 +0100 +++ new/jfrog-cli-2.95.0/huggingface_test.go 2026-03-06 12:07:30.000000000 +0100 @@ -45,14 +45,12 @@ serverDetails.Password = *tests.JfrogPassword } - // NOTE: We do NOT auto-set HF_ENDPOINT here. - // If HF_ENDPOINT is not set, downloads go directly to HuggingFace Hub (huggingface.co) - // If HF_ENDPOINT is set (by user/CI), downloads go through Artifactory - // Build info tests will skip if HF_ENDPOINT is not set since they require Artifactory } func cleanHuggingFaceTest(t *testing.T) { clientTestUtils.UnSetEnvAndAssert(t, coreutils.HomeDir) + clientTestUtils.UnSetEnvAndAssert(t, "HF_ENDPOINT") + clientTestUtils.UnSetEnvAndAssert(t, "HF_TOKEN") tests.CleanFileSystem() } @@ -120,29 +118,63 @@ return isArtifactoryRelated && isAuthError } +// uploadTestModelToLocalRepo uploads minimal test model files to the local HuggingFace repo +// so that subsequent download tests have something to retrieve. +func uploadTestModelToLocalRepo(t *testing.T, jfrogCli *coreTests.JfrogCli, repoID string) { + t.Helper() + tempDir, err := os.MkdirTemp("", "hf-local-setup-*") + require.NoError(t, err, "Setup: failed to create temp dir") + t.Cleanup(func() { _ = os.RemoveAll(tempDir) }) + + require.NoError(t, os.WriteFile(filepath.Join(tempDir, "config.json"), []byte(`{"model_type":"test"}`), 0644)) + require.NoError(t, os.WriteFile(filepath.Join(tempDir, "model.bin"), []byte("test model binary content"), 0644)) + + args := []string{ + "hf", "u", tempDir, repoID, + "--repo-type=model", + "--repo-key=" + tests.HuggingFaceLocalRepo, + } + require.NoError(t, jfrogCli.Exec(args...), "Setup: upload to local repo failed for "+repoID) +} + +// uploadTestDatasetToLocalRepo uploads minimal test dataset files to the local HuggingFace repo. +func uploadTestDatasetToLocalRepo(t *testing.T, jfrogCli *coreTests.JfrogCli, repoID string) { + t.Helper() + tempDir, err := os.MkdirTemp("", "hf-local-dataset-setup-*") + require.NoError(t, err, "Setup: failed to create temp dir for dataset") + t.Cleanup(func() { _ = os.RemoveAll(tempDir) }) + + require.NoError(t, os.WriteFile(filepath.Join(tempDir, "train.json"), []byte(`[{"text":"sample training data"}]`), 0644)) + require.NoError(t, os.WriteFile(filepath.Join(tempDir, "test.json"), []byte(`[{"text":"sample test data"}]`), 0644)) + + args := []string{ + "hf", "u", tempDir, repoID, + "--repo-type=dataset", + "--repo-key=" + tests.HuggingFaceLocalRepo, + } + require.NoError(t, jfrogCli.Exec(args...), "Setup: upload dataset to local repo failed for "+repoID) +} + // TestHuggingFaceDownload tests the HuggingFace download command func TestHuggingFaceDownload(t *testing.T) { initHuggingFaceTest(t) defer cleanHuggingFaceTest(t) - // Check if python3 and huggingface_hub are available checkHuggingFaceHubAvailable(t) - // Test download with a small test model jfrogCli := coreTests.NewJfrogCli(execMain, "jfrog", "") + repoID := "test-org/test-model" + + // Upload test files to the local repo first + uploadTestModelToLocalRepo(t, jfrogCli, repoID) - // Test basic download command structure - // Using sshleifer/tiny-gpt2 which is a very small model (~2MB) designed for testing + // Download from the local repo args := []string{ - "hf", "d", "sshleifer/tiny-gpt2", + "hf", "d", repoID, "--repo-type=model", + "--repo-key=" + tests.HuggingFaceLocalRepo, } - - // Execute and verify success err := jfrogCli.Exec(args...) - if isArtifactoryAuthError(err) { - t.Skipf("Skipping: HF_ENDPOINT is set but Artifactory auth failed: %v", err) - } assert.NoError(t, err, "HuggingFace download command should succeed") } @@ -151,23 +183,22 @@ initHuggingFaceTest(t) defer cleanHuggingFaceTest(t) - // Check if python3 and huggingface_hub are available checkHuggingFaceHubAvailable(t) jfrogCli := coreTests.NewJfrogCli(execMain, "jfrog", "") + repoID := "test-org/test-model-revision" + + // Upload test files to the local repo first (uploaded to default 'main' branch) + uploadTestModelToLocalRepo(t, jfrogCli, repoID) - // Test download with revision parameter - // Using sshleifer/tiny-gpt2 which is a very small model (~2MB) designed for testing + // Download from the local repo specifying revision=main args := []string{ - "hf", "d", "sshleifer/tiny-gpt2", + "hf", "d", repoID, "--repo-type=model", "--revision=main", + "--repo-key=" + tests.HuggingFaceLocalRepo, } - err := jfrogCli.Exec(args...) - if isArtifactoryAuthError(err) { - t.Skipf("Skipping: HF_ENDPOINT is set but Artifactory auth failed: %v", err) - } assert.NoError(t, err, "HuggingFace download with revision should succeed") } @@ -176,31 +207,22 @@ initHuggingFaceTest(t) defer cleanHuggingFaceTest(t) - // Check if python3 and huggingface_hub are available checkHuggingFaceHubAvailable(t) jfrogCli := coreTests.NewJfrogCli(execMain, "jfrog", "") + repoID := "test-org/test-dataset" + + // Upload test dataset files to the local repo first + uploadTestDatasetToLocalRepo(t, jfrogCli, repoID) - // Test download dataset - // Using hf-internal-testing/fixtures_image_utils which is a tiny test dataset (~100KB) + // Download the dataset from the local repo args := []string{ - "hf", "d", "hf-internal-testing/fixtures_image_utils", + "hf", "d", repoID, "--repo-type=dataset", + "--repo-key=" + tests.HuggingFaceLocalRepo, } - err := jfrogCli.Exec(args...) - if err != nil { - if isArtifactoryAuthError(err) { - t.Skipf("Skipping: HF_ENDPOINT is set but Artifactory auth failed: %v", err) - } - // Accept timeout errors as expected when running without HF_TOKEN (rate limiting) - errStr := strings.ToLower(err.Error()) - if strings.Contains(errStr, "timeout") || strings.Contains(errStr, "timed out") { - t.Skipf("Dataset download timed out (likely due to HF rate limiting without HF_TOKEN): %v", err) - } - // Fail on other unexpected errors - assert.NoError(t, err, "HuggingFace download dataset should succeed") - } + assert.NoError(t, err, "HuggingFace download dataset should succeed") } // TestHuggingFaceDownloadWithEtagTimeout tests the HuggingFace download command with etag-timeout @@ -208,23 +230,22 @@ initHuggingFaceTest(t) defer cleanHuggingFaceTest(t) - // Check if python3 and huggingface_hub are available checkHuggingFaceHubAvailable(t) jfrogCli := coreTests.NewJfrogCli(execMain, "jfrog", "") + repoID := "test-org/test-model-etag" + + // Upload test files to the local repo first + uploadTestModelToLocalRepo(t, jfrogCli, repoID) - // Test download with etag-timeout parameter - // Using sshleifer/tiny-gpt2 which is a very small model (~2MB) designed for testing + // Download from the local repo with etag-timeout parameter args := []string{ - "hf", "d", "sshleifer/tiny-gpt2", + "hf", "d", repoID, "--repo-type=model", "--etag-timeout=3600", + "--repo-key=" + tests.HuggingFaceLocalRepo, } - err := jfrogCli.Exec(args...) - if isArtifactoryAuthError(err) { - t.Skipf("Skipping: HF_ENDPOINT is set but Artifactory auth failed: %v", err) - } assert.NoError(t, err, "HuggingFace download with etag-timeout should succeed") } @@ -259,6 +280,7 @@ args := []string{ "hf", "u", tempDir, "test-org/test-model", "--repo-type=model", + "--repo-key=" + tests.HuggingFaceLocalRepo, } err = jfrogCli.Exec(args...) @@ -296,6 +318,7 @@ "hf", "u", tempDir, "test-org/test-model", "--repo-type=model", "--revision=test-branch", + "--repo-key=" + tests.HuggingFaceLocalRepo, } err = jfrogCli.Exec(args...) @@ -336,6 +359,7 @@ args := []string{ "hf", "u", tempDir, "test-org/test-dataset", "--repo-type=dataset", + "--repo-key=" + tests.HuggingFaceLocalRepo, } err = jfrogCli.Exec(args...) @@ -414,6 +438,7 @@ args := []string{ "hf", "d", "non-existent-org/non-existent-model-12345xyz", "--repo-type=model", + "--repo-key=" + tests.HuggingFaceLocalRepo, } err := jfrogCli.Exec(args...) @@ -460,6 +485,7 @@ args := []string{ "hf", "u", tempDir, "test-org/test-empty-model", "--repo-type=model", + "--repo-key=" + tests.HuggingFaceLocalRepo, } err = jfrogCli.Exec(args...) @@ -491,6 +517,7 @@ args := []string{ "hf", "u", "/non/existent/path/to/model", "test-org/test-model", "--repo-type=model", + "--repo-key=" + tests.HuggingFaceLocalRepo, } err := jfrogCli.Exec(args...) @@ -544,6 +571,7 @@ args := []string{ "hf", "u", specialDir, "test-org/test-special-chars-model", "--repo-type=model", + "--repo-key=" + tests.HuggingFaceLocalRepo, } err = jfrogCli.Exec(args...) @@ -581,6 +609,7 @@ args := []string{ "hf", "u", tempDir, repoID, "--repo-type=model", + "--repo-key=" + tests.HuggingFaceLocalRepo, } err = jfrogCli.Exec(args...) @@ -614,44 +643,29 @@ initHuggingFaceTest(t) defer cleanHuggingFaceTest(t) - // Check if python3 and huggingface_hub are available checkHuggingFaceHubAvailable(t) - // Build info collection requires HF_ENDPOINT to be set (Artifactory HuggingFace remote) - // Skip if not configured - this test requires Artifactory setup - if os.Getenv("HF_ENDPOINT") == "" { - t.Skip("Skipping build info test: HF_ENDPOINT not set. Set HF_ENDPOINT to your Artifactory HuggingFace remote URL to run this test.") - } - jfrogCli := coreTests.NewJfrogCli(execMain, "jfrog", "") + repoID := "test-org/test-model-buildinfo" + + // Upload test files to the local repo first + uploadTestModelToLocalRepo(t, jfrogCli, repoID) - buildName := "hf-download-build-test" + buildName := tests.HuggingFaceBuildName + "-download" buildNumber := "1" - // Test download with build info flags - // Using sshleifer/tiny-gpt2 which is a very small model (~2MB) designed for testing + // Download from the local repo with build info flags args := []string{ - "hf", "d", "sshleifer/tiny-gpt2", + "hf", "d", repoID, "--repo-type=model", "--build-name=" + buildName, "--build-number=" + buildNumber, + "--repo-key=" + tests.HuggingFaceLocalRepo, } - err := jfrogCli.Exec(args...) - // Build info collection requires Artifactory HuggingFace remote repo to be configured - if err != nil { - errStr := strings.ToLower(err.Error()) - if strings.Contains(errStr, "connection refused") || strings.Contains(errStr, "connection reset") || - strings.Contains(errStr, "no such host") || strings.Contains(errStr, "aql") || - strings.Contains(errStr, "401") || strings.Contains(errStr, "unauthorized") { - t.Skipf("Skipping: Artifactory HuggingFace remote repo not properly configured: %v", err) - } - assert.NoError(t, err, "HuggingFace download with build info should succeed") - } + assert.NoError(t, err, "HuggingFace download with build info should succeed") - // Clean up build info t.Cleanup(func() { - // Attempt to clean build info (may fail if not created, which is fine) _ = jfrogCli.Exec("rt", "build-discard", buildName, "--max-builds=0") }) } @@ -682,7 +696,7 @@ jfrogCli := coreTests.NewJfrogCli(execMain, "jfrog", "") - buildName := "hf-upload-build-test" + buildName := tests.HuggingFaceBuildName + "-upload" buildNumber := "1" // Test upload with build info flags @@ -691,6 +705,7 @@ "--repo-type=model", "--build-name=" + buildName, "--build-number=" + buildNumber, + "--repo-key=" + tests.HuggingFaceLocalRepo, } err = jfrogCli.Exec(args...) @@ -712,44 +727,30 @@ initHuggingFaceTest(t) defer cleanHuggingFaceTest(t) - // Check if python3 and huggingface_hub are available checkHuggingFaceHubAvailable(t) - // Build info collection requires HF_ENDPOINT to be set (Artifactory HuggingFace remote) - // Skip if not configured - this test requires Artifactory setup - if os.Getenv("HF_ENDPOINT") == "" { - t.Skip("Skipping build info test: HF_ENDPOINT not set. Set HF_ENDPOINT to your Artifactory HuggingFace remote URL to run this test.") - } - jfrogCli := coreTests.NewJfrogCli(execMain, "jfrog", "") + repoID := "test-org/test-model-module" - buildName := "hf-download-module-build-test" + // Upload test files to the local repo first + uploadTestModelToLocalRepo(t, jfrogCli, repoID) + + buildName := tests.HuggingFaceBuildName + "-download-module" buildNumber := "1" - moduleName := "tiny-bert-model-module" + moduleName := "test-model-module" - // Test download with build info and module flags - // Using sshleifer/tiny-gpt2 which is a very small model (~2MB) designed for testing + // Download from the local repo with build info and module flags args := []string{ - "hf", "d", "sshleifer/tiny-gpt2", + "hf", "d", repoID, "--repo-type=model", "--build-name=" + buildName, "--build-number=" + buildNumber, "--module=" + moduleName, + "--repo-key=" + tests.HuggingFaceLocalRepo, } - err := jfrogCli.Exec(args...) - // Build info collection requires Artifactory HuggingFace remote repo to be configured - if err != nil { - errStr := strings.ToLower(err.Error()) - if strings.Contains(errStr, "connection refused") || strings.Contains(errStr, "connection reset") || - strings.Contains(errStr, "no such host") || strings.Contains(errStr, "aql") || - strings.Contains(errStr, "401") || strings.Contains(errStr, "unauthorized") { - t.Skipf("Skipping: Artifactory HuggingFace remote repo not properly configured: %v", err) - } - assert.NoError(t, err, "HuggingFace download with build info and module should succeed") - } + assert.NoError(t, err, "HuggingFace download with build info and module should succeed") - // Clean up build info t.Cleanup(func() { _ = jfrogCli.Exec("rt", "build-discard", buildName, "--max-builds=0") }) @@ -777,7 +778,7 @@ jfrogCli := coreTests.NewJfrogCli(execMain, "jfrog", "") - buildName := "hf-upload-project-build-test" + buildName := tests.HuggingFaceBuildName + "-upload-project" buildNumber := "1" projectKey := "test-project" @@ -788,6 +789,7 @@ "--build-name=" + buildName, "--build-number=" + buildNumber, "--project=" + projectKey, + "--repo-key=" + tests.HuggingFaceLocalRepo, } err = jfrogCli.Exec(args...) @@ -812,45 +814,41 @@ initHuggingFaceTest(t) defer cleanHuggingFaceTest(t) - // Check if python3 and huggingface_hub are available checkHuggingFaceHubAvailable(t) jfrogCli := coreTests.NewJfrogCli(execMain, "jfrog", "") + repoID := "test-org/test-model-cache" - // Download a small model (using model instead of dataset to avoid HF rate limiting issues) - // This test verifies that downloaded files are cached correctly + // Upload test files to the local repo first + uploadTestModelToLocalRepo(t, jfrogCli, repoID) + + // Download from the local repo args := []string{ - "hf", "d", "sshleifer/tiny-gpt2", + "hf", "d", repoID, "--repo-type=model", + "--repo-key=" + tests.HuggingFaceLocalRepo, } - err := jfrogCli.Exec(args...) if err != nil { - // Skip verification if download failed (might be network/auth issues) t.Skipf("Download failed, skipping file verification: %v", err) } - // Get HuggingFace cache directory + // Verify files are cached under ~/.cache/huggingface/hub/ homeDir, err := os.UserHomeDir() require.NoError(t, err, "Failed to get user home directory") - // HuggingFace typically caches to ~/.cache/huggingface/hub/ hfCacheDir := filepath.Join(homeDir, ".cache", "huggingface", "hub") - - // Check if cache directory exists if _, err := os.Stat(hfCacheDir); os.IsNotExist(err) { t.Log("HuggingFace cache directory not found at default location, skipping file verification") return } - // Verify some files exist in cache (model files are cached with specific naming) found := false err = filepath.Walk(hfCacheDir, func(path string, info os.FileInfo, walkErr error) error { if walkErr != nil { - // Skip inaccessible directories/files and continue walking return filepath.SkipDir } - if strings.Contains(path, "tiny-gpt2") { + if strings.Contains(path, "test-model-cache") { found = true return filepath.SkipDir } @@ -863,9 +861,13 @@ // InitHuggingFaceTests initializes HuggingFace tests func InitHuggingFaceTests() { initArtifactoryCli() + cleanUpOldBuilds() + cleanUpOldRepositories() + tests.AddTimestampToGlobalVars() + createRequiredRepos() } // CleanHuggingFaceTests cleans up after HuggingFace tests func CleanHuggingFaceTests() { - // Cleanup is handled per-test + deleteCreatedRepos() } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.94.0/testdata/huggingface_local_repository_config.json new/jfrog-cli-2.95.0/testdata/huggingface_local_repository_config.json --- old/jfrog-cli-2.94.0/testdata/huggingface_local_repository_config.json 1970-01-01 01:00:00.000000000 +0100 +++ new/jfrog-cli-2.95.0/testdata/huggingface_local_repository_config.json 2026-03-06 12:07:30.000000000 +0100 @@ -0,0 +1,5 @@ +{ + "key": "${HUGGINGFACE_LOCAL_REPO}", + "rclass": "local", + "packageType": "huggingfaceml" +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.94.0/utils/cliutils/cli_consts.go new/jfrog-cli-2.95.0/utils/cliutils/cli_consts.go --- old/jfrog-cli-2.94.0/utils/cliutils/cli_consts.go 2026-03-04 11:40:08.000000000 +0100 +++ new/jfrog-cli-2.95.0/utils/cliutils/cli_consts.go 2026-03-06 12:07:30.000000000 +0100 @@ -4,7 +4,7 @@ const ( // General CLI constants - CliVersion = "2.94.0" + CliVersion = "2.95.0" ClientAgent = "jfrog-cli-go" // CLI base commands constants: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.94.0/utils/cliutils/commandsflags.go new/jfrog-cli-2.95.0/utils/cliutils/commandsflags.go --- old/jfrog-cli-2.94.0/utils/cliutils/commandsflags.go 2026-03-04 11:40:08.000000000 +0100 +++ new/jfrog-cli-2.95.0/utils/cliutils/commandsflags.go 2026-03-06 12:07:30.000000000 +0100 @@ -599,6 +599,7 @@ Revision = "revision" RepoType = "repo-type" EtagTimeout = "etag-timeout" + RepoKey = "repo-key" ) var flagsMap = map[string]cli.Flag{ @@ -1767,6 +1768,10 @@ Name: RepoType, Usage: "[Default: model] Type of repository. Can be 'model', 'dataset'.` `", }, + RepoKey: cli.StringFlag{ + Name: RepoKey, + Usage: "Repository Key for uploading/downloading dataset/models.", + }, } var commandFlags = map[string][]string{ @@ -2000,7 +2005,7 @@ BuildName, BuildNumber, module, Project, serverId, username, password, }, HuggingFace: { - BuildName, BuildNumber, module, Project, serverId, Revision, RepoType, EtagTimeout, + BuildName, BuildNumber, module, Project, serverId, Revision, RepoType, EtagTimeout, RepoKey, }, RubyConfig: { global, serverIdResolve, serverIdDeploy, repoResolve, repoDeploy, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.94.0/utils/tests/consts.go new/jfrog-cli-2.95.0/utils/tests/consts.go --- old/jfrog-cli-2.94.0/utils/tests/consts.go 2026-03-04 11:40:08.000000000 +0100 +++ new/jfrog-cli-2.95.0/utils/tests/consts.go 2026-03-06 12:07:30.000000000 +0100 @@ -112,6 +112,7 @@ ConanRemoteRepositoryConfig = "conan_remote_repository_config.json" ConanVirtualRepositoryConfig = "conan_virtual_repository_config.json" HelmLocalRepositoryConfig = "helm_local_repository_config.json" + HuggingFaceLocalRepositoryConfig = "huggingface_local_repository_config.json" ReplicationTempCreate = "replication_push_create.json" Repo1RepositoryConfig = "repo1_repository_config.json" Repo2RepositoryConfig = "repo2_repository_config.json" @@ -213,6 +214,7 @@ ConanRemoteRepo = "cli-conan-remote" ConanVirtualRepo = "cli-conan-virtual" HelmLocalRepo = "cli-helm-local" + HuggingFaceLocalRepo = "cli-huggingface-local" DockerLocalRepo = "cli-docker-local" DockerLocalPromoteRepo = "cli-docker-local-promote" DockerRemoteRepo = "cli-docker-remote" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jfrog-cli-2.94.0/utils/tests/utils.go new/jfrog-cli-2.95.0/utils/tests/utils.go --- old/jfrog-cli-2.94.0/utils/tests/utils.go 2026-03-04 11:40:08.000000000 +0100 +++ new/jfrog-cli-2.95.0/utils/tests/utils.go 2026-03-06 12:07:30.000000000 +0100 @@ -289,6 +289,7 @@ &ConanRemoteRepo: ConanRemoteRepositoryConfig, &ConanVirtualRepo: ConanVirtualRepositoryConfig, &HelmLocalRepo: HelmLocalRepositoryConfig, + &HuggingFaceLocalRepo: HuggingFaceLocalRepositoryConfig, &RtDebianRepo: DebianTestRepositoryConfig, &RtLfsRepo: GitLfsTestRepositoryConfig, &RtRepo1: Repo1RepositoryConfig, @@ -355,7 +356,7 @@ TestPoetry: {&PoetryLocalRepo, &PoetryRemoteRepo}, TestConan: {&ConanLocalRepo, &ConanRemoteRepo}, TestHelm: {&HelmLocalRepo}, - TestHuggingFace: {}, + TestHuggingFace: {&HuggingFaceLocalRepo}, TestPlugins: {&RtRepo1}, TestXray: {&NpmRemoteRepo, &NugetRemoteRepo, &YarnRemoteRepo, &GradleRemoteRepo, &MvnRemoteRepo, &GoRepo, &GoRemoteRepo, &PypiRemoteRepo}, TestAccess: {&RtRepo1}, @@ -485,6 +486,7 @@ "${CONAN_REMOTE_REPO}": ConanRemoteRepo, "${CONAN_VIRTUAL_REPO}": ConanVirtualRepo, "${HELM_REPO}": HelmLocalRepo, + "${HUGGINGFACE_LOCAL_REPO}": HuggingFaceLocalRepo, "${BUILD_NAME1}": RtBuildName1, "${BUILD_NAME2}": RtBuildName2, "${BUNDLE_NAME}": BundleName, @@ -554,6 +556,7 @@ ConanRemoteRepo += uniqueSuffix ConanVirtualRepo += uniqueSuffix HelmLocalRepo += uniqueSuffix + HuggingFaceLocalRepo += uniqueSuffix RtDebianRepo += uniqueSuffix RtLfsRepo += uniqueSuffix RtRepo1 += uniqueSuffix @@ -581,6 +584,7 @@ PoetryBuildName += uniqueSuffix ConanBuildName += uniqueSuffix HelmBuildName += uniqueSuffix + HuggingFaceBuildName += uniqueSuffix RtBuildName1 += uniqueSuffix RtBuildName2 += uniqueSuffix RtBuildNameWithSpecialChars += uniqueSuffix ++++++ jfrog-cli.obsinfo ++++++ --- /var/tmp/diff_new_pack.Eh4tMV/_old 2026-03-09 16:15:31.831230270 +0100 +++ /var/tmp/diff_new_pack.Eh4tMV/_new 2026-03-09 16:15:31.835230431 +0100 @@ -1,5 +1,5 @@ name: jfrog-cli -version: 2.94.0 -mtime: 1772620808 -commit: b63aa5d2180c5a039e5e548d513bfc04e89c9e13 +version: 2.95.0 +mtime: 1772795250 +commit: 1c728785312c6e01baaf86e6d689a7efd4d7ec9d ++++++ vendor.tar.gz ++++++ /work/SRC/openSUSE:Factory/jfrog-cli/vendor.tar.gz /work/SRC/openSUSE:Factory/.jfrog-cli.new.8177/vendor.tar.gz differ: char 28, line 1
