Skip to content

Commit

Permalink
feat(deployment): add deployment table (#323)
Browse files Browse the repository at this point in the history
* adding deployment database table

* adding deployment number to builds

* fixing tests

* adding deployment database test

* go mod tidy

* go mod tidy

* test

* fixing lint errors

* fixing comments

* fixing comments

* adding created_at and created_by fields

* deleting user field

* deployment build changes

* changing build field deployNumber to deploymentID

* fixing things

* changing DeployID back to DeployNumber

---------

Co-authored-by: Claire.Nicholas <Z00B3R3@w6nxmk4t6t.target.com>
  • Loading branch information
claire1618 and Claire.Nicholas authored Dec 22, 2023
1 parent 1eae2f5 commit 26e54c8
Show file tree
Hide file tree
Showing 12 changed files with 624 additions and 44 deletions.
3 changes: 3 additions & 0 deletions constants/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ const (
// TableBuildExecutable defines the table type for the database build_executables table.
TableBuildExecutable = "build_executables"

// TableDeployment defines the table type for the database deployments table.
TableDeployment = "deployments"

// TableHook defines the table type for the database hooks table.
TableHook = "hooks"

Expand Down
8 changes: 8 additions & 0 deletions database/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ type Build struct {
Started sql.NullInt64 `sql:"started"`
Finished sql.NullInt64 `sql:"finished"`
Deploy sql.NullString `sql:"deploy"`
DeployNumber sql.NullInt64 `sql:"deploy_number"`
DeployPayload raw.StringSliceMap `sql:"deploy_payload" gorm:"type:varchar(2000)"`
Clone sql.NullString `sql:"clone"`
Source sql.NullString `sql:"source"`
Expand Down Expand Up @@ -170,6 +171,11 @@ func (b *Build) Nullify() *Build {
b.Deploy.Valid = false
}

// check if the DeployNumber field should be false
if b.DeployNumber.Int64 == 0 {
b.Deploy.Valid = false
}

// check if the Clone field should be false
if len(b.Clone.String) == 0 {
b.Clone.Valid = false
Expand Down Expand Up @@ -282,6 +288,7 @@ func (b *Build) ToLibrary() *library.Build {
build.SetStarted(b.Started.Int64)
build.SetFinished(b.Finished.Int64)
build.SetDeploy(b.Deploy.String)
build.SetDeployNumber(b.DeployNumber.Int64)
build.SetDeployPayload(b.DeployPayload)
build.SetClone(b.Clone.String)
build.SetSource(b.Source.String)
Expand Down Expand Up @@ -365,6 +372,7 @@ func BuildFromLibrary(b *library.Build) *Build {
Started: sql.NullInt64{Int64: b.GetStarted(), Valid: true},
Finished: sql.NullInt64{Int64: b.GetFinished(), Valid: true},
Deploy: sql.NullString{String: b.GetDeploy(), Valid: true},
DeployNumber: sql.NullInt64{Int64: b.GetDeployNumber(), Valid: true},
DeployPayload: b.GetDeployPayload(),
Clone: sql.NullString{String: b.GetClone(), Valid: true},
Source: sql.NullString{String: b.GetSource(), Valid: true},
Expand Down
4 changes: 4 additions & 0 deletions database/build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ func TestDatabase_Build_Nullify(t *testing.T) {
Started: sql.NullInt64{Int64: 0, Valid: false},
Finished: sql.NullInt64{Int64: 0, Valid: false},
Deploy: sql.NullString{String: "", Valid: false},
DeployNumber: sql.NullInt64{Int64: 0, Valid: false},
DeployPayload: nil,
Clone: sql.NullString{String: "", Valid: false},
Source: sql.NullString{String: "", Valid: false},
Expand Down Expand Up @@ -121,6 +122,7 @@ func TestDatabase_Build_ToLibrary(t *testing.T) {
want.SetStarted(1563474078)
want.SetFinished(1563474079)
want.SetDeploy("")
want.SetDeployNumber(0)
want.SetDeployPayload(nil)
want.SetClone("https://github.com/github/octocat.git")
want.SetSource("https://github.com/github/octocat/48afb5bdc41ad69bf22588491333f7cf71135163")
Expand Down Expand Up @@ -212,6 +214,7 @@ func TestDatabase_BuildFromLibrary(t *testing.T) {
b.SetStarted(1563474078)
b.SetFinished(1563474079)
b.SetDeploy("")
b.SetDeployNumber(0)
b.SetDeployPayload(nil)
b.SetClone("https://github.com/github/octocat.git")
b.SetSource("https://github.com/github/octocat/48afb5bdc41ad69bf22588491333f7cf71135163")
Expand Down Expand Up @@ -273,6 +276,7 @@ func testBuild() *Build {
Started: sql.NullInt64{Int64: 1563474078, Valid: true},
Finished: sql.NullInt64{Int64: 1563474079, Valid: true},
Deploy: sql.NullString{String: "", Valid: false},
DeployNumber: sql.NullInt64{Int64: 0, Valid: true},
DeployPayload: raw.StringSliceMap{"foo": "test1", "bar": "test2"},
Clone: sql.NullString{String: "https://github.com/github/octocat.git", Valid: true},
Source: sql.NullString{String: "https://github.com/github/octocat/48afb5bdc41ad69bf22588491333f7cf71135163", Valid: true},
Expand Down
183 changes: 183 additions & 0 deletions database/deployment.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
// SPDX-License-Identifier: Apache-2.0

package database

import (
"database/sql"
"errors"
"fmt"

"github.com/go-vela/types/library"
"github.com/go-vela/types/raw"
"github.com/lib/pq"
)

var (
// ErrEmptyDeploymentNumber defines the error type when a
// Deployment type has an empty Number field provided.
ErrEmptyDeploymentNumber = errors.New("empty deployment number provided")

// ErrEmptyDeploymentRepoID defines the error type when a
// Deployment type has an empty RepoID field provided.
ErrEmptyDeploymentRepoID = errors.New("empty deployment repo_id provided")
)

// Deployment is the database representation of a deployment for a repo.
type Deployment struct {
ID sql.NullInt64 `sql:"id"`
Number sql.NullInt64 `sql:"number"`
RepoID sql.NullInt64 `sql:"repo_id"`
URL sql.NullString `sql:"url"`
Commit sql.NullString `sql:"commit"`
Ref sql.NullString `sql:"ref"`
Task sql.NullString `sql:"task"`
Target sql.NullString `sql:"target"`
Description sql.NullString `sql:"description"`
Payload raw.StringSliceMap `sql:"payload"`
CreatedAt sql.NullInt64 `sql:"created_at"`
CreatedBy sql.NullString `sql:"created_by"`
Builds pq.StringArray `sql:"builds" gorm:"type:varchar(50)"`
}

// Nullify ensures the valid flag for
// the sql.Null types are properly set.
//
// When a field within the Deployment type is the zero
// value for the field, the valid flag is set to
// false causing it to be NULL in the database.
func (d *Deployment) Nullify() *Deployment {
if d == nil {
return nil
}

// check if the ID field should be false
if d.ID.Int64 == 0 {
d.ID.Valid = false
}

// check if the Number field should be false
if d.Number.Int64 == 0 {
d.Number.Valid = false
}

// check if the RepoID field should be false
if d.RepoID.Int64 == 0 {
d.RepoID.Valid = false
}

// check if the URL field should be false
if len(d.URL.String) == 0 {
d.URL.Valid = false
}

// check if the Commit field should be false
if len(d.Commit.String) == 0 {
d.Commit.Valid = false
}

// check if the Ref field should be false
if len(d.Ref.String) == 0 {
d.Ref.Valid = false
}

// check if the Task field should be false
if len(d.Task.String) == 0 {
d.Task.Valid = false
}

// check if the Target field should be false
if len(d.Target.String) == 0 {
d.Target.Valid = false
}

// check if the Description field should be false
if len(d.Description.String) == 0 {
d.Description.Valid = false
}

// check if the CreatedAt field should be false
if d.CreatedAt.Int64 == 0 {
d.CreatedAt.Valid = false
}

// check if the CreatedBy field should be false
if len(d.CreatedBy.String) == 0 {
d.CreatedBy.Valid = false
}

return d
}

// ToLibrary converts the Deployment type
// to a library Deployment type.
func (d *Deployment) ToLibrary(builds []*library.Build) *library.Deployment {
deployment := new(library.Deployment)

deployment.SetID(d.ID.Int64)
deployment.SetNumber(d.Number.Int64)
deployment.SetRepoID(d.RepoID.Int64)
deployment.SetURL(d.URL.String)
deployment.SetCommit(d.Commit.String)
deployment.SetRef(d.Ref.String)
deployment.SetTask(d.Task.String)
deployment.SetTarget(d.Target.String)
deployment.SetDescription(d.Description.String)
deployment.SetPayload(d.Payload)
deployment.SetCreatedAt(d.CreatedAt.Int64)
deployment.SetCreatedBy(d.CreatedBy.String)
deployment.SetBuilds(builds)

return deployment
}

// Validate verifies the necessary fields for
// the Deployment type are populated correctly.
func (d *Deployment) Validate() error {
// verify the RepoID field is populated
if d.RepoID.Int64 <= 0 {
return ErrEmptyDeploymentRepoID
}

// verify the Number field is populated
if d.Number.Int64 <= 0 {
return ErrEmptyDeploymentNumber
}

// ensure that all Deployment string fields
// that can be returned as JSON are sanitized
// to avoid unsafe HTML content
d.Commit = sql.NullString{String: sanitize(d.Commit.String), Valid: d.Commit.Valid}
d.Ref = sql.NullString{String: sanitize(d.Ref.String), Valid: d.Ref.Valid}
d.Task = sql.NullString{String: sanitize(d.Task.String), Valid: d.Task.Valid}
d.Target = sql.NullString{String: sanitize(d.Target.String), Valid: d.Target.Valid}
d.Description = sql.NullString{String: sanitize(d.Description.String), Valid: d.Description.Valid}

return nil
}

// DeploymentFromLibrary converts the library Deployment type
// to a database Deployment type.
func DeploymentFromLibrary(d *library.Deployment) *Deployment {
buildIDs := []string{}
for _, build := range d.GetBuilds() {
buildIDs = append(buildIDs, fmt.Sprint(build.GetID()))
}

deployment := &Deployment{
ID: sql.NullInt64{Int64: d.GetID(), Valid: true},
Number: sql.NullInt64{Int64: d.GetNumber(), Valid: true},
RepoID: sql.NullInt64{Int64: d.GetRepoID(), Valid: true},
URL: sql.NullString{String: d.GetURL(), Valid: true},
Commit: sql.NullString{String: d.GetCommit(), Valid: true},
Ref: sql.NullString{String: d.GetRef(), Valid: true},
Task: sql.NullString{String: d.GetTask(), Valid: true},
Target: sql.NullString{String: d.GetTarget(), Valid: true},
Description: sql.NullString{String: d.GetDescription(), Valid: true},
Payload: d.GetPayload(),
CreatedAt: sql.NullInt64{Int64: d.GetCreatedAt(), Valid: true},
CreatedBy: sql.NullString{String: d.GetCreatedBy(), Valid: true},
Builds: buildIDs,
}

return deployment.Nullify()
}
Loading

0 comments on commit 26e54c8

Please sign in to comment.