Skip to content

Commit 718ff0b

Browse files
committed
refactor: Move gitlab configuration to the separate chain handler (#225)
- add default gitlab-ci-template Signed-off-by: Sergiy Kulanov <[email protected]>
1 parent 7dac188 commit 718ff0b

File tree

8 files changed

+876
-120
lines changed

8 files changed

+876
-120
lines changed

api/v1/codebase_types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ func (in *CodebaseSpec) IsVersionTypeSemver() bool {
144144
type ActionType string
145145

146146
const (
147-
GerritRepositoryProvisioning ActionType = "gerrit_repository_provisioning"
147+
RepositoryProvisioning ActionType = "repository_provisioning"
148148
CIConfiguration ActionType = "ci_configuration"
149149
SetupDeploymentTemplates ActionType = "setup_deployment_templates"
150150
AcceptCodebaseBranchRegistration ActionType = "accept_codebase_branch_registration"

controllers/codebase/service/chain/factory.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@ func MakeChain(ctx context.Context, c client.Client) handler.CodebaseHandler {
2525

2626
ch.Use(
2727
NewPutGitWebRepoUrl(c),
28-
NewPutProject(c, gp, &gerrit.SSHGerritClient{}, gitprovider.NewGitProjectProvider, gitlabCIManager),
28+
NewPutProject(c, gp, &gerrit.SSHGerritClient{}, gitprovider.NewGitProjectProvider),
2929
NewPutWebHook(c, resty.New()),
30+
NewPutGitLabCIConfig(c, gp, gitlabCIManager),
3031
NewPutDeployConfigs(c, gp),
3132
NewPutDefaultCodeBaseBranch(c),
3233
NewCleaner(c),
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
package chain
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"os"
7+
"path/filepath"
8+
9+
corev1 "k8s.io/api/core/v1"
10+
ctrl "sigs.k8s.io/controller-runtime"
11+
"sigs.k8s.io/controller-runtime/pkg/client"
12+
13+
codebaseApi "github.com/epam/edp-codebase-operator/v2/api/v1"
14+
"github.com/epam/edp-codebase-operator/v2/pkg/git"
15+
gitlabci "github.com/epam/edp-codebase-operator/v2/pkg/gitlab"
16+
"github.com/epam/edp-codebase-operator/v2/pkg/util"
17+
)
18+
19+
type PutGitLabCIConfig struct {
20+
client client.Client
21+
git git.Git
22+
gitlabCIManager gitlabci.Manager
23+
}
24+
25+
func NewPutGitLabCIConfig(c client.Client, g git.Git, m gitlabci.Manager) *PutGitLabCIConfig {
26+
return &PutGitLabCIConfig{client: c, git: g, gitlabCIManager: m}
27+
}
28+
29+
func (h *PutGitLabCIConfig) ServeRequest(ctx context.Context, codebase *codebaseApi.Codebase) error {
30+
log := ctrl.LoggerFrom(ctx)
31+
32+
// Skip if not GitLab CI
33+
if codebase.Spec.CiTool != util.CIGitLab {
34+
log.Info("Skip GitLab CI config injection, not using GitLab CI")
35+
return nil
36+
}
37+
38+
// Skip if already pushed (this stage or later)
39+
if codebase.Status.Git == util.ProjectGitLabCIPushedStatus ||
40+
codebase.Status.Git == util.ProjectTemplatesPushedStatus {
41+
log.Info("Skip GitLab CI config, already pushed in previous run")
42+
return nil
43+
}
44+
45+
// Skip if already exists
46+
if h.gitlabCIAlreadyExists(codebase) {
47+
log.Info("Skip GitLab CI config, already exists in repository")
48+
return nil
49+
}
50+
51+
log.Info("Start pushing GitLab CI config")
52+
53+
if err := h.tryToPushGitLabCIConfig(ctx, codebase); err != nil {
54+
setFailedFields(codebase, codebaseApi.RepositoryProvisioning, err.Error())
55+
return fmt.Errorf("failed to push GitLab CI config for %v codebase: %w", codebase.Name, err)
56+
}
57+
58+
log.Info("End pushing GitLab CI config")
59+
60+
// Set status to mark this stage complete
61+
codebase.Status.Git = util.ProjectGitLabCIPushedStatus
62+
if err := h.client.Status().Update(ctx, codebase); err != nil {
63+
setFailedFields(codebase, codebaseApi.RepositoryProvisioning, err.Error())
64+
return fmt.Errorf("failed to set git status %s for codebase %s: %w",
65+
util.ProjectGitLabCIPushedStatus, codebase.Name, err)
66+
}
67+
68+
log.Info("GitLab CI status has been set successfully")
69+
70+
return nil
71+
}
72+
73+
func (h *PutGitLabCIConfig) gitlabCIAlreadyExists(codebase *codebaseApi.Codebase) bool {
74+
wd := util.GetWorkDir(codebase.Name, codebase.Namespace)
75+
gitlabCIPath := filepath.Join(wd, gitlabci.GitLabCIFileName)
76+
77+
// Check if file exists locally first
78+
if _, err := os.Stat(gitlabCIPath); err == nil {
79+
return true
80+
}
81+
82+
return false
83+
}
84+
85+
func (h *PutGitLabCIConfig) tryToPushGitLabCIConfig(ctx context.Context, codebase *codebaseApi.Codebase) error {
86+
log := ctrl.LoggerFrom(ctx)
87+
88+
gitServer := &codebaseApi.GitServer{}
89+
if err := h.client.Get(ctx, client.ObjectKey{Name: codebase.Spec.GitServer, Namespace: codebase.Namespace}, gitServer); err != nil {
90+
return fmt.Errorf("failed to get GitServer: %w", err)
91+
}
92+
93+
gitServerSecret := &corev1.Secret{}
94+
if err := h.client.Get(ctx, client.ObjectKey{Name: gitServer.Spec.NameSshKeySecret, Namespace: codebase.Namespace}, gitServerSecret); err != nil {
95+
return fmt.Errorf("failed to get GitServer secret: %w", err)
96+
}
97+
98+
privateSSHKey := string(gitServerSecret.Data[util.PrivateSShKeyName])
99+
repoSshUrl := util.GetSSHUrl(gitServer, codebase.Spec.GetProjectID())
100+
wd := util.GetWorkDir(codebase.Name, codebase.Namespace)
101+
102+
// Ensure we have the repository locally
103+
if !util.DoesDirectoryExist(wd) || util.IsDirectoryEmpty(wd) {
104+
log.Info("Start cloning repository", "url", repoSshUrl)
105+
106+
if err := h.git.CloneRepositoryBySsh(ctx, privateSSHKey, gitServer.Spec.GitUser, repoSshUrl, wd, gitServer.Spec.SshPort); err != nil {
107+
return fmt.Errorf("failed to clone git repository: %w", err)
108+
}
109+
110+
log.Info("Repository has been cloned", "url", repoSshUrl)
111+
}
112+
113+
ru, err := util.GetRepoUrl(codebase)
114+
if err != nil {
115+
return fmt.Errorf("failed to build repo url: %w", err)
116+
}
117+
118+
log.Info("Start checkout default branch", "branch", codebase.Spec.DefaultBranch, "repo", ru)
119+
120+
err = CheckoutBranch(ru, wd, codebase.Spec.DefaultBranch, h.git, codebase, h.client)
121+
if err != nil {
122+
return fmt.Errorf("failed to checkout default branch %v: %w", codebase.Spec.DefaultBranch, err)
123+
}
124+
125+
log.Info("Default branch has been checked out")
126+
log.Info("Start injecting GitLab CI config")
127+
128+
// Inject the GitLab CI configuration
129+
err = h.gitlabCIManager.InjectGitLabCIConfig(ctx, codebase, wd)
130+
if err != nil {
131+
return fmt.Errorf("failed to inject GitLab CI config: %w", err)
132+
}
133+
134+
log.Info("GitLab CI config has been injected")
135+
log.Info("Start committing changes")
136+
137+
err = h.git.CommitChanges(wd, "Add GitLab CI configuration")
138+
if err != nil {
139+
return fmt.Errorf("failed to commit changes: %w", err)
140+
}
141+
142+
log.Info("Changes have been committed")
143+
log.Info("Start pushing changes")
144+
145+
err = h.git.PushChanges(privateSSHKey, gitServer.Spec.GitUser, wd, gitServer.Spec.SshPort, "--all")
146+
if err != nil {
147+
return fmt.Errorf("failed to push changes: %w", err)
148+
}
149+
150+
log.Info("GitLab CI config has been pushed successfully")
151+
152+
return nil
153+
}

0 commit comments

Comments
 (0)