Skip to content

Commit b0eb1d7

Browse files
Merge remote-tracking branch 'origin/dev' into v2
2 parents e13c4dc + 32020eb commit b0eb1d7

File tree

19 files changed

+546
-78
lines changed

19 files changed

+546
-78
lines changed

Jenkinsfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ node("docker-ubuntu20-xlarge") {
3131
repo = 'jfrog-cli'
3232
sh 'rm -rf temp'
3333
sh 'mkdir temp'
34-
def goRoot = tool 'go-1.23.7'
34+
def goRoot = tool 'go-1.23.9'
3535
env.GOROOT="$goRoot"
3636
env.PATH+=":${goRoot}/bin:/tmp/node-${nodeVersion}-linux-x64/bin"
3737
env.GO111MODULE="on"

build/docker/slim/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
ARG repo_name_21
22
# Remove ${repo_name_21} to pull from Docker Hub.
3-
FROM ${repo_name_21}/jfrog-docker/golang:1.23.7-alpine as builder
3+
FROM ${repo_name_21}/jfrog-docker/golang:1.23.9-alpine as builder
44
ARG image_name=jfrog-cli
55
ARG cli_executable_name
66
WORKDIR /${image_name}

build/npm/v2-jf/package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build/npm/v2-jf/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "jfrog-cli-v2-jf",
3-
"version": "2.75.1",
3+
"version": "2.76.0",
44
"description": "🐸 Command-line interface for JFrog Artifactory, Xray, Distribution, Pipelines and Mission Control 🐸",
55
"homepage": "https://github.com/jfrog/jfrog-cli",
66
"preferGlobal": true,

build/npm/v2/package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build/npm/v2/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "jfrog-cli-v2",
3-
"version": "2.75.1",
3+
"version": "2.76.0",
44
"description": "🐸 Command-line interface for JFrog Artifactory, Xray, Distribution, Pipelines and Mission Control 🐸",
55
"homepage": "https://github.com/jfrog/jfrog-cli",
66
"preferGlobal": true,

buildtools/cli.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -934,9 +934,17 @@ func NpmPublishCmd(c *cli.Context) (err error) {
934934
if npmCmd.GetXrayScan() {
935935
commandsUtils.ConditionalUploadScanFunc = scan.ConditionalUploadDefaultScanFunc
936936
}
937-
printDeploymentView, detailedSummary := log.IsStdErrTerminal(), npmCmd.IsDetailedSummary()
938-
if !detailedSummary {
939-
npmCmd.SetDetailedSummary(printDeploymentView)
937+
938+
var printDeploymentView, detailedSummary bool
939+
940+
// Deployment view and Detailed summary is not supported when using npmrc for publishing since transfer details are not available.
941+
if npmCmd.UseNative() {
942+
printDeploymentView, detailedSummary = false, false
943+
} else {
944+
printDeploymentView, detailedSummary = log.IsStdErrTerminal(), npmCmd.IsDetailedSummary()
945+
if !detailedSummary {
946+
npmCmd.SetDetailedSummary(printDeploymentView)
947+
}
940948
}
941949
err = commands.Exec(npmCmd)
942950
result := npmCmd.Result()

docker_test.go

Lines changed: 114 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,39 @@ func runPushTest(containerManager container.ContainerManagerType, imageName, mod
179179
validateContainerBuild(tests.DockerBuildName, buildNumber, imagePath, module, 7, 5, 7, t)
180180
}
181181

182+
func loginToArtifactory(t *testing.T, container *tests.TestContainer) {
183+
password := *tests.JfrogPassword
184+
user := *tests.JfrogUser
185+
if *tests.JfrogAccessToken != "" {
186+
user = auth.ExtractUsernameFromAccessToken(*tests.JfrogAccessToken)
187+
password = *tests.JfrogAccessToken
188+
}
189+
assert.NoError(t, container.Exec(
190+
context.Background(),
191+
"docker",
192+
"login",
193+
tests.RtContainerHostName,
194+
"--username="+user,
195+
"--password="+password,
196+
))
197+
}
198+
199+
func buildBuilderImage(t *testing.T, workspace, dockerfile, containerName string) *tests.TestContainer {
200+
ctx := context.Background()
201+
testContainer, err := tests.NewContainerRequest().
202+
SetDockerfile(workspace, dockerfile, nil).
203+
Privileged().
204+
Networks(rtNetwork).
205+
Name(containerName).
206+
Mount(mount.Mount{Type: mount.TypeBind, Source: workspace, Target: "/workspace", ReadOnly: false}).
207+
Cmd("--insecure-registry", tests.RtContainerHostName).
208+
WaitFor(wait.ForLog("API listen on /var/run/docker.sock").WithStartupTimeout(5*time.Minute)).
209+
Remove().
210+
Build(ctx, true)
211+
assert.NoError(t, err, "Couldn't create builder image.")
212+
return testContainer
213+
}
214+
182215
// This test validate the collect build-info flow for fat-manifest images.
183216
// The way we build the fat manifest and push it to Artifactory is not important.
184217
// Therefore, this test runs only with docker.
@@ -194,53 +227,30 @@ func TestPushFatManifestImage(t *testing.T) {
194227
assert.NoError(t, fileutils.CreateDirIfNotExist(workspace))
195228
testDataDir := filepath.Join(filepath.FromSlash(tests.GetTestResourcesPath()), "docker")
196229
files, err := os.ReadDir(testDataDir)
197-
198230
assert.NoError(t, err)
199231
for _, file := range files {
200232
if !file.IsDir() {
201233
_, err := tests.ReplaceTemplateVariables(filepath.Join(testDataDir, file.Name()), tests.Out)
202234
assert.NoError(t, err)
203235
}
204236
}
237+
205238
// Build the builder image locally.
206-
ctx := context.Background()
207-
testContainer, err := tests.NewContainerRequest().
208-
SetDockerfile(workspace, "Dockerfile.Buildx.Fatmanifest", nil).
209-
Privileged().
210-
Networks(rtNetwork).
211-
Name("buildx_container").
212-
Mount(mount.Mount{Type: mount.TypeBind, Source: workspace, Target: "/workspace", ReadOnly: false}).
213-
Cmd("--insecure-registry", tests.RtContainerHostName).
214-
// 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.
215-
WaitFor(wait.ForLog("API listen on /var/run/docker.sock").WithStartupTimeout(5*time.Minute)).
216-
Remove().
217-
Build(ctx, true)
218-
assert.NoError(t, err, "Couldn't run create buildx image.")
219-
defer func() { assert.NoError(t, testContainer.Terminate(ctx)) }()
239+
testContainer := buildBuilderImage(t, workspace, "Dockerfile.Buildx.Fatmanifest", "buildx_container")
240+
defer func() { assert.NoError(t, testContainer.Terminate(context.Background())) }()
220241

221242
// Enable the builder util in the container.
222-
err = testContainer.Exec(ctx, "sh", "script.sh")
243+
err = testContainer.Exec(context.Background(), "sh", "script.sh")
223244
assert.NoError(t, err)
224245

225-
// login from the builder container toward the Artifactory.
226-
password := *tests.JfrogPassword
227-
user := *tests.JfrogUser
228-
if *tests.JfrogAccessToken != "" {
229-
user = auth.ExtractUsernameFromAccessToken(*tests.JfrogAccessToken)
230-
password = *tests.JfrogAccessToken
231-
}
232-
assert.NoError(t, testContainer.Exec(
233-
ctx,
234-
"docker",
235-
"login",
236-
tests.RtContainerHostName,
237-
"--username="+user,
238-
"--password="+password))
246+
// Login to Artifactory
247+
loginToArtifactory(t, testContainer)
248+
239249
buildxOutputFile := "buildmetadata"
240250

241-
// Run the builder in the container and push the fat-manifest image to artifactory
251+
// Run the builder in the container and push the fat-manifest image to Artifactory
242252
assert.NoError(t, testContainer.Exec(
243-
ctx,
253+
context.Background(),
244254
"docker",
245255
"buildx",
246256
"build",
@@ -263,20 +273,83 @@ func TestPushFatManifestImage(t *testing.T) {
263273
assert.NoError(t, artifactoryCli.Exec("build-docker-create", tests.DockerLocalRepo, "--image-file="+buildxOutput, "--build-name="+buildName, "--build-number="+buildNumber))
264274
assert.NoError(t, artifactoryCli.Exec("build-publish", buildName, buildNumber))
265275

266-
// Validate the published build-info exits
276+
// Validate the published build-info exists
267277
publishedBuildInfo, found, err := tests.GetBuildInfo(serverDetails, buildName, buildNumber)
268-
if err != nil {
269-
assert.NoError(t, err)
270-
return
278+
assert.NoError(t, err)
279+
assert.True(t, found, "build info was expected to be found")
280+
assert.True(t, len(publishedBuildInfo.BuildInfo.Modules) > 1)
281+
282+
// Validate build-name & build-number properties in all image layers
283+
searchSpec := spec.NewBuilder().Pattern(tests.DockerLocalRepo + "/*").Build(buildName).Recursive(true).BuildSpec()
284+
searchCmd := generic.NewSearchCommand()
285+
searchCmd.SetServerDetails(serverDetails).SetSpec(searchSpec)
286+
reader, err := searchCmd.Search()
287+
assert.NoError(t, err)
288+
totalResults, err := reader.Length()
289+
assert.NoError(t, err)
290+
assert.True(t, totalResults > 1)
291+
}
292+
293+
func TestPushMultiTaggedImage(t *testing.T) {
294+
if !*tests.TestDocker {
295+
t.Skip("Skipping test. To run it, add the '-test.docker=true' option.")
271296
}
272-
if !found {
273-
assert.True(t, found, "build info was expected to be found")
274-
return
297+
298+
buildName := "push-multi-tagged" + tests.DockerBuildName
299+
buildNumber := "1"
300+
301+
// Setup workspace
302+
workspace, err := filepath.Abs(tests.Out)
303+
assert.NoError(t, err)
304+
assert.NoError(t, fileutils.CreateDirIfNotExist(workspace))
305+
testDataDir := filepath.Join(filepath.FromSlash(tests.GetTestResourcesPath()), "docker")
306+
files, err := os.ReadDir(testDataDir)
307+
assert.NoError(t, err)
308+
for _, file := range files {
309+
if !file.IsDir() {
310+
_, err := tests.ReplaceTemplateVariables(filepath.Join(testDataDir, file.Name()), tests.Out)
311+
assert.NoError(t, err)
312+
}
275313
}
276314

277-
assert.True(t, len(publishedBuildInfo.BuildInfo.Modules) > 1)
315+
// Build the builder image locally
316+
testContainer := buildBuilderImage(t, workspace, "Dockerfile.Buildx.Fatmanifest", "buildx_multi_tag_container")
317+
defer func() { assert.NoError(t, testContainer.Terminate(context.Background())) }()
278318

279-
// Validate build-name & build-number properties in all image layers
319+
// Enable builder
320+
assert.NoError(t, testContainer.Exec(context.Background(), "sh", "script.sh"))
321+
322+
// Login to Artifactory
323+
loginToArtifactory(t, testContainer)
324+
325+
// Build & push image with multiple tags
326+
imageName1 := path.Join(tests.RtContainerHostName, tests.DockerLocalRepo, tests.DockerImageName+"-multi:v1")
327+
imageName2 := path.Join(tests.RtContainerHostName, tests.DockerLocalRepo, tests.DockerImageName+"-multi:latest")
328+
buildxOutputFile := "multi-build-metadata"
329+
330+
assert.NoError(t, testContainer.Exec(
331+
context.Background(),
332+
"docker", "buildx", "build",
333+
"--platform", "linux/amd64,linux/arm64",
334+
"-t", imageName1,
335+
"-t", imageName2,
336+
"-f", "Dockerfile.Fatmanifest",
337+
"--metadata-file", "/workspace/"+buildxOutputFile,
338+
"--push", ".",
339+
))
340+
341+
// Run build-docker-create & publish
342+
buildxOutput := filepath.Join(workspace, buildxOutputFile)
343+
assert.NoError(t, artifactoryCli.Exec("build-docker-create", tests.DockerLocalRepo, "--image-file="+buildxOutput, "--build-name="+buildName, "--build-number="+buildNumber))
344+
assert.NoError(t, artifactoryCli.Exec("build-publish", buildName, buildNumber))
345+
346+
// Validate build-info is published
347+
publishedBuildInfo, found, err := tests.GetBuildInfo(serverDetails, buildName, buildNumber)
348+
assert.NoError(t, err)
349+
assert.True(t, found, "build info was expected to be found")
350+
assert.True(t, len(publishedBuildInfo.BuildInfo.Modules) >= 1)
351+
352+
// Validate build-name & build-number properties in all layers
280353
searchSpec := spec.NewBuilder().Pattern(tests.DockerLocalRepo + "/*").Build(buildName).Recursive(true).BuildSpec()
281354
searchCmd := generic.NewSearchCommand()
282355
searchCmd.SetServerDetails(serverDetails).SetSpec(searchSpec)

go.mod

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module github.com/jfrog/jfrog-cli
22

3-
go 1.23.7
3+
go 1.23.9
44

55
replace (
66
// 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 @@ require (
1616
github.com/docker/docker v27.5.1+incompatible
1717
github.com/gocarina/gocsv v0.0.0-20240520201108-78e41c74b4b1
1818
github.com/jfrog/archiver/v3 v3.6.1
19-
github.com/jfrog/build-info-go v1.10.10
19+
github.com/jfrog/build-info-go v1.10.12
2020
github.com/jfrog/gofrog v1.7.6
21-
github.com/jfrog/jfrog-cli-artifactory v0.2.4
22-
github.com/jfrog/jfrog-cli-core/v2 v2.58.5
21+
github.com/jfrog/jfrog-cli-artifactory v0.3.0
22+
github.com/jfrog/jfrog-cli-core/v2 v2.58.6
2323
github.com/jfrog/jfrog-cli-platform-services v1.9.0
24-
github.com/jfrog/jfrog-cli-security v1.17.1
25-
github.com/jfrog/jfrog-client-go v1.52.0
24+
github.com/jfrog/jfrog-cli-security v1.17.2
25+
github.com/jfrog/jfrog-client-go v1.53.0
2626
github.com/jszwec/csvutil v1.10.0
2727
github.com/manifoldco/promptui v0.9.0
2828
github.com/stretchr/testify v1.10.0
@@ -189,10 +189,10 @@ require (
189189
sigs.k8s.io/yaml v1.4.0 // indirect
190190
)
191191

192-
// replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20250505105213-0ba559a374cb
192+
//replace github.com/jfrog/jfrog-cli-artifactory => github.com/jfrog/jfrog-cli-artifactory v0.2.5-0.20250514065555-2ad0e403ae04
193193

194-
// replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.28.1-0.20250406105605-ee90d11546f9
194+
//replace github.com/jfrog/jfrog-cli-core/v2 => github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20250514055103-d3d0d25f7c85
195195

196-
// replace github.com/jfrog/jfrog-cli-artifactory => github.com/jfrog/jfrog-cli-artifactory v0.2.2-0.20250414045808-41544959f9b9
196+
//replace github.com/jfrog/jfrog-client-go => github.com/jfrog/jfrog-client-go v1.28.1-0.20250508130334-f159cff9b11a
197197

198-
// replace github.com/jfrog/jfrog-cli-security => github.com/jfrog/jfrog-cli-security v1.16.3-0.20250402121228-12cce9f88504
198+
//replace github.com/jfrog/jfrog-cli-security => github.com/jfrog/jfrog-cli-security v1.17.2-0.20250511132918-d9cc4cd50020

go.sum

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,8 @@ github.com/jedib0t/go-pretty/v6 v6.6.5 h1:9PgMJOVBedpgYLI56jQRJYqngxYAAzfEUua+3N
176176
github.com/jedib0t/go-pretty/v6 v6.6.5/go.mod h1:Uq/HrbhuFty5WSVNfjpQQe47x16RwVGXIveNGEyGtHs=
177177
github.com/jfrog/archiver/v3 v3.6.1 h1:LOxnkw9pOn45DzCbZNFV6K0+6dCsQ0L8mR3ZcujO5eI=
178178
github.com/jfrog/archiver/v3 v3.6.1/go.mod h1:VgR+3WZS4N+i9FaDwLZbq+jeU4B4zctXL+gL4EMzfLw=
179-
github.com/jfrog/build-info-go v1.10.10 h1:2nOFjV7SX1uisi2rQK7fb4Evm7YkSOdmssrm6Tf4ipc=
180-
github.com/jfrog/build-info-go v1.10.10/go.mod h1:JcISnovFXKx3wWf3p1fcMmlPdt6adxScXvoJN4WXqIE=
179+
github.com/jfrog/build-info-go v1.10.12 h1:KO/YUeKYtDrnpcmsXmwqr6akjzrwA0hSTUB+Op/HF88=
180+
github.com/jfrog/build-info-go v1.10.12/go.mod h1:JcISnovFXKx3wWf3p1fcMmlPdt6adxScXvoJN4WXqIE=
181181
github.com/jfrog/froggit-go v1.17.0 h1:20Ie787WO27SwB2MOHDvsR6yN7fA5WfRnuAbmUqz1Zs=
182182
github.com/jfrog/froggit-go v1.17.0/go.mod h1:HvDkfFfJwIdsXFdqaB+utvD2cLDRmaC3kF8otYb6Chw=
183183
github.com/jfrog/go-mockhttp v0.3.1 h1:/wac8v4GMZx62viZmv4wazB5GNKs+GxawuS1u3maJH8=
@@ -186,16 +186,16 @@ github.com/jfrog/gofrog v1.7.6 h1:QmfAiRzVyaI7JYGsB7cxfAJePAZTzFz0gRWZSE27c6s=
186186
github.com/jfrog/gofrog v1.7.6/go.mod h1:ntr1txqNOZtHplmaNd7rS4f8jpA5Apx8em70oYEe7+4=
187187
github.com/jfrog/jfrog-apps-config v1.0.1 h1:mtv6k7g8A8BVhlHGlSveapqf4mJfonwvXYLipdsOFMY=
188188
github.com/jfrog/jfrog-apps-config v1.0.1/go.mod h1:8AIIr1oY9JuH5dylz2S6f8Ym2MaadPLR6noCBO4C22w=
189-
github.com/jfrog/jfrog-cli-artifactory v0.2.4 h1:n/BlqkH20jW8T1JPr/QHw+D+wsPZsDU0Qq/+eSGzgAg=
190-
github.com/jfrog/jfrog-cli-artifactory v0.2.4/go.mod h1:tXlrvTtG4l0dPdKFG7nlteuSv7vggF/OVwsq44sgVgA=
191-
github.com/jfrog/jfrog-cli-core/v2 v2.58.5 h1:q6HeK1NHgpjAtgNQ0mfX4buovo/CAGTP5C0s7UMg7aQ=
192-
github.com/jfrog/jfrog-cli-core/v2 v2.58.5/go.mod h1:JbLdMCWL0xVZZ0FY7jd+iTi/gKYqRmRpeLBhAFtldfQ=
189+
github.com/jfrog/jfrog-cli-artifactory v0.3.0 h1:nodmuOauNSx2OKwQChQ1fLcnhNs+tgWpOk9caMdAuoI=
190+
github.com/jfrog/jfrog-cli-artifactory v0.3.0/go.mod h1:BliRZeMdqVEKHOtREuowYBgNqwVAFcKY0/veOxQDjwo=
191+
github.com/jfrog/jfrog-cli-core/v2 v2.58.6 h1:cCg9o0M2p52qCnO0Y+Ry8lxbVIJDJy4s948li2UIYaM=
192+
github.com/jfrog/jfrog-cli-core/v2 v2.58.6/go.mod h1:VjXJpjapnKA0eBoCH9+5+nWQOxQJ+uzADMY2DQPkCzE=
193193
github.com/jfrog/jfrog-cli-platform-services v1.9.0 h1:r/ETgJuMUOUu12w20ydsF6paqEaj0khH6bxMRsdNz1Y=
194194
github.com/jfrog/jfrog-cli-platform-services v1.9.0/go.mod h1:pMZMSwhj7yA4VKyj0Skr2lObIyGpZUxNJ40DSLKXU38=
195-
github.com/jfrog/jfrog-cli-security v1.17.1 h1:4gXZ9Q59DOBkntMBDjlcVdZ1jaJUn1bFy4Rhr+SAeqA=
196-
github.com/jfrog/jfrog-cli-security v1.17.1/go.mod h1:655eM28gQHUdT6IC6uQf677tqrN1wEcPRzc+8vcM/vA=
197-
github.com/jfrog/jfrog-client-go v1.52.0 h1:MCmHviUqj3X7iqyOokTkyvV5yBWFwZYDPVXYikl4nf0=
198-
github.com/jfrog/jfrog-client-go v1.52.0/go.mod h1:uRmT8Q1SJymIzId01v0W1o8mGqrRfrwUF53CgEMsH0U=
195+
github.com/jfrog/jfrog-cli-security v1.17.2 h1:368C9S11uiPffYUyy1Q076XmUh7+XrSuIqfqc4izIig=
196+
github.com/jfrog/jfrog-cli-security v1.17.2/go.mod h1:IkjG18ZIe9oHnZIHRlSs6L7Ddlbreiiwtq1BqQiEe70=
197+
github.com/jfrog/jfrog-client-go v1.53.0 h1:oCNuxEtN2VWcbqGdIp1tdYupm7PJZP53etX1Pr24kxY=
198+
github.com/jfrog/jfrog-client-go v1.53.0/go.mod h1:IKmGx4sYeaiSKBnVzp/j6lVrmyRAXTABfo3B02SPxXI=
199199
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
200200
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
201201
github.com/jszwec/csvutil v1.10.0 h1:upMDUxhQKqZ5ZDCs/wy+8Kib8rZR8I8lOR34yJkdqhI=

0 commit comments

Comments
 (0)