Skip to content

Commit d1f2d5d

Browse files
committed
Add environments and deployments to the actions.
This implements #30079
1 parent 0739595 commit d1f2d5d

35 files changed

+2222
-43
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ endif
286286
generate-swagger: $(SWAGGER_SPEC) ## generate the swagger spec from code comments
287287

288288
$(SWAGGER_SPEC): $(GO_SOURCES) $(SWAGGER_SPEC_INPUT)
289-
$(GO) run $(SWAGGER_PACKAGE) generate spec --exclude "$(SWAGGER_EXCLUDE)" --input "$(SWAGGER_SPEC_INPUT)" --output './$(SWAGGER_SPEC)'
289+
$(GO) run $(SWAGGER_PACKAGE) generate spec --exclude "$(SWAGGER_EXCLUDE)" --input "$(SWAGGER_SPEC_INPUT)" --output './$(SWAGGER_SPEC)' --scan-models
290290

291291
.PHONY: swagger-check
292292
swagger-check: generate-swagger

models/actions/deployment.go

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
// Copyright 2025 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package actions
5+
6+
import (
7+
"context"
8+
9+
"code.gitea.io/gitea/models/db"
10+
repo_model "code.gitea.io/gitea/models/repo"
11+
user_model "code.gitea.io/gitea/models/user"
12+
"code.gitea.io/gitea/modules/timeutil"
13+
14+
"xorm.io/builder"
15+
)
16+
17+
// DeploymentStatus represents the deployment status
18+
type DeploymentStatus string
19+
20+
const (
21+
DeploymentStatusQueued DeploymentStatus = "queued"
22+
DeploymentStatusInProgress DeploymentStatus = "in_progress"
23+
DeploymentStatusSuccess DeploymentStatus = "success"
24+
DeploymentStatusFailure DeploymentStatus = "failure"
25+
DeploymentStatusCancelled DeploymentStatus = "cancelled"
26+
DeploymentStatusError DeploymentStatus = "error"
27+
)
28+
29+
// ActionDeployment represents a deployment attempt to an environment
30+
type ActionDeployment struct {
31+
ID int64 `xorm:"pk autoincr"`
32+
RepoID int64 `xorm:"INDEX NOT NULL"`
33+
Repo *repo_model.Repository `xorm:"-"`
34+
RunID int64 `xorm:"INDEX NOT NULL"`
35+
Run *ActionRun `xorm:"-"`
36+
EnvironmentID int64 `xorm:"INDEX NOT NULL"`
37+
Environment *ActionEnvironment `xorm:"-"`
38+
39+
// Deployment details
40+
Ref string `xorm:"INDEX"` // the commit/branch/tag being deployed
41+
CommitSHA string `xorm:"INDEX"` // the commit SHA being deployed
42+
Task string // deployment task/job name
43+
Status DeploymentStatus `xorm:"INDEX"`
44+
Description string `xorm:"TEXT"`
45+
LogURL string `xorm:"TEXT"`
46+
47+
// Creator info
48+
CreatedByID int64 `xorm:"INDEX"`
49+
CreatedBy *user_model.User `xorm:"-"`
50+
CreatedUnix timeutil.TimeStamp `xorm:"created NOT NULL"`
51+
UpdatedUnix timeutil.TimeStamp `xorm:"updated"`
52+
}
53+
54+
func init() {
55+
db.RegisterModel(new(ActionDeployment))
56+
}
57+
58+
// TableName returns the table name for ActionDeployment
59+
func (ActionDeployment) TableName() string {
60+
return "action_deployment"
61+
}
62+
63+
// LoadEnvironment loads the environment for this deployment
64+
func (d *ActionDeployment) LoadEnvironment(ctx context.Context) error {
65+
if d.Environment != nil {
66+
return nil
67+
}
68+
env := &ActionEnvironment{}
69+
has, err := db.GetEngine(ctx).ID(d.EnvironmentID).Get(env)
70+
if err != nil {
71+
return err
72+
}
73+
if has {
74+
d.Environment = env
75+
}
76+
return nil
77+
}
78+
79+
// LoadRun loads the run for this deployment
80+
func (d *ActionDeployment) LoadRun(ctx context.Context) error {
81+
if d.Run != nil {
82+
return nil
83+
}
84+
run := &ActionRun{}
85+
has, err := db.GetEngine(ctx).ID(d.RunID).Get(run)
86+
if err != nil {
87+
return err
88+
}
89+
if has {
90+
d.Run = run
91+
}
92+
return nil
93+
}
94+
95+
// LoadRepo loads the repository for this deployment
96+
func (d *ActionDeployment) LoadRepo(ctx context.Context) error {
97+
if d.Repo != nil {
98+
return nil
99+
}
100+
var err error
101+
d.Repo, err = repo_model.GetRepositoryByID(ctx, d.RepoID)
102+
return err
103+
}
104+
105+
// LoadCreatedBy loads the user who created this deployment
106+
func (d *ActionDeployment) LoadCreatedBy(ctx context.Context) error {
107+
if d.CreatedBy != nil {
108+
return nil
109+
}
110+
var err error
111+
d.CreatedBy, err = user_model.GetUserByID(ctx, d.CreatedByID)
112+
return err
113+
}
114+
115+
// CreateDeploymentOptions contains options for creating a deployment
116+
type CreateDeploymentOptions struct {
117+
RepoID int64
118+
RunID int64
119+
EnvironmentID int64
120+
Ref string
121+
CommitSHA string
122+
Task string
123+
Description string
124+
CreatedByID int64
125+
}
126+
127+
// CreateDeployment creates a new deployment
128+
func CreateDeployment(ctx context.Context, opts CreateDeploymentOptions) (*ActionDeployment, error) {
129+
deployment := &ActionDeployment{
130+
RepoID: opts.RepoID,
131+
RunID: opts.RunID,
132+
EnvironmentID: opts.EnvironmentID,
133+
Ref: opts.Ref,
134+
CommitSHA: opts.CommitSHA,
135+
Task: opts.Task,
136+
Status: DeploymentStatusQueued,
137+
Description: opts.Description,
138+
CreatedByID: opts.CreatedByID,
139+
}
140+
141+
return deployment, db.Insert(ctx, deployment)
142+
}
143+
144+
// FindDeploymentsOptions contains options for finding deployments
145+
type FindDeploymentsOptions struct {
146+
db.ListOptions
147+
RepoID int64
148+
RunID int64
149+
EnvironmentID int64
150+
Status []DeploymentStatus
151+
Ref string
152+
}
153+
154+
func (opts FindDeploymentsOptions) ToConds() builder.Cond {
155+
cond := builder.NewCond()
156+
157+
if opts.RepoID > 0 {
158+
cond = cond.And(builder.Eq{"repo_id": opts.RepoID})
159+
}
160+
161+
if opts.RunID > 0 {
162+
cond = cond.And(builder.Eq{"run_id": opts.RunID})
163+
}
164+
165+
if opts.EnvironmentID > 0 {
166+
cond = cond.And(builder.Eq{"environment_id": opts.EnvironmentID})
167+
}
168+
169+
if len(opts.Status) > 0 {
170+
cond = cond.And(builder.In("status", opts.Status))
171+
}
172+
173+
if opts.Ref != "" {
174+
cond = cond.And(builder.Eq{"ref": opts.Ref})
175+
}
176+
177+
return cond
178+
}
179+
180+
// FindDeployments finds deployments with the given options
181+
func FindDeployments(ctx context.Context, opts FindDeploymentsOptions) ([]*ActionDeployment, error) {
182+
return db.Find[ActionDeployment](ctx, opts)
183+
}
184+
185+
// UpdateDeploymentStatus updates the deployment status
186+
func UpdateDeploymentStatus(ctx context.Context, deploymentID int64, status DeploymentStatus, logURL string) error {
187+
deployment := &ActionDeployment{
188+
Status: status,
189+
LogURL: logURL,
190+
}
191+
_, err := db.GetEngine(ctx).ID(deploymentID).Cols("status", "log_url", "updated_unix").Update(deployment)
192+
return err
193+
}
194+
195+
// DeleteDeployment deletes a deployment
196+
func DeleteDeployment(ctx context.Context, deploymentID int64) error {
197+
_, err := db.GetEngine(ctx).ID(deploymentID).Delete(&ActionDeployment{})
198+
return err
199+
}
200+
201+
// CountDeployments counts deployments for a repository
202+
func CountDeployments(ctx context.Context, repoID int64) (int64, error) {
203+
return db.GetEngine(ctx).Where("repo_id = ?", repoID).Count(&ActionDeployment{})
204+
}

0 commit comments

Comments
 (0)