From dde835511f294d4f17f2236426bbe11459785149 Mon Sep 17 00:00:00 2001 From: hashimoon <98980386+hashimoon@users.noreply.github.com> Date: Thu, 2 Nov 2023 11:49:14 -0700 Subject: [PATCH] [TF-9605] Add validation when configuring Registry Module Publishing Prevent setting tags to `true` when a branch is present for configuring the VCSRepo. --- errors.go | 7 ++-- registry_module.go | 13 +++++++ registry_module_integration_test.go | 60 +++++++++++++++++++++++++++-- 3 files changed, 74 insertions(+), 6 deletions(-) diff --git a/errors.go b/errors.go index e20d15098..8bd08feea 100644 --- a/errors.go +++ b/errors.go @@ -222,9 +222,10 @@ var ( ErrRequiredAgentPoolID = errors.New("'agent' execution mode requires an agent pool ID to be specified") - ErrRequiredAgentMode = errors.New("specifying an agent pool ID requires 'agent' execution mode") - ErrRequiredBranchWhenTestsEnabled = errors.New("VCS branch is required when enabling tests") - ErrRequiredCategory = errors.New("category is required") + ErrRequiredAgentMode = errors.New("specifying an agent pool ID requires 'agent' execution mode") + ErrRequiredBranchWhenTestsEnabled = errors.New("VCS branch is required when enabling tests") + ErrBranchMustBeEmptyWhenTagsEnabled = errors.New("VCS branch must be empty to enable tags") + ErrRequiredCategory = errors.New("category is required") ErrRequiredDestinationType = errors.New("destination type is required") diff --git a/registry_module.go b/registry_module.go index 35984866f..03d6ccc93 100644 --- a/registry_module.go +++ b/registry_module.go @@ -289,6 +289,7 @@ type RegistryModuleVCSRepoOptions struct { // // **Note: This field is still in BETA and subject to change.** Branch *string `json:"branch,omitempty"` + Tags *bool `json:"tags,omitempty"` } type RegistryModuleVCSRepoUpdateOptions struct { @@ -426,6 +427,12 @@ func (r *registryModules) Update(ctx context.Context, moduleID RegistryModuleID, log.Println("[WARN] Support for using the NoCode field is deprecated as of release 1.22.0 and may be removed in a future version. The preferred way to update a no-code module is with the registryNoCodeModules.Update method.") } + if options.VCSRepo != nil { + if options.VCSRepo.Tags != nil && *options.VCSRepo.Tags && validString(options.VCSRepo.Branch) { + return nil, ErrBranchMustBeEmptyWhenTagsEnabled + } + } + org := url.QueryEscape(moduleID.Organization) registryName := url.QueryEscape(string(moduleID.RegistryName)) namespace := url.QueryEscape(moduleID.Namespace) @@ -738,6 +745,12 @@ func (o RegistryModuleCreateWithVCSConnectionOptions) valid() error { } } + if o.VCSRepo.Tags != nil && *o.VCSRepo.Tags { + if validString(o.VCSRepo.Branch) { + return ErrBranchMustBeEmptyWhenTagsEnabled + } + } + return o.VCSRepo.valid() } diff --git a/registry_module_integration_test.go b/registry_module_integration_test.go index e4ab27cbd..11315f1f6 100644 --- a/registry_module_integration_test.go +++ b/registry_module_integration_test.go @@ -160,7 +160,7 @@ func TestRegistryModulesCreate(t *testing.T) { assert.Equal(t, *options.Provider, rm.Provider) assert.Equal(t, options.RegistryName, rm.RegistryName) assert.Equal(t, orgTest.Name, rm.Namespace) - assert.Equal(t, options.NoCode, rm.NoCode) + assert.Equal(t, options.NoCode, Bool(rm.NoCode)) assertRegistryModuleAttributes(t, rm) }) @@ -363,6 +363,43 @@ func TestRegistryModuleUpdateWithVCSConnection(t *testing.T) { assert.False(t, rm.NoCode) }) + t.Run("prevents setting the branch when using tag based publishing", func(t *testing.T) { + options := RegistryModuleUpdateOptions{ + VCSRepo: &RegistryModuleVCSRepoUpdateOptions{ + Branch: String("main"), + Tags: Bool(true), + }, + } + + _, err = client.RegistryModules.Update(ctx, RegistryModuleID{ + Organization: orgTest.Name, + Name: rm.Name, + Provider: rm.Provider, + Namespace: rm.Namespace, + RegistryName: rm.RegistryName, + }, options) + + assert.Error(t, err) + assert.EqualError(t, err, ErrBranchMustBeEmptyWhenTagsEnabled.Error()) + + options = RegistryModuleUpdateOptions{ + VCSRepo: &RegistryModuleVCSRepoUpdateOptions{ + Branch: String(""), + Tags: Bool(true), + }, + } + + rm, err = client.RegistryModules.Update(ctx, RegistryModuleID{ + Organization: orgTest.Name, + Name: rm.Name, + Provider: rm.Provider, + Namespace: rm.Namespace, + RegistryName: rm.RegistryName, + }, options) + + assert.NoError(t, err) + }) + t.Run("toggle between git tag-based and branch-based publishing", func(t *testing.T) { assert.Equal(t, rm.PublishingMechanism, PublishingMechanismTag) @@ -385,7 +422,8 @@ func TestRegistryModuleUpdateWithVCSConnection(t *testing.T) { options = RegistryModuleUpdateOptions{ VCSRepo: &RegistryModuleVCSRepoUpdateOptions{ - Tags: Bool(true), + Branch: String(""), + Tags: Bool(true), }, } rm, err = client.RegistryModules.Update(ctx, RegistryModuleID{ @@ -634,7 +672,7 @@ func TestRegistryModulesShowVersion(t *testing.T) { rmvRead, errRead := client.RegistryModules.ReadVersion(ctx, registryModuleIDTest, *invalidVersion) require.Error(t, errRead) - assert.Equal(t, ErrResourceNotFound, err) + assert.Equal(t, ErrResourceNotFound, errRead) assert.Empty(t, rmvRead) }) } @@ -815,6 +853,22 @@ func TestRegistryModulesCreateWithVCSConnection(t *testing.T) { assert.Nil(t, rm) assert.Equal(t, err, ErrRequiredDisplayIdentifier) }) + + t.Run("when tags are enabled and a branch is provided", func(t *testing.T) { + options := RegistryModuleCreateWithVCSConnectionOptions{ + VCSRepo: &RegistryModuleVCSRepoOptions{ + Identifier: String(githubIdentifier), + OAuthTokenID: String(oauthTokenTest.ID), + DisplayIdentifier: String(githubIdentifier), + Tags: Bool(true), + Branch: String("main"), + }, + } + + rm, err := client.RegistryModules.CreateWithVCSConnection(ctx, options) + assert.Nil(t, rm) + assert.Equal(t, err, ErrBranchMustBeEmptyWhenTagsEnabled) + }) }) t.Run("without options", func(t *testing.T) {