Explorar el Código

deployment revisions

Mohammed Nafees hace 3 años
padre
commit
9bc8677c22

+ 12 - 0
api/types/environment.go

@@ -65,6 +65,18 @@ type Deployment struct {
 	LastWorkflowRunURL string           `json:"last_workflow_run_url"`
 }
 
+type DeploymentRevision struct {
+	RevisionNumber uint                         `json:"revision_number"`
+	DeploymentID   uint                         `json:"deployment_id"`
+	Resources      []DeploymentRevisionResource `json:"resources"`
+}
+
+type DeploymentRevisionResource struct {
+	Name   string           `json:"name"`
+	Status DeploymentStatus `json:"status"`
+	Errors []string         `json:"errors"`
+}
+
 type CreateGHDeploymentRequest struct {
 	ActionID uint `json:"action_id" form:"required"`
 }

+ 49 - 0
internal/models/environment.go

@@ -100,6 +100,53 @@ func (e *Environment) ToEnvironmentType() *types.Environment {
 	return env
 }
 
+type DeploymentRevision struct {
+	gorm.Model
+
+	DeploymentID uint
+
+	RevisionNumber uint
+	Resources      []DeploymentRevisionResource
+}
+
+func (d *DeploymentRevision) ToDeploymentRevisionType() *types.DeploymentRevision {
+	resources := []types.DeploymentRevisionResource{}
+
+	for _, res := range d.Resources {
+		resources = append(resources, res.ToDeploymentResourceType())
+	}
+
+	return &types.DeploymentRevision{
+		RevisionNumber: d.RevisionNumber,
+		DeploymentID:   d.DeploymentID,
+		Resources:      resources,
+	}
+}
+
+type DeploymentRevisionResource struct {
+	gorm.Model
+
+	DeploymentRevisionID uint
+
+	Name   string
+	Status types.DeploymentStatus
+	Errors []byte
+}
+
+func (d *DeploymentRevisionResource) ToDeploymentResourceType() types.DeploymentRevisionResource {
+	res := types.DeploymentRevisionResource{
+		Name:   d.Name,
+		Status: d.Status,
+		Errors: []string{},
+	}
+
+	if len(d.Errors) > 0 {
+		res.Errors = strings.Split(string(d.Errors), ",")
+	}
+
+	return res
+}
+
 type Deployment struct {
 	gorm.Model
 
@@ -116,6 +163,8 @@ type Deployment struct {
 	CommitSHA      string
 	PRBranchFrom   string
 	PRBranchInto   string
+
+	Revisions []DeploymentRevision
 }
 
 func (d *Deployment) ToDeploymentType() *types.Deployment {

+ 3 - 0
internal/repository/environment.go

@@ -19,4 +19,7 @@ type EnvironmentRepository interface {
 	ListDeployments(environmentID uint, states ...string) ([]*models.Deployment, error)
 	UpdateDeployment(deployment *models.Deployment) (*models.Deployment, error)
 	DeleteDeployment(deployment *models.Deployment) (*models.Deployment, error)
+	AddNewDeploymentRevision(deploymentID uint, revision *models.DeploymentRevision) (*models.DeploymentRevision, error)
+	ListDeploymentRevisions(deploymentID uint) ([]*models.DeploymentRevision, error)
+	ReadDeploymentRevision(deploymentID, revisionNumber uint) (*models.DeploymentRevision, error)
 }

+ 97 - 1
internal/repository/gorm/environment.go

@@ -1,6 +1,7 @@
 package gorm
 
 import (
+	"fmt"
 	"strings"
 
 	"github.com/porter-dev/porter/internal/models"
@@ -247,8 +248,103 @@ func (repo *EnvironmentRepository) ListDeployments(environmentID uint, states ..
 }
 
 func (repo *EnvironmentRepository) DeleteDeployment(deployment *models.Deployment) (*models.Deployment, error) {
+	depl := &models.Deployment{}
+
+	if err := repo.db.Where("id = ?", deployment.ID).First(&depl).Error; err != nil {
+		return nil, fmt.Errorf("error fetching deployment ID %d: %w", deployment.ID, err)
+	}
+
+	revisions, err := repo.ListDeploymentRevisions(depl.ID)
+
+	if err != nil {
+		return nil, fmt.Errorf("error fetching revisions for deployment ID %d: %w", depl.ID, err)
+	}
+
+	err = repo.db.Model(&depl).Association("Revisions").Clear()
+
+	if err != nil {
+		return nil, fmt.Errorf("error clearing revision associations for deployment ID %d: %w", depl.ID, err)
+	}
+
+	for _, rev := range revisions {
+		err := repo.db.Model(&rev).Association("Resources").Clear()
+
+		if err != nil {
+			return nil, fmt.Errorf("error clearing resource associations for revision ID %d: %w", rev.ID, err)
+		}
+
+		for _, res := range rev.Resources {
+			if err := repo.db.Delete(&res).Error; err != nil {
+				return nil, fmt.Errorf("error deleting resource ID %d: %w", res.ID, err)
+			}
+		}
+
+		if err := repo.db.Delete(&rev).Error; err != nil {
+			return nil, fmt.Errorf("error deleting revision ID %d: %w", rev.ID, err)
+		}
+	}
+
 	if err := repo.db.Delete(deployment).Error; err != nil {
-		return nil, err
+		return nil, fmt.Errorf("error deleting deployment ID %d: %w", deployment.ID, err)
 	}
+
 	return deployment, nil
 }
+
+func (repo *EnvironmentRepository) AddNewDeploymentRevision(deploymentID uint, revision *models.DeploymentRevision) (*models.DeploymentRevision, error) {
+	if deploymentID == 0 {
+		return nil, fmt.Errorf("deployment ID cannot be set to 0")
+	}
+
+	depl := &models.Deployment{}
+
+	if err := repo.db.Where("id = ?", deploymentID).First(&depl).Error; err != nil {
+		return nil, fmt.Errorf("error fetching deployment ID %d: %w", deploymentID, err)
+	}
+
+	assoc := repo.db.Model(&depl).Association("Revisions")
+
+	if assoc.Error != nil {
+		return nil, fmt.Errorf("error fetting association Revisions for deployment ID %d: %w", deploymentID, assoc.Error)
+	}
+
+	revision.RevisionNumber = uint(assoc.Count() + 1)
+
+	if err := assoc.Append(revision); err != nil {
+		return nil, fmt.Errorf("error appending new revision for deployment ID %d: %w", deploymentID, err)
+	}
+
+	return revision, nil
+}
+
+func (repo *EnvironmentRepository) ListDeploymentRevisions(deploymentID uint) ([]*models.DeploymentRevision, error) {
+	depl := &models.Deployment{}
+
+	if err := repo.db.Where("id = ?", deploymentID).First(&depl).Error; err != nil {
+		return nil, fmt.Errorf("error fetching deployment ID %d: %w", deploymentID, err)
+	}
+
+	var revisions []*models.DeploymentRevision
+
+	if err := repo.db.Preload("Resources").Where("deployment_id = ?", deploymentID).Order("revision_number desc").Find(&revisions).Error; err != nil {
+		return nil, fmt.Errorf("error fetching revisions for deployment ID %d: %w", deploymentID, err)
+	}
+
+	return revisions, nil
+}
+
+func (repo *EnvironmentRepository) ReadDeploymentRevision(deploymentID, revisionNumber uint) (*models.DeploymentRevision, error) {
+	depl := &models.Deployment{}
+
+	if err := repo.db.Where("id = ?", deploymentID).First(&depl).Error; err != nil {
+		return nil, fmt.Errorf("error fetching deployment ID %d: %w", deploymentID, err)
+	}
+
+	revision := &models.DeploymentRevision{}
+
+	if err := repo.db.Preload("Resources").Where("deployment_id = ? AND revision_number = ?", deploymentID, revisionNumber).First(&revision).Error; err != nil {
+		return nil, fmt.Errorf("error fetching revision number %d for deployment ID %d: %w", revisionNumber, deploymentID, err)
+	}
+
+	return revision, nil
+}

+ 12 - 0
internal/repository/test/environment.go

@@ -81,3 +81,15 @@ func (repo *EnvironmentRepository) ListDeployments(environmentID uint, states ..
 func (repo *EnvironmentRepository) DeleteDeployment(deployment *models.Deployment) (*models.Deployment, error) {
 	panic("unimplemented")
 }
+
+func (repo *EnvironmentRepository) AddNewDeploymentRevision(deploymentID uint, revision *models.DeploymentRevision) (*models.DeploymentRevision, error) {
+	panic("unimplemented")
+}
+
+func (repo *EnvironmentRepository) ListDeploymentRevisions(deploymentID uint) ([]*models.DeploymentRevision, error) {
+	panic("unimplemented")
+}
+
+func (repo *EnvironmentRepository) ReadDeploymentRevision(deploymentID, revisionNumber uint) (*models.DeploymentRevision, error) {
+	panic("unimplemented")
+}