@@ -2,12 +2,15 @@ package repository
22
33import (
44 "context"
5+ "fmt"
56 "os"
67 "testing"
8+ "time"
79
810 "github.com/openshift-pipelines/pipelines-as-code/pkg/params"
911 "github.com/openshift-pipelines/pipelines-as-code/pkg/random"
1012 "gotest.tools/v3/assert"
13+ "k8s.io/apimachinery/pkg/api/errors"
1114 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1215)
1316
@@ -16,12 +19,12 @@ func NSTearDown(ctx context.Context, t *testing.T, runcnx *params.Run, targetNS
1619 assert .NilError (t , err )
1720
1821 // Add random suffix to the repo URL so we can keep it for logs collection (if PAC_E2E_KEEP_NS is set)
19- // so we can investigate later if needed and capture its status it captured
20- // we need to rename it so webhooks don't trigger any more runs
22+ // so we can investigate later if needed and capture its status it captured.
23+ // We need to rename it so webhooks don't trigger any more runs and
24+ // the admission webhook does not block creation of a new repository with the same URL.
2125 for _ , repo := range repos .Items {
22- repo .Spec .URL += random .AlphaString (5 )
23- if _ , err := runcnx .Clients .PipelineAsCode .PipelinesascodeV1alpha1 ().Repositories (targetNS ).Update (ctx , & repo , metav1.UpdateOptions {}); err != nil {
24- runcnx .Clients .Log .Warnf ("Failed to renamae Repository URL %s: %v" , repo .Name , err )
26+ if err := renameRepoURLWithRetry (ctx , runcnx , targetNS , repo .Name ); err != nil {
27+ runcnx .Clients .Log .Warnf ("Failed to rename Repository URL %s after retries: %v" , repo .Name , err )
2528 }
2629 }
2730
@@ -31,3 +34,28 @@ func NSTearDown(ctx context.Context, t *testing.T, runcnx *params.Run, targetNS
3134 assert .NilError (t , err )
3235 }
3336}
37+
38+ // renameRepoURLWithRetry renames the repository URL with a random suffix,
39+ // retrying on optimistic lock conflicts (the resource version may change
40+ // between the initial List and the Update if the controller updates status).
41+ func renameRepoURLWithRetry (ctx context.Context , runcnx * params.Run , targetNS , repoName string ) error {
42+ const maxRetries = 3
43+ pacClient := runcnx .Clients .PipelineAsCode .PipelinesascodeV1alpha1 ().Repositories (targetNS )
44+ for attempt := 0 ; attempt < maxRetries ; attempt ++ {
45+ repo , err := pacClient .Get (ctx , repoName , metav1.GetOptions {})
46+ if err != nil {
47+ return fmt .Errorf ("failed to get repository %s: %w" , repoName , err )
48+ }
49+ repo .Spec .URL += random .AlphaString (5 )
50+ if _ , err = pacClient .Update (ctx , repo , metav1.UpdateOptions {}); err != nil {
51+ if errors .IsConflict (err ) {
52+ runcnx .Clients .Log .Infof ("Conflict renaming Repository URL %s, retrying (%d/%d)" , repoName , attempt + 1 , maxRetries )
53+ time .Sleep (time .Duration (attempt + 1 ) * time .Second )
54+ continue
55+ }
56+ return fmt .Errorf ("failed to update repository %s: %w" , repoName , err )
57+ }
58+ return nil
59+ }
60+ return fmt .Errorf ("failed to rename Repository URL %s after %d retries due to conflicts" , repoName , maxRetries )
61+ }
0 commit comments