@@ -94,7 +94,7 @@ func (sourceGitlabInstance *GitlabInstance) copyGroupAvatar(destinationGitlabIns
9494// The function uses goroutines to perform these tasks concurrently and waits for all of them to finish.
9595func (destinationGitlabInstance * GitlabInstance ) updateProjectFromSource (sourceGitlabInstance * GitlabInstance , sourceProject * gitlab.Project , destinationProject * gitlab.Project , copyOptions * utils.MirroringOptions ) []error {
9696 wg := sync.WaitGroup {}
97- maxErrors := 2
97+ maxErrors := 3
9898 if copyOptions .CI_CD_Catalog {
9999 maxErrors ++
100100 }
@@ -106,44 +106,92 @@ func (destinationGitlabInstance *GitlabInstance) updateProjectFromSource(sourceG
106106
107107 go func () {
108108 defer wg .Done ()
109+ errorChan <- destinationGitlabInstance .syncProjectAttributes (sourceProject , destinationProject , copyOptions )
110+ }()
109111
110- zap .L ().Debug ("Enabling project mirror pull" , zap .String (ROLE_SOURCE , sourceProject .HTTPURLToRepo ), zap .String (ROLE_DESTINATION , destinationProject .HTTPURLToRepo ))
111- err := destinationGitlabInstance .enableProjectMirrorPull (sourceProject , destinationProject , copyOptions )
112- if err != nil {
113- errorChan <- fmt .Errorf ("failed to enable project mirror pull for %s: %s" , destinationProject .HTTPURLToRepo , err )
114- }
112+ go func () {
113+ defer wg .Done ()
114+ errorChan <- destinationGitlabInstance .enableProjectMirrorPull (sourceProject , destinationProject , copyOptions )
115115 }()
116116
117117 go func () {
118118 defer wg .Done ()
119- zap .L ().Debug ("Copying project avatar" , zap .String (ROLE_SOURCE , sourceProject .HTTPURLToRepo ), zap .String (ROLE_DESTINATION , destinationProject .HTTPURLToRepo ))
120- err := sourceGitlabInstance .copyProjectAvatar (destinationGitlabInstance , destinationProject , sourceProject )
121- if err != nil {
122- errorChan <- fmt .Errorf ("failed to copy project avatar for %s: %s" , destinationProject .HTTPURLToRepo , err )
123- }
119+ errorChan <- sourceGitlabInstance .copyProjectAvatar (destinationGitlabInstance , destinationProject , sourceProject )
124120 }()
125121
126122 if copyOptions .CI_CD_Catalog {
127123 go func () {
128124 defer wg .Done ()
129- err := destinationGitlabInstance .addProjectToCICDCatalog (destinationProject )
130- if err != nil {
131- errorChan <- fmt .Errorf ("failed to add project %s to CI/CD catalog: %s" , destinationProject .HTTPURLToRepo , err )
132- }
125+ errorChan <- destinationGitlabInstance .addProjectToCICDCatalog (destinationProject )
133126 }()
134127 }
135128
129+ allErrors := []error {}
136130 if copyOptions .MirrorReleases {
137131 go func () {
138132 defer wg .Done ()
139- err := destinationGitlabInstance .mirrorReleases (sourceGitlabInstance , sourceProject , destinationProject )
140- if err != nil {
141- errorChan <- fmt .Errorf ("failed to copy project %s releases: %s" , destinationProject .HTTPURLToRepo , err )
142- }
133+ allErrors = destinationGitlabInstance .mirrorReleases (sourceGitlabInstance , sourceProject , destinationProject )
143134 }()
144135 }
145136
146137 wg .Wait ()
147138 close (errorChan )
148- return utils .MergeErrors (errorChan )
139+ for err := range errorChan {
140+ if err != nil {
141+ allErrors = append (allErrors , err )
142+ }
143+ }
144+ return allErrors
145+ }
146+
147+ // syncProjectAttributes updates the destination project with settings from the source project.
148+ // It checks if any diverged project data exists and if so, it overwrites it.
149+ func (destinationGitlabInstance * GitlabInstance ) syncProjectAttributes (sourceProject * gitlab.Project , destinationProject * gitlab.Project , copyOptions * utils.MirroringOptions ) error {
150+ zap .L ().Debug ("Checking if project requires attributes resync" , zap .String (ROLE_SOURCE , sourceProject .HTTPURLToRepo ), zap .String (ROLE_DESTINATION , destinationProject .HTTPURLToRepo ))
151+ gitlabEditOptions := & gitlab.EditProjectOptions {}
152+ missmatched := false
153+ if sourceProject .Name != destinationProject .Name {
154+ gitlabEditOptions .Name = & sourceProject .Name
155+ missmatched = true
156+ }
157+ if sourceProject .Description != destinationProject .Description {
158+ gitlabEditOptions .Description = & sourceProject .Description
159+ missmatched = true
160+ }
161+ if sourceProject .DefaultBranch != destinationProject .DefaultBranch {
162+ gitlabEditOptions .DefaultBranch = & sourceProject .DefaultBranch
163+ missmatched = true
164+ }
165+ if ! utils .StringArraysMatchValues (sourceProject .Topics , destinationProject .Topics ) {
166+ gitlabEditOptions .Topics = & sourceProject .Topics
167+ missmatched = true
168+ }
169+ if copyOptions .MirrorTriggerBuilds != destinationProject .MirrorTriggerBuilds {
170+ gitlabEditOptions .MirrorTriggerBuilds = & copyOptions .MirrorTriggerBuilds
171+ missmatched = true
172+ }
173+ if ! destinationProject .MirrorOverwritesDivergedBranches {
174+ gitlabEditOptions .MirrorOverwritesDivergedBranches = gitlab .Ptr (true )
175+ missmatched = true
176+ }
177+ if ! destinationProject .Mirror {
178+ gitlabEditOptions .Mirror = gitlab .Ptr (true )
179+ missmatched = true
180+ }
181+ if copyOptions .Visibility != string (destinationProject .Visibility ) {
182+ visibilityValue := utils .ConvertVisibility (copyOptions .Visibility )
183+ gitlabEditOptions .Visibility = & visibilityValue
184+ missmatched = true
185+ }
186+
187+ if missmatched {
188+ destinationProject , _ , err := destinationGitlabInstance .Gitlab .Projects .EditProject (destinationProject .ID , gitlabEditOptions )
189+ if err != nil {
190+ return fmt .Errorf ("failed to edit project %s: %s" , destinationProject .HTTPURLToRepo , err )
191+ }
192+ zap .L ().Debug ("Project attributes resync completed" , zap .String (ROLE_SOURCE , sourceProject .HTTPURLToRepo ), zap .String (ROLE_DESTINATION , destinationProject .HTTPURLToRepo ))
193+ } else {
194+ zap .L ().Debug ("Project attributes are already in sync, skipping" , zap .String (ROLE_SOURCE , sourceProject .HTTPURLToRepo ), zap .String (ROLE_DESTINATION , destinationProject .HTTPURLToRepo ))
195+ }
196+ return nil
149197}
0 commit comments