Skip to content

Commit c8c6146

Browse files
authored
Introduce e2e tests for lifecycle anotate command. (#2964)
1 parent 0fd6cb9 commit c8c6146

File tree

3 files changed

+185
-12
lines changed

3 files changed

+185
-12
lines changed

go.mod

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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-core/v2 => github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20250508140039-bfb5e9a50dfe
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-client-go => github.com/jfrog/jfrog-client-go v1.28.1-0.20250508130334-f159cff9b11a
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-cli-artifactory => github.com/jfrog/jfrog-cli-artifactory v0.2.5-0.20250509052840-40acf11c6080
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: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -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.2.5-0.20250509052840-40acf11c6080 h1:UWqfVXAvKdfru1k7PwNjZXuufcJR6HukzfThz+J2nFw=
190+
github.com/jfrog/jfrog-cli-artifactory v0.2.5-0.20250509052840-40acf11c6080/go.mod h1:MVap+qb0Gft98yJdPe2si2GqtxQczDVEuC8oxbUTDLk=
191+
github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20250508140039-bfb5e9a50dfe h1:17ZlsX/X4orRHqFoyGnEBHIfKFu49AVvyVoRqk7635E=
192+
github.com/jfrog/jfrog-cli-core/v2 v2.31.1-0.20250508140039-bfb5e9a50dfe/go.mod h1:8ODu50AZkrP5xXvUGLizFTL1+qJknSShHNGhGl7OtFQ=
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-0.20250511132918-d9cc4cd50020 h1:CoWRc7ZLXfHojcyzifFG8fwaTniOLg/cDTPhAqQh/dc=
196+
github.com/jfrog/jfrog-cli-security v1.17.2-0.20250511132918-d9cc4cd50020/go.mod h1:9E95ny3WrNoOtMWTtq//SDc0PEnDZxZr3E2o+f90uMk=
197+
github.com/jfrog/jfrog-client-go v1.28.1-0.20250508130334-f159cff9b11a h1:QkebmsUWuurSgp4Lx7k6GtQ0sX3RmJ/d2n+NQ2l2g/E=
198+
github.com/jfrog/jfrog-client-go v1.28.1-0.20250508130334-f159cff9b11a/go.mod h1:uRmT8Q1SJymIzId01v0W1o8mGqrRfrwUF53CgEMsH0U=
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=

lifecycle_test.go

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@ import (
1212
"github.com/jfrog/jfrog-cli/inttestutils"
1313
"github.com/jfrog/jfrog-cli/utils/cliutils"
1414
"github.com/jfrog/jfrog-cli/utils/tests"
15+
artifactoryclientUtils "github.com/jfrog/jfrog-client-go/artifactory/services/utils"
1516
"github.com/jfrog/jfrog-client-go/http/httpclient"
1617
"github.com/jfrog/jfrog-client-go/lifecycle"
1718
"github.com/jfrog/jfrog-client-go/lifecycle/services"
1819
clientUtils "github.com/jfrog/jfrog-client-go/utils"
1920
"github.com/jfrog/jfrog-client-go/utils/errorutils"
2021
"github.com/jfrog/jfrog-client-go/utils/io/fileutils"
22+
"github.com/jfrog/jfrog-client-go/utils/log"
2123
clientTestUtils "github.com/jfrog/jfrog-client-go/utils/tests"
2224
"github.com/stretchr/testify/assert"
2325
"net/http"
@@ -40,6 +42,9 @@ const (
4042
prodEnvironment = "PROD"
4143
number1, number2, number3 = "111", "222", "333"
4244
withoutSigningKey = true
45+
artifactoryLifecycleSetTagMinVersion = "7.111.0"
46+
rbManifestName = "release-bundle.json.evd"
47+
releaseBundlesV2 = "release-bundles-v2"
4348
)
4449

4550
var (
@@ -456,6 +461,174 @@ func deleteReleaseBundleWithProject(t *testing.T, lcManager *lifecycle.Lifecycle
456461
time.Sleep(5 * time.Second)
457462
}
458463

464+
func TestSetReleaseBundleTag(t *testing.T) {
465+
cleanCallback := initLifecycleTest(t, artifactoryLifecycleSetTagMinVersion)
466+
defer cleanCallback()
467+
lcManager := getLcServiceManager(t)
468+
469+
deleteBuilds := uploadBuilds(t)
470+
defer deleteBuilds()
471+
472+
// set tag
473+
createRbFromSpec(t, tests.LifecycleBuilds12, tests.LcRbName1, number1, true, true)
474+
defer deleteReleaseBundle(t, lcManager, tests.LcRbName1, number1)
475+
476+
assertStatusCompleted(t, lcManager, tests.LcRbName1, number1, "")
477+
setReleaseBundleTag(t, lcManager, tests.LcRbName1, number1, "", "bundle-tag")
478+
479+
// unset tag
480+
createRbFromSpec(t, tests.LifecycleBuilds12, tests.LcRbName2, number1, true, true)
481+
defer deleteReleaseBundle(t, lcManager, tests.LcRbName2, number1)
482+
assertStatusCompleted(t, lcManager, tests.LcRbName2, number1, "")
483+
setReleaseBundleTag(t, lcManager, tests.LcRbName1, number1, "", "bundle-tag")
484+
unsetReleaseBundleTag(t, lcManager, tests.LcRbName1, number1)
485+
}
486+
487+
func unsetReleaseBundleTag(t *testing.T, lcManager *lifecycle.LifecycleServicesManager, rbName, version string) {
488+
setReleaseBundleTag(t, lcManager, rbName, version, "", "")
489+
}
490+
491+
func TestReleaseBundleCreateOrUpdateProperties(t *testing.T) {
492+
cleanCallback := initLifecycleTest(t, artifactoryLifecycleSetTagMinVersion)
493+
defer cleanCallback()
494+
lcManager := getLcServiceManager(t)
495+
496+
deleteBuilds := uploadBuilds(t)
497+
defer deleteBuilds()
498+
499+
// set properties
500+
createRbFromSpec(t, tests.LifecycleBuilds12, tests.LcRbName1, number1, true, true)
501+
defer deleteReleaseBundle(t, lcManager, tests.LcRbName1, number1)
502+
assertStatusCompleted(t, lcManager, tests.LcRbName1, number1, "")
503+
setReleaseBundleProperties(t, lcManager, tests.LcRbName1, number1, "default",
504+
"key1=value1;key2=value2")
505+
setReleaseBundleProperties(t, lcManager, tests.LcRbName1, number1, "default",
506+
"key1=value1;key2=''")
507+
}
508+
509+
func TestReleaseBundleDeleteProperties(t *testing.T) {
510+
cleanCallback := initLifecycleTest(t, artifactoryLifecycleSetTagMinVersion)
511+
defer cleanCallback()
512+
lcManager := getLcServiceManager(t)
513+
514+
deleteBuilds := uploadBuilds(t)
515+
defer deleteBuilds()
516+
517+
// set and delete properties
518+
createRbFromSpec(t, tests.LifecycleBuilds12, tests.LcRbName1, number1, true, true)
519+
defer deleteReleaseBundle(t, lcManager, tests.LcRbName1, number1)
520+
assertStatusCompleted(t, lcManager, tests.LcRbName1, number1, "")
521+
setReleaseBundleProperties(t, lcManager, tests.LcRbName1, number1, "default",
522+
"key1=value1;key2=value2")
523+
deleteReleaseBundleProperties(t, lcManager, tests.LcRbName1, number1, "default", "key1,key2")
524+
}
525+
526+
func deleteReleaseBundleProperties(t *testing.T, lcManager *lifecycle.LifecycleServicesManager, rbName,
527+
rbVersion, projectKey, delProps string) {
528+
rbDetails := services.ReleaseBundleDetails{
529+
ReleaseBundleName: rbName,
530+
ReleaseBundleVersion: rbVersion,
531+
}
532+
queryParams := services.CommonOptionalQueryParams{
533+
Async: false,
534+
ProjectKey: projectKey,
535+
}
536+
537+
annotateParams := buildAnnotateParams("", "", delProps, false, false,
538+
true, rbDetails, queryParams)
539+
assert.NoError(t, lcManager.AnnotateReleaseBundle(annotateParams))
540+
// Wait after remote deleting. Can be removed once remote deleting supports sync.
541+
time.Sleep(5 * time.Second)
542+
}
543+
544+
func setReleaseBundleTag(t *testing.T, lcManager *lifecycle.LifecycleServicesManager, rbName, rbVersion,
545+
projectKey, tag string) {
546+
log.Info(fmt.Sprintf("Setting release bundle tag=%s to: %s/%s", tag, rbName, rbVersion))
547+
rbDetails := services.ReleaseBundleDetails{
548+
ReleaseBundleName: rbName,
549+
ReleaseBundleVersion: rbVersion,
550+
}
551+
queryParams := services.CommonOptionalQueryParams{
552+
Async: false,
553+
ProjectKey: projectKey,
554+
}
555+
556+
annotateParams := buildAnnotateParams(tag, "", "", true, false, false,
557+
rbDetails, queryParams)
558+
assert.NoError(t, lcManager.AnnotateReleaseBundle(annotateParams))
559+
// Wait after remote deleting. Can be removed once remote deleting supports sync.
560+
time.Sleep(5 * time.Second)
561+
}
562+
563+
func setReleaseBundleProperties(t *testing.T, lcManager *lifecycle.LifecycleServicesManager, rbName, rbVersion,
564+
projectKey, properties string) {
565+
rbDetails := services.ReleaseBundleDetails{
566+
ReleaseBundleName: rbName,
567+
ReleaseBundleVersion: rbVersion,
568+
}
569+
queryParams := services.CommonOptionalQueryParams{
570+
Async: false,
571+
ProjectKey: projectKey,
572+
}
573+
574+
annotateParams := buildAnnotateParams("", properties, "", false, true,
575+
false, rbDetails, queryParams)
576+
assert.NoError(t, lcManager.AnnotateReleaseBundle(annotateParams))
577+
// Wait after remote deleting. Can be removed once remote deleting supports sync.
578+
time.Sleep(5 * time.Second)
579+
}
580+
581+
func buildAnnotateParams(tag, properties, keysToDelete string, tagExists, propsExist, delExist bool, rbDetails services.ReleaseBundleDetails,
582+
queryParams services.CommonOptionalQueryParams) services.AnnotateOperationParams {
583+
return services.AnnotateOperationParams{
584+
RbTag: services.RbAnnotationTag{
585+
Tag: tag,
586+
Exist: tagExists,
587+
},
588+
RbProps: services.RbAnnotationProps{
589+
Properties: resolveProps(properties),
590+
Exist: propsExist,
591+
},
592+
RbDelProps: services.RbDelProps{
593+
Keys: keysToDelete,
594+
Exist: delExist,
595+
},
596+
RbDetails: rbDetails,
597+
QueryParams: queryParams,
598+
PropertyParams: services.CommonPropParams{
599+
Path: buildManifestPath(queryParams.ProjectKey, rbDetails.ReleaseBundleName, rbDetails.ReleaseBundleVersion),
600+
Recursive: false,
601+
},
602+
ArtifactoryUrl: services.ArtCommonParams{
603+
Url: serverDetails.ArtifactoryUrl,
604+
},
605+
}
606+
}
607+
608+
func buildManifestPath(projectKey, bundleName, bundleVersion string) string {
609+
return fmt.Sprintf("%s/%s/%s/%s", buildRepoKey(projectKey), bundleName, bundleVersion, rbManifestName)
610+
}
611+
612+
func buildRepoKey(project string) string {
613+
if project == "" || project == "default" {
614+
return releaseBundlesV2
615+
}
616+
return fmt.Sprintf("%s-%s", project, releaseBundlesV2)
617+
}
618+
619+
func resolveProps(properties string) map[string][]string {
620+
if properties == "" {
621+
return make(map[string][]string)
622+
}
623+
624+
props, err := artifactoryclientUtils.ParseProperties(properties)
625+
if err != nil {
626+
return make(map[string][]string)
627+
}
628+
629+
return props.ToMap()
630+
}
631+
459632
/*
460633
func remoteDeleteReleaseBundle(t *testing.T, lcManager *lifecycle.LifecycleServicesManager, rbName, rbVersion string) {
461634
params := distribution.NewDistributeReleaseBundleParams(rbName, rbVersion)

0 commit comments

Comments
 (0)