Skip to content

Commit 3700256

Browse files
authored
Added e2e tests for create and update of a draft release bundle commands (#3334)
1 parent da076f1 commit 3700256

File tree

5 files changed

+180
-16
lines changed

5 files changed

+180
-16
lines changed

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ require (
1919
github.com/jfrog/build-info-go v1.13.1-0.20260130140656-2d0d5593fccf
2020
github.com/jfrog/gofrog v1.7.6
2121
github.com/jfrog/jfrog-cli-application v1.0.2-0.20260127112223-c5078af84b5a
22-
github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260129054930-035e3ed7e30d
22+
github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260203090305-f5f8aed71eaf
2323
github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260128134755-624b659a398e
2424
github.com/jfrog/jfrog-cli-evidence v0.8.3-0.20260125120022-1c6f4f382dbb
2525
github.com/jfrog/jfrog-cli-platform-services v1.10.1-0.20251205121610-171eb9b0000e
2626
github.com/jfrog/jfrog-cli-security v1.26.0
27-
github.com/jfrog/jfrog-client-go v1.55.1-0.20260128141727-bd34d78a3e48
27+
github.com/jfrog/jfrog-client-go v1.55.1-0.20260202100450-1b20bddfdb3f
2828
github.com/jszwec/csvutil v1.10.0
2929
github.com/manifoldco/promptui v0.9.0
3030
github.com/spf13/viper v1.21.0

go.sum

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,8 +1218,8 @@ github.com/jfrog/jfrog-apps-config v1.0.1 h1:mtv6k7g8A8BVhlHGlSveapqf4mJfonwvXYL
12181218
github.com/jfrog/jfrog-apps-config v1.0.1/go.mod h1:8AIIr1oY9JuH5dylz2S6f8Ym2MaadPLR6noCBO4C22w=
12191219
github.com/jfrog/jfrog-cli-application v1.0.2-0.20260127112223-c5078af84b5a h1:Yvl7XuMoI1cXk3jzB1oWcZvFy5K3aUAIin9o5GRaqzE=
12201220
github.com/jfrog/jfrog-cli-application v1.0.2-0.20260127112223-c5078af84b5a/go.mod h1:xum2HquWO5uExa/A7MQs3TgJJVEeoqTR+6Z4mfBr1Xw=
1221-
github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260129054930-035e3ed7e30d h1:jyBD9kqAL8eHerZvGmxiTZECA+sYuH3TpodGnnpnPSs=
1222-
github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260129054930-035e3ed7e30d/go.mod h1:ANFZOB4AX+Voo24l1BO8bVvN76m3ZViR1QaK5u3QDgE=
1221+
github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260203090305-f5f8aed71eaf h1:3W7qIxrkJkC1K0vB/By3fVyCkU3qgY9SdHQs7o5RNRo=
1222+
github.com/jfrog/jfrog-cli-artifactory v0.8.1-0.20260203090305-f5f8aed71eaf/go.mod h1:DkLAN+AvZ4v6jcuUStufi9DuhAS1dvSRJhILJyRa9kg=
12231223
github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260128134755-624b659a398e h1:jGtYjWMMfCINDl1JbRtvAijtVwD+j+yvR5BuYMZvRrA=
12241224
github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20260128134755-624b659a398e/go.mod h1:+Hnaikp/xCSPD/q7txxRy4Zc0wzjW/usrCSf+6uONSQ=
12251225
github.com/jfrog/jfrog-cli-evidence v0.8.3-0.20260125120022-1c6f4f382dbb h1:4nGzxRxVcXxkFg95jr+zMjESisZGqSYecXfHsA37rpA=
@@ -1228,8 +1228,8 @@ github.com/jfrog/jfrog-cli-platform-services v1.10.1-0.20251205121610-171eb9b000
12281228
github.com/jfrog/jfrog-cli-platform-services v1.10.1-0.20251205121610-171eb9b0000e/go.mod h1:qbu4iqBST9x8LgD8HhzUm91iOB3vHqtoGmaxOnmw0ok=
12291229
github.com/jfrog/jfrog-cli-security v1.26.0 h1:FcLshS1Ahm0++nV5q7UluFTCVRxH2wEIbqO7ZBag++I=
12301230
github.com/jfrog/jfrog-cli-security v1.26.0/go.mod h1:r9E0BdlNy6mq6gkRGslZRZaYe6WeGhLkpUm8+oEUOvU=
1231-
github.com/jfrog/jfrog-client-go v1.55.1-0.20260128141727-bd34d78a3e48 h1:HY4b9DsUe0Lox1rScYHKmfIZY9PQvy0kfkOefqc/QdQ=
1232-
github.com/jfrog/jfrog-client-go v1.55.1-0.20260128141727-bd34d78a3e48/go.mod h1:sCE06+GngPoyrGO0c+vmhgMoVSP83UMNiZnIuNPzU8U=
1231+
github.com/jfrog/jfrog-client-go v1.55.1-0.20260202100450-1b20bddfdb3f h1:A/5DenqKB4zv9jWhG777/UwhoGL8hCzIndKj0sJ7QSM=
1232+
github.com/jfrog/jfrog-client-go v1.55.1-0.20260202100450-1b20bddfdb3f/go.mod h1:sCE06+GngPoyrGO0c+vmhgMoVSP83UMNiZnIuNPzU8U=
12331233
github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94=
12341234
github.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8=
12351235
github.com/jmespath/go-jmespath v0.4.1-0.20220621161143-b0104c826a24 h1:liMMTbpW34dhU4az1GN0pTPADwNmvoRSeoZ6PItiqnY=

lifecycle_test.go

Lines changed: 133 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ const (
3838
artifactoryLifecycleMinVersion = "7.68.3"
3939
signingKeyOptionalArtifactoryMinVersion = "7.104.1"
4040
promotionTypeFlagArtifactoryMinVersion = "7.106.1"
41+
draftBundleArtifactoryMinVersion = "7.136.0"
4142
gpgKeyPairName = "lc-tests-key-pair"
4243
lcTestdataPath = "lifecycle"
4344
releaseBundlesSpec = "release-bundles-spec.json"
@@ -167,7 +168,7 @@ func TestReleaseBundleCreationFromMultiBundlesUsingCommandFlagWithProject(t *tes
167168
defer deleteBuilds()
168169

169170
// Create first release bundle from builds with project
170-
createRbWithFlags(t, "", "", tests.LcBuildName1, number1, tests.LcRbName1, number1, tests.ProjectKey, true, true)
171+
createRbWithFlags(t, "", "", tests.LcBuildName1, number1, tests.LcRbName1, number1, tests.ProjectKey, true, true, false)
171172
defer deleteReleaseBundleWithProject(t, lcManager, tests.LcRbName1, number1, tests.ProjectKey)
172173
assertStatusCompletedWithProject(t, lcManager, tests.LcRbName1, number1, "", tests.ProjectKey)
173174

@@ -177,7 +178,7 @@ func TestReleaseBundleCreationFromMultiBundlesUsingCommandFlagWithProject(t *tes
177178
assert.True(t, isExist, "Release bundle %s/%s should exist in project %s", tests.LcRbName1, number1, tests.ProjectKey)
178179

179180
// Create second release bundle from builds with project
180-
createRbWithFlags(t, "", "", tests.LcBuildName2, number2, tests.LcRbName2, number2, tests.ProjectKey, true, true)
181+
createRbWithFlags(t, "", "", tests.LcBuildName2, number2, tests.LcRbName2, number2, tests.ProjectKey, true, true, false)
181182
defer deleteReleaseBundleWithProject(t, lcManager, tests.LcRbName2, number2, tests.ProjectKey)
182183
assertStatusCompletedWithProject(t, lcManager, tests.LcRbName2, number2, "", tests.ProjectKey)
183184

@@ -489,6 +490,85 @@ func TestPromoteReleaseBundleWithPromotionTypeFlag(t *testing.T) {
489490
assertStatusCompleted(t, lcManager, tests.LcRbName1, number1, "")
490491
}
491492

493+
func TestReleaseBundleCreationWithDraftFlagFromSpec(t *testing.T) {
494+
cleanCallback := initLifecycleTest(t, draftBundleArtifactoryMinVersion)
495+
defer cleanCallback()
496+
lcManager := getLcServiceManager(t)
497+
498+
deleteBuilds := uploadBuilds(t)
499+
defer deleteBuilds()
500+
501+
// Create draft bundle from spec
502+
createRbFromSpecWithDraft(t, tests.LifecycleBuilds12, tests.LcRbName1, number1, true, true, true)
503+
defer deleteReleaseBundle(t, lcManager, tests.LcRbName1, number1)
504+
assertStatusDraft(t, lcManager, tests.LcRbName1, number1)
505+
}
506+
507+
func TestReleaseBundleCreationWithDraftFlagFromFlags(t *testing.T) {
508+
cleanCallback := initLifecycleTest(t, draftBundleArtifactoryMinVersion)
509+
defer cleanCallback()
510+
lcManager := getLcServiceManager(t)
511+
512+
deleteBuilds := uploadBuilds(t)
513+
defer deleteBuilds()
514+
515+
// Create draft bundle using build-name/build-number flags
516+
createRbWithFlags(t, "", "", tests.LcBuildName2, number2, tests.LcRbName2, number2, "default", true, true, true)
517+
defer deleteReleaseBundle(t, lcManager, tests.LcRbName2, number2)
518+
assertStatusDraft(t, lcManager, tests.LcRbName2, number2)
519+
}
520+
521+
func TestReleaseBundleUpdateWithSpec(t *testing.T) {
522+
cleanCallback := initLifecycleTest(t, draftBundleArtifactoryMinVersion)
523+
defer cleanCallback()
524+
lcManager := getLcServiceManager(t)
525+
526+
deleteBuilds := uploadBuilds(t)
527+
defer deleteBuilds()
528+
529+
// Create a draft bundle from build 1
530+
createRbWithFlags(t, "", "", tests.LcBuildName1, number1, tests.LcRbName1, number1, "default", true, true, true)
531+
defer deleteReleaseBundle(t, lcManager, tests.LcRbName1, number1)
532+
assertStatusDraft(t, lcManager, tests.LcRbName1, number1)
533+
assertRbArtifacts(t, lcManager, tests.LcRbName1, number1, tests.GetExpectedLifecycleBuild1Artifacts())
534+
535+
// Update the draft bundle by adding build 3 (which includes dependencies) using spec file
536+
updateSpecFile, err := tests.CreateSpec(tests.LifecycleBuilds3)
537+
assert.NoError(t, err)
538+
updateRbWithFlags(t, updateSpecFile, tests.LcRbName1, number1, "default", "", true)
539+
540+
// Verify the bundle is still in DRAFT status after update
541+
assertStatusDraft(t, lcManager, tests.LcRbName1, number1)
542+
543+
// Verify the bundle now contains artifacts from both build 1 and build 3
544+
assertRbArtifacts(t, lcManager, tests.LcRbName1, number1, tests.GetExpectedLifecycleUpdateArtifacts())
545+
}
546+
547+
func TestReleaseBundleUpdateWithFlags(t *testing.T) {
548+
cleanCallback := initLifecycleTest(t, draftBundleArtifactoryMinVersion)
549+
defer cleanCallback()
550+
lcManager := getLcServiceManager(t)
551+
552+
deleteBuilds := uploadBuilds(t)
553+
defer deleteBuilds()
554+
555+
// Create a draft bundle from build 2
556+
createRbWithFlags(t, "", "", tests.LcBuildName2, number2, tests.LcRbName2, number2, "default", true, true, true)
557+
defer deleteReleaseBundle(t, lcManager, tests.LcRbName2, number2)
558+
assertStatusDraft(t, lcManager, tests.LcRbName2, number2)
559+
assertRbArtifacts(t, lcManager, tests.LcRbName2, number2, tests.GetExpectedLifecycleBuild2Artifacts())
560+
561+
// Update draft using --source-type-builds flag to add build 3
562+
sourceBuildsFlag := fmt.Sprintf("name=%s,id=%s,include-deps=true", tests.LcBuildName3, number3)
563+
updateRbWithFlags(t, "", tests.LcRbName2, number2, "default", sourceBuildsFlag, true)
564+
565+
// Verify the bundle is still in DRAFT status after update
566+
assertStatusDraft(t, lcManager, tests.LcRbName2, number2)
567+
568+
// Verify the bundle now contains artifacts from both build 2 and build 3
569+
assertRbArtifacts(t, lcManager, tests.LcRbName2, number2, tests.GetExpectedLifecycleUpdateBuild2Artifacts())
570+
}
571+
492572
/*func deleteExportedReleaseBundle(t *testing.T, rbName string) {
493573
assert.NoError(t, os.RemoveAll(rbName))
494574
}*/
@@ -524,13 +604,19 @@ func uploadBuildsWithProject(t *testing.T) func() {
524604
func createRbBackwardCompatible(t *testing.T, specName, sourceOption, rbName, rbVersion string, sync bool) {
525605
specFile, err := getSpecFile(specName)
526606
assert.NoError(t, err)
527-
createRbWithFlags(t, specFile, sourceOption, "", "", rbName, rbVersion, "", sync, false)
607+
createRbWithFlags(t, specFile, sourceOption, "", "", rbName, rbVersion, "", sync, false, false)
528608
}
529609

530610
func createRbFromSpec(t *testing.T, specName, rbName, rbVersion string, sync bool, withoutSigningKey bool) {
531611
specFile, err := tests.CreateSpec(specName)
532612
assert.NoError(t, err)
533-
createRbWithFlags(t, specFile, "spec", "", "", rbName, rbVersion, "", sync, withoutSigningKey)
613+
createRbWithFlags(t, specFile, "spec", "", "", rbName, rbVersion, "", sync, withoutSigningKey, false)
614+
}
615+
616+
func createRbFromSpecWithDraft(t *testing.T, specName, rbName, rbVersion string, sync, withoutSigningKey, draft bool) {
617+
specFile, err := tests.CreateSpec(specName)
618+
assert.NoError(t, err)
619+
createRbWithFlags(t, specFile, "spec", "", "", rbName, rbVersion, "", sync, withoutSigningKey, draft)
534620
}
535621

536622
func TestCreateBundleWithoutSpec(t *testing.T) {
@@ -542,11 +628,11 @@ func TestCreateBundleWithoutSpec(t *testing.T) {
542628
deleteBuilds := uploadBuilds(t)
543629
defer deleteBuilds()
544630

545-
createRbWithFlags(t, "", "", tests.LcBuildName1, number1, tests.LcRbName1, number1, "default", false, false)
631+
createRbWithFlags(t, "", "", tests.LcBuildName1, number1, tests.LcRbName1, number1, "default", false, false, false)
546632
assertStatusCompleted(t, lcManager, tests.LcRbName1, number1, "")
547633
defer deleteReleaseBundle(t, lcManager, tests.LcRbName1, number1)
548634

549-
createRbWithFlags(t, "", "", tests.LcBuildName2, number2, tests.LcRbName2, number2, "default", false, true)
635+
createRbWithFlags(t, "", "", tests.LcBuildName2, number2, tests.LcRbName2, number2, "default", false, true, false)
550636
assertStatusCompleted(t, lcManager, tests.LcRbName2, number2, "")
551637
defer deleteReleaseBundle(t, lcManager, tests.LcRbName2, number2)
552638
}
@@ -566,13 +652,13 @@ func TestCreateBundleWithoutSpecAndWithProject(t *testing.T) {
566652
deleteBuilds := uploadBuildsWithProject(t)
567653
defer deleteBuilds()
568654

569-
createRbWithFlags(t, "", "", tests.LcBuildName1, number1, tests.LcRbName1, number1, tests.ProjectKey, false, false)
655+
createRbWithFlags(t, "", "", tests.LcBuildName1, number1, tests.LcRbName1, number1, tests.ProjectKey, false, false, false)
570656
assertStatusCompletedWithProject(t, lcManager, tests.LcRbName1, number1, "", tests.ProjectKey)
571657
defer deleteReleaseBundleWithProject(t, lcManager, tests.LcRbName1, number1, tests.ProjectKey)
572658
}
573659

574660
func createRbWithFlags(t *testing.T, specFilePath, sourceOption, buildName, buildNumber, rbName, rbVersion, project string,
575-
sync, withoutSigningKey bool,
661+
sync, withoutSigningKey, draft bool,
576662
) {
577663
argsAndOptions := []string{
578664
"rbc",
@@ -601,6 +687,35 @@ func createRbWithFlags(t *testing.T, specFilePath, sourceOption, buildName, buil
601687
argsAndOptions = append(argsAndOptions, getOption(cliutils.Project, project))
602688
}
603689

690+
if draft {
691+
argsAndOptions = append(argsAndOptions, getOption(cliutils.Draft, "true"))
692+
}
693+
694+
assert.NoError(t, lcCli.Exec(argsAndOptions...))
695+
}
696+
697+
func updateRbWithFlags(t *testing.T, specFilePath, rbName, rbVersion, project, sourceTypeBuilds string, sync bool) {
698+
argsAndOptions := []string{
699+
"rbu",
700+
rbName,
701+
rbVersion,
702+
"--add", // Mandatory flag for rbu
703+
}
704+
705+
if specFilePath != "" {
706+
argsAndOptions = append(argsAndOptions, getOption("spec", specFilePath))
707+
}
708+
709+
if sourceTypeBuilds != "" {
710+
argsAndOptions = append(argsAndOptions, getOption("source-type-builds", sourceTypeBuilds))
711+
}
712+
713+
if project != "" {
714+
argsAndOptions = append(argsAndOptions, getOption(cliutils.Project, project))
715+
}
716+
717+
argsAndOptions = append(argsAndOptions, getOption(cliutils.Sync, strconv.FormatBool(sync)))
718+
604719
assert.NoError(t, lcCli.Exec(argsAndOptions...))
605720
}
606721

@@ -665,6 +780,14 @@ func assertStatusCompleted(t *testing.T, lcManager *lifecycle.LifecycleServicesM
665780
assert.Equal(t, services.Completed, resp.Status)
666781
}
667782

783+
func assertStatusDraft(t *testing.T, lcManager *lifecycle.LifecycleServicesManager, rbName, rbVersion string) {
784+
resp, err := getStatus(lcManager, rbName, rbVersion, "")
785+
if !assert.NoError(t, err) {
786+
return
787+
}
788+
assert.Equal(t, services.Draft, resp.Status)
789+
}
790+
668791
// If createdMillis is provided, assert status for promotion. If blank, assert for creation.
669792
//
670793
//nolint:unparam // createdMillis parameter is kept for API consistency with existing tests
@@ -1204,13 +1327,13 @@ func TestReleaseBundlesSearchVersions(t *testing.T) {
12041327
}
12051328

12061329
// Create release bundles with project
1207-
createRbWithFlags(t, "", "", tests.LcBuildName1, number1, projectRbName, projectVersionA, tests.ProjectKey, true, false)
1330+
createRbWithFlags(t, "", "", tests.LcBuildName1, number1, projectRbName, projectVersionA, tests.ProjectKey, true, false, false)
12081331
defer deleteReleaseBundleWithProject(t, lcManager, projectRbName, projectVersionA, tests.ProjectKey)
12091332
assertStatusCompletedWithProject(t, lcManager, projectRbName, projectVersionA, "", tests.ProjectKey)
12101333

12111334
time.Sleep(1 * time.Second)
12121335

1213-
createRbWithFlags(t, "", "", tests.LcBuildName2, number2, projectRbName, projectVersionB, tests.ProjectKey, true, false)
1336+
createRbWithFlags(t, "", "", tests.LcBuildName2, number2, projectRbName, projectVersionB, tests.ProjectKey, true, false, false)
12141337
defer deleteReleaseBundleWithProject(t, lcManager, projectRbName, projectVersionB, tests.ProjectKey)
12151338
assertStatusCompletedWithProject(t, lcManager, projectRbName, projectVersionB, "", tests.ProjectKey)
12161339

utils/cliutils/commandsflags.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,7 @@ const (
592592
SigningKey = "signing-key"
593593
setupRepo = repo
594594
PromotionType = "promotion-type"
595+
Draft = "draft"
595596
)
596597

597598
var flagsMap = map[string]cli.Flag{

utils/tests/consts.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2157,6 +2157,46 @@ func GetExpectedLifecycleCreationByAql() []string {
21572157
}
21582158
}
21592159

2160+
// GetExpectedLifecycleBuild1Artifacts returns expected artifacts from build 1 only.
2161+
func GetExpectedLifecycleBuild1Artifacts() []string {
2162+
return []string{
2163+
RtDevRepo + "/a1.in",
2164+
RtDevRepo + "/a2.in",
2165+
RtDevRepo + "/a3.in",
2166+
}
2167+
}
2168+
2169+
// GetExpectedLifecycleUpdateArtifacts returns expected artifacts after updating a draft bundle
2170+
// that was created from build 1 (a1.in, a2.in, a3.in) with build 3 (dep-file as dependency).
2171+
func GetExpectedLifecycleUpdateArtifacts() []string {
2172+
return []string{
2173+
RtDevRepo + "/a1.in",
2174+
RtDevRepo + "/a2.in",
2175+
RtDevRepo + "/a3.in",
2176+
RtDevRepo + "/dep-file",
2177+
}
2178+
}
2179+
2180+
// GetExpectedLifecycleBuild2Artifacts returns expected artifacts from build 2 only.
2181+
func GetExpectedLifecycleBuild2Artifacts() []string {
2182+
return []string{
2183+
RtDevRepo + "/b1.in",
2184+
RtDevRepo + "/b2.in",
2185+
RtDevRepo + "/b3.in",
2186+
}
2187+
}
2188+
2189+
// GetExpectedLifecycleUpdateBuild2Artifacts returns expected artifacts after updating a draft bundle
2190+
// that was created from build 2 (b1.in, b2.in, b3.in) with build 3 (dep-file as dependency).
2191+
func GetExpectedLifecycleUpdateBuild2Artifacts() []string {
2192+
return []string{
2193+
RtDevRepo + "/b1.in",
2194+
RtDevRepo + "/b2.in",
2195+
RtDevRepo + "/b3.in",
2196+
RtDevRepo + "/dep-file",
2197+
}
2198+
}
2199+
21602200
func GetExpectedLifecycleArtifacts() []string {
21612201
return []string{
21622202
RtProdRepo1 + "/a1.in",

0 commit comments

Comments
 (0)