From 26e54c869418eb841c5cc1d31b3364459378c9b6 Mon Sep 17 00:00:00 2001 From: claire1618 <55173466+claire1618@users.noreply.github.com> Date: Fri, 22 Dec 2023 12:48:44 -0500 Subject: [PATCH 01/11] feat(deployment): add deployment table (#323) * 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 --- constants/table.go | 3 + database/build.go | 8 ++ database/build_test.go | 4 + database/deployment.go | 183 ++++++++++++++++++++++++++ database/deployment_test.go | 255 ++++++++++++++++++++++++++++++++++++ go.mod | 1 + go.sum | 3 +- library/build.go | 30 +++++ library/build_test.go | 16 +++ library/deployment.go | 120 ++++++++++++----- library/deployment_test.go | 44 +++++-- webhook.go | 1 + 12 files changed, 624 insertions(+), 44 deletions(-) create mode 100644 database/deployment.go create mode 100644 database/deployment_test.go diff --git a/constants/table.go b/constants/table.go index 2a73e596..ffd537c6 100644 --- a/constants/table.go +++ b/constants/table.go @@ -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" diff --git a/database/build.go b/database/build.go index d8a7e49b..69309492 100644 --- a/database/build.go +++ b/database/build.go @@ -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"` @@ -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 @@ -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) @@ -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}, diff --git a/database/build_test.go b/database/build_test.go index 90458c44..976c66d2 100644 --- a/database/build_test.go +++ b/database/build_test.go @@ -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}, @@ -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") @@ -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") @@ -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}, diff --git a/database/deployment.go b/database/deployment.go new file mode 100644 index 00000000..6815229f --- /dev/null +++ b/database/deployment.go @@ -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() +} diff --git a/database/deployment_test.go b/database/deployment_test.go new file mode 100644 index 00000000..28f86b6e --- /dev/null +++ b/database/deployment_test.go @@ -0,0 +1,255 @@ +// SPDX-License-Identifier: Apache-2.0 + +package database + +import ( + "database/sql" + "testing" + + "github.com/go-vela/types/library" + "github.com/go-vela/types/raw" + "github.com/google/go-cmp/cmp" + "github.com/lib/pq" +) + +func TestDatabase_Deployment_Nullify(t *testing.T) { + // setup types + var d *Deployment + + want := &Deployment{ + ID: sql.NullInt64{Int64: 0, Valid: false}, + Number: sql.NullInt64{Int64: 0, Valid: false}, + RepoID: sql.NullInt64{Int64: 0, Valid: false}, + URL: sql.NullString{String: "", Valid: false}, + Commit: sql.NullString{String: "", Valid: false}, + Ref: sql.NullString{String: "", Valid: false}, + Task: sql.NullString{String: "", Valid: false}, + Target: sql.NullString{String: "", Valid: false}, + Description: sql.NullString{String: "", Valid: false}, + Payload: nil, + CreatedAt: sql.NullInt64{Int64: 0, Valid: false}, + CreatedBy: sql.NullString{String: "", Valid: false}, + Builds: nil, + } + + // setup tests + tests := []struct { + deployment *Deployment + want *Deployment + }{ + { + deployment: testDeployment(), + want: testDeployment(), + }, + { + deployment: d, + want: nil, + }, + { + deployment: new(Deployment), + want: want, + }, + } + + // run tests + for _, test := range tests { + got := test.deployment.Nullify() + + if diff := cmp.Diff(test.want, got); diff != "" { + t.Errorf("(ToLibrary: -want +got):\n%s", diff) + } + } +} + +func TestDatabase_Deployment_ToLibrary(t *testing.T) { + builds := []*library.Build{} + + buildOne := new(library.Build) + buildOne.SetID(1) + buildOne.SetRepoID(1) + buildOne.SetPipelineID(1) + buildOne.SetNumber(1) + buildOne.SetParent(1) + buildOne.SetEvent("push") + buildOne.SetEventAction("") + buildOne.SetStatus("running") + buildOne.SetError("") + buildOne.SetEnqueued(1563474077) + buildOne.SetCreated(1563474076) + buildOne.SetStarted(1563474078) + buildOne.SetFinished(1563474079) + buildOne.SetDeploy("") + buildOne.SetDeployNumber(0) + buildOne.SetDeployPayload(nil) + buildOne.SetClone("https://github.com/github/octocat.git") + buildOne.SetSource("https://github.com/github/octocat/48afb5bdc41ad69bf22588491333f7cf71135163") + buildOne.SetTitle("push received from https://github.com/github/octocat") + buildOne.SetMessage("First commit...") + buildOne.SetCommit("48afb5bdc41ad69bf22588491333f7cf71135163") + buildOne.SetSender("OctoKitty") + buildOne.SetAuthor("OctoKitty") + buildOne.SetEmail("OctoKitty@github.com") + buildOne.SetLink("https://example.company.com/github/octocat/1") + buildOne.SetBranch("main") + buildOne.SetRef("refs/heads/main") + buildOne.SetBaseRef("") + buildOne.SetHeadRef("") + buildOne.SetHost("example.company.com") + buildOne.SetRuntime("docker") + buildOne.SetDistribution("linux") + buildOne.SetDeployPayload(raw.StringSliceMap{"foo": "test1", "bar": "test2"}) + buildOne.SetApprovedAt(1563474076) + buildOne.SetApprovedBy("OctoCat") + + builds = append(builds, buildOne) + + want := new(library.Deployment) + want.SetID(1) + want.SetNumber(1) + want.SetRepoID(1) + want.SetURL("https://github.com/github/octocat/deployments/1") + want.SetCommit("1234") + want.SetRef("refs/heads/main") + want.SetTask("deploy:vela") + want.SetTarget("production") + want.SetDescription("Deployment request from Vela") + want.SetPayload(raw.StringSliceMap{"foo": "test1"}) + want.SetCreatedAt(1) + want.SetCreatedBy("octocat") + want.SetBuilds(builds) + + got := testDeployment().ToLibrary(builds) + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("(ToLibrary: -want +got):\n%s", diff) + } +} + +func TestDatabase_Deployment_Validate(t *testing.T) { + // setup types + tests := []struct { + failure bool + deployment *Deployment + }{ + { + failure: false, + deployment: testDeployment(), + }, + { // no number set for deployment + failure: true, + deployment: &Deployment{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + RepoID: sql.NullInt64{Int64: 1, Valid: true}, + }, + }, + { // no repoID set for deployment + failure: true, + deployment: &Deployment{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + Number: sql.NullInt64{Int64: 1, Valid: true}, + }, + }, + } + + // run tests + for _, test := range tests { + err := test.deployment.Validate() + + if test.failure { + if err == nil { + t.Errorf("Validate should have returned err") + } + + continue + } + + if err != nil { + t.Errorf("Validate returned err: %v", err) + } + } +} + +func TestDatabase_DeploymentFromLibrary(t *testing.T) { + builds := []*library.Build{} + + buildOne := new(library.Build) + buildOne.SetID(1) + buildOne.SetRepoID(1) + buildOne.SetPipelineID(1) + buildOne.SetNumber(1) + buildOne.SetParent(1) + buildOne.SetEvent("push") + buildOne.SetEventAction("") + buildOne.SetStatus("running") + buildOne.SetError("") + buildOne.SetEnqueued(1563474077) + buildOne.SetCreated(1563474076) + buildOne.SetStarted(1563474078) + buildOne.SetFinished(1563474079) + buildOne.SetDeploy("") + buildOne.SetDeployNumber(0) + buildOne.SetDeployPayload(nil) + buildOne.SetClone("https://github.com/github/octocat.git") + buildOne.SetSource("https://github.com/github/octocat/48afb5bdc41ad69bf22588491333f7cf71135163") + buildOne.SetTitle("push received from https://github.com/github/octocat") + buildOne.SetMessage("First commit...") + buildOne.SetCommit("48afb5bdc41ad69bf22588491333f7cf71135163") + buildOne.SetSender("OctoKitty") + buildOne.SetAuthor("OctoKitty") + buildOne.SetEmail("OctoKitty@github.com") + buildOne.SetLink("https://example.company.com/github/octocat/1") + buildOne.SetBranch("main") + buildOne.SetRef("refs/heads/main") + buildOne.SetBaseRef("") + buildOne.SetHeadRef("") + buildOne.SetHost("example.company.com") + buildOne.SetRuntime("docker") + buildOne.SetDistribution("linux") + buildOne.SetDeployPayload(raw.StringSliceMap{"foo": "test1", "bar": "test2"}) + buildOne.SetApprovedAt(1563474076) + buildOne.SetApprovedBy("OctoCat") + + builds = append(builds, buildOne) + + d := new(library.Deployment) + d.SetID(1) + d.SetNumber(1) + d.SetRepoID(1) + d.SetURL("https://github.com/github/octocat/deployments/1") + d.SetCommit("1234") + d.SetRef("refs/heads/main") + d.SetTask("deploy:vela") + d.SetTarget("production") + d.SetDescription("Deployment request from Vela") + d.SetPayload(raw.StringSliceMap{"foo": "test1"}) + d.SetCreatedAt(1) + d.SetCreatedBy("octocat") + d.SetBuilds(builds) + + want := testDeployment() + + // run test + got := DeploymentFromLibrary(d) + + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("(-want +got):\n%s", diff) + } +} + +// testDeployment is a test helper function to create a Deployment type with all fields set to a fake value. +func testDeployment() *Deployment { + return &Deployment{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + Number: sql.NullInt64{Int64: 1, Valid: true}, + RepoID: sql.NullInt64{Int64: 1, Valid: true}, + URL: sql.NullString{String: "https://github.com/github/octocat/deployments/1", Valid: true}, + Commit: sql.NullString{String: "1234", Valid: true}, + Ref: sql.NullString{String: "refs/heads/main", Valid: true}, + Task: sql.NullString{String: "deploy:vela", Valid: true}, + Target: sql.NullString{String: "production", Valid: true}, + Description: sql.NullString{String: "Deployment request from Vela", Valid: true}, + Payload: raw.StringSliceMap{"foo": "test1"}, + CreatedAt: sql.NullInt64{Int64: 1, Valid: true}, + CreatedBy: sql.NullString{String: "octocat", Valid: true}, + Builds: pq.StringArray{"1"}, + } +} diff --git a/go.mod b/go.mod index 764f3775..161f50a7 100644 --- a/go.mod +++ b/go.mod @@ -13,6 +13,7 @@ require ( require ( github.com/aymerick/douceur v0.2.0 // indirect + github.com/google/go-cmp v0.6.0 github.com/gorilla/css v1.0.0 // indirect github.com/kr/pretty v0.2.0 // indirect golang.org/x/net v0.17.0 // indirect diff --git a/go.sum b/go.sum index 30a8143f..3b490184 100644 --- a/go.sum +++ b/go.sum @@ -8,8 +8,9 @@ github.com/drone/envsubst v1.0.3 h1:PCIBwNDYjs50AsLZPYdfhSATKaRg/FJmDc2D6+C2x8g= github.com/drone/envsubst v1.0.3/go.mod h1:N2jZmlMufstn1KEqvbHjw40h1KyTmnVzHcSc9bFiJ2g= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= diff --git a/library/build.go b/library/build.go index ca091267..5b919dfb 100644 --- a/library/build.go +++ b/library/build.go @@ -29,6 +29,7 @@ type Build struct { Started *int64 `json:"started,omitempty"` Finished *int64 `json:"finished,omitempty"` Deploy *string `json:"deploy,omitempty"` + DeployNumber *int64 `json:"deploy_number,omitempty"` DeployPayload *raw.StringSliceMap `json:"deploy_payload,omitempty"` Clone *string `json:"clone,omitempty"` Source *string `json:"source,omitempty"` @@ -158,6 +159,7 @@ func (b *Build) Environment(workspace, channel string) map[string]string { envs["VELA_BUILD_TARGET"] = target envs["VELA_DEPLOYMENT"] = target envs["BUILD_TARGET"] = target + envs["VELA_DEPLOYMENT_NUMBER"] = ToString(b.GetDeployNumber()) // handle when deployment event is for a tag if strings.HasPrefix(b.GetRef(), "refs/tags/") { @@ -383,6 +385,19 @@ func (b *Build) GetDeploy() string { return *b.Deploy } +// GetDeployNumber returns the DeployNumber field. +// +// When the provided Build type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (b *Build) GetDeployNumber() int64 { + // return zero value if Build type or Deploy field is nil + if b == nil || b.DeployNumber == nil { + return 0 + } + + return *b.DeployNumber +} + // GetDeployPayload returns the DeployPayload field. // // When the provided Build type is nil, or the field within @@ -812,6 +827,19 @@ func (b *Build) SetDeploy(v string) { b.Deploy = &v } +// SetDeployNumber sets the DeployNumber field. +// +// When the provided Build type is nil, it +// will set nothing and immediately return. +func (b *Build) SetDeployNumber(v int64) { + // return if Build type is nil + if b == nil { + return + } + + b.DeployNumber = &v +} + // SetDeployPayload sets the DeployPayload field. // // When the provided Build type is nil, it @@ -1073,6 +1101,7 @@ func (b *Build) String() string { Commit: %s, Created: %d, Deploy: %s, + DeployNumber: %d, DeployPayload: %s, Distribution: %s, Email: %s, @@ -1107,6 +1136,7 @@ func (b *Build) String() string { b.GetCommit(), b.GetCreated(), b.GetDeploy(), + b.GetDeployNumber(), b.GetDeployPayload(), b.GetDistribution(), b.GetEmail(), diff --git a/library/build_test.go b/library/build_test.go index 339daa90..bd0b265c 100644 --- a/library/build_test.go +++ b/library/build_test.go @@ -55,6 +55,7 @@ func TestLibrary_Build_Environment(t *testing.T) { _deploy := testBuild() _deploy.SetEvent("deployment") _deploy.SetDeploy("production") + _deploy.SetDeployNumber(0) _deploy.SetDeployPayload(map[string]string{ "foo": "test1", "bar": "test2", @@ -64,6 +65,7 @@ func TestLibrary_Build_Environment(t *testing.T) { _deployTag.SetRef("refs/tags/v0.1.0") _deployTag.SetEvent("deployment") _deployTag.SetDeploy("production") + _deployTag.SetDeployNumber(0) _deployTag.SetDeployPayload(map[string]string{ "foo": "test1", "bar": "test2", @@ -226,6 +228,7 @@ func TestLibrary_Build_Environment(t *testing.T) { "VELA_BUILD_TITLE": "push received from https://github.com/github/octocat", "VELA_BUILD_WORKSPACE": "TODO", "VELA_DEPLOYMENT": "production", + "VELA_DEPLOYMENT_NUMBER": "0", "BUILD_TARGET": "production", "BUILD_AUTHOR": "OctoKitty", "BUILD_AUTHOR_EMAIL": "OctoKitty@github.com", @@ -286,6 +289,7 @@ func TestLibrary_Build_Environment(t *testing.T) { "VELA_BUILD_TITLE": "push received from https://github.com/github/octocat", "VELA_BUILD_WORKSPACE": "TODO", "VELA_DEPLOYMENT": "production", + "VELA_DEPLOYMENT_NUMBER": "0", "BUILD_AUTHOR": "OctoKitty", "BUILD_AUTHOR_EMAIL": "OctoKitty@github.com", "BUILD_BASE_REF": "", @@ -515,6 +519,10 @@ func TestLibrary_Build_Getters(t *testing.T) { t.Errorf("GetDeploy is %v, want %v", test.build.GetDeploy(), test.want.GetDeploy()) } + if test.build.GetDeployNumber() != test.want.GetDeployNumber() { + t.Errorf("GetDeployNumber is %v, want %v", test.build.GetDeployNumber(), test.want.GetDeployNumber()) + } + if !reflect.DeepEqual(test.build.GetDeployPayload(), test.want.GetDeployPayload()) { t.Errorf("GetDeployPayload is %v, want %v", test.build.GetDeployPayload(), test.want.GetDeployPayload()) } @@ -628,6 +636,7 @@ func TestLibrary_Build_Setters(t *testing.T) { test.build.SetStarted(test.want.GetStarted()) test.build.SetFinished(test.want.GetFinished()) test.build.SetDeploy(test.want.GetDeploy()) + test.build.SetDeployNumber(test.want.GetDeployNumber()) test.build.SetDeployPayload(test.want.GetDeployPayload()) test.build.SetClone(test.want.GetClone()) test.build.SetSource(test.want.GetSource()) @@ -704,6 +713,10 @@ func TestLibrary_Build_Setters(t *testing.T) { t.Errorf("SetDeploy is %v, want %v", test.build.GetDeploy(), test.want.GetDeploy()) } + if test.build.GetDeployNumber() != test.want.GetDeployNumber() { + t.Errorf("SetDeployNumber is %v, want %v", test.build.GetDeployNumber(), test.want.GetDeployNumber()) + } + if !reflect.DeepEqual(test.build.GetDeployPayload(), test.want.GetDeployPayload()) { t.Errorf("GetDeployPayload is %v, want %v", test.build.GetDeployPayload(), test.want.GetDeployPayload()) } @@ -796,6 +809,7 @@ func TestLibrary_Build_String(t *testing.T) { Commit: %s, Created: %d, Deploy: %s, + DeployNumber: %d, DeployPayload: %s, Distribution: %s, Email: %s, @@ -830,6 +844,7 @@ func TestLibrary_Build_String(t *testing.T) { b.GetCommit(), b.GetCreated(), b.GetDeploy(), + b.GetDeployNumber(), b.GetDeployPayload(), b.GetDistribution(), b.GetEmail(), @@ -882,6 +897,7 @@ func testBuild() *Build { b.SetStarted(1563474078) b.SetFinished(1563474079) b.SetDeploy("") + b.SetDeployNumber(0) b.SetDeployPayload(raw.StringSliceMap{"foo": "test1"}) b.SetClone("https://github.com/github/octocat.git") b.SetSource("https://github.com/github/octocat/48afb5bdc41ad69bf22588491333f7cf71135163") diff --git a/library/deployment.go b/library/deployment.go index a620a9e8..b37d80ff 100644 --- a/library/deployment.go +++ b/library/deployment.go @@ -13,16 +13,18 @@ import ( // swagger:model Deployment type Deployment struct { ID *int64 `json:"id,omitempty"` + Number *int64 `json:"number,omitempty"` RepoID *int64 `json:"repo_id,omitempty"` URL *string `json:"url,omitempty"` - User *string `json:"user,omitempty"` Commit *string `json:"commit,omitempty"` Ref *string `json:"ref,omitempty"` Task *string `json:"task,omitempty"` Target *string `json:"target,omitempty"` Description *string `json:"description,omitempty"` Payload *raw.StringSliceMap `json:"payload,omitempty"` - Builds *[]Build `json:"builds,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + Builds []*Build `json:"builds,omitempty"` } // GetID returns the ID field. @@ -38,6 +40,19 @@ func (d *Deployment) GetID() int64 { return *d.ID } +// GetNumber returns the Number field. +// +// When the provided Deployment type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (d *Deployment) GetNumber() int64 { + // return zero value if Deployment type or ID field is nil + if d == nil || d.Number == nil { + return 0 + } + + return *d.Number +} + // GetRepoID returns the RepoID field. // // When the provided Deployment type is nil, or the field within @@ -64,19 +79,6 @@ func (d *Deployment) GetURL() string { return *d.URL } -// GetUser returns the User field. -// -// When the provided Deployment type is nil, or the field within -// the type is nil, it returns the zero value for the field. -func (d *Deployment) GetUser() string { - // return zero value if Deployment type or User field is nil - if d == nil || d.User == nil { - return "" - } - - return *d.User -} - // GetCommit returns the Commit field. // // When the provided Deployment type is nil, or the field within @@ -155,16 +157,42 @@ func (d *Deployment) GetPayload() map[string]string { return *d.Payload } +// GetCreatedAt returns the CreatedAt field. +// +// When the provided Deployment type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (d *Deployment) GetCreatedAt() int64 { + // return zero value if Deployment type or CreatedAt field is nil + if d == nil || d.CreatedAt == nil { + return 0 + } + + return *d.CreatedAt +} + +// GetCreatedBy returns the CreatedBy field. +// +// When the provided Deployment type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (d *Deployment) GetCreatedBy() string { + // return zero value if Deployment type or CreatedBy field is nil + if d == nil || d.CreatedBy == nil { + return "" + } + + return *d.CreatedBy +} + // GetBuilds returns the Builds field. // // When the provided Deployment type is nil, or the field within // the type is nil, it returns the zero value for the field. -func (d *Deployment) GetBuilds() []Build { +func (d *Deployment) GetBuilds() []*Build { if d == nil || d.Builds == nil { - return []Build{} + return []*Build{} } - return *d.Builds + return d.Builds } // SetID sets the ID field. @@ -180,43 +208,43 @@ func (d *Deployment) SetID(v int64) { d.ID = &v } -// SetRepoID sets the RepoID field. +// SetNumber sets the Number field. // // When the provided Deployment type is nil, it // will set nothing and immediately return. -func (d *Deployment) SetRepoID(v int64) { +func (d *Deployment) SetNumber(v int64) { // return if Deployment type is nil if d == nil { return } - d.RepoID = &v + d.Number = &v } -// SetURL sets the URL field. +// SetRepoID sets the RepoID field. // // When the provided Deployment type is nil, it // will set nothing and immediately return. -func (d *Deployment) SetURL(v string) { +func (d *Deployment) SetRepoID(v int64) { // return if Deployment type is nil if d == nil { return } - d.URL = &v + d.RepoID = &v } -// SetUser sets the User field. +// SetURL sets the URL field. // // When the provided Deployment type is nil, it // will set nothing and immediately return. -func (d *Deployment) SetUser(v string) { +func (d *Deployment) SetURL(v string) { // return if Deployment type is nil if d == nil { return } - d.User = &v + d.URL = &v } // SetCommit sets the Commit field. @@ -297,43 +325,73 @@ func (d *Deployment) SetPayload(v raw.StringSliceMap) { d.Payload = &v } +// SetCreatedAt sets the CreatedAt field. +// +// When the provided Deployment type is nil, it +// will set nothing and immediately return. +func (d *Deployment) SetCreatedAt(v int64) { + // return if Deployment type is nil + if d == nil { + return + } + + d.CreatedAt = &v +} + +// SetCreatedBy sets the CreatedBy field. +// +// When the provided Deployment type is nil, it +// will set nothing and immediately return. +func (d *Deployment) SetCreatedBy(v string) { + // return if Deployment type is nil + if d == nil { + return + } + + d.CreatedBy = &v +} + // SetBuilds sets the Builds field. // // When the provided Deployment type is nil, it // will set nothing and immediately return. -func (d *Deployment) SetBuilds(b []Build) { +func (d *Deployment) SetBuilds(b []*Build) { // return if Deployment type is nil if d == nil { return } - d.Builds = &b + d.Builds = b } // String implements the Stringer interface for the Deployment type. func (d *Deployment) String() string { return fmt.Sprintf(`{ Commit: %s, + CreatedAt: %d, + CreatedBy: %s, Description: %s, ID: %d, + Number: %d, Ref: %s, RepoID: %d, Target: %s, Task: %s, URL: %s, - User: %s, Payload: %s, Builds: %d, }`, d.GetCommit(), + d.GetCreatedAt(), + d.GetCreatedBy(), d.GetDescription(), d.GetID(), + d.GetNumber(), d.GetRef(), d.GetRepoID(), d.GetTarget(), d.GetTask(), d.GetURL(), - d.GetUser(), d.GetPayload(), len(d.GetBuilds()), ) diff --git a/library/deployment_test.go b/library/deployment_test.go index 03ce452e..3d13a0be 100644 --- a/library/deployment_test.go +++ b/library/deployment_test.go @@ -38,10 +38,6 @@ func TestLibrary_Deployment_Getters(t *testing.T) { t.Errorf("GetURL is %v, want %v", test.deployment.GetURL(), test.want.GetURL()) } - if test.deployment.GetUser() != test.want.GetUser() { - t.Errorf("GetUser is %v, want %v", test.deployment.GetUser(), test.want.GetUser()) - } - if test.deployment.GetCommit() != test.want.GetCommit() { t.Errorf("GetCommit is %v, want %v", test.deployment.GetCommit(), test.want.GetCommit()) } @@ -65,6 +61,14 @@ func TestLibrary_Deployment_Getters(t *testing.T) { if !reflect.DeepEqual(test.deployment.GetPayload(), test.want.GetPayload()) { t.Errorf("GetPayload is %v, want %v", test.deployment.GetPayload(), test.want.GetPayload()) } + + if test.deployment.GetCreatedAt() != test.want.GetCreatedAt() { + t.Errorf("GetCreatedAt is %v, want %v", test.deployment.GetCreatedAt(), test.want.GetCreatedAt()) + } + + if test.deployment.GetCreatedBy() != test.want.GetCreatedBy() { + t.Errorf("GetCreatedBy is %v, want %v", test.deployment.GetCreatedBy(), test.want.GetCreatedBy()) + } } } @@ -90,20 +94,26 @@ func TestLibrary_Deployment_Setters(t *testing.T) { // run tests for _, test := range tests { test.deployment.SetID(test.want.GetID()) + test.deployment.SetNumber(test.want.GetNumber()) test.deployment.SetRepoID(test.want.GetRepoID()) test.deployment.SetURL(test.want.GetURL()) - test.deployment.SetUser(test.want.GetUser()) test.deployment.SetCommit(test.want.GetCommit()) test.deployment.SetRef(test.want.GetRef()) test.deployment.SetTask(test.want.GetTask()) test.deployment.SetTarget(test.want.GetTarget()) test.deployment.SetDescription(test.want.GetDescription()) test.deployment.SetPayload(test.want.GetPayload()) + test.deployment.SetCreatedAt(test.want.GetCreatedAt()) + test.deployment.SetCreatedBy(test.want.GetCreatedBy()) if test.deployment.GetID() != test.want.GetID() { t.Errorf("SetID is %v, want %v", test.deployment.GetID(), test.want.GetID()) } + if test.deployment.GetNumber() != test.want.GetNumber() { + t.Errorf("SetNumber is %v, want %v", test.deployment.GetNumber(), test.want.GetNumber()) + } + if test.deployment.GetRepoID() != test.want.GetRepoID() { t.Errorf("SetRepoID is %v, want %v", test.deployment.GetRepoID(), test.want.GetRepoID()) } @@ -112,10 +122,6 @@ func TestLibrary_Deployment_Setters(t *testing.T) { t.Errorf("SetURL is %v, want %v", test.deployment.GetURL(), test.want.GetURL()) } - if test.deployment.GetUser() != test.want.GetUser() { - t.Errorf("SetUser is %v, want %v", test.deployment.GetUser(), test.want.GetUser()) - } - if test.deployment.GetCommit() != test.want.GetCommit() { t.Errorf("SetCommit is %v, want %v", test.deployment.GetCommit(), test.want.GetCommit()) } @@ -139,6 +145,14 @@ func TestLibrary_Deployment_Setters(t *testing.T) { if !reflect.DeepEqual(test.deployment.GetPayload(), test.want.GetPayload()) { t.Errorf("SetPayload is %v, want %v", test.deployment.GetPayload(), test.want.GetPayload()) } + + if test.deployment.GetCreatedAt() != test.want.GetCreatedAt() { + t.Errorf("SetCreatedAt is %v, want %v", test.deployment.GetCreatedAt(), test.want.GetCreatedAt()) + } + + if test.deployment.GetCreatedBy() != test.want.GetCreatedBy() { + t.Errorf("SetCreatedBy is %v, want %v", test.deployment.GetCreatedBy(), test.want.GetCreatedBy()) + } } } @@ -148,26 +162,30 @@ func TestLibrary_Deployment_String(t *testing.T) { want := fmt.Sprintf(`{ Commit: %s, + CreatedAt: %d, + CreatedBy: %s, Description: %s, ID: %d, + Number: %d, Ref: %s, RepoID: %d, Target: %s, Task: %s, URL: %s, - User: %s, Payload: %s, Builds: %d, }`, d.GetCommit(), + d.GetCreatedAt(), + d.GetCreatedBy(), d.GetDescription(), d.GetID(), + d.GetNumber(), d.GetRef(), d.GetRepoID(), d.GetTarget(), d.GetTask(), d.GetURL(), - d.GetUser(), d.GetPayload(), len(d.GetBuilds()), ) @@ -186,9 +204,9 @@ func testDeployment() *Deployment { d := new(Deployment) d.SetID(1) + d.SetNumber(0) d.SetRepoID(1) d.SetURL("https://api.github.com/repos/github/octocat/deployments/1") - d.SetUser("octocat") d.SetCommit("48afb5bdc41ad69bf22588491333f7cf71135163") d.SetRef("refs/heads/main") d.SetTask("vela-deploy") @@ -197,6 +215,8 @@ func testDeployment() *Deployment { d.SetPayload(map[string]string{ "foo": "test1", }) + d.SetCreatedAt(1) + d.SetCreatedBy("octocat") return d } diff --git a/webhook.go b/webhook.go index aaddd5c4..d4802cfa 100644 --- a/webhook.go +++ b/webhook.go @@ -30,6 +30,7 @@ type Webhook struct { Repo *library.Repo Build *library.Build PullRequest PullRequest + Deployment *library.Deployment } // ShouldSkip uses the build information From a91bd54636bc8ac5cb36f73f626dffca0ed852ad Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Fri, 5 Jan 2024 13:25:35 -0500 Subject: [PATCH 02/11] enhance(secret): use allow event system (#341) * enhance(secret): use allow event system * fix some typos and linter changes * remove repo version of 'Allowed' --- constants/allow_events.go | 1 + database/secret.go | 8 ++ database/secret_test.go | 26 ++-- library/actions/comment.go | 3 +- library/actions/push.go | 3 +- library/actions/push_test.go | 3 +- library/actions/schedule.go | 53 ++++++++ library/actions/schedule_test.go | 98 ++++++++++++++ library/events.go | 71 +++++++++- library/events_test.go | 39 ++++++ library/repo.go | 32 ----- library/repo_test.go | 35 ----- library/secret.go | 65 ++++----- library/secret_test.go | 222 ++++++++++++++++++++++++++----- 14 files changed, 512 insertions(+), 147 deletions(-) create mode 100644 library/actions/schedule.go create mode 100644 library/actions/schedule_test.go diff --git a/constants/allow_events.go b/constants/allow_events.go index 60d6d88c..f5d2cdd9 100644 --- a/constants/allow_events.go +++ b/constants/allow_events.go @@ -20,4 +20,5 @@ const ( AllowDeployCreate AllowCommentCreate AllowCommentEdit + AllowSchedule ) diff --git a/database/secret.go b/database/secret.go index c955fd96..f9dae86d 100644 --- a/database/secret.go +++ b/database/secret.go @@ -51,6 +51,7 @@ type Secret struct { Type sql.NullString `sql:"type"` Images pq.StringArray `sql:"images" gorm:"type:varchar(1000)"` Events pq.StringArray `sql:"events" gorm:"type:varchar(1000)"` + AllowEvents sql.NullInt64 `sql:"allow_events"` AllowCommand sql.NullBool `sql:"allow_command"` CreatedAt sql.NullInt64 `sql:"created_at"` CreatedBy sql.NullString `sql:"created_by"` @@ -151,6 +152,11 @@ func (s *Secret) Nullify() *Secret { s.Type.Valid = false } + // check if the AllowEvents field should be false + if s.AllowEvents.Int64 == 0 { + s.AllowEvents.Valid = false + } + // check if the CreatedAt field should be false if s.CreatedAt.Int64 == 0 { s.CreatedAt.Valid = false @@ -188,6 +194,7 @@ func (s *Secret) ToLibrary() *library.Secret { secret.SetType(s.Type.String) secret.SetImages(s.Images) secret.SetEvents(s.Events) + secret.SetAllowEvents(library.NewEventsFromMask(s.AllowEvents.Int64)) secret.SetAllowCommand(s.AllowCommand.Bool) secret.SetCreatedAt(s.CreatedAt.Int64) secret.SetCreatedBy(s.CreatedBy.String) @@ -274,6 +281,7 @@ func SecretFromLibrary(s *library.Secret) *Secret { Type: sql.NullString{String: s.GetType(), Valid: true}, Images: pq.StringArray(s.GetImages()), Events: pq.StringArray(s.GetEvents()), + AllowEvents: sql.NullInt64{Int64: s.GetAllowEvents().ToDatabase(), Valid: true}, AllowCommand: sql.NullBool{Bool: s.GetAllowCommand(), Valid: true}, CreatedAt: sql.NullInt64{Int64: s.GetCreatedAt(), Valid: true}, CreatedBy: sql.NullString{String: s.GetCreatedBy(), Valid: true}, diff --git a/database/secret_test.go b/database/secret_test.go index 584faa80..f4c6d23c 100644 --- a/database/secret_test.go +++ b/database/secret_test.go @@ -113,17 +113,18 @@ func TestDatabase_Secret_Nullify(t *testing.T) { var s *Secret want := &Secret{ - ID: sql.NullInt64{Int64: 0, Valid: false}, - Org: sql.NullString{String: "", Valid: false}, - Repo: sql.NullString{String: "", Valid: false}, - Team: sql.NullString{String: "", Valid: false}, - Name: sql.NullString{String: "", Valid: false}, - Value: sql.NullString{String: "", Valid: false}, - Type: sql.NullString{String: "", Valid: false}, - CreatedAt: sql.NullInt64{Int64: 0, Valid: false}, - CreatedBy: sql.NullString{String: "", Valid: false}, - UpdatedAt: sql.NullInt64{Int64: 0, Valid: false}, - UpdatedBy: sql.NullString{String: "", Valid: false}, + ID: sql.NullInt64{Int64: 0, Valid: false}, + Org: sql.NullString{String: "", Valid: false}, + Repo: sql.NullString{String: "", Valid: false}, + Team: sql.NullString{String: "", Valid: false}, + Name: sql.NullString{String: "", Valid: false}, + Value: sql.NullString{String: "", Valid: false}, + Type: sql.NullString{String: "", Valid: false}, + AllowEvents: sql.NullInt64{Int64: 0, Valid: false}, + CreatedAt: sql.NullInt64{Int64: 0, Valid: false}, + CreatedBy: sql.NullString{String: "", Valid: false}, + UpdatedAt: sql.NullInt64{Int64: 0, Valid: false}, + UpdatedBy: sql.NullString{String: "", Valid: false}, } // setup tests @@ -168,6 +169,7 @@ func TestDatabase_Secret_ToLibrary(t *testing.T) { want.SetType("repo") want.SetImages([]string{"alpine"}) want.SetEvents([]string{"push", "tag", "deployment"}) + want.SetAllowEvents(library.NewEventsFromMask(1)) want.SetAllowCommand(true) want.SetCreatedAt(tsCreate) want.SetCreatedBy("octocat") @@ -291,6 +293,7 @@ func TestDatabase_SecretFromLibrary(t *testing.T) { s.SetType("repo") s.SetImages([]string{"alpine"}) s.SetEvents([]string{"push", "tag", "deployment"}) + s.SetAllowEvents(library.NewEventsFromMask(1)) s.SetAllowCommand(true) s.SetCreatedAt(tsCreate) s.SetCreatedBy("octocat") @@ -320,6 +323,7 @@ func testSecret() *Secret { Type: sql.NullString{String: "repo", Valid: true}, Images: []string{"alpine"}, Events: []string{"push", "tag", "deployment"}, + AllowEvents: sql.NullInt64{Int64: 1, Valid: true}, AllowCommand: sql.NullBool{Bool: true, Valid: true}, CreatedAt: sql.NullInt64{Int64: tsCreate, Valid: true}, CreatedBy: sql.NullString{String: "octocat", Valid: true}, diff --git a/library/actions/comment.go b/library/actions/comment.go index b221a132..499cfed6 100644 --- a/library/actions/comment.go +++ b/library/actions/comment.go @@ -1,6 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -// -//nolint:dupl // ignore dup code + package actions import "github.com/go-vela/types/constants" diff --git a/library/actions/push.go b/library/actions/push.go index 38b41866..5472af94 100644 --- a/library/actions/push.go +++ b/library/actions/push.go @@ -1,6 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -// -//nolint:dupl // ignore dup code + package actions import "github.com/go-vela/types/constants" diff --git a/library/actions/push_test.go b/library/actions/push_test.go index 181d0112..fbdb3cb7 100644 --- a/library/actions/push_test.go +++ b/library/actions/push_test.go @@ -115,6 +115,7 @@ func testMask() int64 { constants.AllowPullSync | constants.AllowPullReopen | constants.AllowDeployCreate | - constants.AllowCommentCreate, + constants.AllowCommentCreate | + constants.AllowSchedule, ) } diff --git a/library/actions/schedule.go b/library/actions/schedule.go new file mode 100644 index 00000000..a3ca9d36 --- /dev/null +++ b/library/actions/schedule.go @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: Apache-2.0 + +package actions + +import "github.com/go-vela/types/constants" + +// Schedule is the library representation of the various actions associated +// with the schedule event. +type Schedule struct { + Run *bool `json:"run"` +} + +// FromMask returns the Schedule type resulting from the provided integer mask. +func (a *Schedule) FromMask(mask int64) *Schedule { + a.SetRun(mask&constants.AllowSchedule > 0) + + return a +} + +// ToMask returns the integer mask of the values for the Schedule set. +func (a *Schedule) ToMask() int64 { + mask := int64(0) + + if a.GetRun() { + mask = mask | constants.AllowSchedule + } + + return mask +} + +// GetRun returns the Run field from the provided Schedule. If the object is nil, +// or the field within the object is nil, it returns the zero value instead. +func (a *Schedule) GetRun() bool { + // return zero value if Schedule type or Run field is nil + if a == nil || a.Run == nil { + return false + } + + return *a.Run +} + +// SetRun sets the Schedule Run field. +// +// When the provided Schedule type is nil, it +// will set nothing and immediately return. +func (a *Schedule) SetRun(v bool) { + // return if Schedule type is nil + if a == nil { + return + } + + a.Run = &v +} diff --git a/library/actions/schedule_test.go b/library/actions/schedule_test.go new file mode 100644 index 00000000..52826788 --- /dev/null +++ b/library/actions/schedule_test.go @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: Apache-2.0 + +package actions + +import ( + "reflect" + "testing" + + "github.com/go-vela/types/constants" +) + +func TestLibrary_Schedule_Getters(t *testing.T) { + // setup tests + tests := []struct { + actions *Schedule + want *Schedule + }{ + { + actions: testSchedule(), + want: testSchedule(), + }, + { + actions: new(Schedule), + want: new(Schedule), + }, + } + + // run tests + for _, test := range tests { + if test.actions.GetRun() != test.want.GetRun() { + t.Errorf("GetRun is %v, want %v", test.actions.GetRun(), test.want.GetRun()) + } + } +} + +func TestLibrary_Schedule_Setters(t *testing.T) { + // setup types + var a *Schedule + + // setup tests + tests := []struct { + actions *Schedule + want *Schedule + }{ + { + actions: testSchedule(), + want: testSchedule(), + }, + { + actions: a, + want: new(Schedule), + }, + } + + // run tests + for _, test := range tests { + test.actions.SetRun(test.want.GetRun()) + + if test.actions.GetRun() != test.want.GetRun() { + t.Errorf("SetRun is %v, want %v", test.actions.GetRun(), test.want.GetRun()) + } + } +} + +func TestLibrary_Schedule_FromMask(t *testing.T) { + // setup types + mask := testMask() + + want := testSchedule() + + // run test + got := new(Schedule).FromMask(mask) + + if !reflect.DeepEqual(got, want) { + t.Errorf("FromMask is %v, want %v", got, want) + } +} + +func TestLibrary_Schedule_ToMask(t *testing.T) { + // setup types + actions := testSchedule() + + want := int64(constants.AllowSchedule) + + // run test + got := actions.ToMask() + + if want != got { + t.Errorf("ToMask is %v, want %v", got, want) + } +} + +func testSchedule() *Schedule { + schedule := new(Schedule) + schedule.SetRun(true) + + return schedule +} diff --git a/library/events.go b/library/events.go index ca84fed3..78ce5d8e 100644 --- a/library/events.go +++ b/library/events.go @@ -10,10 +10,11 @@ import ( // Events is the library representation of the various events that generate a // webhook from the SCM. type Events struct { - Push *actions.Push `json:"push"` - PullRequest *actions.Pull `json:"pull_request"` - Deployment *actions.Deploy `json:"deployment"` - Comment *actions.Comment `json:"comment"` + Push *actions.Push `json:"push"` + PullRequest *actions.Pull `json:"pull_request"` + Deployment *actions.Deploy `json:"deployment"` + Comment *actions.Comment `json:"comment"` + Schedule *actions.Schedule `json:"schedule"` } // NewEventsFromMask is an instatiation function for the Events type that @@ -23,6 +24,7 @@ func NewEventsFromMask(mask int64) *Events { pullActions := new(actions.Pull).FromMask(mask) deployActions := new(actions.Deploy).FromMask(mask) commentActions := new(actions.Comment).FromMask(mask) + scheduleActions := new(actions.Schedule).FromMask(mask) e := new(Events) @@ -30,10 +32,43 @@ func NewEventsFromMask(mask int64) *Events { e.SetPullRequest(pullActions) e.SetDeployment(deployActions) e.SetComment(commentActions) + e.SetSchedule(scheduleActions) return e } +// EventAllowed determines whether or not an event is allowed based on the repository settings. +func (e *Events) Allowed(event, action string) bool { + allowed := false + + if len(action) > 0 { + event = event + ":" + action + } + + switch event { + case constants.EventPush: + allowed = e.GetPush().GetBranch() + case constants.EventPull + ":" + constants.ActionOpened: + allowed = e.GetPullRequest().GetOpened() + case constants.EventPull + ":" + constants.ActionSynchronize: + allowed = e.GetPullRequest().GetSynchronize() + case constants.EventPull + ":" + constants.ActionEdited: + allowed = e.GetPullRequest().GetEdited() + case constants.EventTag: + allowed = e.GetPush().GetTag() + case constants.EventComment + ":" + constants.ActionCreated: + allowed = e.GetComment().GetCreated() + case constants.EventComment + ":" + constants.ActionEdited: + allowed = e.GetComment().GetEdited() + case constants.EventDeploy: + allowed = e.GetDeployment().GetCreated() + case constants.EventSchedule: + allowed = e.GetSchedule().GetRun() + } + + return allowed +} + // List is an Events method that generates a comma-separated list of event:action // combinations that are allowed for the repo. func (e *Events) List() []string { @@ -71,6 +106,10 @@ func (e *Events) List() []string { eventSlice = append(eventSlice, constants.EventComment+":"+constants.ActionEdited) } + if e.GetSchedule().GetRun() { + eventSlice = append(eventSlice, constants.EventSchedule) + } + return eventSlice } @@ -123,6 +162,17 @@ func (e *Events) GetComment() *actions.Comment { return e.Comment } +// GetSchedule returns the Schedule field from the provided Events. If the object is nil, +// or the field within the object is nil, it returns the zero value instead. +func (e *Events) GetSchedule() *actions.Schedule { + // return zero value if Events type or Schedule field is nil + if e == nil || e.Schedule == nil { + return new(actions.Schedule) + } + + return e.Schedule +} + // SetPush sets the Events Push field. // // When the provided Events type is nil, it @@ -174,3 +224,16 @@ func (e *Events) SetComment(v *actions.Comment) { e.Comment = v } + +// SetSchedule sets the Events Schedule field. +// +// When the provided Events type is nil, it +// will set nothing and immediately return. +func (e *Events) SetSchedule(v *actions.Schedule) { + // return if Events type is nil + if e == nil { + return + } + + e.Schedule = v +} diff --git a/library/events_test.go b/library/events_test.go index 2023c46b..30ffb963 100644 --- a/library/events_test.go +++ b/library/events_test.go @@ -124,6 +124,41 @@ func TestLibrary_Events_NewEventsFromMask(t *testing.T) { } } +func TestLibrary_Events_Allowed(t *testing.T) { + // setup tests + tests := []struct { + events *Events + event string + action string + want bool + }{ + { + events: testEvents(), + event: "pull_request", + action: "opened", + want: true, + }, + { + events: testEvents(), + event: "deployment", + want: false, + }, + { + events: testEvents(), + event: "push", + want: true, + }, + } + + for _, test := range tests { + got := test.events.Allowed(test.event, test.action) + + if got != test.want { + t.Errorf("Allowed is %v, want %v", got, test.want) + } + } +} + func testEvents() *Events { e := new(Events) @@ -144,10 +179,14 @@ func testEvents() *Events { comment.SetCreated(false) comment.SetEdited(false) + schedule := new(actions.Schedule) + schedule.SetRun(false) + e.SetPush(push) e.SetPullRequest(pr) e.SetDeployment(deploy) e.SetComment(comment) + e.SetSchedule(schedule) return e } diff --git a/library/repo.go b/library/repo.go index b5bd13c1..2b1bdb51 100644 --- a/library/repo.go +++ b/library/repo.go @@ -5,8 +5,6 @@ package library import ( "fmt" "strings" - - "github.com/go-vela/types/constants" ) // Repo is the library representation of a repo. @@ -764,36 +762,6 @@ func (r *Repo) SetApproveBuild(v string) { r.ApproveBuild = &v } -// EventAllowed determines whether or not an event is allowed based on the repository settings. -func (r *Repo) EventAllowed(event, action string) (allowed bool) { - allowed = false - - if len(action) > 0 { - event = event + ":" + action - } - - switch event { - case constants.EventPush: - allowed = r.GetAllowEvents().GetPush().GetBranch() - case constants.EventPull + ":" + constants.ActionOpened: - allowed = r.GetAllowEvents().GetPullRequest().GetOpened() - case constants.EventPull + ":" + constants.ActionSynchronize: - allowed = r.GetAllowEvents().GetPullRequest().GetSynchronize() - case constants.EventPull + ":" + constants.ActionEdited: - allowed = r.GetAllowEvents().GetPullRequest().GetEdited() - case constants.EventTag: - allowed = r.GetAllowEvents().GetPush().GetTag() - case constants.EventComment + ":" + constants.ActionCreated: - allowed = r.GetAllowEvents().GetComment().GetCreated() - case constants.EventComment + ":" + constants.ActionEdited: - allowed = r.GetAllowEvents().GetComment().GetEdited() - case constants.EventDeploy: - allowed = r.GetAllowEvents().GetDeployment().GetCreated() - } - - return -} - // String implements the Stringer interface for the Repo type. // //nolint:dupl // ignore duplicate with test func diff --git a/library/repo_test.go b/library/repo_test.go index 1da2db4a..e536a135 100644 --- a/library/repo_test.go +++ b/library/repo_test.go @@ -331,41 +331,6 @@ func TestLibrary_Repo_Setters(t *testing.T) { } } -func TestLibrary_Repo_EventAllowed(t *testing.T) { - // setup tests - tests := []struct { - repo *Repo - event string - action string - want bool - }{ - { - repo: testRepo(), - event: "pull_request", - action: "opened", - want: true, - }, - { - repo: testRepo(), - event: "deployment", - want: false, - }, - { - repo: new(Repo), - event: "push", - want: false, - }, - } - - for _, test := range tests { - got := test.repo.EventAllowed(test.event, test.action) - - if got != test.want { - t.Errorf("EventAllowed is %v, want %v", got, test.want) - } - } -} - func TestLibrary_Repo_String(t *testing.T) { // setup types r := testRepo() diff --git a/library/secret.go b/library/secret.go index 62dd5e43..2566b4cd 100644 --- a/library/secret.go +++ b/library/secret.go @@ -23,6 +23,7 @@ type Secret struct { Type *string `json:"type,omitempty"` Images *[]string `json:"images,omitempty"` Events *[]string `json:"events,omitempty"` + AllowEvents *Events `json:"allow_events,omitempty"` AllowCommand *bool `json:"allow_command,omitempty"` CreatedAt *int64 `json:"created_at,omitempty"` CreatedBy *string `json:"created_by,omitempty"` @@ -47,6 +48,7 @@ func (s *Secret) Sanitize() *Secret { Type: s.Type, Images: s.Images, Events: s.Events, + AllowEvents: s.AllowEvents, AllowCommand: s.AllowCommand, CreatedAt: s.CreatedAt, CreatedBy: s.CreatedBy, @@ -60,28 +62,17 @@ func (s *Secret) Sanitize() *Secret { // resource. func (s *Secret) Match(from *pipeline.Container) bool { eACL, iACL := false, false - events, images, commands := s.GetEvents(), s.GetImages(), s.GetAllowCommand() + images, commands := s.GetImages(), s.GetAllowCommand() // check if commands are utilized when not allowed if !commands && len(from.Commands) > 0 { return false } - // check incoming events - switch from.Environment["VELA_BUILD_EVENT"] { - case constants.EventPush: - eACL = checkEvent(events, constants.EventPush) - case constants.EventPull: - eACL = checkEvent(events, constants.EventPull) - case constants.EventTag: - eACL = checkEvent(events, constants.EventTag) - case constants.EventDeploy: - eACL = checkEvent(events, constants.EventDeploy) - case constants.EventComment: - eACL = checkEvent(events, constants.EventComment) - case constants.EventSchedule: - eACL = checkEvent(events, constants.EventSchedule) - } + eACL = s.GetAllowEvents().Allowed( + from.Environment["VELA_BUILD_EVENT"], + from.Environment["VELA_BUILD_EVENT_ACTION"], + ) // check images whitelist for _, i := range images { @@ -93,8 +84,6 @@ func (s *Secret) Match(from *pipeline.Container) bool { // inject secrets into environment switch { - case iACL && (len(events) == 0): - return true case eACL && (len(images) == 0): return true case eACL && iACL: @@ -222,6 +211,19 @@ func (s *Secret) GetEvents() []string { return *s.Events } +// GetAllowEvents returns the AllowEvents field. +// +// When the provided Secret type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (s *Secret) GetAllowEvents() *Events { + // return zero value if Secret type or AllowEvents field is nil + if s == nil || s.AllowEvents == nil { + return new(Events) + } + + return s.AllowEvents +} + // GetAllowCommand returns the AllowCommand field. // // When the provided Secret type is nil, or the field within @@ -404,6 +406,19 @@ func (s *Secret) SetEvents(v []string) { s.Events = &v } +// SetAllowEvents sets the AllowEvents field. +// +// When the provided Secret type is nil, it +// will set nothing and immediately return. +func (s *Secret) SetAllowEvents(v *Events) { + // return if Secret type is nil + if s == nil { + return + } + + s.AllowEvents = v +} + // SetAllowCommand sets the AllowCommand field. // // When the provided Secret type is nil, it @@ -473,6 +488,7 @@ func (s *Secret) SetUpdatedBy(v string) { func (s *Secret) String() string { return fmt.Sprintf(`{ AllowCommand: %t, + AllowEvents: %s, Events: %s, ID: %d, Images: %s, @@ -488,6 +504,7 @@ func (s *Secret) String() string { UpdatedBy: %s, }`, s.GetAllowCommand(), + s.GetAllowEvents().List(), s.GetEvents(), s.GetID(), s.GetImages(), @@ -503,15 +520,3 @@ func (s *Secret) String() string { s.GetUpdatedBy(), ) } - -// checkEvent implements a function that iterates through -// a list to check the event is a member of the list. -func checkEvent(events []string, event string) bool { - for _, e := range events { - if e == event { - return true - } - } - - return false -} diff --git a/library/secret_test.go b/library/secret_test.go index 4fe2986f..591c1ac5 100644 --- a/library/secret_test.go +++ b/library/secret_test.go @@ -9,7 +9,9 @@ import ( "time" "github.com/go-vela/types/constants" + "github.com/go-vela/types/library/actions" "github.com/go-vela/types/pipeline" + "github.com/google/go-cmp/cmp" ) func TestLibrary_Secret_Sanitize(t *testing.T) { @@ -30,154 +32,290 @@ func TestLibrary_Secret_Sanitize(t *testing.T) { func TestLibrary_Secret_Match(t *testing.T) { // setup types v := "foo" - booL := false + fBool := false + tBool := true + + testEvents := &Events{ + Push: &actions.Push{ + Branch: &tBool, + Tag: &tBool, + }, + PullRequest: &actions.Pull{ + Opened: &fBool, + Synchronize: &tBool, + Edited: &fBool, + }, + Deployment: &actions.Deploy{ + Created: &tBool, + }, + Comment: &actions.Comment{ + Created: &tBool, + Edited: &tBool, + }, + Schedule: &actions.Schedule{ + Run: &tBool, + }, + } // setup tests tests := []struct { + name string step *pipeline.Container sec *Secret want bool }{ { // test matching secret events + name: "push", step: &pipeline.Container{ Image: "alpine:latest", Environment: map[string]string{"VELA_BUILD_EVENT": "push"}, }, - sec: &Secret{Name: &v, Value: &v, Images: &[]string{}, Events: &[]string{"push"}}, + sec: &Secret{ + Name: &v, + Value: &v, + Images: &[]string{}, + AllowEvents: testEvents, + }, want: true, }, { + name: "pull request opened fail", step: &pipeline.Container{ - Image: "alpine:latest", - Environment: map[string]string{"VELA_BUILD_EVENT": "pull_request"}, + Image: "alpine:latest", + Environment: map[string]string{ + "VELA_BUILD_EVENT": "pull_request", + "VELA_BUILD_EVENT_ACTION": "opened", + }, }, - sec: &Secret{Name: &v, Value: &v, Images: &[]string{}, Events: &[]string{"pull_request"}}, - want: true, + sec: &Secret{ + Name: &v, + Value: &v, + Images: &[]string{}, + AllowEvents: testEvents, + }, + want: false, }, { + name: "tag", step: &pipeline.Container{ Image: "alpine:latest", Environment: map[string]string{"VELA_BUILD_EVENT": "tag"}, }, - sec: &Secret{Name: &v, Value: &v, Images: &[]string{}, Events: &[]string{"tag"}}, + sec: &Secret{ + Name: &v, + Value: &v, + Images: &[]string{}, + AllowEvents: testEvents, + }, want: true, }, { + name: "deployment", step: &pipeline.Container{ Image: "alpine:latest", Environment: map[string]string{"VELA_BUILD_EVENT": "deployment"}, }, - sec: &Secret{Name: &v, Value: &v, Images: &[]string{}, Events: &[]string{"deployment"}}, + sec: &Secret{ + Name: &v, + Value: &v, + Images: &[]string{}, + AllowEvents: testEvents, + }, want: true, }, { + name: "comment created", step: &pipeline.Container{ - Image: "alpine:latest", - Environment: map[string]string{"VELA_BUILD_EVENT": "comment"}, + Image: "alpine:latest", + Environment: map[string]string{ + "VELA_BUILD_EVENT": "comment", + "VELA_BUILD_EVENT_ACTION": "created", + }, + }, + sec: &Secret{ + Name: &v, + Value: &v, + Images: &[]string{}, + AllowEvents: testEvents, }, - sec: &Secret{Name: &v, Value: &v, Images: &[]string{}, Events: &[]string{"comment"}}, want: true, }, { + name: "fake event", step: &pipeline.Container{ Image: "alpine:latest", Environment: map[string]string{"VELA_BUILD_EVENT": "fake_event"}, }, - sec: &Secret{Name: &v, Value: &v, Images: &[]string{}, Events: &[]string{"push"}}, + sec: &Secret{ + Name: &v, + Value: &v, + Images: &[]string{}, + AllowEvents: testEvents, + }, want: false, }, { + name: "push with empty image constraint", step: &pipeline.Container{ Image: "alpine:latest", Environment: map[string]string{"VELA_BUILD_EVENT": "push"}, }, - sec: &Secret{Name: &v, Value: &v, Images: &[]string{}, Events: &[]string{"push", "pull_request"}}, + sec: &Secret{ + Name: &v, + Value: &v, + Images: &[]string{}, + AllowEvents: testEvents, + }, want: true, }, { + name: "schedule", step: &pipeline.Container{ Image: "alpine:latest", Environment: map[string]string{"VELA_BUILD_EVENT": "schedule"}, }, - sec: &Secret{Name: &v, Value: &v, Images: &[]string{}, Events: &[]string{"push", "pull_request", "schedule"}}, + sec: &Secret{ + Name: &v, + Value: &v, + Images: &[]string{}, + AllowEvents: testEvents, + }, want: true, }, { // test matching secret images + name: "image basic", step: &pipeline.Container{ Image: "alpine:latest", Environment: map[string]string{"VELA_BUILD_EVENT": "push"}, }, - sec: &Secret{Name: &v, Value: &v, Images: &[]string{"alpine"}, Events: &[]string{}}, + sec: &Secret{ + Name: &v, + Value: &v, + Images: &[]string{"alpine"}, + AllowEvents: testEvents, + }, want: true, }, { + name: "image and tag", step: &pipeline.Container{ Image: "alpine:latest", Environment: map[string]string{"VELA_BUILD_EVENT": "push"}, }, - sec: &Secret{Name: &v, Value: &v, Images: &[]string{"alpine:latest"}, Events: &[]string{}}, + sec: &Secret{ + Name: &v, + Value: &v, + Images: &[]string{"alpine:latest"}, + AllowEvents: testEvents, + }, want: true, }, { + name: "mismatch tag with same image", step: &pipeline.Container{ Image: "alpine:latest", Environment: map[string]string{"VELA_BUILD_EVENT": "push"}, }, - sec: &Secret{Name: &v, Value: &v, Images: &[]string{"alpine:1"}, Events: &[]string{}}, + sec: &Secret{ + Name: &v, + Value: &v, + Images: &[]string{"alpine:1"}, + AllowEvents: testEvents, + }, want: false, }, { + name: "multiple allowed images", step: &pipeline.Container{ Image: "alpine:latest", Environment: map[string]string{"VELA_BUILD_EVENT": "push"}, }, - sec: &Secret{Name: &v, Value: &v, Images: &[]string{"alpine", "centos"}, Events: &[]string{}}, + sec: &Secret{ + Name: &v, + Value: &v, + Images: &[]string{"alpine", "centos"}, + AllowEvents: testEvents, + }, want: true, }, { // test matching secret events and images + name: "push and image pass", step: &pipeline.Container{ Image: "alpine:latest", Environment: map[string]string{"VELA_BUILD_EVENT": "push"}, }, - sec: &Secret{Name: &v, Value: &v, Images: &[]string{"alpine"}, Events: &[]string{"push"}}, + sec: &Secret{ + Name: &v, + Value: &v, + Images: &[]string{"alpine"}, + AllowEvents: testEvents, + }, want: true, }, { + name: "push and image tag pass", step: &pipeline.Container{ Image: "alpine:latest", Environment: map[string]string{"VELA_BUILD_EVENT": "push"}, }, - sec: &Secret{Name: &v, Value: &v, Images: &[]string{"alpine:latest"}, Events: &[]string{"push"}}, + sec: &Secret{ + Name: &v, + Value: &v, + Images: &[]string{"alpine:latest"}, + AllowEvents: testEvents, + }, want: true, }, { + name: "push and bad image tag", step: &pipeline.Container{ Image: "alpine:latest", Environment: map[string]string{"VELA_BUILD_EVENT": "push"}, }, - sec: &Secret{Name: &v, Value: &v, Images: &[]string{"alpine:1"}, Events: &[]string{"push"}}, + sec: &Secret{ + Name: &v, + Value: &v, + Images: &[]string{"alpine:1"}, + AllowEvents: testEvents, + }, want: false, }, { + name: "mismatch event and match image", step: &pipeline.Container{ - Image: "alpine:latest", - Environment: map[string]string{"VELA_BUILD_EVENT": "pull_request"}, + Image: "alpine:latest", + Environment: map[string]string{ + "VELA_BUILD_EVENT": "pull_request", + "VELA_BUILD_EVENT_ACTION": "edited", + }, + }, + sec: &Secret{ + Name: &v, + Value: &v, + Images: &[]string{"alpine:latest"}, + AllowEvents: testEvents, }, - sec: &Secret{Name: &v, Value: &v, Images: &[]string{"alpine:latest"}, Events: &[]string{"push"}}, want: false, }, { + name: "event and multi image allowed pass", step: &pipeline.Container{ Image: "alpine:latest", Environment: map[string]string{"VELA_BUILD_EVENT": "push"}, }, - sec: &Secret{Name: &v, Value: &v, Images: &[]string{"alpine", "centos"}, Events: &[]string{"push"}}, + sec: &Secret{ + Name: &v, + Value: &v, + Images: &[]string{"alpine", "centos"}, + AllowEvents: testEvents, + }, want: true, }, { // test build events with image ACLs and rulesets + name: "rulesets and push pass", step: &pipeline.Container{ Image: "alpine:latest", Environment: map[string]string{"VELA_BUILD_EVENT": "push"}, @@ -187,10 +325,16 @@ func TestLibrary_Secret_Match(t *testing.T) { }, }, }, - sec: &Secret{Name: &v, Value: &v, Images: &[]string{"alpine"}, Events: &[]string{"push"}}, + sec: &Secret{ + Name: &v, + Value: &v, + Images: &[]string{"alpine"}, + AllowEvents: testEvents, + }, want: true, }, { + name: "no commands allowed", step: &pipeline.Container{ Image: "alpine:latest", Environment: map[string]string{"VELA_BUILD_EVENT": "push"}, @@ -201,7 +345,13 @@ func TestLibrary_Secret_Match(t *testing.T) { }, Commands: []string{"echo hi"}, }, - sec: &Secret{Name: &v, Value: &v, Images: &[]string{"alpine"}, Events: &[]string{"push"}, AllowCommand: &booL}, + sec: &Secret{ + Name: &v, + Value: &v, + Images: &[]string{"alpine"}, + AllowEvents: testEvents, + AllowCommand: &fBool, + }, want: false, }, } @@ -211,7 +361,7 @@ func TestLibrary_Secret_Match(t *testing.T) { got := test.sec.Match(test.step) if got != test.want { - t.Errorf("Match is %v, want %v", got, test.want) + t.Errorf("Match for %s is %v, want %v", test.name, got, test.want) } } } @@ -270,6 +420,10 @@ func TestLibrary_Secret_Getters(t *testing.T) { t.Errorf("GetEvents is %v, want %v", test.secret.GetEvents(), test.want.GetEvents()) } + if !reflect.DeepEqual(test.secret.GetAllowEvents(), test.want.GetAllowEvents()) { + t.Errorf("GetAllowEvents is %v, want %v", test.secret.GetAllowEvents(), test.want.GetAllowEvents()) + } + if test.secret.GetAllowCommand() != test.want.GetAllowCommand() { t.Errorf("GetAllowCommand is %v, want %v", test.secret.GetAllowCommand(), test.want.GetAllowCommand()) } @@ -322,6 +476,7 @@ func TestLibrary_Secret_Setters(t *testing.T) { test.secret.SetType(test.want.GetType()) test.secret.SetImages(test.want.GetImages()) test.secret.SetEvents(test.want.GetEvents()) + test.secret.SetAllowEvents(test.want.GetAllowEvents()) test.secret.SetAllowCommand(test.want.GetAllowCommand()) test.secret.SetCreatedAt(test.want.GetCreatedAt()) test.secret.SetCreatedBy(test.want.GetCreatedBy()) @@ -364,6 +519,10 @@ func TestLibrary_Secret_Setters(t *testing.T) { t.Errorf("SetEvents is %v, want %v", test.secret.GetEvents(), test.want.GetEvents()) } + if !reflect.DeepEqual(test.secret.GetAllowEvents(), test.want.GetAllowEvents()) { + t.Errorf("SetAllowEvents is %v, want %v", test.secret.GetAllowEvents(), test.want.GetAllowEvents()) + } + if test.secret.GetAllowCommand() != test.want.GetAllowCommand() { t.Errorf("SetAllowCommand is %v, want %v", test.secret.GetAllowCommand(), test.want.GetAllowCommand()) } @@ -392,6 +551,7 @@ func TestLibrary_Secret_String(t *testing.T) { want := fmt.Sprintf(`{ AllowCommand: %t, + AllowEvents: %v, Events: %s, ID: %d, Images: %s, @@ -407,6 +567,7 @@ func TestLibrary_Secret_String(t *testing.T) { UpdatedBy: %s, }`, s.GetAllowCommand(), + s.GetAllowEvents().List(), s.GetEvents(), s.GetID(), s.GetImages(), @@ -425,8 +586,8 @@ func TestLibrary_Secret_String(t *testing.T) { // run test got := s.String() - if !reflect.DeepEqual(got, want) { - t.Errorf("String is %v, want %v", got, want) + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("String Mismatch: -want +got):\n%s", diff) } } @@ -447,6 +608,7 @@ func testSecret() *Secret { s.SetType("repo") s.SetImages([]string{"alpine"}) s.SetEvents([]string{"push", "tag", "deployment"}) + s.SetAllowEvents(NewEventsFromMask(1)) s.SetAllowCommand(true) s.SetCreatedAt(tsCreate) s.SetCreatedBy("octocat") From 0d0e2236779601db16bfeffc3683bd378adf3923 Mon Sep 17 00:00:00 2001 From: claire1618 <55173466+claire1618@users.noreply.github.com> Date: Thu, 11 Jan 2024 13:21:44 -0600 Subject: [PATCH 03/11] feat: adding a delete_event (#340) * feat: adding delete event * creating a delete event in types * final touches, fingers crossed * fixing tests * fixing final lint errors * fix: removing old AllowDelete work and removing a naked return * fix: removing leftover allowDelete items from tests * fix: changing library/secret.go to reflect library/repo.go when it comes to allowedEvents * fix: modifying library/secret_test.go to reflect new secret.go changes * fix: removing fix so that it can be included in another PR * fix: small error when fixing merge conflicts * fix: making the linter happy * fix: changing ruleset.go to go with David May's comment * rolling back last change * rolling back last change --------- Co-authored-by: Claire.Nicholas Co-authored-by: Easton Crupper <65553218+ecrupper@users.noreply.github.com> --- constants/action.go | 6 ++ constants/allow_events.go | 2 + constants/event.go | 3 + library/actions/comment.go | 3 +- library/actions/delete.go | 84 +++++++++++++++++++++++++ library/actions/delete_test.go | 108 +++++++++++++++++++++++++++++++++ library/actions/push.go | 3 +- library/actions/push_test.go | 4 +- library/events.go | 37 ++++++++++- library/events_test.go | 20 +++++- library/repo.go | 38 +++++++++++- library/repo_test.go | 4 +- 12 files changed, 303 insertions(+), 9 deletions(-) create mode 100644 library/actions/delete.go create mode 100644 library/actions/delete_test.go diff --git a/constants/action.go b/constants/action.go index bcff84b7..f1e18c6e 100644 --- a/constants/action.go +++ b/constants/action.go @@ -24,4 +24,10 @@ const ( // ActionTransferred defines the action for transferring repository ownership. ActionTransferred = "transferred" + + // ActionBranch defines the action for deleting a branch. + ActionBranch = "branch" + + // ActionTag defines the action for deleting a tag. + ActionTag = "tag" ) diff --git a/constants/allow_events.go b/constants/allow_events.go index f5d2cdd9..3e00f2d2 100644 --- a/constants/allow_events.go +++ b/constants/allow_events.go @@ -21,4 +21,6 @@ const ( AllowCommentCreate AllowCommentEdit AllowSchedule + AllowDeleteBranch + AllowDeleteTag ) diff --git a/constants/event.go b/constants/event.go index cf72a089..9d59f7e5 100644 --- a/constants/event.go +++ b/constants/event.go @@ -7,6 +7,9 @@ const ( // EventComment defines the event type for comments added to a pull request. EventComment = "comment" + // EventDelete defines the event type for build and repo delete events. + EventDelete = "delete" + // EventDeploy defines the event type for build and repo deployment events. EventDeploy = "deployment" diff --git a/library/actions/comment.go b/library/actions/comment.go index 499cfed6..c0e04298 100644 --- a/library/actions/comment.go +++ b/library/actions/comment.go @@ -1,5 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 - +// +//nolint:dupl // similar code to delete.go package actions import "github.com/go-vela/types/constants" diff --git a/library/actions/delete.go b/library/actions/delete.go new file mode 100644 index 00000000..fa88046d --- /dev/null +++ b/library/actions/delete.go @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: Apache-2.0 +// +//nolint:dupl // similar code to push.go +package actions + +import "github.com/go-vela/types/constants" + +// Delete is the library representation of the various actions associated +// with the delete event webhook from the SCM. +type Delete struct { + Branch *bool `json:"branch"` + Tag *bool `json:"tag"` +} + +// FromMask returns the Delete type resulting from the provided integer mask. +func (a *Delete) FromMask(mask int64) *Delete { + a.SetBranch(mask&constants.AllowDeleteBranch > 0) + a.SetTag(mask&constants.AllowDeleteTag > 0) + + return a +} + +// ToMask returns the integer mask of the values for the Delete set. +func (a *Delete) ToMask() int64 { + mask := int64(0) + + if a.GetBranch() { + mask = mask | constants.AllowDeleteBranch + } + + if a.GetTag() { + mask = mask | constants.AllowDeleteTag + } + + return mask +} + +// GetBranch returns the Branch field from the provided Delete. If the object is nil, +// or the field within the object is nil, it returns the zero value instead. +func (a *Delete) GetBranch() bool { + // return zero value if Delete type or Branch field is nil + if a == nil || a.Branch == nil { + return false + } + + return *a.Branch +} + +// GetTag returns the Tag field from the provided Delete. If the object is nil, +// or the field within the object is nil, it returns the zero value instead. +func (a *Delete) GetTag() bool { + // return zero value if Delete type or Tag field is nil + if a == nil || a.Tag == nil { + return false + } + + return *a.Tag +} + +// SetBranch sets the Delete Branch field. +// +// When the provided Delete type is nil, it +// will set nothing and immediately return. +func (a *Delete) SetBranch(v bool) { + // return if Events type is nil + if a == nil { + return + } + + a.Branch = &v +} + +// SetTag sets the Delete Tag field. +// +// When the provided Delete type is nil, it +// will set nothing and immediately return. +func (a *Delete) SetTag(v bool) { + // return if Events type is nil + if a == nil { + return + } + + a.Tag = &v +} diff --git a/library/actions/delete_test.go b/library/actions/delete_test.go new file mode 100644 index 00000000..3c7cd539 --- /dev/null +++ b/library/actions/delete_test.go @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: Apache-2.0 + +package actions + +import ( + "reflect" + "testing" + + "github.com/go-vela/types/constants" +) + +func TestLibrary_Delete_Getters(t *testing.T) { + // setup tests + tests := []struct { + actions *Delete + want *Delete + }{ + { + actions: testDelete(), + want: testDelete(), + }, + { + actions: new(Delete), + want: new(Delete), + }, + } + + // run tests + for _, test := range tests { + if test.actions.GetBranch() != test.want.GetBranch() { + t.Errorf("GetBranch is %v, want %v", test.actions.GetBranch(), test.want.GetBranch()) + } + + if test.actions.GetTag() != test.want.GetTag() { + t.Errorf("GetTag is %v, want %v", test.actions.GetTag(), test.want.GetTag()) + } + } +} + +func TestLibrary_Delete_Setters(t *testing.T) { + // setup types + var a *Delete + + // setup tests + tests := []struct { + actions *Delete + want *Delete + }{ + { + actions: testDelete(), + want: testDelete(), + }, + { + actions: a, + want: new(Delete), + }, + } + + // run tests + for _, test := range tests { + test.actions.SetBranch(test.want.GetBranch()) + test.actions.SetTag(test.want.GetTag()) + + if test.actions.GetBranch() != test.want.GetBranch() { + t.Errorf("SetBranch is %v, want %v", test.actions.GetBranch(), test.want.GetBranch()) + } + + if test.actions.GetTag() != test.want.GetTag() { + t.Errorf("SetTag is %v, want %v", test.actions.GetTag(), test.want.GetTag()) + } + } +} + +func TestLibrary_Delete_FromMask(t *testing.T) { + // setup types + mask := testMask() + + want := testDelete() + + // run test + got := new(Delete).FromMask(mask) + + if !reflect.DeepEqual(got, want) { + t.Errorf("FromMask is %v, want %v", got, want) + } +} + +func TestLibrary_Delete_ToMask(t *testing.T) { + // setup types + actions := testDelete() + + want := int64(constants.AllowDeleteBranch | constants.AllowDeleteTag) + + // run test + got := actions.ToMask() + + if want != got { + t.Errorf("ToMask is %v, want %v", got, want) + } +} + +func testDelete() *Delete { + deletion := new(Delete) + deletion.SetBranch(true) + deletion.SetTag(true) + + return deletion +} diff --git a/library/actions/push.go b/library/actions/push.go index 5472af94..9853f454 100644 --- a/library/actions/push.go +++ b/library/actions/push.go @@ -1,5 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 - +// +//nolint:dupl // similar code to comment.go package actions import "github.com/go-vela/types/constants" diff --git a/library/actions/push_test.go b/library/actions/push_test.go index fbdb3cb7..f8cd4c3b 100644 --- a/library/actions/push_test.go +++ b/library/actions/push_test.go @@ -116,6 +116,8 @@ func testMask() int64 { constants.AllowPullReopen | constants.AllowDeployCreate | constants.AllowCommentCreate | - constants.AllowSchedule, + constants.AllowSchedule | + constants.AllowDeleteBranch | + constants.AllowDeleteTag, ) } diff --git a/library/events.go b/library/events.go index 78ce5d8e..82eeba08 100644 --- a/library/events.go +++ b/library/events.go @@ -15,6 +15,7 @@ type Events struct { Deployment *actions.Deploy `json:"deployment"` Comment *actions.Comment `json:"comment"` Schedule *actions.Schedule `json:"schedule"` + Delete *actions.Delete `json:"delete"` } // NewEventsFromMask is an instatiation function for the Events type that @@ -25,6 +26,7 @@ func NewEventsFromMask(mask int64) *Events { deployActions := new(actions.Deploy).FromMask(mask) commentActions := new(actions.Comment).FromMask(mask) scheduleActions := new(actions.Schedule).FromMask(mask) + deleteActions := new(actions.Delete).FromMask(mask) e := new(Events) @@ -33,6 +35,7 @@ func NewEventsFromMask(mask int64) *Events { e.SetDeployment(deployActions) e.SetComment(commentActions) e.SetSchedule(scheduleActions) + e.SetDelete(deleteActions) return e } @@ -110,12 +113,20 @@ func (e *Events) List() []string { eventSlice = append(eventSlice, constants.EventSchedule) } + if e.GetDelete().GetBranch() { + eventSlice = append(eventSlice, constants.EventDelete+":"+constants.ActionBranch) + } + + if e.GetDelete().GetTag() { + eventSlice = append(eventSlice, constants.EventDelete+":"+constants.ActionTag) + } + return eventSlice } // ToDatabase is an Events method that converts a nested Events struct into an integer event mask. func (e *Events) ToDatabase() int64 { - return 0 | e.GetPush().ToMask() | e.GetPullRequest().ToMask() | e.GetComment().ToMask() | e.GetDeployment().ToMask() + return 0 | e.GetPush().ToMask() | e.GetPullRequest().ToMask() | e.GetComment().ToMask() | e.GetDeployment().ToMask() | e.GetDelete().ToMask() } // GetPush returns the Push field from the provided Events. If the object is nil, @@ -173,6 +184,17 @@ func (e *Events) GetSchedule() *actions.Schedule { return e.Schedule } +// GetDelete returns the Delete field from the provided Events. If the object is nil, +// or the field within the object is nil, it returns the zero value instead. +func (e *Events) GetDelete() *actions.Delete { + // return zero value if Events type or Comment field is nil + if e == nil || e.Delete == nil { + return new(actions.Delete) + } + + return e.Delete +} + // SetPush sets the Events Push field. // // When the provided Events type is nil, it @@ -237,3 +259,16 @@ func (e *Events) SetSchedule(v *actions.Schedule) { e.Schedule = v } + +// SetDelete sets the Events Delete field. +// +// When the provided Events type is nil, it +// will set nothing and immediately return. +func (e *Events) SetDelete(v *actions.Delete) { + // return if Events type is nil + if e == nil { + return + } + + e.Delete = v +} diff --git a/library/events_test.go b/library/events_test.go index 30ffb963..4e3f1458 100644 --- a/library/events_test.go +++ b/library/events_test.go @@ -43,6 +43,10 @@ func TestLibrary_Events_Getters(t *testing.T) { if !reflect.DeepEqual(test.events.GetComment(), test.want.GetComment()) { t.Errorf("GetComment is %v, want %v", test.events.GetPush(), test.want.GetPush()) } + + if !reflect.DeepEqual(test.events.GetDelete(), test.want.GetDelete()) { + t.Errorf("GetDelete is %v, want %v", test.events.GetDelete(), test.want.GetDelete()) + } } } @@ -71,6 +75,7 @@ func TestLibrary_Events_Setters(t *testing.T) { test.events.SetPullRequest(test.want.GetPullRequest()) test.events.SetDeployment(test.want.GetDeployment()) test.events.SetComment(test.want.GetComment()) + test.events.SetDelete(test.want.GetDelete()) if !reflect.DeepEqual(test.events.GetPush(), test.want.GetPush()) { t.Errorf("SetPush is %v, want %v", test.events.GetPush(), test.want.GetPush()) @@ -87,6 +92,10 @@ func TestLibrary_Events_Setters(t *testing.T) { if !reflect.DeepEqual(test.events.GetComment(), test.want.GetComment()) { t.Errorf("SetComment is %v, want %v", test.events.GetComment(), test.want.GetComment()) } + + if !reflect.DeepEqual(test.events.GetDelete(), test.want.GetDelete()) { + t.Errorf("SetDelete is %v, want %v", test.events.GetDelete(), test.want.GetDelete()) + } } } @@ -94,7 +103,7 @@ func TestLibrary_Events_List(t *testing.T) { // setup types e := testEvents() - want := []string{"push", "pull_request:opened", "pull_request:synchronize", "tag"} + want := []string{"push", "pull_request:opened", "pull_request:synchronize", "tag", "delete:branch", "delete:tag"} // run test got := e.List() @@ -111,7 +120,9 @@ func TestLibrary_Events_NewEventsFromMask(t *testing.T) { constants.AllowPushTag | constants.AllowPullOpen | constants.AllowPullSync | - constants.AllowPullReopen, + constants.AllowPullReopen | + constants.AllowDeleteBranch | + constants.AllowDeleteTag, ) want := testEvents() @@ -182,11 +193,16 @@ func testEvents() *Events { schedule := new(actions.Schedule) schedule.SetRun(false) + deletion := new(actions.Delete) + deletion.SetBranch(true) + deletion.SetTag(true) + e.SetPush(push) e.SetPullRequest(pr) e.SetDeployment(deploy) e.SetComment(comment) e.SetSchedule(schedule) + e.SetDelete(deletion) return e } diff --git a/library/repo.go b/library/repo.go index 2b1bdb51..44c9bd58 100644 --- a/library/repo.go +++ b/library/repo.go @@ -5,6 +5,8 @@ package library import ( "fmt" "strings" + + "github.com/go-vela/types/constants" ) // Repo is the library representation of a repo. @@ -364,7 +366,7 @@ func (r *Repo) GetAllowTag() bool { // When the provided Repo type is nil, or the field within // the type is nil, it returns the zero value for the field. func (r *Repo) GetAllowComment() bool { - // return zero value if Repo type or AllowTag field is nil + // return zero value if Repo type or AllowComment field is nil if r == nil || r.AllowComment == nil { return false } @@ -762,6 +764,40 @@ func (r *Repo) SetApproveBuild(v string) { r.ApproveBuild = &v } +// EventAllowed determines whether or not an event is allowed based on the repository settings. +func (r *Repo) EventAllowed(event, action string) (allowed bool) { + allowed = false + + if len(action) > 0 { + event = event + ":" + action + } + + switch event { + case constants.EventPush: + allowed = r.GetAllowEvents().GetPush().GetBranch() + case constants.EventPull + ":" + constants.ActionOpened: + allowed = r.GetAllowEvents().GetPullRequest().GetOpened() + case constants.EventPull + ":" + constants.ActionSynchronize: + allowed = r.GetAllowEvents().GetPullRequest().GetSynchronize() + case constants.EventPull + ":" + constants.ActionEdited: + allowed = r.GetAllowEvents().GetPullRequest().GetEdited() + case constants.EventTag: + allowed = r.GetAllowEvents().GetPush().GetTag() + case constants.EventComment + ":" + constants.ActionCreated: + allowed = r.GetAllowEvents().GetComment().GetCreated() + case constants.EventComment + ":" + constants.ActionEdited: + allowed = r.GetAllowEvents().GetComment().GetEdited() + case constants.EventDeploy: + allowed = r.GetAllowEvents().GetDeployment().GetCreated() + case constants.EventDelete + ":" + constants.ActionBranch: + allowed = r.GetAllowEvents().GetDelete().GetBranch() + case constants.EventDelete + ":" + constants.ActionTag: + allowed = r.GetAllowEvents().GetDelete().GetTag() + } + + return allowed +} + // String implements the Stringer interface for the Repo type. // //nolint:dupl // ignore duplicate with test func diff --git a/library/repo_test.go b/library/repo_test.go index e536a135..e897142b 100644 --- a/library/repo_test.go +++ b/library/repo_test.go @@ -19,7 +19,7 @@ func TestLibrary_Repo_Environment(t *testing.T) { "VELA_REPO_ALLOW_PULL": "false", "VELA_REPO_ALLOW_PUSH": "true", "VELA_REPO_ALLOW_TAG": "false", - "VELA_REPO_ALLOW_EVENTS": "push,pull_request:opened,pull_request:synchronize,tag", + "VELA_REPO_ALLOW_EVENTS": "push,pull_request:opened,pull_request:synchronize,tag,delete:branch,delete:tag", "VELA_REPO_BRANCH": "main", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_BUILD_LIMIT": "10", @@ -40,7 +40,7 @@ func TestLibrary_Repo_Environment(t *testing.T) { "REPOSITORY_ALLOW_PULL": "false", "REPOSITORY_ALLOW_PUSH": "true", "REPOSITORY_ALLOW_TAG": "false", - "REPOSITORY_ALLOW_EVENTS": "push,pull_request:opened,pull_request:synchronize,tag", + "REPOSITORY_ALLOW_EVENTS": "push,pull_request:opened,pull_request:synchronize,tag,delete:branch,delete:tag", "REPOSITORY_BRANCH": "main", "REPOSITORY_CLONE": "https://github.com/github/octocat.git", "REPOSITORY_FULL_NAME": "github/octocat", From 483bff0c86934aa1143e33316ab0d4548e7bf356 Mon Sep 17 00:00:00 2001 From: claire1618 <55173466+claire1618@users.noreply.github.com> Date: Mon, 15 Jan 2024 15:25:25 -0600 Subject: [PATCH 04/11] fix: enabling a delete event to be allowed (#342) Co-authored-by: Claire.Nicholas --- library/events.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library/events.go b/library/events.go index 82eeba08..64ed8609 100644 --- a/library/events.go +++ b/library/events.go @@ -67,6 +67,10 @@ func (e *Events) Allowed(event, action string) bool { allowed = e.GetDeployment().GetCreated() case constants.EventSchedule: allowed = e.GetSchedule().GetRun() + case constants.EventDelete + ":" + constants.ActionBranch: + allowed = e.GetDelete().GetBranch() + case constants.EventDelete + ":" + constants.ActionTag: + allowed = e.GetDelete().GetTag() } return allowed From a4d640c8760ef5a6525a4941b1418635f867f981 Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Mon, 15 Jan 2024 16:34:21 -0500 Subject: [PATCH 05/11] fix(repo): remove dead code EventAllowed (#343) --- library/events.go | 4 +++- library/repo.go | 36 ------------------------------------ 2 files changed, 3 insertions(+), 37 deletions(-) diff --git a/library/events.go b/library/events.go index 64ed8609..34b1d710 100644 --- a/library/events.go +++ b/library/events.go @@ -40,10 +40,12 @@ func NewEventsFromMask(mask int64) *Events { return e } -// EventAllowed determines whether or not an event is allowed based on the repository settings. +// Allowed determines whether or not an event + action is allowed based on whether +// its event:action is set to true in the Events struct. func (e *Events) Allowed(event, action string) bool { allowed := false + // if there is an action, create `event:action` comparator string if len(action) > 0 { event = event + ":" + action } diff --git a/library/repo.go b/library/repo.go index 44c9bd58..845028b9 100644 --- a/library/repo.go +++ b/library/repo.go @@ -5,8 +5,6 @@ package library import ( "fmt" "strings" - - "github.com/go-vela/types/constants" ) // Repo is the library representation of a repo. @@ -764,40 +762,6 @@ func (r *Repo) SetApproveBuild(v string) { r.ApproveBuild = &v } -// EventAllowed determines whether or not an event is allowed based on the repository settings. -func (r *Repo) EventAllowed(event, action string) (allowed bool) { - allowed = false - - if len(action) > 0 { - event = event + ":" + action - } - - switch event { - case constants.EventPush: - allowed = r.GetAllowEvents().GetPush().GetBranch() - case constants.EventPull + ":" + constants.ActionOpened: - allowed = r.GetAllowEvents().GetPullRequest().GetOpened() - case constants.EventPull + ":" + constants.ActionSynchronize: - allowed = r.GetAllowEvents().GetPullRequest().GetSynchronize() - case constants.EventPull + ":" + constants.ActionEdited: - allowed = r.GetAllowEvents().GetPullRequest().GetEdited() - case constants.EventTag: - allowed = r.GetAllowEvents().GetPush().GetTag() - case constants.EventComment + ":" + constants.ActionCreated: - allowed = r.GetAllowEvents().GetComment().GetCreated() - case constants.EventComment + ":" + constants.ActionEdited: - allowed = r.GetAllowEvents().GetComment().GetEdited() - case constants.EventDeploy: - allowed = r.GetAllowEvents().GetDeployment().GetCreated() - case constants.EventDelete + ":" + constants.ActionBranch: - allowed = r.GetAllowEvents().GetDelete().GetBranch() - case constants.EventDelete + ":" + constants.ActionTag: - allowed = r.GetAllowEvents().GetDelete().GetTag() - } - - return allowed -} - // String implements the Stringer interface for the Repo type. // //nolint:dupl // ignore duplicate with test func From 00dcbc6ffa55754367daa69d920e94dad324d25d Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Wed, 17 Jan 2024 10:10:36 -0500 Subject: [PATCH 06/11] enhance(ci): include PR title validation workflow (#344) * enhance(ci): include PR title validation workflow * update action name * include all necessary types * point to docs and add a couple extra options --- .github/workflows/pr-title-validate.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 .github/workflows/pr-title-validate.yml diff --git a/.github/workflows/pr-title-validate.yml b/.github/workflows/pr-title-validate.yml new file mode 100644 index 00000000..f62dacf0 --- /dev/null +++ b/.github/workflows/pr-title-validate.yml @@ -0,0 +1,17 @@ +# name of the action +name: validate PR title + +# trigger on pull_request events of the opened & edited type. +on: + pull_request: + types: [ opened, synchronize, edited, reopened ] + +# pipeline to execute +jobs: + validate: + runs-on: ubuntu-latest + + steps: + - name: validate + run: | + echo "${{ github.event.pull_request.title }}" | grep -Eq '^(feat|fix|chore|refactor|enhance|test|docs)\(.*\):.*$' && (echo "Pass"; exit 0) || (echo "Incorrect Format. Please see https://go-vela.github.io/docs/community/contributing_guidelines/#development-workflow"; exit 1) \ No newline at end of file From 0e2e18b383dedd61cefd7403e4b6fab458f5d9a2 Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Wed, 17 Jan 2024 10:19:28 -0500 Subject: [PATCH 07/11] fix(events): add schedule to ToDatabase and improve tests (#345) --- library/events.go | 14 ++- library/events_test.go | 232 +++++++++++++++++++++++++++++------------ library/repo_test.go | 11 +- 3 files changed, 183 insertions(+), 74 deletions(-) diff --git a/library/events.go b/library/events.go index 34b1d710..fbcb23d0 100644 --- a/library/events.go +++ b/library/events.go @@ -59,6 +59,8 @@ func (e *Events) Allowed(event, action string) bool { allowed = e.GetPullRequest().GetSynchronize() case constants.EventPull + ":" + constants.ActionEdited: allowed = e.GetPullRequest().GetEdited() + case constants.EventPull + ":" + constants.ActionReopened: + allowed = e.GetPullRequest().GetReopened() case constants.EventTag: allowed = e.GetPush().GetTag() case constants.EventComment + ":" + constants.ActionCreated: @@ -99,6 +101,10 @@ func (e *Events) List() []string { eventSlice = append(eventSlice, constants.EventPull+":"+constants.ActionEdited) } + if e.GetPullRequest().GetReopened() { + eventSlice = append(eventSlice, constants.EventPull+":"+constants.ActionReopened) + } + if e.GetPush().GetTag() { eventSlice = append(eventSlice, constants.EventTag) } @@ -132,7 +138,13 @@ func (e *Events) List() []string { // ToDatabase is an Events method that converts a nested Events struct into an integer event mask. func (e *Events) ToDatabase() int64 { - return 0 | e.GetPush().ToMask() | e.GetPullRequest().ToMask() | e.GetComment().ToMask() | e.GetDeployment().ToMask() | e.GetDelete().ToMask() + return 0 | + e.GetPush().ToMask() | + e.GetPullRequest().ToMask() | + e.GetComment().ToMask() | + e.GetDeployment().ToMask() | + e.GetSchedule().ToMask() | + e.GetDelete().ToMask() } // GetPush returns the Push field from the provided Events. If the object is nil, diff --git a/library/events_test.go b/library/events_test.go index 4e3f1458..c1bafe94 100644 --- a/library/events_test.go +++ b/library/events_test.go @@ -8,17 +8,25 @@ import ( "github.com/go-vela/types/constants" "github.com/go-vela/types/library/actions" + "github.com/google/go-cmp/cmp" ) func TestLibrary_Events_Getters(t *testing.T) { + // setup types + eventsOne, eventsTwo := testEvents() + // setup tests tests := []struct { events *Events want *Events }{ { - events: testEvents(), - want: testEvents(), + events: eventsOne, + want: eventsOne, + }, + { + events: eventsTwo, + want: eventsTwo, }, { events: new(Events), @@ -44,6 +52,10 @@ func TestLibrary_Events_Getters(t *testing.T) { t.Errorf("GetComment is %v, want %v", test.events.GetPush(), test.want.GetPush()) } + if !reflect.DeepEqual(test.events.GetSchedule(), test.want.GetSchedule()) { + t.Errorf("GetSchedule is %v, want %v", test.events.GetSchedule(), test.want.GetSchedule()) + } + if !reflect.DeepEqual(test.events.GetDelete(), test.want.GetDelete()) { t.Errorf("GetDelete is %v, want %v", test.events.GetDelete(), test.want.GetDelete()) } @@ -54,14 +66,20 @@ func TestLibrary_Events_Setters(t *testing.T) { // setup types var e *Events + eventsOne, eventsTwo := testEvents() + // setup tests tests := []struct { events *Events want *Events }{ { - events: testEvents(), - want: testEvents(), + events: eventsOne, + want: eventsOne, + }, + { + events: eventsTwo, + want: eventsTwo, }, { events: e, @@ -75,6 +93,7 @@ func TestLibrary_Events_Setters(t *testing.T) { test.events.SetPullRequest(test.want.GetPullRequest()) test.events.SetDeployment(test.want.GetDeployment()) test.events.SetComment(test.want.GetComment()) + test.events.SetSchedule(test.want.GetSchedule()) test.events.SetDelete(test.want.GetDelete()) if !reflect.DeepEqual(test.events.GetPush(), test.want.GetPush()) { @@ -93,6 +112,10 @@ func TestLibrary_Events_Setters(t *testing.T) { t.Errorf("SetComment is %v, want %v", test.events.GetComment(), test.want.GetComment()) } + if !reflect.DeepEqual(test.events.GetSchedule(), test.want.GetSchedule()) { + t.Errorf("SetSchedule is %v, want %v", test.events.GetSchedule(), test.want.GetSchedule()) + } + if !reflect.DeepEqual(test.events.GetDelete(), test.want.GetDelete()) { t.Errorf("SetDelete is %v, want %v", test.events.GetDelete(), test.want.GetDelete()) } @@ -101,108 +124,181 @@ func TestLibrary_Events_Setters(t *testing.T) { func TestLibrary_Events_List(t *testing.T) { // setup types - e := testEvents() + eventsOne, eventsTwo := testEvents() + + wantOne := []string{ + "push", + "pull_request:opened", + "pull_request:synchronize", + "pull_request:reopened", + "tag", + "comment:created", + "schedule", + "delete:branch", + } - want := []string{"push", "pull_request:opened", "pull_request:synchronize", "tag", "delete:branch", "delete:tag"} + wantTwo := []string{ + "pull_request:edited", + "deployment", + "comment:edited", + "delete:tag", + } // run test - got := e.List() + gotOne := eventsOne.List() + + if diff := cmp.Diff(wantOne, gotOne); diff != "" { + t.Errorf("(List: -want +got):\n%s", diff) + } + + gotTwo := eventsTwo.List() - if !reflect.DeepEqual(got, want) { - t.Errorf("List is %v, want %v", got, want) + if diff := cmp.Diff(wantTwo, gotTwo); diff != "" { + t.Errorf("(List Inverse: -want +got):\n%s", diff) } } -func TestLibrary_Events_NewEventsFromMask(t *testing.T) { +func TestLibrary_Events_NewEventsFromMask_ToDatabase(t *testing.T) { // setup mask - mask := int64( + maskOne := int64( constants.AllowPushBranch | constants.AllowPushTag | constants.AllowPullOpen | constants.AllowPullSync | constants.AllowPullReopen | - constants.AllowDeleteBranch | + constants.AllowCommentCreate | + constants.AllowSchedule | + constants.AllowDeleteBranch, + ) + + maskTwo := int64( + constants.AllowPullEdit | + constants.AllowCommentEdit | + constants.AllowDeployCreate | constants.AllowDeleteTag, ) - want := testEvents() + wantOne, wantTwo := testEvents() // run test - got := NewEventsFromMask(mask) + gotOne := NewEventsFromMask(maskOne) + + if diff := cmp.Diff(wantOne, gotOne); diff != "" { + t.Errorf("(NewEventsFromMask: -want +got):\n%s", diff) + } + + gotTwo := NewEventsFromMask(maskTwo) - if !reflect.DeepEqual(got, want) { - t.Errorf("NewEventsFromMask is %v, want %v", got, want) + if diff := cmp.Diff(wantTwo, gotTwo); diff != "" { + t.Errorf("(NewEventsFromMask Inverse: -want +got):\n%s", diff) + } + + // ensure ToDatabase maps back to masks + if gotOne.ToDatabase() != maskOne { + t.Errorf("ToDatabase returned %d, want %d", gotOne.ToDatabase(), maskOne) + } + + if gotTwo.ToDatabase() != maskTwo { + t.Errorf("ToDatabase returned %d, want %d", gotTwo.ToDatabase(), maskTwo) } } func TestLibrary_Events_Allowed(t *testing.T) { + // setup types + eventsOne, eventsTwo := testEvents() + // setup tests tests := []struct { - events *Events event string action string want bool }{ - { - events: testEvents(), - event: "pull_request", - action: "opened", - want: true, - }, - { - events: testEvents(), - event: "deployment", - want: false, - }, - { - events: testEvents(), - event: "push", - want: true, - }, + {event: "push", want: true}, + {event: "tag", want: true}, + {event: "pull_request", action: "opened", want: true}, + {event: "pull_request", action: "synchronize", want: true}, + {event: "pull_request", action: "edited", want: false}, + {event: "pull_request", action: "reopened", want: true}, + {event: "deployment", want: false}, + {event: "comment", action: "created", want: true}, + {event: "comment", action: "edited", want: false}, + {event: "schedule", want: true}, + {event: "delete", action: "branch", want: true}, + {event: "delete", action: "tag", want: false}, } for _, test := range tests { - got := test.events.Allowed(test.event, test.action) + gotOne := eventsOne.Allowed(test.event, test.action) + gotTwo := eventsTwo.Allowed(test.event, test.action) + + if gotOne != test.want { + t.Errorf("Allowed for %s/%s is %v, want %v", test.event, test.action, gotOne, test.want) + } - if got != test.want { - t.Errorf("Allowed is %v, want %v", got, test.want) + if gotTwo == test.want { + t.Errorf("Allowed Inverse for %s/%s is %v, want %v", test.event, test.action, gotTwo, !test.want) } } } -func testEvents() *Events { - e := new(Events) - - pr := new(actions.Pull) - pr.SetOpened(true) - pr.SetSynchronize(true) - pr.SetEdited(false) - pr.SetReopened(true) - - push := new(actions.Push) - push.SetBranch(true) - push.SetTag(true) - - deploy := new(actions.Deploy) - deploy.SetCreated(false) +// testEvents is a helper test function that returns an Events struct and its inverse for unit test coverage. +func testEvents() (*Events, *Events) { + tBool := true + fBool := false - comment := new(actions.Comment) - comment.SetCreated(false) - comment.SetEdited(false) - - schedule := new(actions.Schedule) - schedule.SetRun(false) - - deletion := new(actions.Delete) - deletion.SetBranch(true) - deletion.SetTag(true) + e1 := &Events{ + Push: &actions.Push{ + Branch: &tBool, + Tag: &tBool, + }, + PullRequest: &actions.Pull{ + Opened: &tBool, + Synchronize: &tBool, + Edited: &fBool, + Reopened: &tBool, + }, + Deployment: &actions.Deploy{ + Created: &fBool, + }, + Comment: &actions.Comment{ + Created: &tBool, + Edited: &fBool, + }, + Schedule: &actions.Schedule{ + Run: &tBool, + }, + Delete: &actions.Delete{ + Branch: &tBool, + Tag: &fBool, + }, + } - e.SetPush(push) - e.SetPullRequest(pr) - e.SetDeployment(deploy) - e.SetComment(comment) - e.SetSchedule(schedule) - e.SetDelete(deletion) + e2 := &Events{ + Push: &actions.Push{ + Branch: &fBool, + Tag: &fBool, + }, + PullRequest: &actions.Pull{ + Opened: &fBool, + Synchronize: &fBool, + Edited: &tBool, + Reopened: &fBool, + }, + Deployment: &actions.Deploy{ + Created: &tBool, + }, + Comment: &actions.Comment{ + Created: &fBool, + Edited: &tBool, + }, + Schedule: &actions.Schedule{ + Run: &fBool, + }, + Delete: &actions.Delete{ + Branch: &fBool, + Tag: &tBool, + }, + } - return e + return e1, e2 } diff --git a/library/repo_test.go b/library/repo_test.go index e897142b..2f2684cd 100644 --- a/library/repo_test.go +++ b/library/repo_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/go-vela/types/constants" + "github.com/google/go-cmp/cmp" ) func TestLibrary_Repo_Environment(t *testing.T) { @@ -19,7 +20,7 @@ func TestLibrary_Repo_Environment(t *testing.T) { "VELA_REPO_ALLOW_PULL": "false", "VELA_REPO_ALLOW_PUSH": "true", "VELA_REPO_ALLOW_TAG": "false", - "VELA_REPO_ALLOW_EVENTS": "push,pull_request:opened,pull_request:synchronize,tag,delete:branch,delete:tag", + "VELA_REPO_ALLOW_EVENTS": "push,pull_request:opened,pull_request:synchronize,pull_request:reopened,tag,comment:created,schedule,delete:branch", "VELA_REPO_BRANCH": "main", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_BUILD_LIMIT": "10", @@ -40,7 +41,7 @@ func TestLibrary_Repo_Environment(t *testing.T) { "REPOSITORY_ALLOW_PULL": "false", "REPOSITORY_ALLOW_PUSH": "true", "REPOSITORY_ALLOW_TAG": "false", - "REPOSITORY_ALLOW_EVENTS": "push,pull_request:opened,pull_request:synchronize,tag,delete:branch,delete:tag", + "REPOSITORY_ALLOW_EVENTS": "push,pull_request:opened,pull_request:synchronize,pull_request:reopened,tag,comment:created,schedule,delete:branch", "REPOSITORY_BRANCH": "main", "REPOSITORY_CLONE": "https://github.com/github/octocat.git", "REPOSITORY_FULL_NAME": "github/octocat", @@ -56,8 +57,8 @@ func TestLibrary_Repo_Environment(t *testing.T) { // run test got := testRepo().Environment() - if !reflect.DeepEqual(got, want) { - t.Errorf("Environment is %v, want %v", got, want) + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("(Environment: -want +got):\n%s", diff) } } @@ -402,7 +403,7 @@ func TestLibrary_Repo_String(t *testing.T) { func testRepo() *Repo { r := new(Repo) - e := testEvents() + e, _ := testEvents() r.SetID(1) r.SetOrg("github") From f40578eb2dac13c44adc43835a63c75c411b2f12 Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Wed, 17 Jan 2024 11:17:17 -0500 Subject: [PATCH 08/11] enhance(env): add VELA_PULL_REQUEST_SOURCE and _TARGET to comment type (#346) --- .github/workflows/pr-title-validate.yml | 2 +- library/build.go | 2 ++ library/build_test.go | 13 +++++++++---- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pr-title-validate.yml b/.github/workflows/pr-title-validate.yml index f62dacf0..aa3588f6 100644 --- a/.github/workflows/pr-title-validate.yml +++ b/.github/workflows/pr-title-validate.yml @@ -12,6 +12,6 @@ jobs: runs-on: ubuntu-latest steps: - - name: validate + - name: validate title run: | echo "${{ github.event.pull_request.title }}" | grep -Eq '^(feat|fix|chore|refactor|enhance|test|docs)\(.*\):.*$' && (echo "Pass"; exit 0) || (echo "Incorrect Format. Please see https://go-vela.github.io/docs/community/contributing_guidelines/#development-workflow"; exit 1) \ No newline at end of file diff --git a/library/build.go b/library/build.go index 5b919dfb..3c872933 100644 --- a/library/build.go +++ b/library/build.go @@ -148,6 +148,8 @@ func (b *Build) Environment(workspace, channel string) map[string]string { envs["BUILD_PULL_REQUEST_NUMBER"] = number envs["VELA_BUILD_PULL_REQUEST"] = number envs["VELA_PULL_REQUEST"] = number + envs["VELA_PULL_REQUEST_SOURCE"] = b.GetHeadRef() + envs["VELA_PULL_REQUEST_TARGET"] = b.GetBaseRef() } // check if the Build event is deployment diff --git a/library/build_test.go b/library/build_test.go index bd0b265c..5c82c7a3 100644 --- a/library/build_test.go +++ b/library/build_test.go @@ -9,6 +9,7 @@ import ( "time" "github.com/go-vela/types/raw" + "github.com/google/go-cmp/cmp" ) func TestLibrary_Build_Duration(t *testing.T) { @@ -51,6 +52,8 @@ func TestLibrary_Build_Environment(t *testing.T) { _comment.SetEvent("comment") _comment.SetEventAction("created") _comment.SetRef("refs/pulls/1/head") + _comment.SetHeadRef("dev") + _comment.SetBaseRef("main") _deploy := testBuild() _deploy.SetEvent("deployment") @@ -146,7 +149,7 @@ func TestLibrary_Build_Environment(t *testing.T) { "VELA_BUILD_APPROVED_BY": "OctoCat", "VELA_BUILD_AUTHOR": "OctoKitty", "VELA_BUILD_AUTHOR_EMAIL": "OctoKitty@github.com", - "VELA_BUILD_BASE_REF": "", + "VELA_BUILD_BASE_REF": "main", "VELA_BUILD_BRANCH": "main", "VELA_BUILD_CHANNEL": "TODO", "VELA_BUILD_CLONE": "https://github.com/github/octocat.git", @@ -171,9 +174,11 @@ func TestLibrary_Build_Environment(t *testing.T) { "VELA_BUILD_TITLE": "push received from https://github.com/github/octocat", "VELA_BUILD_WORKSPACE": "TODO", "VELA_PULL_REQUEST": "1", + "VELA_PULL_REQUEST_SOURCE": "dev", + "VELA_PULL_REQUEST_TARGET": "main", "BUILD_AUTHOR": "OctoKitty", "BUILD_AUTHOR_EMAIL": "OctoKitty@github.com", - "BUILD_BASE_REF": "", + "BUILD_BASE_REF": "main", "BUILD_BRANCH": "main", "BUILD_CHANNEL": "TODO", "BUILD_CLONE": "https://github.com/github/octocat.git", @@ -439,8 +444,8 @@ func TestLibrary_Build_Environment(t *testing.T) { for _, test := range tests { got := test.build.Environment("TODO", "TODO") - if !reflect.DeepEqual(got, test.want) { - t.Errorf("Environment is %v, want %v", got, test.want) + if diff := cmp.Diff(test.want, got); diff != "" { + t.Errorf("(Environment: -want +got):\n%s", diff) } } } From 8a6ef2dcdbe20b4135bf2b3094e278c7a741755c Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Wed, 17 Jan 2024 15:01:59 -0500 Subject: [PATCH 09/11] fix(ci): title validator handle no parentheses + enforce whitespace (#347) --- .github/workflows/pr-title-validate.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr-title-validate.yml b/.github/workflows/pr-title-validate.yml index aa3588f6..223f7cdf 100644 --- a/.github/workflows/pr-title-validate.yml +++ b/.github/workflows/pr-title-validate.yml @@ -14,4 +14,4 @@ jobs: steps: - name: validate title run: | - echo "${{ github.event.pull_request.title }}" | grep -Eq '^(feat|fix|chore|refactor|enhance|test|docs)\(.*\):.*$' && (echo "Pass"; exit 0) || (echo "Incorrect Format. Please see https://go-vela.github.io/docs/community/contributing_guidelines/#development-workflow"; exit 1) \ No newline at end of file + echo "${{ github.event.pull_request.title }}" | grep -Eq '^(feat|fix|chore|refactor|enhance|test|docs)(\(.*\)|):\s.+$' && (echo "Pass"; exit 0) || (echo "Incorrect Format. Please see https://go-vela.github.io/docs/community/contributing_guidelines/#development-workflow"; exit 1) \ No newline at end of file From d058de26b401c176425f5265dd3b0ff77714e3f5 Mon Sep 17 00:00:00 2001 From: claire1618 <55173466+claire1618@users.noreply.github.com> Date: Mon, 22 Jan 2024 11:57:04 -0600 Subject: [PATCH 10/11] feat: remodling EventDelete to resemble EventTag (#348) * fix: enabling a delete event to be allowed * fix: remodling delete event to resemble tag * fix: making linter happy * fix: fixing tests * fix: changing some syntax in push.go * fix: changing some syntax in push.go * fix: making sure to only set BUILD_TAG for a delete:tag as opposed to all delete events * fix: making sure to only set BUILD_TAG for a delete:tag as opposed to all delete events * fix: clarifying comment --------- Co-authored-by: Claire.Nicholas --- constants/allow_events.go | 4 +- library/actions/comment.go | 3 +- library/actions/delete.go | 84 ------------------------- library/actions/delete_test.go | 108 --------------------------------- library/actions/deploy.go | 3 +- library/actions/pull.go | 3 +- library/actions/push.go | 64 ++++++++++++++++++- library/actions/push_test.go | 20 ++++-- library/actions/schedule.go | 3 +- library/build.go | 11 ++++ library/events.go | 38 ++---------- library/events_test.go | 39 ++++-------- webhook.go | 10 +-- webhook_test.go | 40 +++++------- 14 files changed, 131 insertions(+), 299 deletions(-) delete mode 100644 library/actions/delete.go delete mode 100644 library/actions/delete_test.go diff --git a/constants/allow_events.go b/constants/allow_events.go index 3e00f2d2..4a163a73 100644 --- a/constants/allow_events.go +++ b/constants/allow_events.go @@ -21,6 +21,6 @@ const ( AllowCommentCreate AllowCommentEdit AllowSchedule - AllowDeleteBranch - AllowDeleteTag + AllowPushDeleteBranch + AllowPushDeleteTag ) diff --git a/library/actions/comment.go b/library/actions/comment.go index c0e04298..499cfed6 100644 --- a/library/actions/comment.go +++ b/library/actions/comment.go @@ -1,6 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -// -//nolint:dupl // similar code to delete.go + package actions import "github.com/go-vela/types/constants" diff --git a/library/actions/delete.go b/library/actions/delete.go deleted file mode 100644 index fa88046d..00000000 --- a/library/actions/delete.go +++ /dev/null @@ -1,84 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// -//nolint:dupl // similar code to push.go -package actions - -import "github.com/go-vela/types/constants" - -// Delete is the library representation of the various actions associated -// with the delete event webhook from the SCM. -type Delete struct { - Branch *bool `json:"branch"` - Tag *bool `json:"tag"` -} - -// FromMask returns the Delete type resulting from the provided integer mask. -func (a *Delete) FromMask(mask int64) *Delete { - a.SetBranch(mask&constants.AllowDeleteBranch > 0) - a.SetTag(mask&constants.AllowDeleteTag > 0) - - return a -} - -// ToMask returns the integer mask of the values for the Delete set. -func (a *Delete) ToMask() int64 { - mask := int64(0) - - if a.GetBranch() { - mask = mask | constants.AllowDeleteBranch - } - - if a.GetTag() { - mask = mask | constants.AllowDeleteTag - } - - return mask -} - -// GetBranch returns the Branch field from the provided Delete. If the object is nil, -// or the field within the object is nil, it returns the zero value instead. -func (a *Delete) GetBranch() bool { - // return zero value if Delete type or Branch field is nil - if a == nil || a.Branch == nil { - return false - } - - return *a.Branch -} - -// GetTag returns the Tag field from the provided Delete. If the object is nil, -// or the field within the object is nil, it returns the zero value instead. -func (a *Delete) GetTag() bool { - // return zero value if Delete type or Tag field is nil - if a == nil || a.Tag == nil { - return false - } - - return *a.Tag -} - -// SetBranch sets the Delete Branch field. -// -// When the provided Delete type is nil, it -// will set nothing and immediately return. -func (a *Delete) SetBranch(v bool) { - // return if Events type is nil - if a == nil { - return - } - - a.Branch = &v -} - -// SetTag sets the Delete Tag field. -// -// When the provided Delete type is nil, it -// will set nothing and immediately return. -func (a *Delete) SetTag(v bool) { - // return if Events type is nil - if a == nil { - return - } - - a.Tag = &v -} diff --git a/library/actions/delete_test.go b/library/actions/delete_test.go deleted file mode 100644 index 3c7cd539..00000000 --- a/library/actions/delete_test.go +++ /dev/null @@ -1,108 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - -package actions - -import ( - "reflect" - "testing" - - "github.com/go-vela/types/constants" -) - -func TestLibrary_Delete_Getters(t *testing.T) { - // setup tests - tests := []struct { - actions *Delete - want *Delete - }{ - { - actions: testDelete(), - want: testDelete(), - }, - { - actions: new(Delete), - want: new(Delete), - }, - } - - // run tests - for _, test := range tests { - if test.actions.GetBranch() != test.want.GetBranch() { - t.Errorf("GetBranch is %v, want %v", test.actions.GetBranch(), test.want.GetBranch()) - } - - if test.actions.GetTag() != test.want.GetTag() { - t.Errorf("GetTag is %v, want %v", test.actions.GetTag(), test.want.GetTag()) - } - } -} - -func TestLibrary_Delete_Setters(t *testing.T) { - // setup types - var a *Delete - - // setup tests - tests := []struct { - actions *Delete - want *Delete - }{ - { - actions: testDelete(), - want: testDelete(), - }, - { - actions: a, - want: new(Delete), - }, - } - - // run tests - for _, test := range tests { - test.actions.SetBranch(test.want.GetBranch()) - test.actions.SetTag(test.want.GetTag()) - - if test.actions.GetBranch() != test.want.GetBranch() { - t.Errorf("SetBranch is %v, want %v", test.actions.GetBranch(), test.want.GetBranch()) - } - - if test.actions.GetTag() != test.want.GetTag() { - t.Errorf("SetTag is %v, want %v", test.actions.GetTag(), test.want.GetTag()) - } - } -} - -func TestLibrary_Delete_FromMask(t *testing.T) { - // setup types - mask := testMask() - - want := testDelete() - - // run test - got := new(Delete).FromMask(mask) - - if !reflect.DeepEqual(got, want) { - t.Errorf("FromMask is %v, want %v", got, want) - } -} - -func TestLibrary_Delete_ToMask(t *testing.T) { - // setup types - actions := testDelete() - - want := int64(constants.AllowDeleteBranch | constants.AllowDeleteTag) - - // run test - got := actions.ToMask() - - if want != got { - t.Errorf("ToMask is %v, want %v", got, want) - } -} - -func testDelete() *Delete { - deletion := new(Delete) - deletion.SetBranch(true) - deletion.SetTag(true) - - return deletion -} diff --git a/library/actions/deploy.go b/library/actions/deploy.go index e2b663bf..d4970611 100644 --- a/library/actions/deploy.go +++ b/library/actions/deploy.go @@ -1,5 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 - +// +//nolint:dupl // similar code to schedule.go package actions import "github.com/go-vela/types/constants" diff --git a/library/actions/pull.go b/library/actions/pull.go index 9a134a6f..609c6248 100644 --- a/library/actions/pull.go +++ b/library/actions/pull.go @@ -1,5 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 - +// +//nolint:dupl // similar code to push.go package actions import "github.com/go-vela/types/constants" diff --git a/library/actions/push.go b/library/actions/push.go index 9853f454..ed19c48f 100644 --- a/library/actions/push.go +++ b/library/actions/push.go @@ -8,14 +8,18 @@ import "github.com/go-vela/types/constants" // Push is the library representation of the various actions associated // with the push event webhook from the SCM. type Push struct { - Branch *bool `json:"branch"` - Tag *bool `json:"tag"` + Branch *bool `json:"branch"` + Tag *bool `json:"tag"` + DeleteBranch *bool `json:"delete_branch"` + DeleteTag *bool `json:"delete_tag"` } // FromMask returns the Push type resulting from the provided integer mask. func (a *Push) FromMask(mask int64) *Push { a.SetBranch(mask&constants.AllowPushBranch > 0) a.SetTag(mask&constants.AllowPushTag > 0) + a.SetDeleteBranch(mask&constants.AllowPushDeleteBranch > 0) + a.SetDeleteTag(mask&constants.AllowPushDeleteTag > 0) return a } @@ -32,6 +36,14 @@ func (a *Push) ToMask() int64 { mask = mask | constants.AllowPushTag } + if a.GetDeleteBranch() { + mask = mask | constants.AllowPushDeleteBranch + } + + if a.GetDeleteTag() { + mask = mask | constants.AllowPushDeleteTag + } + return mask } @@ -57,6 +69,28 @@ func (a *Push) GetTag() bool { return *a.Tag } +// GetDeleteBranch returns the DeleteBranch field from the provided Push. If the object is nil, +// or the field within the object is nil, it returns the zero value instead. +func (a *Push) GetDeleteBranch() bool { + // return zero value if Push type or DeleteBranch field is nil + if a == nil || a.DeleteBranch == nil { + return false + } + + return *a.DeleteBranch +} + +// GetDeleteTag returns the DeleteTag field from the provided Push. If the object is nil, +// or the field within the object is nil, it returns the zero value instead. +func (a *Push) GetDeleteTag() bool { + // return zero value if Push type or DeleteTag field is nil + if a == nil || a.DeleteTag == nil { + return false + } + + return *a.DeleteTag +} + // SetBranch sets the Push Branch field. // // When the provided Push type is nil, it @@ -82,3 +116,29 @@ func (a *Push) SetTag(v bool) { a.Tag = &v } + +// SetDeleteBranch sets the Push DeleteBranch field. +// +// When the provided Push type is nil, it +// will set nothing and immediately return. +func (a *Push) SetDeleteBranch(v bool) { + // return if Events type is nil + if a == nil { + return + } + + a.DeleteBranch = &v +} + +// SetDeleteTag sets the Push DeleteTag field. +// +// When the provided Push type is nil, it +// will set nothing and immediately return. +func (a *Push) SetDeleteTag(v bool) { + // return if Events type is nil + if a == nil { + return + } + + a.DeleteTag = &v +} diff --git a/library/actions/push_test.go b/library/actions/push_test.go index f8cd4c3b..330444ba 100644 --- a/library/actions/push_test.go +++ b/library/actions/push_test.go @@ -60,6 +60,8 @@ func TestLibrary_Push_Setters(t *testing.T) { for _, test := range tests { test.actions.SetBranch(test.want.GetBranch()) test.actions.SetTag(test.want.GetTag()) + test.actions.SetDeleteBranch(test.want.GetDeleteBranch()) + test.actions.SetDeleteTag(test.want.GetDeleteTag()) if test.actions.GetBranch() != test.want.GetBranch() { t.Errorf("SetBranch is %v, want %v", test.actions.GetBranch(), test.want.GetBranch()) @@ -68,6 +70,14 @@ func TestLibrary_Push_Setters(t *testing.T) { if test.actions.GetTag() != test.want.GetTag() { t.Errorf("SetTag is %v, want %v", test.actions.GetTag(), test.want.GetTag()) } + + if test.actions.GetDeleteBranch() != test.want.GetDeleteBranch() { + t.Errorf("SetDeleteBranch is %v, want %v", test.actions.GetDeleteBranch(), test.want.GetDeleteBranch()) + } + + if test.actions.GetDeleteTag() != test.want.GetDeleteTag() { + t.Errorf("SetDeleteTag is %v, want %v", test.actions.GetDeleteTag(), test.want.GetDeleteTag()) + } } } @@ -89,7 +99,7 @@ func TestLibrary_Push_ToMask(t *testing.T) { // setup types actions := testPush() - want := int64(constants.AllowPushBranch | constants.AllowPushTag) + want := int64(constants.AllowPushBranch | constants.AllowPushTag | constants.AllowPushDeleteBranch | constants.AllowPushDeleteTag) // run test got := actions.ToMask() @@ -103,6 +113,8 @@ func testPush() *Push { push := new(Push) push.SetBranch(true) push.SetTag(true) + push.SetDeleteBranch(true) + push.SetDeleteTag(true) return push } @@ -111,13 +123,13 @@ func testMask() int64 { return int64( constants.AllowPushBranch | constants.AllowPushTag | + constants.AllowPushDeleteBranch | + constants.AllowPushDeleteTag | constants.AllowPullOpen | constants.AllowPullSync | constants.AllowPullReopen | constants.AllowDeployCreate | constants.AllowCommentCreate | - constants.AllowSchedule | - constants.AllowDeleteBranch | - constants.AllowDeleteTag, + constants.AllowSchedule, ) } diff --git a/library/actions/schedule.go b/library/actions/schedule.go index a3ca9d36..634e638f 100644 --- a/library/actions/schedule.go +++ b/library/actions/schedule.go @@ -1,5 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 - +// +//nolint:dupl // similar code to deploy.go package actions import "github.com/go-vela/types/constants" diff --git a/library/build.go b/library/build.go index 3c872933..2ca9c368 100644 --- a/library/build.go +++ b/library/build.go @@ -202,6 +202,17 @@ func (b *Build) Environment(workspace, channel string) map[string]string { envs["VELA_BUILD_TAG"] = tag } + // check if the Build event is delete:tag + if strings.EqualFold(b.GetEvent(), constants.EventDelete) && strings.EqualFold(b.GetEventAction(), constants.ActionTag) { + // capture the tag reference, which has been stored in the Branch variable due to issues that arose + // when the Ref is set to the deleted tag + tag := b.GetBranch() + + // add the tag reference to the list + envs["BUILD_TAG"] = tag + envs["VELA_BUILD_TAG"] = tag + } + return envs } diff --git a/library/events.go b/library/events.go index fbcb23d0..88074d80 100644 --- a/library/events.go +++ b/library/events.go @@ -15,7 +15,6 @@ type Events struct { Deployment *actions.Deploy `json:"deployment"` Comment *actions.Comment `json:"comment"` Schedule *actions.Schedule `json:"schedule"` - Delete *actions.Delete `json:"delete"` } // NewEventsFromMask is an instatiation function for the Events type that @@ -26,7 +25,6 @@ func NewEventsFromMask(mask int64) *Events { deployActions := new(actions.Deploy).FromMask(mask) commentActions := new(actions.Comment).FromMask(mask) scheduleActions := new(actions.Schedule).FromMask(mask) - deleteActions := new(actions.Delete).FromMask(mask) e := new(Events) @@ -35,7 +33,6 @@ func NewEventsFromMask(mask int64) *Events { e.SetDeployment(deployActions) e.SetComment(commentActions) e.SetSchedule(scheduleActions) - e.SetDelete(deleteActions) return e } @@ -72,9 +69,9 @@ func (e *Events) Allowed(event, action string) bool { case constants.EventSchedule: allowed = e.GetSchedule().GetRun() case constants.EventDelete + ":" + constants.ActionBranch: - allowed = e.GetDelete().GetBranch() + allowed = e.GetPush().GetDeleteBranch() case constants.EventDelete + ":" + constants.ActionTag: - allowed = e.GetDelete().GetTag() + allowed = e.GetPush().GetDeleteTag() } return allowed @@ -125,11 +122,11 @@ func (e *Events) List() []string { eventSlice = append(eventSlice, constants.EventSchedule) } - if e.GetDelete().GetBranch() { + if e.GetPush().GetDeleteBranch() { eventSlice = append(eventSlice, constants.EventDelete+":"+constants.ActionBranch) } - if e.GetDelete().GetTag() { + if e.GetPush().GetDeleteTag() { eventSlice = append(eventSlice, constants.EventDelete+":"+constants.ActionTag) } @@ -143,8 +140,7 @@ func (e *Events) ToDatabase() int64 { e.GetPullRequest().ToMask() | e.GetComment().ToMask() | e.GetDeployment().ToMask() | - e.GetSchedule().ToMask() | - e.GetDelete().ToMask() + e.GetSchedule().ToMask() } // GetPush returns the Push field from the provided Events. If the object is nil, @@ -202,17 +198,6 @@ func (e *Events) GetSchedule() *actions.Schedule { return e.Schedule } -// GetDelete returns the Delete field from the provided Events. If the object is nil, -// or the field within the object is nil, it returns the zero value instead. -func (e *Events) GetDelete() *actions.Delete { - // return zero value if Events type or Comment field is nil - if e == nil || e.Delete == nil { - return new(actions.Delete) - } - - return e.Delete -} - // SetPush sets the Events Push field. // // When the provided Events type is nil, it @@ -277,16 +262,3 @@ func (e *Events) SetSchedule(v *actions.Schedule) { e.Schedule = v } - -// SetDelete sets the Events Delete field. -// -// When the provided Events type is nil, it -// will set nothing and immediately return. -func (e *Events) SetDelete(v *actions.Delete) { - // return if Events type is nil - if e == nil { - return - } - - e.Delete = v -} diff --git a/library/events_test.go b/library/events_test.go index c1bafe94..a26cc4dc 100644 --- a/library/events_test.go +++ b/library/events_test.go @@ -55,10 +55,6 @@ func TestLibrary_Events_Getters(t *testing.T) { if !reflect.DeepEqual(test.events.GetSchedule(), test.want.GetSchedule()) { t.Errorf("GetSchedule is %v, want %v", test.events.GetSchedule(), test.want.GetSchedule()) } - - if !reflect.DeepEqual(test.events.GetDelete(), test.want.GetDelete()) { - t.Errorf("GetDelete is %v, want %v", test.events.GetDelete(), test.want.GetDelete()) - } } } @@ -94,7 +90,6 @@ func TestLibrary_Events_Setters(t *testing.T) { test.events.SetDeployment(test.want.GetDeployment()) test.events.SetComment(test.want.GetComment()) test.events.SetSchedule(test.want.GetSchedule()) - test.events.SetDelete(test.want.GetDelete()) if !reflect.DeepEqual(test.events.GetPush(), test.want.GetPush()) { t.Errorf("SetPush is %v, want %v", test.events.GetPush(), test.want.GetPush()) @@ -115,10 +110,6 @@ func TestLibrary_Events_Setters(t *testing.T) { if !reflect.DeepEqual(test.events.GetSchedule(), test.want.GetSchedule()) { t.Errorf("SetSchedule is %v, want %v", test.events.GetSchedule(), test.want.GetSchedule()) } - - if !reflect.DeepEqual(test.events.GetDelete(), test.want.GetDelete()) { - t.Errorf("SetDelete is %v, want %v", test.events.GetDelete(), test.want.GetDelete()) - } } } @@ -163,19 +154,19 @@ func TestLibrary_Events_NewEventsFromMask_ToDatabase(t *testing.T) { maskOne := int64( constants.AllowPushBranch | constants.AllowPushTag | + constants.AllowPushDeleteBranch | constants.AllowPullOpen | constants.AllowPullSync | constants.AllowPullReopen | constants.AllowCommentCreate | - constants.AllowSchedule | - constants.AllowDeleteBranch, + constants.AllowSchedule, ) maskTwo := int64( - constants.AllowPullEdit | + constants.AllowPushDeleteTag | + constants.AllowPullEdit | constants.AllowCommentEdit | - constants.AllowDeployCreate | - constants.AllowDeleteTag, + constants.AllowDeployCreate, ) wantOne, wantTwo := testEvents() @@ -248,8 +239,10 @@ func testEvents() (*Events, *Events) { e1 := &Events{ Push: &actions.Push{ - Branch: &tBool, - Tag: &tBool, + Branch: &tBool, + Tag: &tBool, + DeleteBranch: &tBool, + DeleteTag: &fBool, }, PullRequest: &actions.Pull{ Opened: &tBool, @@ -267,16 +260,14 @@ func testEvents() (*Events, *Events) { Schedule: &actions.Schedule{ Run: &tBool, }, - Delete: &actions.Delete{ - Branch: &tBool, - Tag: &fBool, - }, } e2 := &Events{ Push: &actions.Push{ - Branch: &fBool, - Tag: &fBool, + Branch: &fBool, + Tag: &fBool, + DeleteBranch: &fBool, + DeleteTag: &tBool, }, PullRequest: &actions.Pull{ Opened: &fBool, @@ -294,10 +285,6 @@ func testEvents() (*Events, *Events) { Schedule: &actions.Schedule{ Run: &fBool, }, - Delete: &actions.Delete{ - Branch: &fBool, - Tag: &tBool, - }, } return e1, e2 diff --git a/webhook.go b/webhook.go index d4802cfa..1941e38f 100644 --- a/webhook.go +++ b/webhook.go @@ -10,8 +10,7 @@ import ( ) var ( - skipDeleteEventMsg = "tag/branch delete event" - skipDirectiveMsg = "skip ci directive found in commit title/message" + skipDirectiveMsg = "skip ci directive found in commit title/message" ) // PullRequest defines the data pulled from PRs while @@ -39,13 +38,6 @@ type Webhook struct { func (w *Webhook) ShouldSkip() (bool, string) { // push or tag event if strings.EqualFold(constants.EventPush, w.Build.GetEvent()) || strings.EqualFold(constants.EventTag, w.Build.GetEvent()) { - // the head commit will return null in the hook - // payload from the scm when the event is - // associated with a branch/tag delete - if len(w.Build.GetCommit()) == 0 { - return true, skipDeleteEventMsg - } - // check for skip ci directive in message or title if hasSkipDirective(w.Build.GetMessage()) || hasSkipDirective(w.Build.GetTitle()) { diff --git a/webhook_test.go b/webhook_test.go index 061ad8a4..7beb39be 100644 --- a/webhook_test.go +++ b/webhook_test.go @@ -17,72 +17,62 @@ func TestWebhook_ShouldSkip(t *testing.T) { wantString string }{ { - &Webhook{Build: testPushBuild("testing [SKIP CI]", "", constants.EventPush, true)}, + &Webhook{Build: testPushBuild("testing [SKIP CI]", "", constants.EventPush)}, true, skipDirectiveMsg, }, { - &Webhook{Build: testPushBuild("testing", "wip [ci skip]", constants.EventPush, true)}, + &Webhook{Build: testPushBuild("testing", "wip [ci skip]", constants.EventPush)}, true, skipDirectiveMsg, }, { - &Webhook{Build: testPushBuild("testing [skip VELA]", "", constants.EventPush, true)}, + &Webhook{Build: testPushBuild("testing [skip VELA]", "", constants.EventPush)}, true, skipDirectiveMsg, }, { - &Webhook{Build: testPushBuild("testing", "wip [vela skip]", constants.EventPush, true)}, + &Webhook{Build: testPushBuild("testing", "wip [vela skip]", constants.EventPush)}, true, skipDirectiveMsg, }, { - &Webhook{Build: testPushBuild("testing ***NO_CI*** ok", "nothing", constants.EventPush, true)}, + &Webhook{Build: testPushBuild("testing ***NO_CI*** ok", "nothing", constants.EventPush)}, true, skipDirectiveMsg, }, { - &Webhook{Build: testPushBuild("testing ok", "nothing", constants.EventPush, false)}, - true, - skipDeleteEventMsg, - }, - { - &Webhook{Build: testPushBuild("testing ok", "nothing", constants.EventPush, true)}, + &Webhook{Build: testPushBuild("testing ok", "nothing", constants.EventPush)}, false, "", }, { - &Webhook{Build: testPushBuild("testing [SKIP CI]", "", constants.EventTag, true)}, + &Webhook{Build: testPushBuild("testing [SKIP CI]", "", constants.EventTag)}, true, skipDirectiveMsg, }, { - &Webhook{Build: testPushBuild("testing", "wip [ci skip]", constants.EventTag, true)}, + &Webhook{Build: testPushBuild("testing", "wip [ci skip]", constants.EventTag)}, true, skipDirectiveMsg, }, { - &Webhook{Build: testPushBuild("testing [skip VELA]", "", constants.EventTag, true)}, + &Webhook{Build: testPushBuild("testing [skip VELA]", "", constants.EventTag)}, true, skipDirectiveMsg, }, { - &Webhook{Build: testPushBuild("testing", "wip [vela skip]", constants.EventTag, true)}, + &Webhook{Build: testPushBuild("testing", "wip [vela skip]", constants.EventTag)}, true, skipDirectiveMsg, }, { - &Webhook{Build: testPushBuild("testing ***NO_CI*** ok", "nothing", constants.EventTag, true)}, + &Webhook{Build: testPushBuild("testing ***NO_CI*** ok", "nothing", constants.EventTag)}, true, skipDirectiveMsg, }, { - &Webhook{Build: testPushBuild("testing ok", "nothing", constants.EventTag, false)}, - true, - skipDeleteEventMsg, - }, - { - &Webhook{Build: testPushBuild("testing ok", "nothing", constants.EventTag, true)}, + &Webhook{Build: testPushBuild("testing ok", "nothing", constants.EventTag)}, false, "", }, @@ -102,7 +92,7 @@ func TestWebhook_ShouldSkip(t *testing.T) { } } -func testPushBuild(message, title, event string, hasCommit bool) *library.Build { +func testPushBuild(message, title, event string) *library.Build { b := new(library.Build) b.SetEvent(event) @@ -115,9 +105,7 @@ func testPushBuild(message, title, event string, hasCommit bool) *library.Build b.SetTitle(title) } - if hasCommit { - b.SetCommit("deadbeef") - } + b.SetCommit("deadbeef") return b } From 1625a79ce6fbc1ae48b6c72fe8054c61cad78087 Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Thu, 25 Jan 2024 13:21:49 -0500 Subject: [PATCH 11/11] chore(deps): bulk update deps (#349) --- .github/workflows/codeql-analysis.yml | 6 +++--- .github/workflows/reviewdog.yml | 8 ++++---- .github/workflows/schema.yml | 2 +- .github/workflows/test.yml | 2 +- .github/workflows/validate.yml | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 3dd5aac1..cb770451 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -39,7 +39,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@74483a38d39275f33fcff5f35b679b5ca4a26a99 # v2 + uses: github/codeql-action/init@0b21cf2492b6b02c465a3e5d7c473717ad7721ba # v3 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -50,7 +50,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@74483a38d39275f33fcff5f35b679b5ca4a26a99 # v2 + uses: github/codeql-action/autobuild@0b21cf2492b6b02c465a3e5d7c473717ad7721ba # v3 # ℹī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -64,4 +64,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@74483a38d39275f33fcff5f35b679b5ca4a26a99 # v2 + uses: github/codeql-action/analyze@0b21cf2492b6b02c465a3e5d7c473717ad7721ba # v3 diff --git a/.github/workflows/reviewdog.yml b/.github/workflows/reviewdog.yml index 475efe79..7e131da2 100644 --- a/.github/workflows/reviewdog.yml +++ b/.github/workflows/reviewdog.yml @@ -15,7 +15,7 @@ jobs: uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 - name: install go - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4 + uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5 with: # use version from go.mod file go-version-file: 'go.mod' @@ -23,7 +23,7 @@ jobs: check-latest: true - name: golangci-lint - uses: reviewdog/action-golangci-lint@94d61e3205b61acf4ddabfeb13c5f8a13eb4167b # v2 + uses: reviewdog/action-golangci-lint@f016e796a429b33094d0da6e86af3fa5479afe65 # v2 with: github_token: ${{ secrets.github_token }} golangci_lint_flags: "--config=.golangci.yml" @@ -39,7 +39,7 @@ jobs: uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 - name: install go - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4 + uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5 with: # use version from go.mod file go-version-file: 'go.mod' @@ -47,7 +47,7 @@ jobs: check-latest: true - name: golangci-lint - uses: reviewdog/action-golangci-lint@94d61e3205b61acf4ddabfeb13c5f8a13eb4167b # v2 + uses: reviewdog/action-golangci-lint@f016e796a429b33094d0da6e86af3fa5479afe65 # v2 with: github_token: ${{ secrets.github_token }} golangci_lint_flags: "--config=.golangci.yml" diff --git a/.github/workflows/schema.yml b/.github/workflows/schema.yml index cdeb0b1f..7112d3ee 100644 --- a/.github/workflows/schema.yml +++ b/.github/workflows/schema.yml @@ -16,7 +16,7 @@ jobs: uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 - name: install go - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4 + uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5 with: # use version from go.mod file go-version-file: 'go.mod' diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8e0021db..03244cd1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,7 +17,7 @@ jobs: uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 - name: install go - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4 + uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5 with: # use version from go.mod file go-version-file: 'go.mod' diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 72ad5d8a..bc6cdf74 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -17,7 +17,7 @@ jobs: uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 - name: install go - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4 + uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5 with: # use version from go.mod file go-version-file: 'go.mod'