feat: environment model + deployment tracking (phase 3a)
- Environment/Deployment XORM models + migration 010 - Full CRUD API: GET/POST/PATCH/DELETE /environments + /deployments - Deployment status update endpoint, publishes deployment.* NATS events - EnvironmentsPage with deploy cards, history accordion, deploy modal - Sidebar Environments nav item between Pipelines and Settings - Repo page deployment status badges (env name + SHA pill per environment) - Environment/Deployment types in types/api.ts + environments.ts query hooks
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
package models
|
||||
|
||||
import "time"
|
||||
|
||||
// DeployStatus represents the lifecycle state of a deployment.
|
||||
type DeployStatus string
|
||||
|
||||
const (
|
||||
DeployStatusPending DeployStatus = "pending"
|
||||
DeployStatusInProgress DeployStatus = "in_progress"
|
||||
DeployStatusSuccess DeployStatus = "success"
|
||||
DeployStatusFailure DeployStatus = "failure"
|
||||
DeployStatusCancelled DeployStatus = "cancelled"
|
||||
)
|
||||
|
||||
// Environment is a named deployment target for a repository (e.g. production, staging, dev).
|
||||
// ProtectionRules is a JSON blob: {"require_approval":true,"required_reviewers":1}
|
||||
type Environment struct {
|
||||
ID int64 `xorm:"'id' pk autoincr" json:"id"`
|
||||
RepoID int64 `xorm:"'repo_id' notnull index" json:"repoId"`
|
||||
Name string `xorm:"'name' varchar(100) notnull" json:"name"`
|
||||
URL string `xorm:"'url' varchar(500)" json:"url"`
|
||||
ProtectionRules string `xorm:"'protection_rules' text" json:"protectionRules"` // JSON
|
||||
CreatedAt time.Time `xorm:"'created_at' created" json:"createdAt"`
|
||||
UpdatedAt time.Time `xorm:"'updated_at' updated" json:"updatedAt"`
|
||||
}
|
||||
|
||||
// Deployment records a single deploy event to an Environment.
|
||||
// RunID optionally links the deployment to a PipelineRun that triggered it.
|
||||
type Deployment struct {
|
||||
ID int64 `xorm:"'id' pk autoincr" json:"id"`
|
||||
EnvID int64 `xorm:"'env_id' notnull index" json:"envId"`
|
||||
RepoID int64 `xorm:"'repo_id' notnull index" json:"repoId"`
|
||||
SHA string `xorm:"'sha' varchar(40) notnull" json:"sha"`
|
||||
Ref string `xorm:"'ref' varchar(255)" json:"ref"` // refs/heads/main or tag
|
||||
Status DeployStatus `xorm:"'status' varchar(20) notnull" json:"status"`
|
||||
TriggeredBy string `xorm:"'triggered_by' varchar(64)" json:"triggeredBy"` // username
|
||||
Description string `xorm:"'description' text" json:"description"`
|
||||
RunID *int64 `xorm:"'run_id'" json:"runId"` // optional PipelineRun link
|
||||
StartedAt *time.Time `xorm:"'started_at'" json:"startedAt"`
|
||||
FinishedAt *time.Time `xorm:"'finished_at'" json:"finishedAt"`
|
||||
CreatedAt time.Time `xorm:"'created_at' created" json:"createdAt"`
|
||||
}
|
||||
@@ -37,5 +37,8 @@ func Run(engine *xorm.Engine) error {
|
||||
if err := Run008(engine); err != nil {
|
||||
return err
|
||||
}
|
||||
return Run009(engine)
|
||||
if err := Run009(engine); err != nil {
|
||||
return err
|
||||
}
|
||||
return Run010(engine)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/forgeo/forgebucket/internal/models"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func Run010(engine *xorm.Engine) error {
|
||||
return engine.Sync2(
|
||||
&models.Environment{},
|
||||
&models.Deployment{},
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user