Skip to content
This repository was archived by the owner on May 30, 2024. It is now read-only.

Commit 3785dc1

Browse files
author
Noah Hanjun Lee
authored
Simplify the logic of deployment. (#189)
* Migrate 'GetNextDeploymentNumberOfRepo' into the interactor package. * Migrate 'HasLockOfRepoForEnv' into the interactor package.
1 parent 0f94f87 commit 3785dc1

File tree

14 files changed

+219
-243
lines changed

14 files changed

+219
-243
lines changed

internal/interactor/deployment.go

Lines changed: 66 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,46 +9,85 @@ import (
99
"github.com/gitploy-io/gitploy/ent"
1010
"github.com/gitploy-io/gitploy/ent/approval"
1111
"github.com/gitploy-io/gitploy/ent/deployment"
12+
"github.com/gitploy-io/gitploy/pkg/e"
1213
"github.com/gitploy-io/gitploy/vo"
1314
"go.uber.org/zap"
1415
)
1516

16-
func (i *Interactor) Deploy(ctx context.Context, u *ent.User, r *ent.Repo, d *ent.Deployment, e *vo.Env) (*ent.Deployment, error) {
17-
d.ProductionEnvironment = e.IsProductionEnvironment()
18-
d.UserID = u.ID
19-
d.RepoID = r.ID
17+
func (i *Interactor) Deploy(ctx context.Context, u *ent.User, r *ent.Repo, d *ent.Deployment, env *vo.Env) (*ent.Deployment, error) {
18+
// Verify the payload is deployable.
19+
if locked, err := i.Store.HasLockOfRepoForEnv(ctx, r, d.Env); locked {
20+
return nil, e.NewError(
21+
e.ErrorCodeDeploymentLocked,
22+
err,
23+
)
24+
} else if err != nil {
25+
return nil, err
26+
}
27+
28+
number, err := i.Store.GetNextDeploymentNumberOfRepo(ctx, r)
29+
if err != nil {
30+
return nil, e.NewError(
31+
e.ErrorCodeInternalError,
32+
err,
33+
)
34+
}
2035

21-
if !e.IsApprovalEabled() {
22-
rd, err := i.SCM.CreateRemoteDeployment(ctx, u, r, d, e)
23-
if err != nil {
24-
return nil, err
36+
if env.IsApprovalEabled() {
37+
d := &ent.Deployment{
38+
Number: number,
39+
Type: d.Type,
40+
Env: d.Env,
41+
Ref: d.Ref,
42+
Status: deployment.StatusWaiting,
43+
ProductionEnvironment: env.IsProductionEnvironment(),
44+
IsRollback: d.IsRollback,
45+
IsApprovalEnabled: true,
46+
RequiredApprovalCount: env.Approval.RequiredCount,
47+
UserID: u.ID,
48+
RepoID: r.ID,
2549
}
2650

27-
// Save the state of the remote deployment.
28-
d.UID = rd.UID
29-
d.Sha = rd.SHA
30-
d.HTMLURL = rd.HTLMURL
31-
d.Status = deployment.StatusCreated
51+
i.log.Debug("Save a new deployment to wait approvals.", zap.Any("deployment", d))
52+
return i.Store.CreateDeployment(ctx, d)
53+
}
3254

33-
d, err := i.Store.CreateDeployment(ctx, d)
34-
if err != nil {
35-
return nil, fmt.Errorf("It failed to save a new deployment.: %w", err)
36-
}
55+
i.log.Debug("Create a new remote deployment.")
56+
rd, err := i.SCM.CreateRemoteDeployment(ctx, u, r, d, env)
57+
if err != nil {
58+
return nil, err
59+
}
3760

38-
i.CreateDeploymentStatus(ctx, &ent.DeploymentStatus{
39-
Status: string(deployment.StatusCreated),
40-
Description: "Gitploy starts to deploy.",
41-
DeploymentID: d.ID,
42-
})
61+
d = &ent.Deployment{
62+
Number: number,
63+
Type: d.Type,
64+
Env: d.Env,
65+
Ref: d.Ref,
66+
Status: deployment.StatusCreated,
67+
UID: rd.UID,
68+
Sha: rd.SHA,
69+
HTMLURL: rd.HTLMURL,
70+
ProductionEnvironment: env.IsProductionEnvironment(),
71+
IsRollback: d.IsRollback,
72+
IsApprovalEnabled: false,
73+
RequiredApprovalCount: 0,
74+
UserID: u.ID,
75+
RepoID: r.ID,
76+
}
4377

44-
return d, nil
78+
i.log.Debug("Create a new deployment with the payload.", zap.Any("deployment", d))
79+
d, err = i.Store.CreateDeployment(ctx, d)
80+
if err != nil {
81+
return nil, fmt.Errorf("It failed to save a new deployment.: %w", err)
4582
}
4683

47-
d.IsApprovalEnabled = true
48-
d.RequiredApprovalCount = e.Approval.RequiredCount
49-
d.Status = deployment.StatusWaiting
84+
i.CreateDeploymentStatus(ctx, &ent.DeploymentStatus{
85+
Status: string(deployment.StatusCreated),
86+
Description: "Gitploy starts to deploy.",
87+
DeploymentID: d.ID,
88+
})
5089

51-
return i.Store.CreateDeployment(ctx, d)
90+
return d, nil
5291
}
5392

5493
func (i *Interactor) IsApproved(ctx context.Context, d *ent.Deployment) bool {

internal/interactor/deployment_test.go

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,9 @@ func TestInteractor_Deploy(t *testing.T) {
3838
ID: 1,
3939
},
4040
d: &ent.Deployment{
41-
Number: 3,
42-
Type: deployment.TypeCommit,
43-
Ref: "3ee3221",
44-
Env: "local",
41+
Type: deployment.TypeCommit,
42+
Ref: "3ee3221",
43+
Env: "local",
4544
},
4645
e: &vo.Env{},
4746
}
@@ -55,6 +54,18 @@ func TestInteractor_Deploy(t *testing.T) {
5554
UID = 1000
5655
)
5756

57+
t.Log("MOCK - Check the environment is locked.")
58+
store.
59+
EXPECT().
60+
HasLockOfRepoForEnv(ctx, gomock.Eq(input.r), gomock.Eq(input.d.Env)).
61+
Return(false, nil)
62+
63+
t.Log("MOCK - Get the next deployment number.")
64+
store.
65+
EXPECT().
66+
GetNextDeploymentNumberOfRepo(ctx, gomock.Eq(input.r)).
67+
Return(1, nil)
68+
5869
t.Logf("Returns a new remote deployment with UID = %d", UID)
5970
scm.
6071
EXPECT().
@@ -67,7 +78,7 @@ func TestInteractor_Deploy(t *testing.T) {
6778
store.
6879
EXPECT().
6980
CreateDeployment(ctx, gomock.Eq(&ent.Deployment{
70-
Number: input.d.Number,
81+
Number: 1,
7182
Type: input.d.Type,
7283
Ref: input.d.Ref,
7384
Env: input.d.Env,
@@ -95,7 +106,7 @@ func TestInteractor_Deploy(t *testing.T) {
95106

96107
expected := &ent.Deployment{
97108
ID: ID,
98-
Number: input.d.Number,
109+
Number: 1,
99110
Type: input.d.Type,
100111
Ref: input.d.Ref,
101112
Env: input.d.Env,
@@ -144,11 +155,23 @@ func TestInteractor_Deploy(t *testing.T) {
144155
ID = 1
145156
)
146157

158+
t.Log("MOCK - Check the environment is locked.")
159+
store.
160+
EXPECT().
161+
HasLockOfRepoForEnv(ctx, gomock.Eq(input.r), gomock.Eq(input.d.Env)).
162+
Return(false, nil)
163+
164+
t.Log("MOCK - Get the next deployment number.")
165+
store.
166+
EXPECT().
167+
GetNextDeploymentNumberOfRepo(ctx, gomock.Eq(input.r)).
168+
Return(1, nil)
169+
147170
t.Logf("Check the deployment has configurations of approval.")
148171
store.
149172
EXPECT().
150173
CreateDeployment(ctx, gomock.Eq(&ent.Deployment{
151-
Number: input.d.Number,
174+
Number: 1,
152175
Type: input.d.Type,
153176
Ref: input.d.Ref,
154177
Env: input.d.Env,
@@ -173,7 +196,7 @@ func TestInteractor_Deploy(t *testing.T) {
173196

174197
expected := &ent.Deployment{
175198
ID: ID,
176-
Number: input.d.Number,
199+
Number: 1,
177200
Type: input.d.Type,
178201
Ref: input.d.Ref,
179202
Env: input.d.Env,

internal/pkg/github/deployment.go

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,36 +7,40 @@ import (
77
"net/http"
88

99
"github.com/gitploy-io/gitploy/ent"
10+
"github.com/gitploy-io/gitploy/pkg/e"
1011
"github.com/gitploy-io/gitploy/vo"
1112
"github.com/google/go-github/v32/github"
1213
)
1314

14-
func (g *Github) CreateRemoteDeployment(ctx context.Context, u *ent.User, r *ent.Repo, d *ent.Deployment, e *vo.Env) (*vo.RemoteDeployment, error) {
15+
func (g *Github) CreateRemoteDeployment(ctx context.Context, u *ent.User, r *ent.Repo, d *ent.Deployment, env *vo.Env) (*vo.RemoteDeployment, error) {
1516
gd, res, err := g.Client(ctx, u.Token).
1617
Repositories.
1718
CreateDeployment(ctx, r.Namespace, r.Name, &github.DeploymentRequest{
1819
Ref: github.String(d.Ref),
19-
Environment: github.String(e.Name),
20-
Task: e.Task,
21-
Description: e.Description,
22-
AutoMerge: e.AutoMerge,
23-
RequiredContexts: e.RequiredContexts,
24-
Payload: e.Payload,
25-
ProductionEnvironment: e.ProductionEnvironment,
20+
Environment: github.String(env.Name),
21+
Task: env.Task,
22+
Description: env.Description,
23+
AutoMerge: env.AutoMerge,
24+
RequiredContexts: env.RequiredContexts,
25+
Payload: env.Payload,
26+
ProductionEnvironment: env.ProductionEnvironment,
2627
})
2728
if res.StatusCode == http.StatusConflict {
28-
return nil, &vo.UnprocessibleDeploymentError{
29-
Message: "There is a merge conflict or the commit's status checks failed",
30-
Err: err,
31-
}
29+
return nil, e.NewError(
30+
e.ErrorCodeDeploymentUndeployable,
31+
err,
32+
)
3233
} else if res.StatusCode == http.StatusUnprocessableEntity {
33-
return nil, &vo.UnprocessibleDeploymentError{
34-
Message: "Validation failed",
35-
Err: err,
36-
}
34+
return nil, e.NewError(
35+
e.ErrorCodeDeploymentInvalid,
36+
err,
37+
)
3738
}
3839
if err != nil {
39-
return nil, err
40+
return nil, e.NewError(
41+
e.ErrorCodeInternalError,
42+
err,
43+
)
4044
}
4145

4246
var url string

internal/pkg/store/deployment.go

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"github.com/gitploy-io/gitploy/ent/deployment"
1010
"github.com/gitploy-io/gitploy/ent/perm"
1111
"github.com/gitploy-io/gitploy/ent/predicate"
12+
"github.com/gitploy-io/gitploy/pkg/e"
1213
)
1314

1415
func (s *Store) CountDeployments(ctx context.Context) (int, error) {
@@ -214,8 +215,16 @@ func (s *Store) CreateDeployment(ctx context.Context, d *ent.Deployment) (*ent.D
214215
SetUserID(d.UserID).
215216
SetRepoID(d.RepoID).
216217
Save(ctx)
217-
if err != nil {
218-
return nil, err
218+
if ent.IsConstraintError(err) {
219+
return nil, e.NewError(
220+
e.ErrorCodeDeploymentConflict,
221+
err,
222+
)
223+
} else if err != nil {
224+
return nil, e.NewError(
225+
e.ErrorCodeInternalError,
226+
err,
227+
)
219228
}
220229

221230
s.c.Repo.
@@ -241,7 +250,10 @@ func (s *Store) UpdateDeployment(ctx context.Context, d *ent.Deployment) (*ent.D
241250
SetStatus(d.Status).
242251
Save(ctx)
243252
if err != nil {
244-
return nil, err
253+
return nil, e.NewError(
254+
e.ErrorCodeInternalError,
255+
err,
256+
)
245257
}
246258

247259
return d, nil

internal/pkg/store/lock.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66

77
"github.com/gitploy-io/gitploy/ent"
88
"github.com/gitploy-io/gitploy/ent/lock"
9+
"github.com/gitploy-io/gitploy/pkg/e"
910
)
1011

1112
func (s *Store) ListExpiredLocksLessThanTime(ctx context.Context, t time.Time) ([]*ent.Lock, error) {
@@ -55,7 +56,10 @@ func (s *Store) HasLockOfRepoForEnv(ctx context.Context, r *ent.Repo, env string
5556
WithRepo().
5657
Count(ctx)
5758
if err != nil {
58-
return false, err
59+
return false, e.NewError(
60+
e.ErrorCodeInternalError,
61+
err,
62+
)
5963
}
6064

6165
return cnt > 0, nil

0 commit comments

Comments
 (0)