From 07949d4f16c6e6f09630dd73019a129b99448623 Mon Sep 17 00:00:00 2001 From: David May <49894298+wass3rw3rk@users.noreply.github.com> Date: Thu, 29 Feb 2024 12:07:21 -0600 Subject: [PATCH 01/71] enhance(ci): keep clone image updated via renovate (#1072) this should help us keep the clone image up-to-date --- .github/renovate.json | 12 ++++++++++++ cmd/vela-server/main.go | 3 ++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/.github/renovate.json b/.github/renovate.json index b24babc90..35014f984 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -2,5 +2,17 @@ "$schema": "https://docs.renovatebot.com/renovate-schema.json", "extends": [ "local>go-vela/renovate-config" + ], + "regexManagers": [ + { + "description": "Update docker images in go files", + "fileMatch": [ + "^.*\\.go$" + ], + "matchStrings": [ + "\\/\\/ renovate: image=(?.*?)\\s+?.*[:|=]\\s+\"(?.*)\"\\,?" + ], + "versioningTemplate": "docker" + } ] } diff --git a/cmd/vela-server/main.go b/cmd/vela-server/main.go index c2875409e..715c821a2 100644 --- a/cmd/vela-server/main.go +++ b/cmd/vela-server/main.go @@ -88,7 +88,8 @@ func main() { EnvVars: []string{"VELA_CLONE_IMAGE"}, Name: "clone-image", Usage: "the clone image to use for the injected clone step", - Value: "target/vela-git:v0.8.0@sha256:02de004ae9dbf184c70039cb9ce431c31d6e7580eb9e6ec64a97ebf108aa65cb", + // renovate: image=target/vela-git + Value: "target/vela-git:v0.8.0@sha256:02de004ae9dbf184c70039cb9ce431c31d6e7580eb9e6ec64a97ebf108aa65cb", }, &cli.StringSliceFlag{ EnvVars: []string{"VELA_REPO_ALLOWLIST"}, From 0563995ec903dcb9de81f30ab52c8a08701fea9a Mon Sep 17 00:00:00 2001 From: David May <49894298+wass3rw3rk@users.noreply.github.com> Date: Thu, 29 Feb 2024 13:37:37 -0600 Subject: [PATCH 02/71] fix(renovate): add datasourceTemplate (#1074) closes https://github.com/go-vela/server/issues/254 --- .github/renovate.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/renovate.json b/.github/renovate.json index 35014f984..6d795ad41 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -12,7 +12,8 @@ "matchStrings": [ "\\/\\/ renovate: image=(?.*?)\\s+?.*[:|=]\\s+\"(?.*)\"\\,?" ], - "versioningTemplate": "docker" + "versioningTemplate": "docker", + "datasourceTemplate": "docker" } ] } From 4a26eb417b62d47548e8319368c7e74a7f748c0d Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Tue, 5 Mar 2024 12:32:31 -0500 Subject: [PATCH 03/71] fix(build-approval): correct approved_by and disallow self-approval (#1075) --- api/build/approve.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/api/build/approve.go b/api/build/approve.go index 84aedb418..037160282 100644 --- a/api/build/approve.go +++ b/api/build/approve.go @@ -86,6 +86,7 @@ func ApproveBuild(c *gin.Context) { "user": u.GetName(), }) + // verify build is in correct status if !strings.EqualFold(b.GetStatus(), constants.StatusPendingApproval) { retErr := fmt.Errorf("unable to approve build %s/%d: build not in pending approval state", r.GetFullName(), b.GetNumber()) util.HandleError(c, http.StatusBadRequest, retErr) @@ -93,10 +94,18 @@ func ApproveBuild(c *gin.Context) { return } + // verify user is not the sender of the build + if strings.EqualFold(u.GetName(), b.GetSender()) { + retErr := fmt.Errorf("unable to approve build %s/%d: approver cannot be the sender of the build", r.GetFullName(), b.GetNumber()) + util.HandleError(c, http.StatusBadRequest, retErr) + + return + } + logger.Debugf("user %s approved build %s/%d for execution", u.GetName(), r.GetFullName(), b.GetNumber()) // send API call to capture the repo owner - u, err := database.FromContext(c).GetUser(ctx, r.GetUserID()) + owner, err := database.FromContext(c).GetUser(ctx, r.GetUserID()) if err != nil { retErr := fmt.Errorf("unable to get owner for %s: %w", r.GetFullName(), err) @@ -105,6 +114,7 @@ func ApproveBuild(c *gin.Context) { return } + // set fields b.SetStatus(constants.StatusPending) b.SetApprovedAt(time.Now().Unix()) b.SetApprovedBy(u.GetName()) @@ -122,7 +132,7 @@ func ApproveBuild(c *gin.Context) { database.FromContext(c), b, r, - u, + owner, b.GetHost(), ) From a645c822da1d91e1f4159b69685224232683bebb Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Tue, 12 Mar 2024 14:42:44 -0400 Subject: [PATCH 04/71] Merge pull request from GHSA-69p4-j5v5-x234 * fix(secrets): add new field allow_substitution * pull in types and integration testing --- api/secret/create.go | 8 ++++ api/secret/update.go | 4 ++ database/integration_test.go | 3 ++ database/secret/create_test.go | 18 ++++----- database/secret/get_org_test.go | 4 +- database/secret/get_repo_test.go | 4 +- database/secret/get_team_test.go | 4 +- database/secret/get_test.go | 4 +- database/secret/list_org_test.go | 6 +-- database/secret/list_repo_test.go | 6 +-- database/secret/list_team_test.go | 6 +-- database/secret/list_test.go | 6 +-- database/secret/secret_test.go | 31 ++++++++-------- database/secret/table.go | 62 ++++++++++++++++--------------- database/secret/update_test.go | 18 ++++----- go.mod | 2 +- go.sum | 4 +- mock/server/secret.go | 1 + secret/native/create_test.go | 4 ++ secret/native/get_test.go | 1 + secret/native/list_test.go | 2 + secret/native/update.go | 5 +++ secret/native/update_test.go | 2 + 23 files changed, 119 insertions(+), 86 deletions(-) diff --git a/api/secret/create.go b/api/secret/create.go index 8423bc8cb..3845f4b7c 100644 --- a/api/secret/create.go +++ b/api/secret/create.go @@ -234,6 +234,14 @@ func CreateSecret(c *gin.Context) { input.SetAllowCommand(true) } + // default to not allow substitution for shared secrets + if strings.EqualFold(input.GetType(), constants.SecretShared) && input.AllowSubstitution == nil { + input.SetAllowSubstitution(false) + input.SetAllowCommand(false) + } else if input.AllowSubstitution == nil { + input.SetAllowSubstitution(true) + } + // check if secret is a shared secret if strings.EqualFold(t, constants.SecretShared) { // update the team instead of repo diff --git a/api/secret/update.go b/api/secret/update.go index 86870d03d..98c78e031 100644 --- a/api/secret/update.go +++ b/api/secret/update.go @@ -152,6 +152,10 @@ func UpdateSecret(c *gin.Context) { input.SetAllowCommand(input.GetAllowCommand()) } + if input.AllowSubstitution != nil { + input.SetAllowSubstitution(input.GetAllowSubstitution()) + } + // check if secret is a shared secret if strings.EqualFold(t, constants.SecretShared) { // update the team instead of repo diff --git a/database/integration_test.go b/database/integration_test.go index 16ca38062..585cc4134 100644 --- a/database/integration_test.go +++ b/database/integration_test.go @@ -2314,6 +2314,7 @@ func newResources() *Resources { secretOrg.SetEvents([]string{"push", "tag", "deployment"}) secretOrg.SetAllowEvents(library.NewEventsFromMask(1)) secretOrg.SetAllowCommand(true) + secretOrg.SetAllowSubstitution(true) secretOrg.SetCreatedAt(time.Now().UTC().Unix()) secretOrg.SetCreatedBy("octocat") secretOrg.SetUpdatedAt(time.Now().Add(time.Hour * 1).UTC().Unix()) @@ -2331,6 +2332,7 @@ func newResources() *Resources { secretRepo.SetEvents([]string{"push", "tag", "deployment"}) secretRepo.SetAllowEvents(library.NewEventsFromMask(1)) secretRepo.SetAllowCommand(true) + secretRepo.SetAllowSubstitution(true) secretRepo.SetCreatedAt(time.Now().UTC().Unix()) secretRepo.SetCreatedBy("octocat") secretRepo.SetUpdatedAt(time.Now().Add(time.Hour * 1).UTC().Unix()) @@ -2347,6 +2349,7 @@ func newResources() *Resources { secretShared.SetImages([]string{"alpine"}) secretShared.SetEvents([]string{"push", "tag", "deployment"}) secretShared.SetAllowCommand(true) + secretShared.SetAllowSubstitution(true) secretShared.SetAllowEvents(library.NewEventsFromMask(1)) secretShared.SetCreatedAt(time.Now().UTC().Unix()) secretShared.SetCreatedBy("octocat") diff --git a/database/secret/create_test.go b/database/secret/create_test.go index b5d0c3ba5..eeec4c363 100644 --- a/database/secret/create_test.go +++ b/database/secret/create_test.go @@ -60,23 +60,23 @@ func TestSecret_Engine_CreateSecret(t *testing.T) { // ensure the mock expects the repo secrets query _mock.ExpectQuery(`INSERT INTO "secrets" -("org","repo","team","name","value","type","images","events","allow_events","allow_command","created_at","created_by","updated_at","updated_by","id") -VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15) RETURNING "id"`). - WithArgs("foo", "bar", nil, "baz", AnyArgument{}, "repo", nil, nil, 1, false, 1, "user", 1, "user2", 1). +("org","repo","team","name","value","type","images","events","allow_events","allow_command","allow_substitution","created_at","created_by","updated_at","updated_by","id") +VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16) RETURNING "id"`). + WithArgs("foo", "bar", nil, "baz", AnyArgument{}, "repo", nil, nil, 1, false, false, 1, "user", 1, "user2", 1). WillReturnRows(_rows) // ensure the mock expects the org secrets query _mock.ExpectQuery(`INSERT INTO "secrets" -("org","repo","team","name","value","type","images","events","allow_events","allow_command","created_at","created_by","updated_at","updated_by","id") -VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15) RETURNING "id"`). - WithArgs("foo", "*", nil, "bar", AnyArgument{}, "org", nil, nil, 3, false, 1, "user", 1, "user2", 2). +("org","repo","team","name","value","type","images","events","allow_events","allow_command","allow_substitution","created_at","created_by","updated_at","updated_by","id") +VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16) RETURNING "id"`). + WithArgs("foo", "*", nil, "bar", AnyArgument{}, "org", nil, nil, 3, false, false, 1, "user", 1, "user2", 2). WillReturnRows(_rows) // ensure the mock expects the shared secrets query _mock.ExpectQuery(`INSERT INTO "secrets" -("org","repo","team","name","value","type","images","events","allow_events","allow_command","created_at","created_by","updated_at","updated_by","id") -VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15) RETURNING "id"`). - WithArgs("foo", nil, "bar", "baz", AnyArgument{}, "shared", nil, nil, 1, false, 1, "user", 1, "user2", 3). +("org","repo","team","name","value","type","images","events","allow_events","allow_command","allow_substitution","created_at","created_by","updated_at","updated_by","id") +VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16) RETURNING "id"`). + WithArgs("foo", nil, "bar", "baz", AnyArgument{}, "shared", nil, nil, 1, false, false, 1, "user", 1, "user2", 3). WillReturnRows(_rows) _sqlite := testSqlite(t) diff --git a/database/secret/get_org_test.go b/database/secret/get_org_test.go index dec38ba8a..840fa2f91 100644 --- a/database/secret/get_org_test.go +++ b/database/secret/get_org_test.go @@ -32,8 +32,8 @@ func TestSecret_Engine_GetSecretForOrg(t *testing.T) { // create expected result in mock _rows := sqlmock.NewRows( - []string{"id", "type", "org", "repo", "team", "name", "value", "images", "events", "allow_events", "allow_command", "created_at", "created_by", "updated_at", "updated_by"}). - AddRow(1, "org", "foo", "*", "", "baz", "bar", nil, nil, 1, false, 1, "user", 1, "user2") + []string{"id", "type", "org", "repo", "team", "name", "value", "images", "events", "allow_events", "allow_command", "allow_substitution", "created_at", "created_by", "updated_at", "updated_by"}). + AddRow(1, "org", "foo", "*", "", "baz", "bar", nil, nil, 1, false, false, 1, "user", 1, "user2") // ensure the mock expects the query _mock.ExpectQuery(`SELECT * FROM "secrets" WHERE type = $1 AND org = $2 AND name = $3 LIMIT $4`). diff --git a/database/secret/get_repo_test.go b/database/secret/get_repo_test.go index 3f0282a6b..c4ed2c472 100644 --- a/database/secret/get_repo_test.go +++ b/database/secret/get_repo_test.go @@ -42,8 +42,8 @@ func TestSecret_Engine_GetSecretForRepo(t *testing.T) { // create expected result in mock _rows := sqlmock.NewRows( - []string{"id", "type", "org", "repo", "team", "name", "value", "images", "events", "allow_events", "allow_command", "created_at", "created_by", "updated_at", "updated_by"}). - AddRow(1, "repo", "foo", "bar", "", "baz", "foob", nil, nil, 1, false, 1, "user", 1, "user2") + []string{"id", "type", "org", "repo", "team", "name", "value", "images", "events", "allow_events", "allow_command", "allow_substitution", "created_at", "created_by", "updated_at", "updated_by"}). + AddRow(1, "repo", "foo", "bar", "", "baz", "foob", nil, nil, 1, false, false, 1, "user", 1, "user2") // ensure the mock expects the query _mock.ExpectQuery(`SELECT * FROM "secrets" WHERE type = $1 AND org = $2 AND repo = $3 AND name = $4 LIMIT $5`). diff --git a/database/secret/get_team_test.go b/database/secret/get_team_test.go index e36674a35..a39012c26 100644 --- a/database/secret/get_team_test.go +++ b/database/secret/get_team_test.go @@ -32,8 +32,8 @@ func TestSecret_Engine_GetSecretForTeam(t *testing.T) { // create expected result in mock _rows := sqlmock.NewRows( - []string{"id", "type", "org", "repo", "team", "name", "value", "images", "events", "allow_events", "allow_command", "created_at", "created_by", "updated_at", "updated_by"}). - AddRow(1, "shared", "foo", "", "bar", "baz", "foob", nil, nil, 1, false, 1, "user", 1, "user2") + []string{"id", "type", "org", "repo", "team", "name", "value", "images", "events", "allow_events", "allow_command", "allow_substitution", "created_at", "created_by", "updated_at", "updated_by"}). + AddRow(1, "shared", "foo", "", "bar", "baz", "foob", nil, nil, 1, false, false, 1, "user", 1, "user2") // ensure the mock expects the query _mock.ExpectQuery(`SELECT * FROM "secrets" WHERE type = $1 AND org = $2 AND team = $3 AND name = $4 LIMIT $5`). diff --git a/database/secret/get_test.go b/database/secret/get_test.go index 979f626e0..8b8d4d9c5 100644 --- a/database/secret/get_test.go +++ b/database/secret/get_test.go @@ -31,8 +31,8 @@ func TestSecret_Engine_GetSecret(t *testing.T) { // create expected result in mock _rows := sqlmock.NewRows( - []string{"id", "type", "org", "repo", "team", "name", "value", "images", "events", "allow_events", "allow_command", "created_at", "created_by", "updated_at", "updated_by"}). - AddRow(1, "repo", "foo", "bar", "", "baz", "foob", nil, nil, 1, false, 1, "user", 1, "user2") + []string{"id", "type", "org", "repo", "team", "name", "value", "images", "events", "allow_events", "allow_command", "allow_substitution", "created_at", "created_by", "updated_at", "updated_by"}). + AddRow(1, "repo", "foo", "bar", "", "baz", "foob", nil, nil, 1, false, false, 1, "user", 1, "user2") // ensure the mock expects the query _mock.ExpectQuery(`SELECT * FROM "secrets" WHERE id = $1 LIMIT $2`).WithArgs(1, 1).WillReturnRows(_rows) diff --git a/database/secret/list_org_test.go b/database/secret/list_org_test.go index 9fe2da2e1..024d7a05a 100644 --- a/database/secret/list_org_test.go +++ b/database/secret/list_org_test.go @@ -52,9 +52,9 @@ func TestSecret_Engine_ListSecretsForOrg(t *testing.T) { // create expected name query result in mock _rows = sqlmock.NewRows( - []string{"id", "type", "org", "repo", "team", "name", "value", "images", "events", "allow_events", "allow_command", "created_at", "created_by", "updated_at", "updated_by"}). - AddRow(2, "org", "foo", "*", "", "bar", "baz", nil, nil, 1, false, 1, "user", 1, "user2"). - AddRow(1, "org", "foo", "*", "", "baz", "bar", nil, nil, 1, false, 1, "user", 1, "user2") + []string{"id", "type", "org", "repo", "team", "name", "value", "images", "events", "allow_events", "allow_command", "allow_substitution", "created_at", "created_by", "updated_at", "updated_by"}). + AddRow(2, "org", "foo", "*", "", "bar", "baz", nil, nil, 1, false, false, 1, "user", 1, "user2"). + AddRow(1, "org", "foo", "*", "", "baz", "bar", nil, nil, 1, false, false, 1, "user", 1, "user2") // ensure the mock expects the name query _mock.ExpectQuery(`SELECT * FROM "secrets" WHERE type = $1 AND org = $2 ORDER BY id DESC LIMIT $3`). diff --git a/database/secret/list_repo_test.go b/database/secret/list_repo_test.go index 838dd96f9..eb97e4c52 100644 --- a/database/secret/list_repo_test.go +++ b/database/secret/list_repo_test.go @@ -63,9 +63,9 @@ func TestSecret_Engine_ListSecretsForRepo(t *testing.T) { // create expected name query result in mock _rows = sqlmock.NewRows( - []string{"id", "type", "org", "repo", "team", "name", "value", "images", "events", "allow_events", "allow_command", "created_at", "created_by", "updated_at", "updated_by"}). - AddRow(2, "repo", "foo", "bar", "", "foob", "baz", nil, nil, 1, false, 1, "user", 1, "user2"). - AddRow(1, "repo", "foo", "bar", "", "baz", "foob", nil, nil, 1, false, 1, "user", 1, "user2") + []string{"id", "type", "org", "repo", "team", "name", "value", "images", "events", "allow_events", "allow_command", "allow_substitution", "created_at", "created_by", "updated_at", "updated_by"}). + AddRow(2, "repo", "foo", "bar", "", "foob", "baz", nil, nil, 1, false, false, 1, "user", 1, "user2"). + AddRow(1, "repo", "foo", "bar", "", "baz", "foob", nil, nil, 1, false, false, 1, "user", 1, "user2") // ensure the mock expects the name query _mock.ExpectQuery(`SELECT * FROM "secrets" WHERE type = $1 AND org = $2 AND repo = $3 ORDER BY id DESC LIMIT $4`). diff --git a/database/secret/list_team_test.go b/database/secret/list_team_test.go index bed709312..fd925935e 100644 --- a/database/secret/list_team_test.go +++ b/database/secret/list_team_test.go @@ -53,9 +53,9 @@ func TestSecret_Engine_ListSecretsForTeam(t *testing.T) { // create expected name query result in mock _rows = sqlmock.NewRows( - []string{"id", "type", "org", "repo", "team", "name", "value", "images", "events", "allow_events", "allow_command", "created_at", "created_by", "updated_at", "updated_by"}). - AddRow(2, "shared", "foo", "", "bar", "foob", "baz", nil, nil, 1, false, 1, "user", 1, "user2"). - AddRow(1, "shared", "foo", "", "bar", "baz", "foob", nil, nil, 1, false, 1, "user", 1, "user2") + []string{"id", "type", "org", "repo", "team", "name", "value", "images", "events", "allow_events", "allow_command", "allow_substitution", "created_at", "created_by", "updated_at", "updated_by"}). + AddRow(2, "shared", "foo", "", "bar", "foob", "baz", nil, nil, 1, false, false, 1, "user", 1, "user2"). + AddRow(1, "shared", "foo", "", "bar", "baz", "foob", nil, nil, 1, false, false, 1, "user", 1, "user2") // ensure the mock expects the name query _mock.ExpectQuery(`SELECT * FROM "secrets" WHERE type = $1 AND org = $2 AND team = $3 ORDER BY id DESC LIMIT $4`). diff --git a/database/secret/list_test.go b/database/secret/list_test.go index 8077637ee..a1a0e9e38 100644 --- a/database/secret/list_test.go +++ b/database/secret/list_test.go @@ -50,9 +50,9 @@ func TestSecret_Engine_ListSecrets(t *testing.T) { // create expected result in mock _rows = sqlmock.NewRows( - []string{"id", "type", "org", "repo", "team", "name", "value", "images", "events", "allow_events", "allow_command", "created_at", "created_by", "updated_at", "updated_by"}). - AddRow(1, "repo", "foo", "bar", "", "baz", "foob", nil, nil, 1, false, 1, "user", 1, "user2"). - AddRow(2, "repo", "foo", "bar", "", "foob", "baz", nil, nil, 1, false, 1, "user", 1, "user2") + []string{"id", "type", "org", "repo", "team", "name", "value", "images", "events", "allow_events", "allow_command", "allow_substitution", "created_at", "created_by", "updated_at", "updated_by"}). + AddRow(1, "repo", "foo", "bar", "", "baz", "foob", nil, nil, 1, false, false, 1, "user", 1, "user2"). + AddRow(2, "repo", "foo", "bar", "", "foob", "baz", nil, nil, 1, false, false, 1, "user", 1, "user2") // ensure the mock expects the query _mock.ExpectQuery(`SELECT * FROM "secrets"`).WillReturnRows(_rows) diff --git a/database/secret/secret_test.go b/database/secret/secret_test.go index 31156ebca..e4b74ec9a 100644 --- a/database/secret/secret_test.go +++ b/database/secret/secret_test.go @@ -210,21 +210,22 @@ func testRepo() *library.Repo { // Secret type with all fields set to their zero values. func testSecret() *library.Secret { return &library.Secret{ - ID: new(int64), - Org: new(string), - Repo: new(string), - Team: new(string), - Name: new(string), - Value: new(string), - Type: new(string), - Images: new([]string), - Events: new([]string), - AllowEvents: testEvents(), - AllowCommand: new(bool), - CreatedAt: new(int64), - CreatedBy: new(string), - UpdatedAt: new(int64), - UpdatedBy: new(string), + ID: new(int64), + Org: new(string), + Repo: new(string), + Team: new(string), + Name: new(string), + Value: new(string), + Type: new(string), + Images: new([]string), + Events: new([]string), + AllowEvents: testEvents(), + AllowCommand: new(bool), + AllowSubstitution: new(bool), + CreatedAt: new(int64), + CreatedBy: new(string), + UpdatedAt: new(int64), + UpdatedBy: new(string), } } diff --git a/database/secret/table.go b/database/secret/table.go index f3d42ea46..67fd6b8b9 100644 --- a/database/secret/table.go +++ b/database/secret/table.go @@ -14,21 +14,22 @@ const ( CREATE TABLE IF NOT EXISTS secrets ( - id SERIAL PRIMARY KEY, - type VARCHAR(100), - org VARCHAR(250), - repo VARCHAR(250), - team VARCHAR(250), - name VARCHAR(250), - value BYTEA, - images VARCHAR(1000), - events VARCHAR(1000), - allow_events INTEGER, - allow_command BOOLEAN, - created_at INTEGER, - created_by VARCHAR(250), - updated_at INTEGER, - updated_by VARCHAR(250), + id SERIAL PRIMARY KEY, + type VARCHAR(100), + org VARCHAR(250), + repo VARCHAR(250), + team VARCHAR(250), + name VARCHAR(250), + value BYTEA, + images VARCHAR(1000), + events VARCHAR(1000), + allow_events INTEGER, + allow_command BOOLEAN, + allow_substitution BOOLEAN, + created_at INTEGER, + created_by VARCHAR(250), + updated_at INTEGER, + updated_by VARCHAR(250), UNIQUE(type, org, repo, name), UNIQUE(type, org, team, name) ); @@ -39,21 +40,22 @@ secrets ( CREATE TABLE IF NOT EXISTS secrets ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - type TEXT, - org TEXT, - repo TEXT, - team TEXT, - name TEXT, - value TEXT, - images TEXT, - events TEXT, - allow_events INTEGER, - allow_command BOOLEAN, - created_at INTEGER, - created_by TEXT, - updated_at INTEGER, - updated_by TEXT, + id INTEGER PRIMARY KEY AUTOINCREMENT, + type TEXT, + org TEXT, + repo TEXT, + team TEXT, + name TEXT, + value TEXT, + images TEXT, + events TEXT, + allow_events INTEGER, + allow_command BOOLEAN, + allow_substitution BOOLEAN, + created_at INTEGER, + created_by TEXT, + updated_at INTEGER, + updated_by TEXT, UNIQUE(type, org, repo, name), UNIQUE(type, org, team, name) ); diff --git a/database/secret/update_test.go b/database/secret/update_test.go index f26ddaa24..5797471f2 100644 --- a/database/secret/update_test.go +++ b/database/secret/update_test.go @@ -57,23 +57,23 @@ func TestSecret_Engine_UpdateSecret(t *testing.T) { // ensure the mock expects the repo query _mock.ExpectExec(`UPDATE "secrets" -SET "org"=$1,"repo"=$2,"team"=$3,"name"=$4,"value"=$5,"type"=$6,"images"=$7,"events"=$8,"allow_events"=$9,"allow_command"=$10,"created_at"=$11,"created_by"=$12,"updated_at"=$13,"updated_by"=$14 -WHERE "id" = $15`). - WithArgs("foo", "bar", nil, "baz", AnyArgument{}, "repo", nil, nil, 1, false, 1, "user", AnyArgument{}, "user2", 1). +SET "org"=$1,"repo"=$2,"team"=$3,"name"=$4,"value"=$5,"type"=$6,"images"=$7,"events"=$8,"allow_events"=$9,"allow_command"=$10,"allow_substitution"=$11,"created_at"=$12,"created_by"=$13,"updated_at"=$14,"updated_by"=$15 +WHERE "id" = $16`). + WithArgs("foo", "bar", nil, "baz", AnyArgument{}, "repo", nil, nil, 1, false, false, 1, "user", AnyArgument{}, "user2", 1). WillReturnResult(sqlmock.NewResult(1, 1)) // ensure the mock expects the org query _mock.ExpectExec(`UPDATE "secrets" -SET "org"=$1,"repo"=$2,"team"=$3,"name"=$4,"value"=$5,"type"=$6,"images"=$7,"events"=$8,"allow_events"=$9,"allow_command"=$10,"created_at"=$11,"created_by"=$12,"updated_at"=$13,"updated_by"=$14 -WHERE "id" = $15`). - WithArgs("foo", "*", nil, "bar", AnyArgument{}, "org", nil, nil, 1, false, 1, "user", AnyArgument{}, "user2", 2). +SET "org"=$1,"repo"=$2,"team"=$3,"name"=$4,"value"=$5,"type"=$6,"images"=$7,"events"=$8,"allow_events"=$9,"allow_command"=$10,"allow_substitution"=$11,"created_at"=$12,"created_by"=$13,"updated_at"=$14,"updated_by"=$15 +WHERE "id" = $16`). + WithArgs("foo", "*", nil, "bar", AnyArgument{}, "org", nil, nil, 1, false, false, 1, "user", AnyArgument{}, "user2", 2). WillReturnResult(sqlmock.NewResult(1, 1)) // ensure the mock expects the shared query _mock.ExpectExec(`UPDATE "secrets" -SET "org"=$1,"repo"=$2,"team"=$3,"name"=$4,"value"=$5,"type"=$6,"images"=$7,"events"=$8,"allow_events"=$9,"allow_command"=$10,"created_at"=$11,"created_by"=$12,"updated_at"=$13,"updated_by"=$14 -WHERE "id" = $15`). - WithArgs("foo", nil, "bar", "baz", AnyArgument{}, "shared", nil, nil, 1, false, 1, "user", NowTimestamp{}, "user2", 3). +SET "org"=$1,"repo"=$2,"team"=$3,"name"=$4,"value"=$5,"type"=$6,"images"=$7,"events"=$8,"allow_events"=$9,"allow_command"=$10,"allow_substitution"=$11,"created_at"=$12,"created_by"=$13,"updated_at"=$14,"updated_by"=$15 +WHERE "id" = $16`). + WithArgs("foo", nil, "bar", "baz", AnyArgument{}, "shared", nil, nil, 1, false, false, 1, "user", NowTimestamp{}, "user2", 3). WillReturnResult(sqlmock.NewResult(1, 1)) _sqlite := testSqlite(t) diff --git a/go.mod b/go.mod index 3cfaeb5fb..902d50a32 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/drone/envsubst v1.0.3 github.com/gin-gonic/gin v1.9.1 github.com/go-playground/assert/v2 v2.2.0 - github.com/go-vela/types v0.23.1 + github.com/go-vela/types v0.23.2-0.20240312183632-2e046fceb8fe github.com/golang-jwt/jwt/v5 v5.2.0 github.com/google/go-cmp v0.6.0 github.com/google/go-github/v59 v59.0.0 diff --git a/go.sum b/go.sum index d2dde2a27..940468eaa 100644 --- a/go.sum +++ b/go.sum @@ -86,8 +86,8 @@ github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw= github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= -github.com/go-vela/types v0.23.1 h1:st4BeDcYVyaaFqblU1YroztNvmYLBgmfZpWq0En0Sg0= -github.com/go-vela/types v0.23.1/go.mod h1:AAqgxIw1aRBgPkE/5juGuiwh/JZuOtL8fcPaEkjFWwQ= +github.com/go-vela/types v0.23.2-0.20240312183632-2e046fceb8fe h1:Fb28yre0nrX1GNeyPN8i8rruTlW8MnPVF3Fo5xTuOkg= +github.com/go-vela/types v0.23.2-0.20240312183632-2e046fceb8fe/go.mod h1:AAqgxIw1aRBgPkE/5juGuiwh/JZuOtL8fcPaEkjFWwQ= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= diff --git a/mock/server/secret.go b/mock/server/secret.go index 1747fbcf4..34fcd4b76 100644 --- a/mock/server/secret.go +++ b/mock/server/secret.go @@ -49,6 +49,7 @@ const ( } }, "allow_command": true, + "allow_substitution": true, "created_at": 1, "created_by": "Octocat", "updated_at": 2, diff --git a/secret/native/create_test.go b/secret/native/create_test.go index 0463e33ff..02a114976 100644 --- a/secret/native/create_test.go +++ b/secret/native/create_test.go @@ -25,6 +25,7 @@ func TestNative_Create_Org(t *testing.T) { want.SetEvents([]string{"foo", "bar"}) want.SetAllowEvents(library.NewEventsFromMask(1)) want.SetAllowCommand(false) + want.SetAllowSubstitution(false) want.SetCreatedAt(1) want.SetCreatedBy("user") want.SetUpdatedAt(1) @@ -73,6 +74,7 @@ func TestNative_Create_Repo(t *testing.T) { want.SetEvents([]string{"foo", "bar"}) want.SetAllowEvents(library.NewEventsFromMask(1)) want.SetAllowCommand(false) + want.SetAllowSubstitution(false) want.SetCreatedAt(1) want.SetCreatedBy("user") want.SetUpdatedAt(1) @@ -121,6 +123,7 @@ func TestNative_Create_Shared(t *testing.T) { want.SetEvents([]string{"foo", "bar"}) want.SetAllowEvents(library.NewEventsFromMask(1)) want.SetAllowCommand(false) + want.SetAllowSubstitution(false) want.SetCreatedAt(1) want.SetCreatedBy("user") want.SetUpdatedAt(1) @@ -169,6 +172,7 @@ func TestNative_Create_Invalid(t *testing.T) { sec.SetEvents([]string{"foo", "bar"}) sec.SetAllowEvents(library.NewEventsFromMask(1)) sec.SetAllowCommand(false) + sec.SetAllowSubstitution(false) sec.SetCreatedAt(1) sec.SetCreatedBy("user") sec.SetUpdatedAt(1) diff --git a/secret/native/get_test.go b/secret/native/get_test.go index a835e1143..b9b56e51e 100644 --- a/secret/native/get_test.go +++ b/secret/native/get_test.go @@ -25,6 +25,7 @@ func TestNative_Get(t *testing.T) { want.SetEvents([]string{"foo", "bar"}) want.SetAllowEvents(library.NewEventsFromMask(1)) want.SetAllowCommand(false) + want.SetAllowSubstitution(false) want.SetCreatedAt(1) want.SetCreatedBy("user") want.SetUpdatedAt(1) diff --git a/secret/native/list_test.go b/secret/native/list_test.go index 41dbf1691..b01e3a546 100644 --- a/secret/native/list_test.go +++ b/secret/native/list_test.go @@ -25,6 +25,7 @@ func TestNative_List(t *testing.T) { sOne.SetEvents([]string{"foo", "bar"}) sOne.SetAllowEvents(library.NewEventsFromMask(1)) sOne.SetAllowCommand(false) + sOne.SetAllowSubstitution(false) sOne.SetCreatedAt(1) sOne.SetCreatedBy("user") sOne.SetUpdatedAt(1) @@ -42,6 +43,7 @@ func TestNative_List(t *testing.T) { sTwo.SetEvents([]string{"foo", "bar"}) sTwo.SetAllowEvents(library.NewEventsFromMask(1)) sTwo.SetAllowCommand(false) + sTwo.SetAllowSubstitution(false) sTwo.SetCreatedAt(1) sTwo.SetCreatedBy("user") sTwo.SetUpdatedAt(1) diff --git a/secret/native/update.go b/secret/native/update.go index ece04c5b9..7e2c92d0c 100644 --- a/secret/native/update.go +++ b/secret/native/update.go @@ -44,6 +44,11 @@ func (c *client) Update(ctx context.Context, sType, org, name string, s *library secret.SetAllowCommand(s.GetAllowCommand()) } + // update allow_substitution if set + if s.AllowSubstitution != nil { + secret.SetAllowSubstitution(s.GetAllowSubstitution()) + } + // update updated_at if set secret.SetUpdatedAt(s.GetUpdatedAt()) diff --git a/secret/native/update_test.go b/secret/native/update_test.go index b5dc82c97..38d7a3b5b 100644 --- a/secret/native/update_test.go +++ b/secret/native/update_test.go @@ -26,6 +26,7 @@ func TestNative_Update(t *testing.T) { original.SetEvents([]string{"foob", "bar"}) original.SetAllowEvents(library.NewEventsFromMask(1)) original.SetAllowCommand(true) + original.SetAllowSubstitution(true) original.SetCreatedAt(1) original.SetCreatedBy("user") original.SetUpdatedAt(time.Now().UTC().Unix()) @@ -43,6 +44,7 @@ func TestNative_Update(t *testing.T) { want.SetEvents([]string{"foo", "bar"}) want.SetAllowEvents(library.NewEventsFromMask(3)) want.SetAllowCommand(false) + want.SetAllowSubstitution(false) want.SetCreatedAt(1) want.SetCreatedBy("user") want.SetUpdatedAt(time.Now().UTC().Unix()) From abf95206298a214c38f6da90318ee2c73b0d33e3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 12 Mar 2024 14:08:42 -0500 Subject: [PATCH 05/71] chore(deps): update all non-major dependencies (#1069) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/codeql-analysis.yml | 6 ++-- .github/workflows/reviewdog.yml | 4 +-- .github/workflows/test.yml | 2 +- go.mod | 25 +++++++------- go.sum | 50 +++++++++++++-------------- 5 files changed, 42 insertions(+), 45 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index f15404847..b5d001de4 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -47,7 +47,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@47b3d888fe66b639e431abf22ebca059152f1eea # v3.24.5 + uses: github/codeql-action/init@3ab4101902695724f9365a384f86c1074d94e18c # v3.24.7 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -58,7 +58,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@47b3d888fe66b639e431abf22ebca059152f1eea # v3.24.5 + uses: github/codeql-action/autobuild@3ab4101902695724f9365a384f86c1074d94e18c # v3.24.7 # ℹī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -72,4 +72,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@47b3d888fe66b639e431abf22ebca059152f1eea # v3.24.5 + uses: github/codeql-action/analyze@3ab4101902695724f9365a384f86c1074d94e18c # v3.24.7 diff --git a/.github/workflows/reviewdog.yml b/.github/workflows/reviewdog.yml index ab18a35ac..9cf940fd5 100644 --- a/.github/workflows/reviewdog.yml +++ b/.github/workflows/reviewdog.yml @@ -23,7 +23,7 @@ jobs: check-latest: true - name: golangci-lint - uses: reviewdog/action-golangci-lint@8e1117c7d327bbfb1eb7ec8dc2d895d13e6e17c3 # v2.6.0 + uses: reviewdog/action-golangci-lint@00311c26a97213f93f2fd3a3524d66762e956ae0 # v2.6.1 with: github_token: ${{ secrets.github_token }} golangci_lint_flags: "--config=.golangci.yml --timeout=5m" @@ -47,7 +47,7 @@ jobs: check-latest: true - name: golangci-lint - uses: reviewdog/action-golangci-lint@8e1117c7d327bbfb1eb7ec8dc2d895d13e6e17c3 # v2.6.0 + uses: reviewdog/action-golangci-lint@00311c26a97213f93f2fd3a3524d66762e956ae0 # v2.6.1 with: github_token: ${{ secrets.github_token }} golangci_lint_flags: "--config=.golangci.yml --timeout=5m" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ec185448b..08ecae82e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -28,7 +28,7 @@ jobs: make test - name: coverage - uses: codecov/codecov-action@0cfda1dd0a4ad9efc75517f399d859cd1ea4ced1 # v4.0.2 + uses: codecov/codecov-action@54bcd8715eee62d40e33596ef5e8f0f48dbbccab # v4.1.0 with: token: ${{ secrets.CODECOV_TOKEN }} file: coverage.out \ No newline at end of file diff --git a/go.mod b/go.mod index 902d50a32..2619dc0ac 100644 --- a/go.mod +++ b/go.mod @@ -7,15 +7,15 @@ require ( github.com/DATA-DOG/go-sqlmock v1.5.2 github.com/Masterminds/semver/v3 v3.2.1 github.com/Masterminds/sprig/v3 v3.2.3 - github.com/adhocore/gronx v1.6.7 + github.com/adhocore/gronx v1.8.0 github.com/alicebob/miniredis/v2 v2.31.1 - github.com/aws/aws-sdk-go v1.50.24 + github.com/aws/aws-sdk-go v1.50.37 github.com/buildkite/yaml v0.0.0-20181016232759-0caa5f0796e3 github.com/drone/envsubst v1.0.3 github.com/gin-gonic/gin v1.9.1 github.com/go-playground/assert/v2 v2.2.0 github.com/go-vela/types v0.23.2-0.20240312183632-2e046fceb8fe - github.com/golang-jwt/jwt/v5 v5.2.0 + github.com/golang-jwt/jwt/v5 v5.2.1 github.com/google/go-cmp v0.6.0 github.com/google/go-github/v59 v59.0.0 github.com/google/uuid v1.6.0 @@ -26,17 +26,17 @@ require ( github.com/hashicorp/vault/api v1.12.0 github.com/joho/godotenv v1.5.1 github.com/pkg/errors v0.9.1 - github.com/prometheus/client_golang v1.18.0 + github.com/prometheus/client_golang v1.19.0 github.com/redis/go-redis/v9 v9.5.1 github.com/sirupsen/logrus v1.9.3 github.com/spf13/afero v1.11.0 github.com/urfave/cli/v2 v2.27.1 - go.starlark.net v0.0.0-20240123142251-f86470692795 - golang.org/x/crypto v0.19.0 - golang.org/x/oauth2 v0.17.0 + go.starlark.net v0.0.0-20240311180835-efac67204ba7 + golang.org/x/crypto v0.21.0 + golang.org/x/oauth2 v0.18.0 golang.org/x/sync v0.6.0 gopkg.in/square/go-jose.v2 v2.6.0 - gorm.io/driver/postgres v1.5.6 + gorm.io/driver/postgres v1.5.7 gorm.io/driver/sqlite v1.5.5 gorm.io/gorm v1.25.7 k8s.io/apimachinery v0.29.2 @@ -93,7 +93,6 @@ require ( github.com/mattn/go-colorable v0.1.8 // indirect github.com/mattn/go-isatty v0.0.19 // indirect github.com/mattn/go-sqlite3 v1.14.17 // indirect - github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect github.com/microcosm-cc/bluemonday v1.0.26 // indirect github.com/mitchellh/copystructure v1.0.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect @@ -103,7 +102,7 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pelletier/go-toml/v2 v2.0.8 // indirect github.com/prometheus/client_model v0.5.0 // indirect - github.com/prometheus/common v0.45.0 // indirect + github.com/prometheus/common v0.48.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/ryanuber/go-glob v1.0.0 // indirect @@ -114,12 +113,12 @@ require ( github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/yuin/gopher-lua v1.1.0 // indirect golang.org/x/arch v0.3.0 // indirect - golang.org/x/net v0.21.0 // indirect - golang.org/x/sys v0.17.0 // indirect + golang.org/x/net v0.22.0 // indirect + golang.org/x/sys v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.5.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/protobuf v1.31.0 // indirect + google.golang.org/protobuf v1.32.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/klog/v2 v2.110.1 // indirect diff --git a/go.sum b/go.sum index 940468eaa..3856f8e2f 100644 --- a/go.sum +++ b/go.sum @@ -16,8 +16,8 @@ github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tN github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/adhocore/gronx v1.6.7 h1:yE/AKQP/yhjMRqV943XiPqBdmUwIF8VHJwm6KZhnk48= -github.com/adhocore/gronx v1.6.7/go.mod h1:7oUY1WAU8rEJWmAxXR2DN0JaO4gi9khSgKjiRypqteg= +github.com/adhocore/gronx v1.8.0 h1:BHgzaGyS7zPmuMVqiIxyAwvKpwAX+bR7bCxDVacfhuo= +github.com/adhocore/gronx v1.8.0/go.mod h1:7oUY1WAU8rEJWmAxXR2DN0JaO4gi9khSgKjiRypqteg= github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a h1:HbKu58rmZpUGpz5+4FfNmIU+FmZg2P3Xaj2v2bfNWmk= github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= @@ -25,8 +25,8 @@ github.com/alicebob/miniredis/v2 v2.11.1/go.mod h1:UA48pmi7aSazcGAvcdKcBB49z521I github.com/alicebob/miniredis/v2 v2.31.1 h1:7XAt0uUg3DtwEKW5ZAGa+K7FZV2DdKQo5K/6TTnfX8Y= github.com/alicebob/miniredis/v2 v2.31.1/go.mod h1:UB/T2Uztp7MlFSDakaX1sTXUv5CASoprx0wulRT6HBg= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/aws/aws-sdk-go v1.50.24 h1:3o2Pg7mOoVL0jv54vWtuafoZqAeEXLhm1tltWA2GcEw= -github.com/aws/aws-sdk-go v1.50.24/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/aws/aws-sdk-go v1.50.37 h1:gnAf6eYPSTb4QpVwugtWFqD07QXOoX7LewRrtLUx3lI= +github.com/aws/aws-sdk-go v1.50.37/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -92,8 +92,8 @@ github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw= -github.com/golang-jwt/jwt/v5 v5.2.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= +github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= @@ -195,8 +195,6 @@ github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APP github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM= github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= -github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= -github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= github.com/microcosm-cc/bluemonday v1.0.26 h1:xbqSvqzQMeEHCqMi64VAs4d8uy6Mequs3rQ0k/Khz58= github.com/microcosm-cc/bluemonday v1.0.26/go.mod h1:JyzOCs9gkyQyjs+6h10UEVSe02CGwkhd72Xdqh78TWs= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= @@ -223,12 +221,12 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= -github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= +github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= +github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= -github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= -github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= +github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE= +github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/redis/go-redis/v9 v9.5.1 h1:H1X4D3yHPaYrkL5X06Wh6xNVM/pX0Ft4RV0vMGvLBh8= @@ -278,8 +276,8 @@ github.com/yuin/gopher-lua v0.0.0-20190206043414-8bfc7677f583/go.mod h1:gqRgreBU github.com/yuin/gopher-lua v0.0.0-20191213034115-f46add6fdb5c/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ= github.com/yuin/gopher-lua v1.1.0 h1:BojcDhfyDWgU2f2TOzYK/g5p2gxMrku8oupLDqlnSqE= github.com/yuin/gopher-lua v1.1.0/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= -go.starlark.net v0.0.0-20240123142251-f86470692795 h1:LmbG8Pq7KDGkglKVn8VpZOZj6vb9b8nKEGcg9l03epM= -go.starlark.net v0.0.0-20240123142251-f86470692795/go.mod h1:LcLNIzVOMp4oV+uusnpk+VU+SzXaJakUuBjoCSWH5dM= +go.starlark.net v0.0.0-20240311180835-efac67204ba7 h1:xH7OJPtjgdj/xXykge/wGPAAqik97FbEVJR55lEY0tQ= +go.starlark.net v0.0.0-20240311180835-efac67204ba7/go.mod h1:MrdO7XaMF3dE3MzuP6mrG0EB3NC7rLWSiEcu9Ii50g8= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= @@ -289,8 +287,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= -golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= @@ -303,10 +301,10 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ= -golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= +golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= +golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= +golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -328,8 +326,8 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= @@ -355,8 +353,8 @@ google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6 google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= +google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -370,8 +368,8 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gorm.io/driver/postgres v1.5.6 h1:ydr9xEd5YAM0vxVDY0X139dyzNz10spDiDlC7+ibLeU= -gorm.io/driver/postgres v1.5.6/go.mod h1:3e019WlBaYI5o5LIdNV+LyxCMNtLOQETBXL2h4chKpA= +gorm.io/driver/postgres v1.5.7 h1:8ptbNJTDbEmhdr62uReG5BGkdQyeasu/FZHxI0IMGnM= +gorm.io/driver/postgres v1.5.7/go.mod h1:3e019WlBaYI5o5LIdNV+LyxCMNtLOQETBXL2h4chKpA= gorm.io/driver/sqlite v1.5.5 h1:7MDMtUZhV065SilG62E0MquljeArQZNfJnjd9i9gx3E= gorm.io/driver/sqlite v1.5.5/go.mod h1:6NgQ7sQWAIFsPrJJl1lSNSu2TABh0ZZ/zm5fosATavE= gorm.io/gorm v1.25.7 h1:VsD6acwRjz2zFxGO50gPO6AkNs7KKnvfzUjHQhZDz/A= From 997a8857f7cee73f5b98c6a06e4d6094d7f01c92 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Mar 2024 14:12:45 -0500 Subject: [PATCH 06/71] chore(deps): bump github.com/go-jose/go-jose/v3 from 3.0.1 to 3.0.3 (#1078) --- go.mod | 2 +- go.sum | 22 +++++++++++++++++----- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 2619dc0ac..e1dd7d19c 100644 --- a/go.mod +++ b/go.mod @@ -59,7 +59,7 @@ require ( github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/ghodss/yaml v1.0.0 // indirect github.com/gin-contrib/sse v0.1.0 // indirect - github.com/go-jose/go-jose/v3 v3.0.1 // indirect + github.com/go-jose/go-jose/v3 v3.0.3 // indirect github.com/go-logr/logr v1.3.0 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect diff --git a/go.sum b/go.sum index 3856f8e2f..1b3e68dcc 100644 --- a/go.sum +++ b/go.sum @@ -72,8 +72,8 @@ github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= -github.com/go-jose/go-jose/v3 v3.0.1 h1:pWmKFVtt+Jl0vBZTIpz/eAKwsm6LkIxDVVbFHKkchhA= -github.com/go-jose/go-jose/v3 v3.0.1/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= +github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k= +github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= @@ -103,9 +103,9 @@ github.com/gomodule/redigo v1.7.1-0.20190322064113-39e2c31b7ca3/go.mod h1:B4C85q github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0= github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 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/google/go-github/v59 v59.0.0 h1:7h6bgpF5as0YQLLkEiVqpgtJqjimMYhBkD4jT5aN3VA= @@ -252,7 +252,6 @@ github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpE github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= @@ -282,16 +281,17 @@ golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUu golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= @@ -301,6 +301,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= @@ -309,6 +311,7 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -325,17 +328,25 @@ golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= @@ -345,6 +356,7 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 270dee4ccda8a04eb62b3f4b72cb40039314c734 Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Tue, 12 Mar 2024 15:25:39 -0400 Subject: [PATCH 07/71] chore(deps): upgrade types to v0.23.2 (#1079) --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index e1dd7d19c..e54e31377 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/drone/envsubst v1.0.3 github.com/gin-gonic/gin v1.9.1 github.com/go-playground/assert/v2 v2.2.0 - github.com/go-vela/types v0.23.2-0.20240312183632-2e046fceb8fe + github.com/go-vela/types v0.23.2 github.com/golang-jwt/jwt/v5 v5.2.1 github.com/google/go-cmp v0.6.0 github.com/google/go-github/v59 v59.0.0 diff --git a/go.sum b/go.sum index 1b3e68dcc..1cac891fb 100644 --- a/go.sum +++ b/go.sum @@ -86,8 +86,8 @@ github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw= github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= -github.com/go-vela/types v0.23.2-0.20240312183632-2e046fceb8fe h1:Fb28yre0nrX1GNeyPN8i8rruTlW8MnPVF3Fo5xTuOkg= -github.com/go-vela/types v0.23.2-0.20240312183632-2e046fceb8fe/go.mod h1:AAqgxIw1aRBgPkE/5juGuiwh/JZuOtL8fcPaEkjFWwQ= +github.com/go-vela/types v0.23.2 h1:QDt2lta7FPEfN2RK/Bn++DkqyjGIB4H/Q4XkFAj3hXQ= +github.com/go-vela/types v0.23.2/go.mod h1:aTE6dzssqTGOvU6m2/vsI9NoSW/3hH/yLzf3cCSo0Zk= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= From aa44bf36d8360f812938179786876914dcf5a17b Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Thu, 14 Mar 2024 18:46:01 -0400 Subject: [PATCH 08/71] fix(vault): fix for integer64 fields (#1083) --- secret/vault/vault.go | 36 +++++++++-- secret/vault/vault_test.go | 119 ++++++++++++++++++++++--------------- 2 files changed, 101 insertions(+), 54 deletions(-) diff --git a/secret/vault/vault.go b/secret/vault/vault.go index 977ea60f9..dab603db0 100644 --- a/secret/vault/vault.go +++ b/secret/vault/vault.go @@ -3,6 +3,7 @@ package vault import ( + "encoding/json" "fmt" "time" @@ -158,9 +159,12 @@ func secretFromVault(vault *api.Secret) *library.Secret { v, ok = data["allow_events"] if ok { - mask, ok := v.(int64) + maskJSON, ok := v.(json.Number) if ok { - s.SetAllowEvents(library.NewEventsFromMask(mask)) + mask, err := maskJSON.Int64() + if err == nil { + s.SetAllowEvents(library.NewEventsFromMask(mask)) + } } } @@ -241,12 +245,24 @@ func secretFromVault(vault *api.Secret) *library.Secret { } } + // set allow_substitution if found in Vault secret + v, ok = data["allow_substitution"] + if ok { + substitution, ok := v.(bool) + if ok { + s.SetAllowSubstitution(substitution) + } + } + // set created_at if found in Vault secret v, ok = data["created_at"] if ok { - createdAt, ok := v.(int64) + createdAtJSON, ok := v.(json.Number) if ok { - s.SetCreatedAt(createdAt) + createdAt, err := createdAtJSON.Int64() + if err == nil { + s.SetCreatedAt(createdAt) + } } } @@ -262,9 +278,12 @@ func secretFromVault(vault *api.Secret) *library.Secret { // set updated_at if found in Vault secret v, ok = data["updated_at"] if ok { - updatedAt, ok := v.(int64) + updatedAtJSON, ok := v.(json.Number) if ok { - s.SetUpdatedAt(updatedAt) + updatedAt, err := updatedAtJSON.Int64() + if err == nil { + s.SetUpdatedAt(updatedAt) + } } } @@ -336,6 +355,11 @@ func vaultFromSecret(s *library.Secret) *api.Secret { vault.Data["allow_command"] = s.GetAllowCommand() } + // set allow_substitution if found in Vela secret + if s.AllowSubstitution != nil { + vault.Data["allow_substitution"] = s.GetAllowSubstitution() + } + // set created_at if found in Vela secret if s.GetCreatedAt() > 0 { vault.Data["created_at"] = s.GetCreatedAt() diff --git a/secret/vault/vault_test.go b/secret/vault/vault_test.go index 9cee893d9..8893d5c3c 100644 --- a/secret/vault/vault_test.go +++ b/secret/vault/vault_test.go @@ -3,12 +3,15 @@ package vault import ( + "encoding/json" "net/http" "net/http/httptest" "reflect" + "strings" "testing" "github.com/go-vela/types/library" + "github.com/google/go-cmp/cmp" "github.com/hashicorp/vault/api" ) @@ -93,42 +96,12 @@ func TestVault_New_Error(t *testing.T) { func TestVault_secretFromVault(t *testing.T) { // setup types inputV1 := &api.Secret{ - Data: map[string]interface{}{ - "events": []interface{}{"foo", "bar"}, - "allow_events": int64(1), - "images": []interface{}{"foo", "bar"}, - "name": "bar", - "org": "foo", - "repo": "*", - "team": "foob", - "type": "org", - "value": "baz", - "allow_command": true, - "created_at": int64(1563474077), - "created_by": "octocat", - "updated_at": int64(1563474079), - "updated_by": "octocat2", - }, + Data: testVaultSecretData(), } inputV2 := &api.Secret{ Data: map[string]interface{}{ - "data": map[string]interface{}{ - "events": []interface{}{"foo", "bar"}, - "allow_events": int64(1), - "images": []interface{}{"foo", "bar"}, - "name": "bar", - "org": "foo", - "repo": "*", - "team": "foob", - "type": "org", - "value": "baz", - "allow_command": true, - "created_at": int64(1563474077), - "created_by": "octocat", - "updated_at": int64(1563474079), - "updated_by": "octocat2", - }, + "data": testVaultSecretData(), }, } @@ -143,6 +116,7 @@ func TestVault_secretFromVault(t *testing.T) { want.SetAllowEvents(library.NewEventsFromMask(1)) want.SetImages([]string{"foo", "bar"}) want.SetAllowCommand(true) + want.SetAllowSubstitution(true) want.SetCreatedAt(1563474077) want.SetCreatedBy("octocat") want.SetUpdatedAt(1563474079) @@ -184,6 +158,7 @@ func TestVault_vaultFromSecret(t *testing.T) { s.SetAllowEvents(library.NewEventsFromMask(1)) s.SetImages([]string{"foo", "bar"}) s.SetAllowCommand(true) + s.SetAllowSubstitution(true) s.SetCreatedAt(1563474077) s.SetCreatedBy("octocat") s.SetUpdatedAt(1563474079) @@ -191,27 +166,75 @@ func TestVault_vaultFromSecret(t *testing.T) { want := &api.Secret{ Data: map[string]interface{}{ - "events": []string{"foo", "bar"}, - "allow_events": int64(1), - "images": []string{"foo", "bar"}, - "name": "bar", - "org": "foo", - "repo": "*", - "team": "foob", - "type": "org", - "value": "baz", - "allow_command": true, - "created_at": int64(1563474077), - "created_by": "octocat", - "updated_at": int64(1563474079), - "updated_by": "octocat2", + "events": []string{"foo", "bar"}, + "allow_events": int64(1), + "images": []string{"foo", "bar"}, + "name": "bar", + "org": "foo", + "repo": "*", + "team": "foob", + "type": "org", + "value": "baz", + "allow_command": true, + "allow_substitution": true, + "created_at": int64(1563474077), + "created_by": "octocat", + "updated_at": int64(1563474079), + "updated_by": "octocat2", }, } // run test got := vaultFromSecret(s) - if !reflect.DeepEqual(got, want) { - t.Errorf("vaultFromSecret is %v, want %v", got, want) + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("vaultFromSecret() mismatch (-got +want):\n%s", diff) + } +} + +func TestVault_AccurateSecretFields(t *testing.T) { + testSecret := library.Secret{} + + tSecret := reflect.TypeOf(testSecret) + + vaultSecret := testVaultSecretData() + + for i := 0; i < tSecret.NumField(); i++ { + field := tSecret.Field(i) + + jsonTag := field.Tag.Get("json") + if jsonTag == "" { + continue + } + + jsonTag = strings.Split(jsonTag, ",")[0] + if strings.EqualFold(jsonTag, "id") { + continue // skip id field + } + + if vaultSecret[jsonTag] == nil { + t.Errorf("vaultSecret missing field with JSON tag %s", jsonTag) + } + } +} + +// helper function to return a test Vault secret data. +func testVaultSecretData() map[string]interface{} { + return map[string]interface{}{ + "events": []interface{}{"foo", "bar"}, + "allow_events": json.Number("1"), + "images": []interface{}{"foo", "bar"}, + "name": "bar", + "org": "foo", + "repo": "*", + "team": "foob", + "type": "org", + "value": "baz", + "allow_command": true, + "allow_substitution": true, + "created_at": json.Number("1563474077"), + "created_by": "octocat", + "updated_at": json.Number("1563474079"), + "updated_by": "octocat2", } } From 0c3e6200977406684e1e4e66bebd5307949a3f33 Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Fri, 15 Mar 2024 11:20:59 -0400 Subject: [PATCH 09/71] fix(vault): add update logic for allow events and allow substitution (#1085) * fix(vault): add update logic for allow events and allow substitution * fix tests --- secret/vault/create_test.go | 21 +++++++++++++++++++++ secret/vault/get_test.go | 21 +++++++++++++++++++++ secret/vault/list_test.go | 21 +++++++++++++++++++++ secret/vault/testdata/v1/org.json | 9 ++++++++- secret/vault/testdata/v1/repo.json | 19 ++++++++++--------- secret/vault/testdata/v1/shared.json | 19 ++++++++++--------- secret/vault/testdata/v2/org.json | 19 ++++++++++--------- secret/vault/testdata/v2/repo.json | 19 ++++++++++--------- secret/vault/testdata/v2/shared.json | 19 ++++++++++--------- secret/vault/update.go | 8 ++++++++ secret/vault/update_test.go | 21 +++++++++++++++++++++ 11 files changed, 150 insertions(+), 46 deletions(-) diff --git a/secret/vault/create_test.go b/secret/vault/create_test.go index bcb41b60a..129b0e487 100644 --- a/secret/vault/create_test.go +++ b/secret/vault/create_test.go @@ -52,6 +52,13 @@ func TestVault_Create_Org(t *testing.T) { sec.SetType("org") sec.SetImages([]string{"foo", "bar"}) sec.SetEvents([]string{"foo", "bar"}) + sec.SetAllowCommand(true) + sec.SetAllowSubstitution(true) + sec.SetAllowEvents(library.NewEventsFromMask(1)) + sec.SetCreatedAt(1563474077) + sec.SetCreatedBy("octocat") + sec.SetUpdatedAt(1563474079) + sec.SetUpdatedBy("octocat2") type args struct { version string @@ -136,6 +143,13 @@ func TestVault_Create_Repo(t *testing.T) { sec.SetType("repo") sec.SetImages([]string{"foo", "bar"}) sec.SetEvents([]string{"foo", "bar"}) + sec.SetAllowCommand(true) + sec.SetAllowSubstitution(true) + sec.SetAllowEvents(library.NewEventsFromMask(3)) + sec.SetCreatedAt(1563474077) + sec.SetCreatedBy("octocat") + sec.SetUpdatedAt(1563474079) + sec.SetUpdatedBy("octocat2") type args struct { version string @@ -221,6 +235,13 @@ func TestVault_Create_Shared(t *testing.T) { sec.SetType("shared") sec.SetImages([]string{"foo", "bar"}) sec.SetEvents([]string{"foo", "bar"}) + sec.SetAllowCommand(false) + sec.SetAllowSubstitution(false) + sec.SetAllowEvents(library.NewEventsFromMask(1)) + sec.SetCreatedAt(1563474077) + sec.SetCreatedBy("octocat") + sec.SetUpdatedAt(1563474079) + sec.SetUpdatedBy("octocat2") type args struct { version string diff --git a/secret/vault/get_test.go b/secret/vault/get_test.go index 66f582727..2c811e9fd 100644 --- a/secret/vault/get_test.go +++ b/secret/vault/get_test.go @@ -52,6 +52,13 @@ func TestVault_Get_Org(t *testing.T) { want.SetType("org") want.SetImages([]string{"foo", "bar"}) want.SetEvents([]string{"foo", "bar"}) + want.SetAllowCommand(true) + want.SetAllowSubstitution(true) + want.SetAllowEvents(library.NewEventsFromMask(1)) + want.SetCreatedAt(1563474077) + want.SetCreatedBy("octocat") + want.SetUpdatedAt(1563474079) + want.SetUpdatedBy("octocat2") type args struct { version string @@ -136,6 +143,13 @@ func TestVault_Get_Repo(t *testing.T) { want.SetType("repo") want.SetImages([]string{"foo", "bar"}) want.SetEvents([]string{"foo", "bar"}) + want.SetAllowCommand(true) + want.SetAllowSubstitution(true) + want.SetAllowEvents(library.NewEventsFromMask(3)) + want.SetCreatedAt(1563474077) + want.SetCreatedBy("octocat") + want.SetUpdatedAt(1563474079) + want.SetUpdatedBy("octocat2") type args struct { version string @@ -220,6 +234,13 @@ func TestVault_Get_Shared(t *testing.T) { want.SetType("shared") want.SetImages([]string{"foo", "bar"}) want.SetEvents([]string{"foo", "bar"}) + want.SetAllowCommand(false) + want.SetAllowSubstitution(false) + want.SetAllowEvents(library.NewEventsFromMask(1)) + want.SetCreatedAt(1563474077) + want.SetCreatedBy("octocat") + want.SetUpdatedAt(1563474079) + want.SetUpdatedBy("octocat2") type args struct { version string diff --git a/secret/vault/list_test.go b/secret/vault/list_test.go index 127a127a2..3a6c2ab60 100644 --- a/secret/vault/list_test.go +++ b/secret/vault/list_test.go @@ -67,6 +67,13 @@ func TestVault_List_Org(t *testing.T) { sec.SetType("org") sec.SetImages([]string{"foo", "bar"}) sec.SetEvents([]string{"foo", "bar"}) + sec.SetAllowCommand(true) + sec.SetAllowSubstitution(true) + sec.SetAllowEvents(library.NewEventsFromMask(1)) + sec.SetCreatedAt(1563474077) + sec.SetCreatedBy("octocat") + sec.SetUpdatedAt(1563474079) + sec.SetUpdatedBy("octocat2") want := []*library.Secret{sec} @@ -198,6 +205,13 @@ func TestVault_List_Repo(t *testing.T) { sec.SetType("repo") sec.SetImages([]string{"foo", "bar"}) sec.SetEvents([]string{"foo", "bar"}) + sec.SetAllowCommand(true) + sec.SetAllowSubstitution(true) + sec.SetAllowEvents(library.NewEventsFromMask(3)) + sec.SetCreatedAt(1563474077) + sec.SetCreatedBy("octocat") + sec.SetUpdatedAt(1563474079) + sec.SetUpdatedBy("octocat2") want := []*library.Secret{sec} @@ -314,6 +328,13 @@ func TestVault_List_Shared(t *testing.T) { sec.SetType("shared") sec.SetImages([]string{"foo", "bar"}) sec.SetEvents([]string{"foo", "bar"}) + sec.SetAllowCommand(false) + sec.SetAllowSubstitution(false) + sec.SetAllowEvents(library.NewEventsFromMask(1)) + sec.SetCreatedAt(1563474077) + sec.SetCreatedBy("octocat") + sec.SetUpdatedAt(1563474079) + sec.SetUpdatedBy("octocat2") want := []*library.Secret{sec} diff --git a/secret/vault/testdata/v1/org.json b/secret/vault/testdata/v1/org.json index f73f1769e..bfae2f798 100644 --- a/secret/vault/testdata/v1/org.json +++ b/secret/vault/testdata/v1/org.json @@ -16,7 +16,14 @@ "org": "foo", "repo": "*", "type": "org", - "value": "baz" + "value": "baz", + "allow_command": true, + "allow_substitution": true, + "allow_events": 1, + "created_at": 1563474077, + "created_by": "octocat", + "updated_at": 1563474079, + "updated_by": "octocat2" }, "wrap_info": null, "warnings": null, diff --git a/secret/vault/testdata/v1/repo.json b/secret/vault/testdata/v1/repo.json index f0ef1d417..a4b983696 100644 --- a/secret/vault/testdata/v1/repo.json +++ b/secret/vault/testdata/v1/repo.json @@ -4,19 +4,20 @@ "renewable": false, "lease_duration": 2764800, "data": { - "events": [ - "foo", - "bar" - ], - "images": [ - "foo", - "bar" - ], + "events": ["foo", "bar"], + "images": ["foo", "bar"], "name": "baz", "org": "foo", "repo": "bar", "type": "repo", - "value": "foob" + "value": "foob", + "allow_command": true, + "allow_substitution": true, + "allow_events": 3, + "created_at": 1563474077, + "created_by": "octocat", + "updated_at": 1563474079, + "updated_by": "octocat2" }, "wrap_info": null, "warnings": null, diff --git a/secret/vault/testdata/v1/shared.json b/secret/vault/testdata/v1/shared.json index 6d070ae6f..e070dff61 100644 --- a/secret/vault/testdata/v1/shared.json +++ b/secret/vault/testdata/v1/shared.json @@ -4,19 +4,20 @@ "renewable": false, "lease_duration": 2764800, "data": { - "events": [ - "foo", - "bar" - ], - "images": [ - "foo", - "bar" - ], + "events": ["foo", "bar"], + "images": ["foo", "bar"], "name": "baz", "org": "foo", "team": "bar", "type": "shared", - "value": "foob" + "value": "foob", + "allow_command": false, + "allow_substitution": false, + "allow_events": 1, + "created_at": 1563474077, + "created_by": "octocat", + "updated_at": 1563474079, + "updated_by": "octocat2" }, "wrap_info": null, "warnings": null, diff --git a/secret/vault/testdata/v2/org.json b/secret/vault/testdata/v2/org.json index 8aabdab2c..0ae9c8bd1 100644 --- a/secret/vault/testdata/v2/org.json +++ b/secret/vault/testdata/v2/org.json @@ -5,19 +5,20 @@ "renewable": false, "data": { "data": { - "events": [ - "foo", - "bar" - ], - "images": [ - "foo", - "bar" - ], + "events": ["foo", "bar"], + "images": ["foo", "bar"], "name": "bar", "org": "foo", "repo": "*", "type": "org", - "value": "baz" + "value": "baz", + "allow_command": true, + "allow_substitution": true, + "allow_events": 1, + "created_at": 1563474077, + "created_by": "octocat", + "updated_at": 1563474079, + "updated_by": "octocat2" }, "metadata": { "created_time": "2020-08-14T15:43:44.3462581Z", diff --git a/secret/vault/testdata/v2/repo.json b/secret/vault/testdata/v2/repo.json index bec309b84..29b3e7569 100644 --- a/secret/vault/testdata/v2/repo.json +++ b/secret/vault/testdata/v2/repo.json @@ -5,19 +5,20 @@ "renewable": false, "data": { "data": { - "events": [ - "foo", - "bar" - ], - "images": [ - "foo", - "bar" - ], + "events": ["foo", "bar"], + "images": ["foo", "bar"], "name": "baz", "org": "foo", "repo": "bar", "type": "repo", - "value": "foob" + "value": "foob", + "allow_command": true, + "allow_substitution": true, + "allow_events": 3, + "created_at": 1563474077, + "created_by": "octocat", + "updated_at": 1563474079, + "updated_by": "octocat2" }, "metadata": { "created_time": "2020-08-14T15:43:44.3462581Z", diff --git a/secret/vault/testdata/v2/shared.json b/secret/vault/testdata/v2/shared.json index ffb6c84f0..961da3c6b 100644 --- a/secret/vault/testdata/v2/shared.json +++ b/secret/vault/testdata/v2/shared.json @@ -5,19 +5,20 @@ "renewable": false, "data": { "data": { - "events": [ - "foo", - "bar" - ], - "images": [ - "foo", - "bar" - ], + "events": ["foo", "bar"], + "images": ["foo", "bar"], "name": "baz", "org": "foo", "team": "bar", "type": "shared", - "value": "foob" + "value": "foob", + "allow_command": false, + "allow_substitution": false, + "allow_events": 1, + "created_at": 1563474077, + "created_by": "octocat", + "updated_at": 1563474079, + "updated_by": "octocat2" }, "metadata": { "created_time": "2020-08-14T15:43:44.3462581Z", diff --git a/secret/vault/update.go b/secret/vault/update.go index 9082b2ff4..5655dcb9d 100644 --- a/secret/vault/update.go +++ b/secret/vault/update.go @@ -49,6 +49,10 @@ func (c *client) Update(ctx context.Context, sType, org, name string, s *library vault.Data["events"] = s.GetEvents() } + if s.GetAllowEvents().ToDatabase() != 0 { + vault.Data["allow_events"] = s.GetAllowEvents().ToDatabase() + } + if s.Images != nil { vault.Data["images"] = s.GetImages() } @@ -61,6 +65,10 @@ func (c *client) Update(ctx context.Context, sType, org, name string, s *library vault.Data["allow_command"] = s.GetAllowCommand() } + if s.AllowSubstitution != nil { + vault.Data["allow_substitution"] = s.GetAllowSubstitution() + } + // validate the secret err = database.SecretFromLibrary(secretFromVault(vault)).Validate() if err != nil { diff --git a/secret/vault/update_test.go b/secret/vault/update_test.go index c17c2c936..94f247c7e 100644 --- a/secret/vault/update_test.go +++ b/secret/vault/update_test.go @@ -67,6 +67,13 @@ func TestVault_Update_Org(t *testing.T) { sec.SetType("org") sec.SetImages([]string{"foo", "bar"}) sec.SetEvents([]string{"foo", "bar"}) + sec.SetAllowCommand(true) + sec.SetAllowSubstitution(true) + sec.SetAllowEvents(library.NewEventsFromMask(1)) + sec.SetCreatedAt(1563474077) + sec.SetCreatedBy("octocat") + sec.SetUpdatedAt(1563474079) + sec.SetUpdatedBy("octocat2") type args struct { version string @@ -167,6 +174,13 @@ func TestVault_Update_Repo(t *testing.T) { sec.SetType("repo") sec.SetImages([]string{"foo", "bar"}) sec.SetEvents([]string{"foo", "bar"}) + sec.SetAllowCommand(true) + sec.SetAllowSubstitution(true) + sec.SetAllowEvents(library.NewEventsFromMask(3)) + sec.SetCreatedAt(1563474077) + sec.SetCreatedBy("octocat") + sec.SetUpdatedAt(1563474079) + sec.SetUpdatedBy("octocat2") type args struct { version string @@ -267,6 +281,13 @@ func TestVault_Update_Shared(t *testing.T) { sec.SetType("shared") sec.SetImages([]string{"foo", "bar"}) sec.SetEvents([]string{"foo", "bar"}) + sec.SetAllowCommand(false) + sec.SetAllowSubstitution(false) + sec.SetAllowEvents(library.NewEventsFromMask(1)) + sec.SetCreatedAt(1563474077) + sec.SetCreatedBy("octocat") + sec.SetUpdatedAt(1563474079) + sec.SetUpdatedBy("octocat2") type args struct { version string From 219ab9197d423bc69443be8a7b7eebbeec857fff Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Fri, 15 Mar 2024 14:41:10 -0400 Subject: [PATCH 10/71] fix(vault): parse pre-v0.23 vault secrets (#1086) * fix(vault): parse pre-v0.23 vault secrets * linter overlord --- secret/vault/vault.go | 40 ++++++++++++++++++++++++++++++++++++++ secret/vault/vault_test.go | 30 ++++++++++++++++++++++++---- 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/secret/vault/vault.go b/secret/vault/vault.go index dab603db0..d9f3d79b5 100644 --- a/secret/vault/vault.go +++ b/secret/vault/vault.go @@ -8,6 +8,7 @@ import ( "time" "github.com/aws/aws-sdk-go/service/sts/stsiface" + "github.com/go-vela/types/constants" "github.com/go-vela/types/library" "github.com/hashicorp/vault/api" "github.com/pkg/errors" @@ -157,6 +158,7 @@ func secretFromVault(vault *api.Secret) *library.Secret { } } + // set allow_events if found in Vault secret v, ok = data["allow_events"] if ok { maskJSON, ok := v.(json.Number) @@ -166,6 +168,35 @@ func secretFromVault(vault *api.Secret) *library.Secret { s.SetAllowEvents(library.NewEventsFromMask(mask)) } } + } else { + // if not found, convert events to allow_events + // this happens when vault secret has not been updated since before v0.23 + events, ok := data["events"] + if ok { + allowEventsMask := int64(0) + + for _, element := range events.([]interface{}) { + event, ok := element.(string) + if ok { + switch event { + case constants.EventPush: + allowEventsMask |= constants.AllowPushBranch + case constants.EventPull: + allowEventsMask |= constants.AllowPullOpen | constants.AllowPullReopen | constants.AllowPullSync + case constants.EventComment: + allowEventsMask |= constants.AllowCommentCreate | constants.AllowCommentEdit + case constants.EventDeploy: + allowEventsMask |= constants.AllowDeployCreate + case constants.EventTag: + allowEventsMask |= constants.AllowPushTag + case constants.EventSchedule: + allowEventsMask |= constants.AllowSchedule + } + } + } + + s.SetAllowEvents(library.NewEventsFromMask(allowEventsMask)) + } } // set images if found in Vault secret @@ -252,6 +283,15 @@ func secretFromVault(vault *api.Secret) *library.Secret { if ok { s.SetAllowSubstitution(substitution) } + } else { + // set allow_substitution to allow_command value if not found in Vault secret + cmd, ok := data["allow_command"] + if ok { + command, ok := cmd.(bool) + if ok { + s.SetAllowSubstitution(command) + } + } } // set created_at if found in Vault secret diff --git a/secret/vault/vault_test.go b/secret/vault/vault_test.go index 8893d5c3c..cec5d02c8 100644 --- a/secret/vault/vault_test.go +++ b/secret/vault/vault_test.go @@ -105,6 +105,27 @@ func TestVault_secretFromVault(t *testing.T) { }, } + // test vault secret from pre-v0.23 release + inputLegacy := &api.Secret{ + Data: map[string]interface{}{ + "data": map[string]interface{}{ + "events": []interface{}{"push", "tag", "deployment"}, + "images": []interface{}{"foo", "bar"}, + "name": "bar", + "org": "foo", + "repo": "*", + "team": "foob", + "type": "org", + "value": "baz", + "allow_command": true, + "created_at": json.Number("1563474077"), + "created_by": "octocat", + "updated_at": json.Number("1563474079"), + "updated_by": "octocat2", + }, + }, + } + want := new(library.Secret) want.SetOrg("foo") want.SetRepo("*") @@ -112,8 +133,8 @@ func TestVault_secretFromVault(t *testing.T) { want.SetName("bar") want.SetValue("baz") want.SetType("org") - want.SetEvents([]string{"foo", "bar"}) - want.SetAllowEvents(library.NewEventsFromMask(1)) + want.SetEvents([]string{"push", "tag", "deployment"}) + want.SetAllowEvents(library.NewEventsFromMask(8195)) want.SetImages([]string{"foo", "bar"}) want.SetAllowCommand(true) want.SetAllowSubstitution(true) @@ -132,6 +153,7 @@ func TestVault_secretFromVault(t *testing.T) { }{ {"v1", args{secret: inputV1}}, {"v2", args{secret: inputV2}}, + {"legacy", args{secret: inputLegacy}}, } for _, tt := range tests { @@ -221,8 +243,8 @@ func TestVault_AccurateSecretFields(t *testing.T) { // helper function to return a test Vault secret data. func testVaultSecretData() map[string]interface{} { return map[string]interface{}{ - "events": []interface{}{"foo", "bar"}, - "allow_events": json.Number("1"), + "events": []interface{}{"push", "tag", "deployment"}, + "allow_events": json.Number("8195"), "images": []interface{}{"foo", "bar"}, "name": "bar", "org": "foo", From fd0dc1c5c32f5cbfc80bbfcec050bfd6c1893322 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 15 Mar 2024 13:44:43 -0500 Subject: [PATCH 11/71] fix(deps): update all non-major dependencies (#1080) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 18 ++++++++---------- go.sum | 45 ++++++++++++++++++++------------------------- 2 files changed, 28 insertions(+), 35 deletions(-) diff --git a/go.mod b/go.mod index e54e31377..00c81a760 100644 --- a/go.mod +++ b/go.mod @@ -7,9 +7,9 @@ require ( github.com/DATA-DOG/go-sqlmock v1.5.2 github.com/Masterminds/semver/v3 v3.2.1 github.com/Masterminds/sprig/v3 v3.2.3 - github.com/adhocore/gronx v1.8.0 - github.com/alicebob/miniredis/v2 v2.31.1 - github.com/aws/aws-sdk-go v1.50.37 + github.com/adhocore/gronx v1.8.1 + github.com/alicebob/miniredis/v2 v2.32.1 + github.com/aws/aws-sdk-go v1.51.0 github.com/buildkite/yaml v0.0.0-20181016232759-0caa5f0796e3 github.com/drone/envsubst v1.0.3 github.com/gin-gonic/gin v1.9.1 @@ -23,7 +23,7 @@ require ( github.com/hashicorp/go-cleanhttp v0.5.2 github.com/hashicorp/go-multierror v1.1.1 github.com/hashicorp/go-retryablehttp v0.7.5 - github.com/hashicorp/vault/api v1.12.0 + github.com/hashicorp/vault/api v1.12.1 github.com/joho/godotenv v1.5.1 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.19.0 @@ -31,7 +31,7 @@ require ( github.com/sirupsen/logrus v1.9.3 github.com/spf13/afero v1.11.0 github.com/urfave/cli/v2 v2.27.1 - go.starlark.net v0.0.0-20240311180835-efac67204ba7 + go.starlark.net v0.0.0-20240314022150-ee8ed142361c golang.org/x/crypto v0.21.0 golang.org/x/oauth2 v0.18.0 golang.org/x/sync v0.6.0 @@ -55,7 +55,6 @@ require ( github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/fatih/color v1.10.0 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/ghodss/yaml v1.0.0 // indirect github.com/gin-contrib/sse v0.1.0 // indirect @@ -90,8 +89,7 @@ require ( github.com/kr/text v0.2.0 // indirect github.com/leodido/go-urn v1.2.4 // indirect github.com/lib/pq v1.10.9 // indirect - github.com/mattn/go-colorable v0.1.8 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-sqlite3 v1.14.17 // indirect github.com/microcosm-cc/bluemonday v1.0.26 // indirect github.com/mitchellh/copystructure v1.0.0 // indirect @@ -111,14 +109,14 @@ require ( github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.11 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect - github.com/yuin/gopher-lua v1.1.0 // indirect + github.com/yuin/gopher-lua v1.1.1 // indirect golang.org/x/arch v0.3.0 // indirect golang.org/x/net v0.22.0 // indirect golang.org/x/sys v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.5.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/protobuf v1.32.0 // indirect + google.golang.org/protobuf v1.33.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/klog/v2 v2.110.1 // indirect diff --git a/go.sum b/go.sum index 1cac891fb..016bf5cbe 100644 --- a/go.sum +++ b/go.sum @@ -2,7 +2,6 @@ github.com/Bose/minisentinel v0.0.0-20200130220412-917c5a9223bb h1:ZVN4Iat3runWO github.com/Bose/minisentinel v0.0.0-20200130220412-917c5a9223bb/go.mod h1:WsAABbY4HQBgd3mGuG4KMNTbHJCPvx9IVBHzysbknss= github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU= github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU= -github.com/DmitriyVTitov/size v1.5.0/go.mod h1:le6rNI4CoLQV1b9gzp1+3d7hMAD/uu2QcJ+aYbNgiU0= github.com/FZambia/sentinel v1.0.0 h1:KJ0ryjKTZk5WMp0dXvSdNqp3lFaW1fNFuEYfrkLOYIc= github.com/FZambia/sentinel v1.0.0/go.mod h1:ytL1Am/RLlAoAXG6Kj5LNuw/TRRQrv2rt2FT26vP5gI= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= @@ -16,17 +15,17 @@ github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tN github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/adhocore/gronx v1.8.0 h1:BHgzaGyS7zPmuMVqiIxyAwvKpwAX+bR7bCxDVacfhuo= -github.com/adhocore/gronx v1.8.0/go.mod h1:7oUY1WAU8rEJWmAxXR2DN0JaO4gi9khSgKjiRypqteg= +github.com/adhocore/gronx v1.8.1 h1:F2mLTG5sB11z7vplwD4iydz3YCEjstSfYmCrdSm3t6A= +github.com/adhocore/gronx v1.8.1/go.mod h1:7oUY1WAU8rEJWmAxXR2DN0JaO4gi9khSgKjiRypqteg= github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a h1:HbKu58rmZpUGpz5+4FfNmIU+FmZg2P3Xaj2v2bfNWmk= github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= github.com/alicebob/miniredis/v2 v2.11.1/go.mod h1:UA48pmi7aSazcGAvcdKcBB49z521IC9VjTTRz2nIaJE= -github.com/alicebob/miniredis/v2 v2.31.1 h1:7XAt0uUg3DtwEKW5ZAGa+K7FZV2DdKQo5K/6TTnfX8Y= -github.com/alicebob/miniredis/v2 v2.31.1/go.mod h1:UB/T2Uztp7MlFSDakaX1sTXUv5CASoprx0wulRT6HBg= +github.com/alicebob/miniredis/v2 v2.32.1 h1:Bz7CciDnYSaa0mX5xODh6GUITRSx+cVhjNoOR4JssBo= +github.com/alicebob/miniredis/v2 v2.32.1/go.mod h1:AqkLNAfUm0K07J28hnAyyQKf/x0YkCY/g5DCtuL01Mw= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/aws/aws-sdk-go v1.50.37 h1:gnAf6eYPSTb4QpVwugtWFqD07QXOoX7LewRrtLUx3lI= -github.com/aws/aws-sdk-go v1.50.37/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/aws/aws-sdk-go v1.51.0 h1:EA6GlEYMT3ouCO+v+oTWzKB/vcoHD2T9H9qulRx3lPg= +github.com/aws/aws-sdk-go v1.51.0/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -62,8 +61,8 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cu github.com/drone/envsubst v1.0.3 h1:PCIBwNDYjs50AsLZPYdfhSATKaRg/FJmDc2D6+C2x8g= github.com/drone/envsubst v1.0.3/go.mod h1:N2jZmlMufstn1KEqvbHjw40h1KyTmnVzHcSc9bFiJ2g= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg= -github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= @@ -94,7 +93,6 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= @@ -146,8 +144,8 @@ github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0S github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/vault/api v1.12.0 h1:meCpJSesvzQyao8FCOgk2fGdoADAnbDu2WPJN1lDLJ4= -github.com/hashicorp/vault/api v1.12.0/go.mod h1:si+lJCYO7oGkIoNPAN8j3azBLTn9SjMGS+jFaHd1Cck= +github.com/hashicorp/vault/api v1.12.1 h1:WzGN4X5jrJdNO39g6Sa55djNio3I9DxEBOTmCZE7tm0= +github.com/hashicorp/vault/api v1.12.1/go.mod h1:1pqP/sErScodde+ybJCyP+ONC4jzEg7Dmawg/QLWo1k= github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4= github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA= @@ -187,12 +185,11 @@ github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A= github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM= github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/microcosm-cc/bluemonday v1.0.26 h1:xbqSvqzQMeEHCqMi64VAs4d8uy6Mequs3rQ0k/Khz58= @@ -273,10 +270,10 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/gopher-lua v0.0.0-20190206043414-8bfc7677f583/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ= github.com/yuin/gopher-lua v0.0.0-20191213034115-f46add6fdb5c/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ= -github.com/yuin/gopher-lua v1.1.0 h1:BojcDhfyDWgU2f2TOzYK/g5p2gxMrku8oupLDqlnSqE= -github.com/yuin/gopher-lua v1.1.0/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= -go.starlark.net v0.0.0-20240311180835-efac67204ba7 h1:xH7OJPtjgdj/xXykge/wGPAAqik97FbEVJR55lEY0tQ= -go.starlark.net v0.0.0-20240311180835-efac67204ba7/go.mod h1:MrdO7XaMF3dE3MzuP6mrG0EB3NC7rLWSiEcu9Ii50g8= +github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M= +github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= +go.starlark.net v0.0.0-20240314022150-ee8ed142361c h1:roAjH18hZcwI4hHStHbkXjF5b7UUyZ/0SG3hXNN1SjA= +go.starlark.net v0.0.0-20240314022150-ee8ed142361c/go.mod h1:YKMCv9b1WrfWmeqdV5MAuEHWsu5iC+fe6kYl2sQjdI8= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= @@ -318,8 +315,6 @@ golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -365,8 +360,8 @@ google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6 google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= -google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= From f77ef48a8bce62907561d073e028fe9b330222a7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Mar 2024 13:49:15 -0500 Subject: [PATCH 12/71] chore(deps): bump github.com/jackc/pgx/v5 from 5.4.3 to 5.5.4 (#1084) Bumps [github.com/jackc/pgx/v5](https://github.com/jackc/pgx) from 5.4.3 to 5.5.4. - [Changelog](https://github.com/jackc/pgx/blob/master/CHANGELOG.md) - [Commits](https://github.com/jackc/pgx/compare/v5.4.3...v5.5.4) --- updated-dependencies: - dependency-name: github.com/jackc/pgx/v5 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 3 ++- go.sum | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 00c81a760..745dcc4c5 100644 --- a/go.mod +++ b/go.mod @@ -80,7 +80,8 @@ require ( github.com/imdario/mergo v0.3.11 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect - github.com/jackc/pgx/v5 v5.4.3 // indirect + github.com/jackc/pgx/v5 v5.5.4 // indirect + github.com/jackc/puddle/v2 v2.2.1 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect diff --git a/go.sum b/go.sum index 016bf5cbe..7493cb0e0 100644 --- a/go.sum +++ b/go.sum @@ -154,8 +154,10 @@ github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsI github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= -github.com/jackc/pgx/v5 v5.4.3 h1:cxFyXhxlvAifxnkKKdlxv8XqUf59tDlYjnV5YYfsJJY= -github.com/jackc/pgx/v5 v5.4.3/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA= +github.com/jackc/pgx/v5 v5.5.4 h1:Xp2aQS8uXButQdnCMWNmvx6UysWQQC+u1EoizjguY+8= +github.com/jackc/pgx/v5 v5.5.4/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A= +github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk= +github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= From 1809638e7e729857c4ae9fb441796644ddb9aa1a Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Tue, 19 Mar 2024 12:11:25 -0400 Subject: [PATCH 13/71] refactor(types)!: move worker type to server and nest API object (#997) * refactor(types): move worker type to server and nest API object * fix integration test * appease linter overlord * fix double param error * remove database types and be consistent with api types imports * allow for exclaim * remove library references and remove stutter * fix: use concrete list var * fix: test pointer --------- Co-authored-by: Jordan Brockopp Co-authored-by: davidvader --- .github/workflows/validate-pr-title.yml | 2 +- api/types/worker.go | 370 +++++++++++++++++++++++ api/types/worker_test.go | 224 ++++++++++++++ api/worker/create.go | 3 +- api/worker/get.go | 18 +- api/worker/list.go | 23 +- api/worker/update.go | 8 +- database/integration_test.go | 19 +- database/worker/create.go | 9 +- database/worker/create_test.go | 2 +- database/worker/delete.go | 7 +- database/worker/get.go | 9 +- database/worker/get_hostname.go | 9 +- database/worker/get_hostname_test.go | 5 +- database/worker/get_test.go | 5 +- database/worker/interface.go | 14 +- database/worker/list.go | 15 +- database/worker/list_test.go | 15 +- database/worker/update.go | 9 +- database/worker/update_test.go | 2 +- database/worker/worker.go | 204 +++++++++++++ database/worker/worker_test.go | 52 +++- go.mod | 4 +- mock/server/worker.go | 124 +++++++- mock/server/worker_test.go | 23 +- router/middleware/logger_test.go | 3 +- router/middleware/worker/context.go | 8 +- router/middleware/worker/context_test.go | 6 +- router/middleware/worker/worker.go | 4 +- router/middleware/worker/worker_test.go | 12 +- util/util.go | 33 ++ util/util_test.go | 83 +++++ 32 files changed, 1222 insertions(+), 102 deletions(-) create mode 100644 api/types/worker.go create mode 100644 api/types/worker_test.go create mode 100644 util/util_test.go diff --git a/.github/workflows/validate-pr-title.yml b/.github/workflows/validate-pr-title.yml index 462f9be92..ec3674f79 100644 --- a/.github/workflows/validate-pr-title.yml +++ b/.github/workflows/validate-pr-title.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)(\(.*\)|):\s.+$' && (echo "Pass"; exit 0) || (echo "Incorrect Format. Please see https://go-vela.github.io/docs/community/contributing_guidelines/#development-workflow"; exit 1) + 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) diff --git a/api/types/worker.go b/api/types/worker.go new file mode 100644 index 000000000..4c06a0e69 --- /dev/null +++ b/api/types/worker.go @@ -0,0 +1,370 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "fmt" + + "github.com/go-vela/types/library" +) + +// Worker is the API representation of a worker. +// +// swagger:model Worker +type Worker struct { + ID *int64 `json:"id,omitempty"` + Hostname *string `json:"hostname,omitempty"` + Address *string `json:"address,omitempty"` + Routes *[]string `json:"routes,omitempty"` + Active *bool `json:"active,omitempty"` + Status *string `json:"status,omitempty"` + LastStatusUpdateAt *int64 `json:"last_status_update_at,omitempty"` + RunningBuilds *[]*library.Build `json:"running_builds,omitempty"` + LastBuildStartedAt *int64 `json:"last_build_started_at,omitempty"` + LastBuildFinishedAt *int64 `json:"last_build_finished_at,omitempty"` + LastCheckedIn *int64 `json:"last_checked_in,omitempty"` + BuildLimit *int64 `json:"build_limit,omitempty"` +} + +// GetID returns the ID field. +// +// When the provided Worker type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (w *Worker) GetID() int64 { + // return zero value if Worker type or ID field is nil + if w == nil || w.ID == nil { + return 0 + } + + return *w.ID +} + +// GetHostname returns the Hostname field. +// +// When the provided Worker type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (w *Worker) GetHostname() string { + // return zero value if Worker type or Hostname field is nil + if w == nil || w.Hostname == nil { + return "" + } + + return *w.Hostname +} + +// GetAddress returns the Address field. +// +// When the provided Worker type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (w *Worker) GetAddress() string { + // return zero value if Worker type or Address field is nil + if w == nil || w.Address == nil { + return "" + } + + return *w.Address +} + +// GetRoutes returns the Routes field. +// +// When the provided Worker type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (w *Worker) GetRoutes() []string { + // return zero value if Worker type or Routes field is nil + if w == nil || w.Routes == nil { + return []string{} + } + + return *w.Routes +} + +// GetActive returns the Active field. +// +// When the provided Worker type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (w *Worker) GetActive() bool { + // return zero value if Worker type or Active field is nil + if w == nil || w.Active == nil { + return false + } + + return *w.Active +} + +// GetStatus returns the Status field. +// +// When the provided Worker type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (w *Worker) GetStatus() string { + // return zero value if Worker type or Status field is nil + if w == nil || w.Status == nil { + return "" + } + + return *w.Status +} + +// GetLastStatusUpdateAt returns the LastStatusUpdateAt field. +// +// When the provided Worker type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (w *Worker) GetLastStatusUpdateAt() int64 { + // return zero value if Worker type or LastStatusUpdateAt field is nil + if w == nil || w.LastStatusUpdateAt == nil { + return 0 + } + + return *w.LastStatusUpdateAt +} + +// GetRunningBuilds returns the RunningBuilds field. +// +// When the provided Worker type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (w *Worker) GetRunningBuilds() []*library.Build { + // return zero value if Worker type or RunningBuilds field is nil + if w == nil || w.RunningBuilds == nil { + return []*library.Build{} + } + + return *w.RunningBuilds +} + +// GetLastBuildStartedAt returns the LastBuildStartedAt field. +// +// When the provided Worker type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (w *Worker) GetLastBuildStartedAt() int64 { + // return zero value if Worker type or LastBuildStartedAt field is nil + if w == nil || w.LastBuildStartedAt == nil { + return 0 + } + + return *w.LastBuildStartedAt +} + +// GetLastBuildFinishedAt returns the LastBuildFinishedAt field. +// +// When the provided Worker type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (w *Worker) GetLastBuildFinishedAt() int64 { + // return zero value if Worker type or LastBuildFinishedAt field is nil + if w == nil || w.LastBuildFinishedAt == nil { + return 0 + } + + return *w.LastBuildFinishedAt +} + +// GetLastCheckedIn returns the LastCheckedIn field. +// +// When the provided Worker type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (w *Worker) GetLastCheckedIn() int64 { + // return zero value if Worker type or LastCheckedIn field is nil + if w == nil || w.LastCheckedIn == nil { + return 0 + } + + return *w.LastCheckedIn +} + +// GetBuildLimit returns the BuildLimit field. +// +// When the provided Worker type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (w *Worker) GetBuildLimit() int64 { + // return zero value if Worker type or BuildLimit field is nil + if w == nil || w.BuildLimit == nil { + return 0 + } + + return *w.BuildLimit +} + +// SetID sets the ID field. +// +// When the provided Worker type is nil, it +// will set nothing and immediately return. +func (w *Worker) SetID(v int64) { + // return if Worker type is nil + if w == nil { + return + } + + w.ID = &v +} + +// SetHostname sets the Hostname field. +// +// When the provided Worker type is nil, it +// will set nothing and immediately return. +func (w *Worker) SetHostname(v string) { + // return if Worker type is nil + if w == nil { + return + } + + w.Hostname = &v +} + +// SetAddress sets the Address field. +// +// When the provided Worker type is nil, it +// will set nothing and immediately return. +func (w *Worker) SetAddress(v string) { + // return if Worker type is nil + if w == nil { + return + } + + w.Address = &v +} + +// SetRoutes sets the Routes field. +// +// When the provided Worker type is nil, it +// will set nothing and immediately return. +func (w *Worker) SetRoutes(v []string) { + // return if Worker type is nil + if w == nil { + return + } + + w.Routes = &v +} + +// SetActive sets the Active field. +// +// When the provided Worker type is nil, it +// will set nothing and immediately return. +func (w *Worker) SetActive(v bool) { + // return if Worker type is nil + if w == nil { + return + } + + w.Active = &v +} + +// SetStatus sets the Status field. +// +// When the provided Worker type is nil, it +// will set nothing and immediately return. +func (w *Worker) SetStatus(v string) { + // return if Worker type is nil + if w == nil { + return + } + + w.Status = &v +} + +// SetLastStatusUpdateAt sets the LastStatusUpdateAt field. +// +// When the provided Worker type is nil, it +// will set nothing and immediately return. +func (w *Worker) SetLastStatusUpdateAt(v int64) { + // return if Worker type is nil + if w == nil { + return + } + + w.LastStatusUpdateAt = &v +} + +// SetRunningBuilds sets the RunningBuilds field. +// +// When the provided Worker type is nil, it +// will set nothing and immediately return. +func (w *Worker) SetRunningBuilds(builds []*library.Build) { + // return if Worker type is nil + if w == nil { + return + } + + w.RunningBuilds = &builds +} + +// SetLastBuildStartedAt sets the LastBuildStartedAt field. +// +// When the provided Worker type is nil, it +// will set nothing and immediately return. +func (w *Worker) SetLastBuildStartedAt(v int64) { + // return if Worker type is nil + if w == nil { + return + } + + w.LastBuildStartedAt = &v +} + +// SetLastBuildFinishedAt sets the LastBuildFinishedAt field. +// +// When the provided Worker type is nil, it +// will set nothing and immediately return. +func (w *Worker) SetLastBuildFinishedAt(v int64) { + // return if Worker type is nil + if w == nil { + return + } + + w.LastBuildFinishedAt = &v +} + +// SetLastCheckedIn sets the LastCheckedIn field. +// +// When the provided Worker type is nil, it +// will set nothing and immediately return. +func (w *Worker) SetLastCheckedIn(v int64) { + // return if Worker type is nil + if w == nil { + return + } + + w.LastCheckedIn = &v +} + +// SetBuildLimit sets the LastBuildLimit field. +// +// When the provided Worker type is nil, it +// will set nothing and immediately return. +func (w *Worker) SetBuildLimit(v int64) { + // return if Worker type is nil + if w == nil { + return + } + + w.BuildLimit = &v +} + +// String implements the Stringer interface for the Worker type. +func (w *Worker) String() string { + return fmt.Sprintf(`{ + ID: %d, + Hostname: %s, + Address: %s, + Routes: %s, + Active: %t, + Status: %s, + LastStatusUpdateAt: %v, + LastBuildStartedAt: %v, + LastBuildFinishedAt: %v, + LastCheckedIn: %v, + BuildLimit: %v, + RunningBuilds: %v, +}`, + w.GetID(), + w.GetHostname(), + w.GetAddress(), + w.GetRoutes(), + w.GetActive(), + w.GetStatus(), + w.GetLastStatusUpdateAt(), + w.GetLastBuildStartedAt(), + w.GetLastBuildFinishedAt(), + w.GetLastCheckedIn(), + w.GetBuildLimit(), + w.GetRunningBuilds(), + ) +} diff --git a/api/types/worker_test.go b/api/types/worker_test.go new file mode 100644 index 000000000..19d2defb5 --- /dev/null +++ b/api/types/worker_test.go @@ -0,0 +1,224 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "fmt" + "reflect" + "testing" + "time" + + "github.com/go-vela/types/library" +) + +func TestTypes_Worker_Getters(t *testing.T) { + // setup tests + tests := []struct { + worker *Worker + want *Worker + }{ + { + worker: testWorker(), + want: testWorker(), + }, + { + worker: new(Worker), + want: new(Worker), + }, + } + + // run tests + for _, test := range tests { + if test.worker.GetID() != test.want.GetID() { + t.Errorf("GetID is %v, want %v", test.worker.GetID(), test.want.GetID()) + } + + if test.worker.GetHostname() != test.want.GetHostname() { + t.Errorf("GetHostname is %v, want %v", test.worker.GetHostname(), test.want.GetHostname()) + } + + if test.worker.GetAddress() != test.want.GetAddress() { + t.Errorf("Getaddress is %v, want %v", test.worker.GetAddress(), test.want.GetAddress()) + } + + if !reflect.DeepEqual(test.worker.GetRoutes(), test.want.GetRoutes()) { + t.Errorf("GetRoutes is %v, want %v", test.worker.GetRoutes(), test.want.GetRoutes()) + } + + if test.worker.GetActive() != test.want.GetActive() { + t.Errorf("GetActive is %v, want %v", test.worker.GetActive(), test.want.GetActive()) + } + + if test.worker.GetStatus() != test.want.GetStatus() { + t.Errorf("GetStatus is %v, want %v", test.worker.GetStatus(), test.want.GetStatus()) + } + + if test.worker.GetLastStatusUpdateAt() != test.want.GetLastStatusUpdateAt() { + t.Errorf("GetLastStatusUpdateAt is %v, want %v", test.worker.GetLastStatusUpdateAt(), test.want.GetLastStatusUpdateAt()) + } + + if !reflect.DeepEqual(test.worker.GetRunningBuilds(), test.want.GetRunningBuilds()) { + t.Errorf("GetRunningBuildIDs is %v, want %v", test.worker.GetRunningBuilds(), test.want.GetRunningBuilds()) + } + + if test.worker.GetLastBuildStartedAt() != test.want.GetLastBuildStartedAt() { + t.Errorf("GetLastBuildStartedAt is %v, want %v", test.worker.GetLastBuildStartedAt(), test.want.GetLastBuildStartedAt()) + } + + if test.worker.GetLastBuildFinishedAt() != test.want.GetLastBuildFinishedAt() { + t.Errorf("GetLastBuildFinishedAt is %v, want %v", test.worker.GetLastBuildFinishedAt(), test.want.GetLastBuildFinishedAt()) + } + + if test.worker.GetLastCheckedIn() != test.want.GetLastCheckedIn() { + t.Errorf("GetLastCheckedIn is %v, want %v", test.worker.GetLastCheckedIn(), test.want.GetLastCheckedIn()) + } + + if test.worker.GetBuildLimit() != test.want.GetBuildLimit() { + t.Errorf("GetBuildLimit is %v, want %v", test.worker.GetBuildLimit(), test.want.GetBuildLimit()) + } + } +} + +func TestTypes_Worker_Setters(t *testing.T) { + // setup types + var w *Worker + + // setup tests + tests := []struct { + worker *Worker + want *Worker + }{ + { + worker: testWorker(), + want: testWorker(), + }, + { + worker: w, + want: new(Worker), + }, + } + + // run tests + for _, test := range tests { + test.worker.SetID(test.want.GetID()) + test.worker.SetHostname(test.want.GetHostname()) + test.worker.SetAddress(test.want.GetAddress()) + test.worker.SetRoutes(test.want.GetRoutes()) + test.worker.SetActive(test.want.GetActive()) + test.worker.SetStatus(test.want.GetStatus()) + test.worker.SetLastStatusUpdateAt(test.want.GetLastStatusUpdateAt()) + test.worker.SetRunningBuilds(test.want.GetRunningBuilds()) + test.worker.SetLastBuildStartedAt(test.want.GetLastBuildStartedAt()) + test.worker.SetLastBuildFinishedAt(test.want.GetLastBuildFinishedAt()) + test.worker.SetLastCheckedIn(test.want.GetLastCheckedIn()) + test.worker.SetBuildLimit(test.want.GetBuildLimit()) + + if test.worker.GetID() != test.want.GetID() { + t.Errorf("SetID is %v, want %v", test.worker.GetID(), test.want.GetID()) + } + + if test.worker.GetHostname() != test.want.GetHostname() { + t.Errorf("SetHostname is %v, want %v", test.worker.GetHostname(), test.want.GetHostname()) + } + + if test.worker.GetAddress() != test.want.GetAddress() { + t.Errorf("SetAddress is %v, want %v", test.worker.GetAddress(), test.want.GetAddress()) + } + + if !reflect.DeepEqual(test.worker.GetRoutes(), test.want.GetRoutes()) { + t.Errorf("SetRoutes is %v, want %v", test.worker.GetRoutes(), test.want.GetRoutes()) + } + + if test.worker.GetActive() != test.want.GetActive() { + t.Errorf("SetActive is %v, want %v", test.worker.GetActive(), test.want.GetActive()) + } + + if test.worker.GetStatus() != test.want.GetStatus() { + t.Errorf("SetStatus is %v, want %v", test.worker.GetStatus(), test.want.GetStatus()) + } + + if test.worker.GetLastStatusUpdateAt() != test.want.GetLastStatusUpdateAt() { + t.Errorf("SetLastStatusUpdateAt is %v, want %v", test.worker.GetLastStatusUpdateAt(), test.want.GetLastStatusUpdateAt()) + } + + if test.worker.GetLastBuildStartedAt() != test.want.GetLastBuildStartedAt() { + t.Errorf("SetLastBuildStartedAt is %v, want %v", test.worker.GetLastBuildStartedAt(), test.want.GetLastBuildStartedAt()) + } + + if test.worker.GetLastBuildFinishedAt() != test.want.GetLastBuildFinishedAt() { + t.Errorf("SetLastBuildFinishedAt is %v, want %v", test.worker.GetLastBuildFinishedAt(), test.want.GetLastBuildFinishedAt()) + } + + if test.worker.GetLastCheckedIn() != test.want.GetLastCheckedIn() { + t.Errorf("SetLastCheckedIn is %v, want %v", test.worker.GetLastCheckedIn(), test.want.GetLastCheckedIn()) + } + + if test.worker.GetBuildLimit() != test.want.GetBuildLimit() { + t.Errorf("SetBuildLimit is %v, want %v", test.worker.GetBuildLimit(), test.want.GetBuildLimit()) + } + } +} + +func TestTypes_Worker_String(t *testing.T) { + // setup types + w := testWorker() + + want := fmt.Sprintf(`{ + ID: %d, + Hostname: %s, + Address: %s, + Routes: %s, + Active: %t, + Status: %s, + LastStatusUpdateAt: %v, + LastBuildStartedAt: %v, + LastBuildFinishedAt: %v, + LastCheckedIn: %v, + BuildLimit: %v, + RunningBuilds: %v, +}`, + w.GetID(), + w.GetHostname(), + w.GetAddress(), + w.GetRoutes(), + w.GetActive(), + w.GetStatus(), + w.GetLastStatusUpdateAt(), + w.GetLastBuildStartedAt(), + w.GetLastBuildFinishedAt(), + w.GetLastCheckedIn(), + w.GetBuildLimit(), + w.GetRunningBuilds(), + ) + + // run test + got := w.String() + + if !reflect.DeepEqual(got, want) { + t.Errorf("String is %v, want %v", got, want) + } +} + +// testWorker is a test helper function to create a Worker +// type with all fields set to a fake value. +func testWorker() *Worker { + b := new(library.Build) + b.SetID(1) + + w := new(Worker) + + w.SetID(1) + w.SetHostname("worker_0") + w.SetAddress("http://localhost:8080") + w.SetRoutes([]string{"vela"}) + w.SetActive(true) + w.SetStatus("available") + w.SetLastStatusUpdateAt(time.Time{}.UTC().Unix()) + w.SetRunningBuilds([]*library.Build{b}) + w.SetLastBuildStartedAt(time.Time{}.UTC().Unix()) + w.SetLastBuildFinishedAt(time.Time{}.UTC().Unix()) + w.SetLastCheckedIn(time.Time{}.UTC().Unix()) + w.SetBuildLimit(2) + + return w +} diff --git a/api/worker/create.go b/api/worker/create.go index 07edf3acc..d91898885 100644 --- a/api/worker/create.go +++ b/api/worker/create.go @@ -9,6 +9,7 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/internal/token" "github.com/go-vela/server/router/middleware/claims" @@ -58,7 +59,7 @@ func CreateWorker(c *gin.Context) { ctx := c.Request.Context() // capture body from API request - input := new(library.Worker) + input := new(types.Worker) err := c.Bind(input) if err != nil { diff --git a/api/worker/get.go b/api/worker/get.go index a8a4d6931..b7bebd149 100644 --- a/api/worker/get.go +++ b/api/worker/get.go @@ -11,6 +11,7 @@ import ( "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/router/middleware/worker" "github.com/go-vela/server/util" + "github.com/go-vela/types/library" "github.com/sirupsen/logrus" ) @@ -55,14 +56,21 @@ func GetWorker(c *gin.Context) { "worker": w.GetHostname(), }).Infof("reading worker %s", w.GetHostname()) - w, err := database.FromContext(c).GetWorkerForHostname(ctx, w.GetHostname()) - if err != nil { - retErr := fmt.Errorf("unable to get workers: %w", err) + rBs := []*library.Build{} - util.HandleError(c, http.StatusNotFound, retErr) + for _, b := range w.GetRunningBuilds() { + build, err := database.FromContext(c).GetBuild(ctx, b.GetID()) + if err != nil { + retErr := fmt.Errorf("unable to read build %d: %w", b.GetID(), err) + util.HandleError(c, http.StatusInternalServerError, retErr) - return + return + } + + rBs = append(rBs, build) } + w.SetRunningBuilds(rBs) + c.JSON(http.StatusOK, w) } diff --git a/api/worker/list.go b/api/worker/list.go index f402144da..82673eccf 100644 --- a/api/worker/list.go +++ b/api/worker/list.go @@ -12,6 +12,7 @@ import ( "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" + "github.com/go-vela/types/library" "github.com/sirupsen/logrus" ) @@ -86,7 +87,7 @@ func ListWorkers(c *gin.Context) { return } - w, err := database.FromContext(c).ListWorkers(ctx, active, before, after) + workers, err := database.FromContext(c).ListWorkers(ctx, active, before, after) if err != nil { retErr := fmt.Errorf("unable to get workers: %w", err) @@ -95,5 +96,23 @@ func ListWorkers(c *gin.Context) { return } - c.JSON(http.StatusOK, w) + for _, w := range workers { + rBs := []*library.Build{} + + for _, b := range w.GetRunningBuilds() { + build, err := database.FromContext(c).GetBuild(ctx, b.GetID()) + if err != nil { + retErr := fmt.Errorf("unable to read build %d: %w", b.GetID(), err) + util.HandleError(c, http.StatusInternalServerError, retErr) + + return + } + + rBs = append(rBs, build) + } + + w.SetRunningBuilds(rBs) + } + + c.JSON(http.StatusOK, workers) } diff --git a/api/worker/update.go b/api/worker/update.go index d95ddf7af..e5b842a0d 100644 --- a/api/worker/update.go +++ b/api/worker/update.go @@ -7,11 +7,11 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/router/middleware/worker" "github.com/go-vela/server/util" - "github.com/go-vela/types/library" "github.com/sirupsen/logrus" ) @@ -71,7 +71,7 @@ func UpdateWorker(c *gin.Context) { }).Infof("updating worker %s", w.GetHostname()) // capture body from API request - input := new(library.Worker) + input := new(types.Worker) err := c.Bind(input) if err != nil { @@ -97,9 +97,9 @@ func UpdateWorker(c *gin.Context) { w.SetActive(input.GetActive()) } - if input.RunningBuildIDs != nil { + if input.RunningBuilds != nil { // update runningBuildIDs if set - w.SetRunningBuildIDs(input.GetRunningBuildIDs()) + w.SetRunningBuilds(input.GetRunningBuilds()) } if len(input.GetStatus()) > 0 { diff --git a/database/integration_test.go b/database/integration_test.go index 585cc4134..29ac6774d 100644 --- a/database/integration_test.go +++ b/database/integration_test.go @@ -10,6 +10,7 @@ import ( "testing" "time" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database/build" "github.com/go-vela/server/database/deployment" "github.com/go-vela/server/database/executable" @@ -43,7 +44,7 @@ type Resources struct { Services []*library.Service Steps []*library.Step Users []*library.User - Workers []*library.Worker + Workers []*api.Worker } func TestDatabase_Integration(t *testing.T) { @@ -2446,7 +2447,13 @@ func newResources() *Resources { userTwo.SetActive(true) userTwo.SetAdmin(false) - workerOne := new(library.Worker) + _bPartialOne := new(library.Build) + _bPartialOne.SetID(1) + + _bPartialTwo := new(library.Build) + _bPartialTwo.SetID(2) + + workerOne := new(api.Worker) workerOne.SetID(1) workerOne.SetHostname("worker-1.example.com") workerOne.SetAddress("https://worker-1.example.com") @@ -2454,13 +2461,13 @@ func newResources() *Resources { workerOne.SetActive(true) workerOne.SetStatus("available") workerOne.SetLastStatusUpdateAt(time.Now().UTC().Unix()) - workerOne.SetRunningBuildIDs([]string{"12345"}) + workerOne.SetRunningBuilds([]*library.Build{_bPartialOne}) workerOne.SetLastBuildStartedAt(time.Now().UTC().Unix()) workerOne.SetLastBuildFinishedAt(time.Now().UTC().Unix()) workerOne.SetLastCheckedIn(time.Now().UTC().Unix() - 60) workerOne.SetBuildLimit(1) - workerTwo := new(library.Worker) + workerTwo := new(api.Worker) workerTwo.SetID(2) workerTwo.SetHostname("worker-2.example.com") workerTwo.SetAddress("https://worker-2.example.com") @@ -2468,7 +2475,7 @@ func newResources() *Resources { workerTwo.SetActive(true) workerTwo.SetStatus("available") workerTwo.SetLastStatusUpdateAt(time.Now().UTC().Unix()) - workerTwo.SetRunningBuildIDs([]string{"12345"}) + workerTwo.SetRunningBuilds([]*library.Build{_bPartialTwo}) workerTwo.SetLastBuildStartedAt(time.Now().UTC().Unix()) workerTwo.SetLastBuildFinishedAt(time.Now().UTC().Unix()) workerTwo.SetLastCheckedIn(time.Now().UTC().Unix() - 60) @@ -2487,7 +2494,7 @@ func newResources() *Resources { Services: []*library.Service{serviceOne, serviceTwo}, Steps: []*library.Step{stepOne, stepTwo}, Users: []*library.User{userOne, userTwo}, - Workers: []*library.Worker{workerOne, workerTwo}, + Workers: []*api.Worker{workerOne, workerTwo}, } } diff --git a/database/worker/create.go b/database/worker/create.go index 12b386319..131bb393f 100644 --- a/database/worker/create.go +++ b/database/worker/create.go @@ -5,14 +5,13 @@ package worker import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" "github.com/sirupsen/logrus" ) // CreateWorker creates a new worker in the database. -func (e *engine) CreateWorker(ctx context.Context, w *library.Worker) (*library.Worker, error) { +func (e *engine) CreateWorker(ctx context.Context, w *api.Worker) (*api.Worker, error) { e.logger.WithFields(logrus.Fields{ "worker": w.GetHostname(), }).Tracef("creating worker %s in the database", w.GetHostname()) @@ -20,7 +19,7 @@ func (e *engine) CreateWorker(ctx context.Context, w *library.Worker) (*library. // cast the library type to database type // // https://pkg.go.dev/github.com/go-vela/types/database#WorkerFromLibrary - worker := database.WorkerFromLibrary(w) + worker := FromAPI(w) // validate the necessary fields are populated // @@ -33,5 +32,5 @@ func (e *engine) CreateWorker(ctx context.Context, w *library.Worker) (*library. // send query to the database result := e.client.Table(constants.TableWorker).Create(worker) - return worker.ToLibrary(), result.Error + return worker.ToAPI(w.GetRunningBuilds()), result.Error } diff --git a/database/worker/create_test.go b/database/worker/create_test.go index dad81473a..6809bb33e 100644 --- a/database/worker/create_test.go +++ b/database/worker/create_test.go @@ -28,7 +28,7 @@ func TestWorker_Engine_CreateWorker(t *testing.T) { _mock.ExpectQuery(`INSERT INTO "workers" ("hostname","address","routes","active","status","last_status_update_at","running_build_ids","last_build_started_at","last_build_finished_at","last_checked_in","build_limit","id") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12) RETURNING "id"`). - WithArgs("worker_0", "localhost", nil, true, nil, nil, nil, nil, nil, nil, nil, 1). + WithArgs("worker_0", "localhost", nil, true, nil, nil, `{"1"}`, nil, nil, nil, nil, 1). WillReturnRows(_rows) _sqlite := testSqlite(t) diff --git a/database/worker/delete.go b/database/worker/delete.go index ba846db91..ee391567e 100644 --- a/database/worker/delete.go +++ b/database/worker/delete.go @@ -5,14 +5,13 @@ package worker import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" "github.com/sirupsen/logrus" ) // DeleteWorker deletes an existing worker from the database. -func (e *engine) DeleteWorker(ctx context.Context, w *library.Worker) error { +func (e *engine) DeleteWorker(ctx context.Context, w *api.Worker) error { e.logger.WithFields(logrus.Fields{ "worker": w.GetHostname(), }).Tracef("deleting worker %s from the database", w.GetHostname()) @@ -20,7 +19,7 @@ func (e *engine) DeleteWorker(ctx context.Context, w *library.Worker) error { // cast the library type to database type // // https://pkg.go.dev/github.com/go-vela/types/database#WorkerFromLibrary - worker := database.WorkerFromLibrary(w) + worker := FromAPI(w) // send query to the database return e.client. diff --git a/database/worker/get.go b/database/worker/get.go index 12201d4d5..7531fd05a 100644 --- a/database/worker/get.go +++ b/database/worker/get.go @@ -5,17 +5,16 @@ package worker import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" ) // GetWorker gets a worker by ID from the database. -func (e *engine) GetWorker(ctx context.Context, id int64) (*library.Worker, error) { +func (e *engine) GetWorker(ctx context.Context, id int64) (*api.Worker, error) { e.logger.Tracef("getting worker %d from the database", id) // variable to store query results - w := new(database.Worker) + w := new(Worker) // send query to the database and store result in variable err := e.client. @@ -30,5 +29,5 @@ func (e *engine) GetWorker(ctx context.Context, id int64) (*library.Worker, erro // return the worker // // https://pkg.go.dev/github.com/go-vela/types/database#Worker.ToLibrary - return w.ToLibrary(), nil + return w.ToAPI(convertToBuilds(w.RunningBuildIDs)), nil } diff --git a/database/worker/get_hostname.go b/database/worker/get_hostname.go index 3370620a0..f596850af 100644 --- a/database/worker/get_hostname.go +++ b/database/worker/get_hostname.go @@ -5,20 +5,19 @@ package worker import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" "github.com/sirupsen/logrus" ) // GetWorkerForHostname gets a worker by hostname from the database. -func (e *engine) GetWorkerForHostname(ctx context.Context, hostname string) (*library.Worker, error) { +func (e *engine) GetWorkerForHostname(ctx context.Context, hostname string) (*api.Worker, error) { e.logger.WithFields(logrus.Fields{ "worker": hostname, }).Tracef("getting worker %s from the database", hostname) // variable to store query results - w := new(database.Worker) + w := new(Worker) // send query to the database and store result in variable err := e.client. @@ -33,5 +32,5 @@ func (e *engine) GetWorkerForHostname(ctx context.Context, hostname string) (*li // return the worker // // https://pkg.go.dev/github.com/go-vela/types/database#Worker.ToLibrary - return w.ToLibrary(), nil + return w.ToAPI(convertToBuilds(w.RunningBuildIDs)), nil } diff --git a/database/worker/get_hostname_test.go b/database/worker/get_hostname_test.go index cf264ab0c..7d5043340 100644 --- a/database/worker/get_hostname_test.go +++ b/database/worker/get_hostname_test.go @@ -8,7 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" ) func TestWorker_Engine_GetWorkerForName(t *testing.T) { @@ -18,6 +18,7 @@ func TestWorker_Engine_GetWorkerForName(t *testing.T) { _worker.SetHostname("worker_0") _worker.SetAddress("localhost") _worker.SetActive(true) + _worker.SetRunningBuilds(nil) // sqlmock cannot parse string array values _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() @@ -43,7 +44,7 @@ func TestWorker_Engine_GetWorkerForName(t *testing.T) { failure bool name string database *engine - want *library.Worker + want *api.Worker }{ { failure: false, diff --git a/database/worker/get_test.go b/database/worker/get_test.go index bfd9bf2a3..566f8232b 100644 --- a/database/worker/get_test.go +++ b/database/worker/get_test.go @@ -8,7 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" ) func TestWorker_Engine_GetWorker(t *testing.T) { @@ -18,6 +18,7 @@ func TestWorker_Engine_GetWorker(t *testing.T) { _worker.SetHostname("worker_0") _worker.SetAddress("localhost") _worker.SetActive(true) + _worker.SetRunningBuilds(nil) _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() @@ -43,7 +44,7 @@ func TestWorker_Engine_GetWorker(t *testing.T) { failure bool name string database *engine - want *library.Worker + want *api.Worker }{ { failure: false, diff --git a/database/worker/interface.go b/database/worker/interface.go index 589e8971b..8f8d024a1 100644 --- a/database/worker/interface.go +++ b/database/worker/interface.go @@ -5,7 +5,7 @@ package worker import ( "context" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" ) // WorkerInterface represents the Vela interface for worker @@ -29,15 +29,15 @@ type WorkerInterface interface { // CountWorkers defines a function that gets the count of all workers. CountWorkers(context.Context) (int64, error) // CreateWorker defines a function that creates a new worker. - CreateWorker(context.Context, *library.Worker) (*library.Worker, error) + CreateWorker(context.Context, *api.Worker) (*api.Worker, error) // DeleteWorker defines a function that deletes an existing worker. - DeleteWorker(context.Context, *library.Worker) error + DeleteWorker(context.Context, *api.Worker) error // GetWorker defines a function that gets a worker by ID. - GetWorker(context.Context, int64) (*library.Worker, error) + GetWorker(context.Context, int64) (*api.Worker, error) // GetWorkerForHostname defines a function that gets a worker by hostname. - GetWorkerForHostname(context.Context, string) (*library.Worker, error) + GetWorkerForHostname(context.Context, string) (*api.Worker, error) // ListWorkers defines a function that gets a list of all workers. - ListWorkers(context.Context, string, int64, int64) ([]*library.Worker, error) + ListWorkers(context.Context, string, int64, int64) ([]*api.Worker, error) // UpdateWorker defines a function that updates an existing worker. - UpdateWorker(context.Context, *library.Worker) (*library.Worker, error) + UpdateWorker(context.Context, *api.Worker) (*api.Worker, error) } diff --git a/database/worker/list.go b/database/worker/list.go index bb8169d61..daa9a7e06 100644 --- a/database/worker/list.go +++ b/database/worker/list.go @@ -7,18 +7,17 @@ import ( "fmt" "strconv" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" ) // ListWorkers gets a list of all workers from the database. -func (e *engine) ListWorkers(ctx context.Context, active string, before, after int64) ([]*library.Worker, error) { +func (e *engine) ListWorkers(ctx context.Context, active string, before, after int64) ([]*api.Worker, error) { e.logger.Trace("listing all workers from the database") // variables to store query results and return value - w := new([]database.Worker) - workers := []*library.Worker{} + results := new([]Worker) + workers := []*api.Worker{} // build query with checked in constraints query := e.client.Table(constants.TableWorker). @@ -37,20 +36,20 @@ func (e *engine) ListWorkers(ctx context.Context, active string, before, after i } // send query to the database and store result in variable - err := query.Find(&w).Error + err := query.Find(&results).Error if err != nil { return nil, err } // iterate through all query results - for _, worker := range *w { + for _, worker := range *results { // https://golang.org/doc/faq#closures_and_goroutines tmp := worker // convert query result to library type // // https://pkg.go.dev/github.com/go-vela/types/database#Worker.ToLibrary - workers = append(workers, tmp.ToLibrary()) + workers = append(workers, tmp.ToAPI(convertToBuilds(tmp.RunningBuildIDs))) } return workers, nil diff --git a/database/worker/list_test.go b/database/worker/list_test.go index 4a5988228..4de8883a6 100644 --- a/database/worker/list_test.go +++ b/database/worker/list_test.go @@ -8,7 +8,7 @@ import ( "time" "github.com/DATA-DOG/go-sqlmock" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" "github.com/google/go-cmp/cmp" ) @@ -21,6 +21,7 @@ func TestWorker_Engine_ListWorkers(t *testing.T) { _workerOne.SetHostname("worker_0") _workerOne.SetAddress("localhost") _workerOne.SetActive(true) + _workerOne.SetRunningBuilds(nil) _workerOne.SetLastCheckedIn(newer) _workerTwo := testWorker() @@ -29,6 +30,7 @@ func TestWorker_Engine_ListWorkers(t *testing.T) { _workerTwo.SetAddress("localhost") _workerTwo.SetActive(true) _workerTwo.SetLastCheckedIn(older) + _workerTwo.SetRunningBuilds(nil) _workerThree := testWorker() _workerThree.SetID(3) @@ -36,6 +38,7 @@ func TestWorker_Engine_ListWorkers(t *testing.T) { _workerThree.SetAddress("localhost") _workerThree.SetActive(false) _workerThree.SetLastCheckedIn(newer) + _workerThree.SetRunningBuilds(nil) _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() @@ -75,7 +78,7 @@ func TestWorker_Engine_ListWorkers(t *testing.T) { active string name string database *engine - want []*library.Worker + want []*api.Worker }{ { failure: false, @@ -83,7 +86,7 @@ func TestWorker_Engine_ListWorkers(t *testing.T) { active: "all", name: "sqlite3 before filter", database: _sqlite, - want: []*library.Worker{_workerTwo}, + want: []*api.Worker{_workerTwo}, }, { failure: false, @@ -91,7 +94,7 @@ func TestWorker_Engine_ListWorkers(t *testing.T) { active: "all", name: "postgres catch all", database: _postgres, - want: []*library.Worker{_workerOne, _workerTwo, _workerThree}, + want: []*api.Worker{_workerOne, _workerTwo, _workerThree}, }, { failure: false, @@ -99,7 +102,7 @@ func TestWorker_Engine_ListWorkers(t *testing.T) { active: "all", name: "sqlite3 catch all", database: _sqlite, - want: []*library.Worker{_workerOne, _workerTwo, _workerThree}, + want: []*api.Worker{_workerOne, _workerTwo, _workerThree}, }, { failure: false, @@ -107,7 +110,7 @@ func TestWorker_Engine_ListWorkers(t *testing.T) { active: "true", name: "sqlite3 active filter", database: _sqlite, - want: []*library.Worker{_workerOne, _workerTwo}, + want: []*api.Worker{_workerOne, _workerTwo}, }, } diff --git a/database/worker/update.go b/database/worker/update.go index 3cae0d164..0349ffe85 100644 --- a/database/worker/update.go +++ b/database/worker/update.go @@ -5,14 +5,13 @@ package worker import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" "github.com/sirupsen/logrus" ) // UpdateWorker updates an existing worker in the database. -func (e *engine) UpdateWorker(ctx context.Context, w *library.Worker) (*library.Worker, error) { +func (e *engine) UpdateWorker(ctx context.Context, w *api.Worker) (*api.Worker, error) { e.logger.WithFields(logrus.Fields{ "worker": w.GetHostname(), }).Tracef("updating worker %s in the database", w.GetHostname()) @@ -20,7 +19,7 @@ func (e *engine) UpdateWorker(ctx context.Context, w *library.Worker) (*library. // cast the library type to database type // // https://pkg.go.dev/github.com/go-vela/types/database#WorkerFromLibrary - worker := database.WorkerFromLibrary(w) + worker := FromAPI(w) // validate the necessary fields are populated // @@ -33,5 +32,5 @@ func (e *engine) UpdateWorker(ctx context.Context, w *library.Worker) (*library. // send query to the database result := e.client.Table(constants.TableWorker).Save(worker) - return worker.ToLibrary(), result.Error + return worker.ToAPI(w.GetRunningBuilds()), result.Error } diff --git a/database/worker/update_test.go b/database/worker/update_test.go index d077bc567..5a483660b 100644 --- a/database/worker/update_test.go +++ b/database/worker/update_test.go @@ -25,7 +25,7 @@ func TestWorker_Engine_UpdateWorker(t *testing.T) { _mock.ExpectExec(`UPDATE "workers" SET "hostname"=$1,"address"=$2,"routes"=$3,"active"=$4,"status"=$5,"last_status_update_at"=$6,"running_build_ids"=$7,"last_build_started_at"=$8,"last_build_finished_at"=$9,"last_checked_in"=$10,"build_limit"=$11 WHERE "id" = $12`). - WithArgs("worker_0", "localhost", nil, true, nil, nil, nil, nil, nil, nil, nil, 1). + WithArgs("worker_0", "localhost", nil, true, nil, nil, `{"1"}`, nil, nil, nil, nil, 1). WillReturnResult(sqlmock.NewResult(1, 1)) _sqlite := testSqlite(t) diff --git a/database/worker/worker.go b/database/worker/worker.go index 09b69176a..d12055ded 100644 --- a/database/worker/worker.go +++ b/database/worker/worker.go @@ -4,14 +4,35 @@ package worker import ( "context" + "database/sql" + "errors" "fmt" + "strconv" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/util" "github.com/go-vela/types/constants" + "github.com/go-vela/types/library" + "github.com/lib/pq" "github.com/sirupsen/logrus" "gorm.io/gorm" ) +var ( + // ErrEmptyWorkerHost defines the error type when a + // Worker type has an empty Host field provided. + ErrEmptyWorkerHost = errors.New("empty worker hostname provided") + + // ErrEmptyWorkerAddress defines the error type when a + // Worker type has an empty Address field provided. + ErrEmptyWorkerAddress = errors.New("empty worker address provided") + + // ErrExceededRunningBuildIDsLimit defines the error type when a + // Worker type has RunningBuildIDs field provided that exceeds the database limit. + ErrExceededRunningBuildIDsLimit = errors.New("exceeded running build ids limit") +) + type ( // config represents the settings required to create the engine that implements the WorkerInterface interface. config struct { @@ -36,6 +57,22 @@ type ( // https://pkg.go.dev/github.com/sirupsen/logrus#Entry logger *logrus.Entry } + + // Worker is the database representation of a worker. + Worker struct { + ID sql.NullInt64 `sql:"id"` + Hostname sql.NullString `sql:"hostname"` + Address sql.NullString `sql:"address"` + Routes pq.StringArray `sql:"routes" gorm:"type:varchar(1000)"` + Active sql.NullBool `sql:"active"` + Status sql.NullString `sql:"status"` + LastStatusUpdateAt sql.NullInt64 `sql:"last_status_update_at"` + RunningBuildIDs pq.StringArray `sql:"running_build_ids" gorm:"type:varchar(500)"` + LastBuildStartedAt sql.NullInt64 `sql:"last_build_started_at"` + LastBuildFinishedAt sql.NullInt64 `sql:"last_build_finished_at"` + LastCheckedIn sql.NullInt64 `sql:"last_checked_in"` + BuildLimit sql.NullInt64 `sql:"build_limit"` + } ) // New creates and returns a Vela service for integrating with workers in the database. @@ -79,3 +116,170 @@ func New(opts ...EngineOpt) (*engine, error) { return e, nil } + +// Nullify ensures the valid flag for +// the sql.Null types are properly set. +// +// When a field within the Build type is the zero +// value for the field, the valid flag is set to +// false causing it to be NULL in the database. +func (w *Worker) Nullify() *Worker { + if w == nil { + return nil + } + + // check if the ID field should be false + if w.ID.Int64 == 0 { + w.ID.Valid = false + } + + // check if the Hostname field should be false + if len(w.Hostname.String) == 0 { + w.Hostname.Valid = false + } + + // check if the Address field should be false + if len(w.Address.String) == 0 { + w.Address.Valid = false + } + + // check if the Status field should be false + if len(w.Status.String) == 0 { + w.Status.Valid = false + } + + // check if the LastStatusUpdateAt field should be false + if w.LastStatusUpdateAt.Int64 == 0 { + w.LastStatusUpdateAt.Valid = false + } + + // check if the LastBuildStartedAt field should be false + if w.LastBuildStartedAt.Int64 == 0 { + w.LastBuildStartedAt.Valid = false + } + + // check if the LastBuildFinishedAt field should be false + if w.LastBuildFinishedAt.Int64 == 0 { + w.LastBuildFinishedAt.Valid = false + } + + // check if the LastCheckedIn field should be false + if w.LastCheckedIn.Int64 == 0 { + w.LastCheckedIn.Valid = false + } + + if w.BuildLimit.Int64 == 0 { + w.BuildLimit.Valid = false + } + + return w +} + +// ToAPI converts the Worker type +// to an API Worker type. +func (w *Worker) ToAPI(builds []*library.Build) *api.Worker { + worker := new(api.Worker) + + worker.SetID(w.ID.Int64) + worker.SetHostname(w.Hostname.String) + worker.SetAddress(w.Address.String) + worker.SetRoutes(w.Routes) + worker.SetActive(w.Active.Bool) + worker.SetStatus(w.Status.String) + worker.SetLastStatusUpdateAt(w.LastStatusUpdateAt.Int64) + worker.SetRunningBuilds(builds) + worker.SetLastBuildStartedAt(w.LastBuildStartedAt.Int64) + worker.SetLastBuildFinishedAt(w.LastBuildFinishedAt.Int64) + worker.SetLastCheckedIn(w.LastCheckedIn.Int64) + worker.SetBuildLimit(w.BuildLimit.Int64) + + return worker +} + +// Validate verifies the necessary fields for +// the Worker type are populated correctly. +func (w *Worker) Validate() error { + // verify the Host field is populated + if len(w.Hostname.String) == 0 { + return ErrEmptyWorkerHost + } + + // verify the Address field is populated + if len(w.Address.String) == 0 { + return ErrEmptyWorkerAddress + } + + // calculate total size of RunningBuildIds + total := 0 + for _, f := range w.RunningBuildIDs { + total += len(f) + } + + // verify the RunningBuildIds field is within the database constraints + // len is to factor in number of comma separators included in the database field, + // removing 1 due to the last item not having an appended comma + if (total + len(w.RunningBuildIDs) - 1) > constants.RunningBuildIDsMaxSize { + return ErrExceededRunningBuildIDsLimit + } + + // ensure that all Worker string fields + // that can be returned as JSON are sanitized + // to avoid unsafe HTML content + w.Hostname = sql.NullString{String: util.Sanitize(w.Hostname.String), Valid: w.Hostname.Valid} + w.Address = sql.NullString{String: util.Sanitize(w.Address.String), Valid: w.Address.Valid} + + // ensure that all Routes are sanitized + // to avoid unsafe HTML content + for i, v := range w.Routes { + w.Routes[i] = util.Sanitize(v) + } + + return nil +} + +// FromAPI converts the API worker type +// to a database worker type. +func FromAPI(w *api.Worker) *Worker { + var rBs []string + + for _, b := range w.GetRunningBuilds() { + rBs = append(rBs, fmt.Sprint(b.GetID())) + } + + worker := &Worker{ + ID: sql.NullInt64{Int64: w.GetID(), Valid: true}, + Hostname: sql.NullString{String: w.GetHostname(), Valid: true}, + Address: sql.NullString{String: w.GetAddress(), Valid: true}, + Routes: pq.StringArray(w.GetRoutes()), + Active: sql.NullBool{Bool: w.GetActive(), Valid: true}, + Status: sql.NullString{String: w.GetStatus(), Valid: true}, + LastStatusUpdateAt: sql.NullInt64{Int64: w.GetLastStatusUpdateAt(), Valid: true}, + RunningBuildIDs: pq.StringArray(rBs), + LastBuildStartedAt: sql.NullInt64{Int64: w.GetLastBuildStartedAt(), Valid: true}, + LastBuildFinishedAt: sql.NullInt64{Int64: w.GetLastBuildFinishedAt(), Valid: true}, + LastCheckedIn: sql.NullInt64{Int64: w.GetLastCheckedIn(), Valid: true}, + BuildLimit: sql.NullInt64{Int64: w.GetBuildLimit(), Valid: true}, + } + + return worker.Nullify() +} + +// convertToBuilds is a helper function that generates build objects with ID fields given a list of IDs. +func convertToBuilds(ids []string) []*library.Build { + // create stripped build objects holding the IDs + var rBs []*library.Build + + for _, b := range ids { + id, err := strconv.ParseInt(b, 10, 64) + if err != nil { + return nil + } + + build := new(library.Build) + build.SetID(id) + + rBs = append(rBs, build) + } + + return rBs +} diff --git a/database/worker/worker_test.go b/database/worker/worker_test.go index a219d1ffc..8c6896eb7 100644 --- a/database/worker/worker_test.go +++ b/database/worker/worker_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/library" "github.com/sirupsen/logrus" @@ -106,6 +107,48 @@ func TestWorker_New(t *testing.T) { } } +func TestWorker_convertToBuilds(t *testing.T) { + _buildOne := new(library.Build) + _buildOne.SetID(1) + + _buildTwo := new(library.Build) + _buildTwo.SetID(2) + + // setup tests + tests := []struct { + name string + ids []string + want []*library.Build + }{ + { + name: "one id", + ids: []string{"1"}, + want: []*library.Build{_buildOne}, + }, + { + name: "multiple ids", + ids: []string{"1", "2"}, + want: []*library.Build{_buildOne, _buildTwo}, + }, + { + name: "not int64", + ids: []string{"1", "foo"}, + want: nil, + }, + } + + // run tests + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got := convertToBuilds(test.ids) + + if !reflect.DeepEqual(got, test.want) { + t.Errorf("convertToBuilds for %s is %v, want %v", test.name, got, test.want) + } + }) + } +} + // testPostgres is a helper function to create a Postgres engine for testing. func testPostgres(t *testing.T) (*engine, sqlmock.Sqlmock) { // create the new mock sql database @@ -166,8 +209,11 @@ func testSqlite(t *testing.T) *engine { // testWorker is a test helper function to create a library // Worker type with all fields set to their zero values. -func testWorker() *library.Worker { - return &library.Worker{ +func testWorker() *api.Worker { + b := new(library.Build) + b.SetID(1) + + return &api.Worker{ ID: new(int64), Hostname: new(string), Address: new(string), @@ -175,7 +221,7 @@ func testWorker() *library.Worker { Active: new(bool), Status: new(string), LastStatusUpdateAt: new(int64), - RunningBuildIDs: new([]string), + RunningBuilds: &[]*library.Build{b}, LastBuildStartedAt: new(int64), LastBuildFinishedAt: new(int64), LastCheckedIn: new(int64), diff --git a/go.mod b/go.mod index 745dcc4c5..7d043ce7f 100644 --- a/go.mod +++ b/go.mod @@ -25,6 +25,8 @@ require ( github.com/hashicorp/go-retryablehttp v0.7.5 github.com/hashicorp/vault/api v1.12.1 github.com/joho/godotenv v1.5.1 + github.com/lib/pq v1.10.9 + github.com/microcosm-cc/bluemonday v1.0.26 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.19.0 github.com/redis/go-redis/v9 v9.5.1 @@ -89,10 +91,8 @@ require ( github.com/klauspost/cpuid/v2 v2.2.4 // indirect github.com/kr/text v0.2.0 // indirect github.com/leodido/go-urn v1.2.4 // indirect - github.com/lib/pq v1.10.9 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-sqlite3 v1.14.17 // indirect - github.com/microcosm-cc/bluemonday v1.0.26 // indirect github.com/mitchellh/copystructure v1.0.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect diff --git a/mock/server/worker.go b/mock/server/worker.go index 6abf38451..edc758460 100644 --- a/mock/server/worker.go +++ b/mock/server/worker.go @@ -9,6 +9,7 @@ import ( "strings" "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types" "github.com/go-vela/types/library" ) @@ -27,12 +28,71 @@ const ( ], "active": true, "last_checked_in": 1602612590, - "status": "idle", - "last_status_update_at": 160000000, - "running_build_ids": [], - "last_build_started_at": 1, - "last_build_finished_at": 2, - "build_limit": 1 + "status": "busy", + "last_status_update_at": 1602612590, + "last_build_started_at": 1602612590, + "last_build_finished_at": 1602612590, + "build_limit": 2, + "running_builds": [ + { + "id": 2, + "repo_id": 1, + "number": 2, + "parent": 1, + "event": "push", + "status": "running", + "error": "", + "enqueued": 1563474204, + "created": 1563474204, + "started": 1563474204, + "finished": 0, + "deploy": "", + "clone": "https://github.com/github/octocat.git", + "source": "https://github.com/github/octocat/commit/48afb5bdc41ad69bf22588491333f7cf71135163", + "title": "push received from https://github.com/github/octocat", + "message": "Second commit...", + "commit": "48afb5bdc41ad69bf22588491333f7cf71135163", + "sender": "OctoKitty", + "author": "OctoKitty", + "email": "octokitty@github.com", + "link": "https://vela.example.company.com/github/octocat/1", + "branch": "main", + "ref": "refs/heads/main", + "base_ref": "", + "host": "ed95dcc0687c", + "runtime": "", + "distribution": "" + }, + { + "id": 1, + "repo_id": 1, + "number": 1, + "parent": 1, + "event": "push", + "status": "running", + "error": "", + "enqueued": 1563474077, + "created": 1563474076, + "started": 1563474077, + "finished": 0, + "deploy": "", + "clone": "https://github.com/github/octocat.git", + "source": "https://github.com/github/octocat/commit/48afb5bdc41ad69bf22588491333f7cf71135163", + "title": "push received from https://github.com/github/octocat", + "message": "First commit...", + "commit": "48afb5bdc41ad69bf22588491333f7cf71135163", + "sender": "OctoKitty", + "author": "OctoKitty", + "email": "octokitty@github.com", + "link": "https://vela.example.company.com/github/octocat/1", + "branch": "main", + "ref": "refs/heads/main", + "base_ref": "", + "host": "82823eb770b0", + "runtime": "", + "distribution": "" + } + ] }` // WorkersResp represents a JSON return for one to many workers. @@ -47,7 +107,43 @@ const ( "large:docker" ], "active": true, - "last_checked_in": 1602612590 + "last_checked_in": 1602612590, + "status": "available", + "last_status_update_at": 1602612590, + "last_build_started_at": 1602612590, + "last_build_finished_at": 1602612590, + "build_limit": 2, + "running_builds": [ + { + "id": 2, + "repo_id": 1, + "number": 2, + "parent": 1, + "event": "push", + "status": "running", + "error": "", + "enqueued": 1563474204, + "created": 1563474204, + "started": 1563474204, + "finished": 0, + "deploy": "", + "clone": "https://github.com/github/octocat.git", + "source": "https://github.com/github/octocat/commit/48afb5bdc41ad69bf22588491333f7cf71135163", + "title": "push received from https://github.com/github/octocat", + "message": "Second commit...", + "commit": "48afb5bdc41ad69bf22588491333f7cf71135163", + "sender": "OctoKitty", + "author": "OctoKitty", + "email": "octokitty@github.com", + "link": "https://vela.example.company.com/github/octocat/1", + "branch": "main", + "ref": "refs/heads/main", + "base_ref": "", + "host": "ed95dcc0687c", + "runtime": "", + "distribution": "" + } + ] }, { "id": 2, @@ -59,7 +155,13 @@ const ( "large:docker" ], "active": true, - "last_checked_in": 1602612590 + "last_checked_in": 1602612590, + "status": "idle", + "last_status_update_at": 1602612590, + "last_build_started_at": 1602612590, + "last_build_finished_at": 1602612590, + "build_limit": 2, + "running_builds": [] } ]` @@ -93,7 +195,7 @@ const ( func getWorkers(c *gin.Context) { data := []byte(WorkersResp) - var body []library.Worker + var body []api.Worker _ = json.Unmarshal(data, &body) c.JSON(http.StatusOK, body) @@ -113,7 +215,7 @@ func getWorker(c *gin.Context) { data := []byte(WorkerResp) - var body library.Worker + var body api.Worker _ = json.Unmarshal(data, &body) c.JSON(http.StatusOK, body) @@ -145,7 +247,7 @@ func updateWorker(c *gin.Context) { data := []byte(WorkerResp) - var body library.Worker + var body api.Worker _ = json.Unmarshal(data, &body) c.JSON(http.StatusOK, body) diff --git a/mock/server/worker_test.go b/mock/server/worker_test.go index defc3bd86..a9a46b810 100644 --- a/mock/server/worker_test.go +++ b/mock/server/worker_test.go @@ -7,11 +7,11 @@ import ( "reflect" "testing" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" ) func TestWorker_ActiveWorkerResp(t *testing.T) { - testWorker := library.Worker{} + testWorker := api.Worker{} err := json.Unmarshal([]byte(WorkerResp), &testWorker) if err != nil { @@ -26,3 +26,22 @@ func TestWorker_ActiveWorkerResp(t *testing.T) { } } } + +func TestWorker_ListActiveWorkerResp(t *testing.T) { + testWorkers := []api.Worker{} + + err := json.Unmarshal([]byte(WorkersResp), &testWorkers) + if err != nil { + t.Errorf("error unmarshaling worker: %v", err) + } + + for index, worker := range testWorkers { + tWorker := reflect.TypeOf(worker) + + for i := 0; i < tWorker.NumField(); i++ { + if reflect.ValueOf(worker).Field(i).IsNil() { + t.Errorf("WorkersResp index %d missing field %s", index, tWorker.Field(i).Name) + } + } + } +} diff --git a/router/middleware/logger_test.go b/router/middleware/logger_test.go index 9264ade1a..bfc084437 100644 --- a/router/middleware/logger_test.go +++ b/router/middleware/logger_test.go @@ -14,6 +14,7 @@ import ( "time" "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/service" @@ -58,7 +59,7 @@ func TestMiddleware_Logger(t *testing.T) { u.SetName("foo") u.SetToken("bar") - w := new(library.Worker) + w := new(api.Worker) w.SetID(1) w.SetHostname("worker_0") w.SetAddress("localhost") diff --git a/router/middleware/worker/context.go b/router/middleware/worker/context.go index a7780a3e8..2e9772a9e 100644 --- a/router/middleware/worker/context.go +++ b/router/middleware/worker/context.go @@ -5,7 +5,7 @@ package worker import ( "context" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" ) const key = "worker" @@ -16,13 +16,13 @@ type Setter interface { } // FromContext returns the Worker associated with this context. -func FromContext(c context.Context) *library.Worker { +func FromContext(c context.Context) *api.Worker { value := c.Value(key) if value == nil { return nil } - w, ok := value.(*library.Worker) + w, ok := value.(*api.Worker) if !ok { return nil } @@ -32,6 +32,6 @@ func FromContext(c context.Context) *library.Worker { // ToContext adds the Worker to this context if it supports // the Setter interface. -func ToContext(c Setter, w *library.Worker) { +func ToContext(c Setter, w *api.Worker) { c.Set(key, w) } diff --git a/router/middleware/worker/context_test.go b/router/middleware/worker/context_test.go index 76efd687b..6fd731e90 100644 --- a/router/middleware/worker/context_test.go +++ b/router/middleware/worker/context_test.go @@ -5,7 +5,7 @@ package worker import ( "testing" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" "github.com/gin-gonic/gin" ) @@ -13,7 +13,7 @@ import ( func TestWorker_FromContext(t *testing.T) { // setup types num := int64(1) - want := &library.Worker{ID: &num} + want := &api.Worker{ID: &num} // setup context gin.SetMode(gin.TestMode) @@ -72,7 +72,7 @@ func TestWorker_FromContext_Empty(t *testing.T) { func TestWorker_ToContext(t *testing.T) { // setup types num := int64(1) - want := &library.Worker{ID: &num} + want := &api.Worker{ID: &num} // setup context gin.SetMode(gin.TestMode) diff --git a/router/middleware/worker/worker.go b/router/middleware/worker/worker.go index 11586af9c..5a78d14a4 100644 --- a/router/middleware/worker/worker.go +++ b/router/middleware/worker/worker.go @@ -7,14 +7,14 @@ import ( "net/http" "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/util" - "github.com/go-vela/types/library" "github.com/sirupsen/logrus" ) // Retrieve gets the worker in the given context. -func Retrieve(c *gin.Context) *library.Worker { +func Retrieve(c *gin.Context) *api.Worker { return FromContext(c) } diff --git a/router/middleware/worker/worker_test.go b/router/middleware/worker/worker_test.go index 2d3578cd0..277ed8c09 100644 --- a/router/middleware/worker/worker_test.go +++ b/router/middleware/worker/worker_test.go @@ -10,13 +10,14 @@ import ( "testing" "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/types/library" ) func TestWorker_Retrieve(t *testing.T) { // setup types - want := new(library.Worker) + want := new(api.Worker) want.SetID(1) // setup context @@ -34,7 +35,10 @@ func TestWorker_Retrieve(t *testing.T) { func TestWorker_Establish(t *testing.T) { // setup types - want := new(library.Worker) + b := new(library.Build) + b.SetID(1) + + want := new(api.Worker) want.SetID(1) want.SetHostname("worker_0") want.SetAddress("localhost") @@ -42,13 +46,13 @@ func TestWorker_Establish(t *testing.T) { want.SetActive(true) want.SetStatus("available") want.SetLastStatusUpdateAt(12345) - want.SetRunningBuildIDs([]string{}) + want.SetRunningBuilds([]*library.Build{b}) want.SetLastBuildStartedAt(12345) want.SetLastBuildFinishedAt(12345) want.SetLastCheckedIn(12345) want.SetBuildLimit(0) - got := new(library.Worker) + got := new(api.Worker) // setup database db, err := database.NewTest() diff --git a/util/util.go b/util/util.go index 840dbc04f..5d9ce644f 100644 --- a/util/util.go +++ b/util/util.go @@ -4,9 +4,11 @@ package util import ( "html" + "net/url" "strings" "github.com/go-vela/types/library" + "github.com/microcosm-cc/bluemonday" "github.com/gin-gonic/gin" "github.com/go-vela/types" @@ -128,3 +130,34 @@ func CheckAllowlist(r *library.Repo, allowlist []string) bool { return false } + +// Sanitize is a helper function to verify the provided input +// field does not contain HTML content. If the input field +// does contain HTML, then the function will sanitize and +// potentially remove the HTML if deemed malicious. +func Sanitize(field string) string { + // create new HTML input microcosm-cc/bluemonday policy + p := bluemonday.StrictPolicy() + + // create a URL query unescaped string from the field + queryUnescaped, err := url.QueryUnescape(field) + if err != nil { + // overwrite URL query unescaped string with field + queryUnescaped = field + } + + // create an HTML escaped string from the field + htmlEscaped := html.EscapeString(queryUnescaped) + + // create a microcosm-cc/bluemonday escaped string from the field + bluemondayEscaped := p.Sanitize(queryUnescaped) + + // check if the field contains html + if !strings.EqualFold(htmlEscaped, bluemondayEscaped) { + // create new HTML input microcosm-cc/bluemonday policy + return bluemondayEscaped + } + + // return the unmodified field + return field +} diff --git a/util/util_test.go b/util/util_test.go new file mode 100644 index 000000000..bf4c458f1 --- /dev/null +++ b/util/util_test.go @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: Apache-2.0 + +package util + +import ( + "testing" +) + +func TestUtil_Sanitize(t *testing.T) { + // setup tests + tests := []struct { + name string + value string + want string + }{ + { + name: "percent", + value: `%`, + want: `%`, + }, + { + name: "quoted", + value: `"hello"`, + want: `"hello"`, + }, + { + name: "email", + value: `OctoKitty@github.com`, + want: `OctoKitty@github.com`, + }, + { + name: "url", + value: `https://github.com/go-vela`, + want: `https://github.com/go-vela`, + }, + { + name: "encoded", + value: `+ added foo %25 + updated bar %22 +`, + want: `+ added foo %25 + updated bar %22 +`, + }, + { + name: "html with headers", + value: `Merge pull request #1 from me/patch-1\n\n

hello

is now

hello

`, + want: `Merge pull request #1 from me/patch-1\n\nhello is now hello`, + }, + { + name: "html with email", + value: `Co-authored-by: OctoKitty `, + want: `Co-authored-by: OctoKitty `, + }, + { + name: "html with href", + value: `Google`, + want: `Google`, + }, + { + name: "local cross-site script", + value: ``, + want: ``, + }, + { + name: "remote cross-site script", + value: ``, + want: ``, + }, + { + name: "embedded cross-site script", + value: `%3cDIV%20STYLE%3d%22width%3a%20expression(alert('XSS'))%3b%22%3e`, + want: ``, + }, + } + + // run tests + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got := Sanitize(test.value) + + if got != test.want { + t.Errorf("sanitize is %v, want %v", got, test.want) + } + }) + } +} From 7a6e89aaa4b3f59c0af735ff058ae68187add12b Mon Sep 17 00:00:00 2001 From: Jordan Brockopp Date: Wed, 20 Mar 2024 10:59:38 -0500 Subject: [PATCH 14/71] fix(api/webhook): build approval for fork-no-write (#1088) * fix(api/webhook): build approval for fork-no-write * chore: address linter feedback --- api/webhook/post.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/api/webhook/post.go b/api/webhook/post.go index 038d53fe7..5fbf1327c 100644 --- a/api/webhook/post.go +++ b/api/webhook/post.go @@ -762,6 +762,8 @@ func PostWebhook(c *gin.Context) { // if the webhook was from a Pull event from a forked repository, verify it is allowed to run if webhook.PullRequest.IsFromFork { + logrus.Tracef("inside %s workflow for fork PR build %s/%d", repo.GetApproveBuild(), r.GetFullName(), b.GetNumber()) + switch repo.GetApproveBuild() { case constants.ApproveForkAlways: err = gatekeepBuild(c, b, repo, u) @@ -782,7 +784,7 @@ func PostWebhook(c *gin.Context) { return } - fallthrough + logrus.Debugf("fork PR build %s/%d automatically running without approval", repo.GetFullName(), b.GetNumber()) case constants.ApproveOnce: // determine if build sender is in the contributors list for the repo // From 0df024eea3e42f9fd61fc296b66e67f0d3caf0c4 Mon Sep 17 00:00:00 2001 From: dave vader <48764154+plyr4@users.noreply.github.com> Date: Thu, 21 Mar 2024 13:17:14 -0500 Subject: [PATCH 15/71] fix: swagger typo (#1092) --- api/worker/create.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/worker/create.go b/api/worker/create.go index d91898885..38f9eb786 100644 --- a/api/worker/create.go +++ b/api/worker/create.go @@ -40,7 +40,7 @@ import ( // '201': // description: Successfully created the worker and retrieved auth token // schema: -// "$ref": "#definitions/Token" +// "$ref": "#/definitions/Token" // '400': // description: Unable to create the worker // schema: From 8a5955d9114fefec86f683ea6fbb1bb101c2d40a Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Mon, 25 Mar 2024 10:34:27 -0400 Subject: [PATCH 16/71] refactor: create re-usable `CompileAndPublish` function (#1063) * init commit * comments and prnum logic * fix issue comment test * add a comment to trigger a new commit * renaming * more renaming * enqueue take item instead of 3 resources * fix error return for bad route and change create form --- api/build/approve.go | 7 +- api/build/compile_publish.go | 470 +++++++++++++++++++++++++++++++++++ api/build/create.go | 300 ++-------------------- api/build/enqueue.go | 56 +++++ api/build/publish.go | 62 ----- api/build/restart.go | 300 ++-------------------- api/webhook/post.go | 435 +++----------------------------- cmd/vela-server/schedule.go | 260 ++----------------- scm/github/webhook.go | 18 +- scm/github/webhook_test.go | 30 +-- util/util.go | 17 +- 11 files changed, 643 insertions(+), 1312 deletions(-) create mode 100644 api/build/compile_publish.go create mode 100644 api/build/enqueue.go delete mode 100644 api/build/publish.go diff --git a/api/build/approve.go b/api/build/approve.go index 037160282..5b41616b5 100644 --- a/api/build/approve.go +++ b/api/build/approve.go @@ -16,6 +16,7 @@ import ( "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" + "github.com/go-vela/types" "github.com/go-vela/types/constants" "github.com/sirupsen/logrus" ) @@ -126,13 +127,11 @@ func ApproveBuild(c *gin.Context) { } // publish the build to the queue - go PublishToQueue( + go Enqueue( ctx, queue.FromGinContext(c), database.FromContext(c), - b, - r, - owner, + types.ToItem(b, r, owner), b.GetHost(), ) diff --git a/api/build/compile_publish.go b/api/build/compile_publish.go new file mode 100644 index 000000000..114e121a5 --- /dev/null +++ b/api/build/compile_publish.go @@ -0,0 +1,470 @@ +// SPDX-License-Identifier: Apache-2.0 + +package build + +import ( + "context" + "fmt" + "net/http" + "strconv" + "strings" + "time" + + "github.com/go-vela/server/compiler" + "github.com/go-vela/server/database" + "github.com/go-vela/server/queue" + "github.com/go-vela/server/scm" + "github.com/go-vela/server/util" + "github.com/go-vela/types" + "github.com/go-vela/types/constants" + "github.com/go-vela/types/library" + "github.com/go-vela/types/pipeline" + "github.com/sirupsen/logrus" +) + +// CompileAndPublishConfig is a struct that contains information for the CompileAndPublish function. +type CompileAndPublishConfig struct { + Build *library.Build + Repo *library.Repo + Metadata *types.Metadata + BaseErr string + Source string + Comment string + Retries int +} + +// CompileAndPublish is a helper function to generate the queue items for a build. It takes a form +// as well as the database, scm, compiler, and queue services as arguments. It is used in webhook handling, +// schedule processing, and API build creation. +// +//nolint:funlen,gocyclo // ignore function length due to comments, error handling, and general complexity of function +func CompileAndPublish( + c context.Context, + cfg CompileAndPublishConfig, + database database.Interface, + scm scm.Service, + compiler compiler.Engine, + queue queue.Service, +) (bool, *pipeline.Build, *types.Item, error) { + logrus.Debugf("generating queue items for build %s/%d", cfg.Repo.GetFullName(), cfg.Build.GetNumber()) + + // assign variables from form for readibility + r := cfg.Repo + b := cfg.Build + baseErr := cfg.BaseErr + + // send API call to capture repo owner + logrus.Debugf("capturing owner of repository %s", cfg.Repo.GetFullName()) + + u, err := database.GetUser(c, r.GetUserID()) + if err != nil { + retErr := fmt.Errorf("%s: failed to get owner for %s: %w", baseErr, r.GetFullName(), err) + util.HandleError(c, http.StatusBadRequest, retErr) + + return false, nil, nil, retErr + } + + // confirm current repo owner has at least write access to repo (needed for status update later) + _, err = scm.RepoAccess(c, u.GetName(), u.GetToken(), r.GetOrg(), r.GetName()) + if err != nil { + retErr := fmt.Errorf("unable to publish build to queue: repository owner %s no longer has write access to repository %s", u.GetName(), r.GetFullName()) + util.HandleError(c, http.StatusUnauthorized, retErr) + + return false, nil, nil, retErr + } + + // get pull request number from build if event is pull_request or issue_comment + var prNum int + if strings.EqualFold(b.GetEvent(), constants.EventPull) || strings.EqualFold(b.GetEvent(), constants.EventComment) { + prNum, err = getPRNumberFromBuild(b) + if err != nil { + retErr := fmt.Errorf("%s: failed to get pull request number for %s: %w", baseErr, r.GetFullName(), err) + util.HandleError(c, http.StatusBadRequest, retErr) + + return false, nil, nil, retErr + } + } + + // if the event is issue_comment and the issue is a pull request, + // call SCM for more data not provided in webhook payload + if strings.EqualFold(cfg.Source, "webhook") && strings.EqualFold(b.GetEvent(), constants.EventComment) { + if err != nil { + retErr := fmt.Errorf("%s: failed to get pull request number for %s: %w", baseErr, r.GetFullName(), err) + util.HandleError(c, http.StatusBadRequest, retErr) + + return false, nil, nil, retErr + } + + commit, branch, baseref, headref, err := scm.GetPullRequest(c, u, r, prNum) + if err != nil { + retErr := fmt.Errorf("%s: failed to get pull request info for %s: %w", baseErr, r.GetFullName(), err) + util.HandleError(c, http.StatusInternalServerError, retErr) + + return false, nil, nil, retErr + } + + b.SetCommit(commit) + b.SetBranch(strings.ReplaceAll(branch, "refs/heads/", "")) + b.SetBaseRef(baseref) + b.SetHeadRef(headref) + } + + // if the source is from a schedule, fetch the commit sha from schedule branch (same as build branch at this moment) + if strings.EqualFold(cfg.Source, "schedule") { + // send API call to capture the commit sha for the branch + _, commit, err := scm.GetBranch(c, u, r, b.GetBranch()) + if err != nil { + retErr := fmt.Errorf("failed to get commit for repo %s on %s branch: %w", r.GetFullName(), r.GetBranch(), err) + util.HandleError(c, http.StatusInternalServerError, retErr) + + return false, nil, nil, retErr + } + + b.SetCommit(commit) + } + + // create SQL filters for querying pending and running builds for repo + filters := map[string]interface{}{ + "status": []string{constants.StatusPending, constants.StatusRunning}, + } + + // send API call to capture the number of pending or running builds for the repo + builds, err := database.CountBuildsForRepo(c, r, filters) + if err != nil { + retErr := fmt.Errorf("%s: unable to get count of builds for repo %s", baseErr, r.GetFullName()) + util.HandleError(c, http.StatusBadRequest, retErr) + + return false, nil, nil, retErr + } + + logrus.Debugf("currently %d builds running on repo %s", builds, r.GetFullName()) + + // check if the number of pending and running builds exceeds the limit for the repo + if builds >= r.GetBuildLimit() { + retErr := fmt.Errorf("%s: repo %s has exceeded the concurrent build limit of %d", baseErr, r.GetFullName(), r.GetBuildLimit()) + util.HandleError(c, http.StatusBadRequest, retErr) + + return false, nil, nil, retErr + } + + // update fields in build object + // this is necessary in case source is restart and the build is prepopulated with these values + b.SetID(0) + b.SetCreated(time.Now().UTC().Unix()) + b.SetEnqueued(0) + b.SetStarted(0) + b.SetFinished(0) + b.SetStatus(constants.StatusPending) + b.SetError("") + b.SetHost("") + b.SetRuntime("") + b.SetDistribution("") + + // variable to store changeset files + var files []string + + // check if the build event is not issue_comment or pull_request + if !strings.EqualFold(b.GetEvent(), constants.EventComment) && + !strings.EqualFold(b.GetEvent(), constants.EventPull) && + !strings.EqualFold(b.GetEvent(), constants.EventDelete) { + // send API call to capture list of files changed for the commit + files, err = scm.Changeset(c, u, r, b.GetCommit()) + if err != nil { + retErr := fmt.Errorf("%s: failed to get changeset for %s: %w", baseErr, r.GetFullName(), err) + util.HandleError(c, http.StatusInternalServerError, retErr) + + return false, nil, nil, retErr + } + } + + // check if the build event is a pull_request + if strings.EqualFold(b.GetEvent(), constants.EventPull) && prNum > 0 { + // send API call to capture list of files changed for the pull request + files, err = scm.ChangesetPR(c, u, r, prNum) + if err != nil { + retErr := fmt.Errorf("%s: failed to get changeset for %s: %w", baseErr, r.GetFullName(), err) + util.HandleError(c, http.StatusInternalServerError, retErr) + + return false, nil, nil, retErr + } + } + + var ( + // variable to store the raw pipeline configuration + pipelineFile []byte + // variable to store executable pipeline + p *pipeline.Build + // variable to store pipeline configuration + pipeline *library.Pipeline + // variable to store the pipeline type for the repository + pipelineType = r.GetPipelineType() + // variable to store updated repository record + repo *library.Repo + ) + + // implement a loop to process asynchronous operations with a retry limit + // + // Some operations taken during the webhook workflow can lead to race conditions + // failing to successfully process the request. This logic ensures we attempt our + // best efforts to handle these cases gracefully. + for i := 0; i < cfg.Retries; i++ { + logrus.Debugf("compilation loop - attempt %d", i+1) + // check if we're on the first iteration of the loop + if i > 0 { + // incrementally sleep in between retries + time.Sleep(time.Duration(i) * time.Second) + } + + // send database call to attempt to capture the pipeline if we already processed it before + pipeline, err = database.GetPipelineForRepo(c, b.GetCommit(), r) + if err != nil { // assume the pipeline doesn't exist in the database yet + // send API call to capture the pipeline configuration file + pipelineFile, err = scm.ConfigBackoff(c, u, r, b.GetCommit()) + if err != nil { + retErr := fmt.Errorf("%s: unable to get pipeline configuration for %s: %w", baseErr, r.GetFullName(), err) + + util.HandleError(c, http.StatusNotFound, retErr) + + return false, nil, nil, retErr + } + } else { + pipelineFile = pipeline.GetData() + } + + // send API call to capture repo for the counter (grabbing repo again to ensure counter is correct) + repo, err = database.GetRepoForOrg(c, r.GetOrg(), r.GetName()) + if err != nil { + retErr := fmt.Errorf("%s: unable to get repo %s: %w", baseErr, r.GetFullName(), err) + + // check if the retry limit has been exceeded + if i < cfg.Retries-1 { + logrus.WithError(retErr).Warningf("retrying #%d", i+1) + + // continue to the next iteration of the loop + continue + } + + util.HandleError(c, http.StatusBadRequest, retErr) + + return false, nil, nil, retErr + } + + // update DB record of repo (repo) with any changes captured from webhook payload (r) + repo.SetTopics(r.GetTopics()) + repo.SetBranch(r.GetBranch()) + + // update the build numbers based off repo counter + inc := repo.GetCounter() + 1 + repo.SetCounter(inc) + b.SetNumber(inc) + + // populate the build link if a web address is provided + if len(cfg.Metadata.Vela.WebAddress) > 0 { + b.SetLink( + fmt.Sprintf("%s/%s/%d", cfg.Metadata.Vela.WebAddress, repo.GetFullName(), b.GetNumber()), + ) + } + + // ensure we use the expected pipeline type when compiling + // + // The pipeline type for a repo can change at any time which can break compiling + // existing pipelines in the system for that repo. To account for this, we update + // the repo pipeline type to match what was defined for the existing pipeline + // before compiling. After we're done compiling, we reset the pipeline type. + if len(pipeline.GetType()) > 0 { + repo.SetPipelineType(pipeline.GetType()) + } + + var compiled *library.Pipeline + // parse and compile the pipeline configuration file + p, compiled, err = compiler. + Duplicate(). + WithBuild(b). + WithComment(cfg.Comment). + WithCommit(b.GetCommit()). + WithFiles(files). + WithMetadata(cfg.Metadata). + WithRepo(repo). + WithUser(u). + Compile(pipelineFile) + if err != nil { + // format the error message with extra information + err = fmt.Errorf("unable to compile pipeline configuration for %s: %w", repo.GetFullName(), err) + + // log the error for traceability + logrus.Error(err.Error()) + + retErr := fmt.Errorf("%s: %w", baseErr, err) + util.HandleError(c, http.StatusInternalServerError, retErr) + + return false, nil, nil, retErr + } + + // reset the pipeline type for the repo + // + // The pipeline type for a repo can change at any time which can break compiling + // existing pipelines in the system for that repo. To account for this, we update + // the repo pipeline type to match what was defined for the existing pipeline + // before compiling. After we're done compiling, we reset the pipeline type. + repo.SetPipelineType(pipelineType) + + // skip the build if pipeline compiled to only the init and clone steps + skip := SkipEmptyBuild(p) + if skip != "" { + // set build to successful status + b.SetStatus(constants.StatusSkipped) + + // send API call to set the status on the commit + err = scm.Status(c, u, b, repo.GetOrg(), repo.GetName()) + if err != nil { + logrus.Errorf("unable to set commit status for %s/%d: %v", repo.GetFullName(), b.GetNumber(), err) + } + + return false, + nil, + &types.Item{ + Build: b, + }, + nil + } + + // check if the pipeline did not already exist in the database + if pipeline == nil { + pipeline = compiled + pipeline.SetRepoID(repo.GetID()) + pipeline.SetCommit(b.GetCommit()) + pipeline.SetRef(b.GetRef()) + + // send API call to create the pipeline + pipeline, err = database.CreatePipeline(c, pipeline) + if err != nil { + retErr := fmt.Errorf("%s: failed to create pipeline for %s: %w", baseErr, repo.GetFullName(), err) + + // check if the retry limit has been exceeded + if i < cfg.Retries-1 { + logrus.WithError(retErr).Warningf("retrying #%d", i+1) + + // continue to the next iteration of the loop + continue + } + + util.HandleError(c, http.StatusBadRequest, retErr) + + return false, nil, nil, retErr + } + } + + b.SetPipelineID(pipeline.GetID()) + + // create the objects from the pipeline in the database + // TODO: + // - if a build gets created and something else fails midway, + // the next loop will attempt to create the same build, + // using the same Number and thus create a constraint + // conflict; consider deleting the partially created + // build object in the database + err = PlanBuild(c, database, p, b, repo) + if err != nil { + retErr := fmt.Errorf("%s: %w", baseErr, err) + + // check if the retry limit has been exceeded + if i < cfg.Retries-1 { + logrus.WithError(retErr).Warningf("retrying #%d", i+1) + + // reset fields set by cleanBuild for retry + b.SetError("") + b.SetStatus(constants.StatusPending) + b.SetFinished(0) + + // continue to the next iteration of the loop + continue + } + + util.HandleError(c, http.StatusInternalServerError, retErr) + + return false, nil, nil, retErr + } + + // break the loop because everything was successful + break + } // end of retry loop + + // send API call to update repo for ensuring counter is incremented + repo, err = database.UpdateRepo(c, repo) + if err != nil { + retErr := fmt.Errorf("%s: failed to update repo %s: %w", baseErr, repo.GetFullName(), err) + util.HandleError(c, http.StatusBadRequest, retErr) + + return false, nil, nil, retErr + } + + // return error if pipeline didn't get populated + if p == nil { + retErr := fmt.Errorf("%s: failed to set pipeline for %s: %w", baseErr, repo.GetFullName(), err) + util.HandleError(c, http.StatusBadRequest, retErr) + + return false, nil, nil, retErr + } + + // return error if build didn't get populated + if b == nil { + retErr := fmt.Errorf("%s: failed to set build for %s: %w", baseErr, repo.GetFullName(), err) + util.HandleError(c, http.StatusBadRequest, retErr) + + return false, nil, nil, retErr + } + + // send API call to capture the triggered build + b, err = database.GetBuildForRepo(c, repo, b.GetNumber()) + if err != nil { + retErr := fmt.Errorf("%s: failed to get new build %s/%d: %w", baseErr, repo.GetFullName(), b.GetNumber(), err) + util.HandleError(c, http.StatusInternalServerError, retErr) + + return false, nil, nil, retErr + } + + // determine queue route + route, err := queue.Route(&p.Worker) + if err != nil { + retErr := fmt.Errorf("unable to set route for build %d for %s: %w", b.GetNumber(), r.GetFullName(), err) + + // error out the build + CleanBuild(c, database, b, nil, nil, retErr) + + return false, nil, nil, retErr + } + + // temporarily set host to the route before it gets picked up by a worker + b.SetHost(route) + + // publish the pipeline.Build to the build_executables table to be requested by a worker + err = PublishBuildExecutable(c, database, p, b) + if err != nil { + retErr := fmt.Errorf("unable to publish build executable for %s/%d: %w", repo.GetFullName(), b.GetNumber(), err) + util.HandleError(c, http.StatusInternalServerError, retErr) + + return false, nil, nil, retErr + } + + return true, p, types.ToItem(b, repo, u), nil +} + +// getPRNumberFromBuild is a helper function to +// extract the pull request number from a Build. +func getPRNumberFromBuild(b *library.Build) (int, error) { + // parse out pull request number from base ref + // + // pattern: refs/pull/1/head + var parts []string + if strings.HasPrefix(b.GetRef(), "refs/pull/") { + parts = strings.Split(b.GetRef(), "/") + } + + // just being safe to avoid out of range index errors + if len(parts) < 3 { + return 0, fmt.Errorf("invalid ref: %s", b.GetRef()) + } + + // return the results of converting number to string + return strconv.Atoi(parts[2]) +} diff --git a/api/build/create.go b/api/build/create.go index 991946c88..09916d245 100644 --- a/api/build/create.go +++ b/api/build/create.go @@ -5,9 +5,6 @@ package build import ( "fmt" "net/http" - "strconv" - "strings" - "time" "github.com/gin-gonic/gin" "github.com/go-vela/server/compiler" @@ -19,9 +16,7 @@ import ( "github.com/go-vela/server/scm" "github.com/go-vela/server/util" "github.com/go-vela/types" - "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/go-vela/types/pipeline" "github.com/sirupsen/logrus" ) @@ -75,8 +70,6 @@ import ( // "$ref": "#/definitions/Error" // CreateBuild represents the API handler to create a build in the configured backend. -// -//nolint:funlen,gocyclo // ignore function length and cyclomatic complexity func CreateBuild(c *gin.Context) { // capture middleware values m := c.MustGet("metadata").(*types.Metadata) @@ -109,10 +102,7 @@ func CreateBuild(c *gin.Context) { } // verify the build has a valid event and the repo allows that event type - if (input.GetEvent() == constants.EventPush && !r.GetAllowPush()) || - (input.GetEvent() == constants.EventPull && !r.GetAllowPull()) || - (input.GetEvent() == constants.EventTag && !r.GetAllowTag()) || - (input.GetEvent() == constants.EventDeploy && !r.GetAllowDeploy()) { + if !r.GetAllowEvents().Allowed(input.GetEvent(), input.GetEventAction()) { retErr := fmt.Errorf("unable to create new build: %s does not have %s events enabled", r.GetFullName(), input.GetEvent()) util.HandleError(c, http.StatusBadRequest, retErr) @@ -120,286 +110,38 @@ func CreateBuild(c *gin.Context) { return } - // send API call to capture the repo owner - u, err = database.FromContext(c).GetUser(ctx, r.GetUserID()) - if err != nil { - retErr := fmt.Errorf("unable to get owner for %s: %w", r.GetFullName(), err) - - util.HandleError(c, http.StatusBadRequest, retErr) - - return - } - - // create SQL filters for querying pending and running builds for repo - filters := map[string]interface{}{ - "status": []string{constants.StatusPending, constants.StatusRunning}, - } - - // send API call to capture the number of pending or running builds for the repo - builds, err := database.FromContext(c).CountBuildsForRepo(ctx, r, filters) - if err != nil { - retErr := fmt.Errorf("unable to create new build: unable to get count of builds for repo %s", r.GetFullName()) - - util.HandleError(c, http.StatusBadRequest, retErr) - - return - } - - // check if the number of pending and running builds exceeds the limit for the repo - if builds >= r.GetBuildLimit() { - retErr := fmt.Errorf("unable to create new build: repo %s has exceeded the concurrent build limit of %d", r.GetFullName(), r.GetBuildLimit()) - - util.HandleError(c, http.StatusBadRequest, retErr) - - return - } - - // update fields in build object - input.SetRepoID(r.GetID()) - input.SetStatus(constants.StatusPending) - input.SetCreated(time.Now().UTC().Unix()) - - // set the parent equal to the current repo counter - input.SetParent(r.GetCounter()) - // check if the parent is set to 0 - if input.GetParent() == 0 { - // parent should be "1" if it's the first build ran - input.SetParent(1) - } - - // update the build numbers based off repo counter - inc := r.GetCounter() + 1 - r.SetCounter(inc) - input.SetNumber(inc) - - // populate the build link if a web address is provided - if len(m.Vela.WebAddress) > 0 { - input.SetLink( - fmt.Sprintf("%s/%s/%d", m.Vela.WebAddress, r.GetFullName(), input.GetNumber()), - ) - } - - // variable to store changeset files - var files []string - // check if the build event is not issue_comment or pull_request - if !strings.EqualFold(input.GetEvent(), constants.EventComment) && - !strings.EqualFold(input.GetEvent(), constants.EventPull) { - // send API call to capture list of files changed for the commit - files, err = scm.FromContext(c).Changeset(ctx, u, r, input.GetCommit()) - if err != nil { - retErr := fmt.Errorf("unable to create new build: failed to get changeset for %s: %w", r.GetFullName(), err) - - util.HandleError(c, http.StatusInternalServerError, retErr) - - return - } - } - - // check if the build event is a pull_request - if strings.EqualFold(input.GetEvent(), constants.EventPull) { - // capture number from build - number, err := getPRNumberFromBuild(input) - if err != nil { - retErr := fmt.Errorf("unable to create new build: failed to get pull_request number for %s: %w", r.GetFullName(), err) - - util.HandleError(c, http.StatusInternalServerError, retErr) - - return - } - - // send API call to capture list of files changed for the pull request - files, err = scm.FromContext(c).ChangesetPR(ctx, u, r, number) - if err != nil { - retErr := fmt.Errorf("unable to create new build: failed to get changeset for %s: %w", r.GetFullName(), err) - - util.HandleError(c, http.StatusInternalServerError, retErr) - - return - } + // create config + config := CompileAndPublishConfig{ + Build: input, + Repo: r, + Metadata: m, + BaseErr: "unable to create build", + Source: "create", + Retries: 1, } - var ( - // variable to store the raw pipeline configuration - config []byte - // variable to store executable pipeline - p *pipeline.Build - // variable to store pipeline configuration - pipeline *library.Pipeline - // variable to store the pipeline type for the repository - pipelineType = r.GetPipelineType() + _, _, item, err := CompileAndPublish( + c, + config, + database.FromContext(c), + scm.FromContext(c), + compiler.FromContext(c), + queue.FromContext(c), ) - // send API call to attempt to capture the pipeline - pipeline, err = database.FromContext(c).GetPipelineForRepo(ctx, input.GetCommit(), r) - if err != nil { // assume the pipeline doesn't exist in the database yet - // send API call to capture the pipeline configuration file - config, err = scm.FromContext(c).ConfigBackoff(ctx, u, r, input.GetCommit()) - if err != nil { - retErr := fmt.Errorf("unable to create new build: failed to get pipeline configuration for %s: %w", r.GetFullName(), err) - - util.HandleError(c, http.StatusNotFound, retErr) - - return - } - } else { - config = pipeline.GetData() - } - - // ensure we use the expected pipeline type when compiling - // - // The pipeline type for a repo can change at any time which can break compiling - // existing pipelines in the system for that repo. To account for this, we update - // the repo pipeline type to match what was defined for the existing pipeline - // before compiling. After we're done compiling, we reset the pipeline type. - if len(pipeline.GetType()) > 0 { - r.SetPipelineType(pipeline.GetType()) - } - - var compiled *library.Pipeline - // parse and compile the pipeline configuration file - p, compiled, err = compiler.FromContext(c). - Duplicate(). - WithBuild(input). - WithFiles(files). - WithMetadata(m). - WithRepo(r). - WithUser(u). - Compile(config) - if err != nil { - retErr := fmt.Errorf("unable to compile pipeline configuration for %s/%d: %w", r.GetFullName(), input.GetNumber(), err) - - util.HandleError(c, http.StatusInternalServerError, retErr) - - return - } - // reset the pipeline type for the repo - // - // The pipeline type for a repo can change at any time which can break compiling - // existing pipelines in the system for that repo. To account for this, we update - // the repo pipeline type to match what was defined for the existing pipeline - // before compiling. After we're done compiling, we reset the pipeline type. - r.SetPipelineType(pipelineType) - - // skip the build if only the init or clone steps are found - skip := SkipEmptyBuild(p) - if skip != "" { - // set build to successful status - input.SetStatus(constants.StatusSuccess) - - // send API call to set the status on the commit - err = scm.FromContext(c).Status(ctx, u, input, r.GetOrg(), r.GetName()) - if err != nil { - logger.Errorf("unable to set commit status for %s/%d: %v", r.GetFullName(), input.GetNumber(), err) - } - - c.JSON(http.StatusOK, skip) - - return - } - - // check if the pipeline did not already exist in the database - // - //nolint:dupl // ignore duplicate code - if pipeline == nil { - pipeline = compiled - pipeline.SetRepoID(r.GetID()) - pipeline.SetCommit(input.GetCommit()) - pipeline.SetRef(input.GetRef()) - - // send API call to create the pipeline - pipeline, err = database.FromContext(c).CreatePipeline(ctx, pipeline) - if err != nil { - retErr := fmt.Errorf("unable to create new build: failed to create pipeline for %s: %w", r.GetFullName(), err) - - util.HandleError(c, http.StatusBadRequest, retErr) - - return - } - } - - input.SetPipelineID(pipeline.GetID()) - - // create the objects from the pipeline in the database - err = PlanBuild(ctx, database.FromContext(c), p, input, r) - if err != nil { - util.HandleError(c, http.StatusInternalServerError, err) - - return - } - - // send API call to update repo for ensuring counter is incremented - r, err = database.FromContext(c).UpdateRepo(ctx, r) - if err != nil { - retErr := fmt.Errorf("unable to create new build: failed to update repo %s: %w", r.GetFullName(), err) - - util.HandleError(c, http.StatusBadRequest, retErr) - - return - } - - // send API call to capture the created build - input, _ = database.FromContext(c).GetBuildForRepo(ctx, r, input.GetNumber()) - - c.JSON(http.StatusCreated, input) - - // send API call to set the status on the commit except for scheduled build - if input.GetEvent() != constants.EventSchedule { - err = scm.FromContext(c).Status(ctx, u, input, r.GetOrg(), r.GetName()) - if err != nil { - logger.Errorf("unable to set commit status for build %s/%d: %v", r.GetFullName(), input.GetNumber(), err) - } - } - - // determine queue route - route, err := queue.FromGinContext(c).Route(&p.Worker) + // error handling done in CompileAndPublish if err != nil { - logrus.Errorf("unable to set route for build %d for %s: %v", input.GetNumber(), r.GetFullName(), err) - - // error out the build - CleanBuild(ctx, database.FromContext(c), input, nil, nil, err) - return } - // temporarily set host to the route before it gets picked up by a worker - input.SetHost(route) - - err = PublishBuildExecutable(ctx, database.FromContext(c), p, input) - if err != nil { - retErr := fmt.Errorf("unable to publish build executable for %s/%d: %w", r.GetFullName(), input.GetNumber(), err) - util.HandleError(c, http.StatusInternalServerError, retErr) - - return - } + c.JSON(http.StatusCreated, item.Build) // publish the build to the queue - go PublishToQueue( + go Enqueue( ctx, queue.FromGinContext(c), database.FromContext(c), - input, - r, - u, - route, + item, + item.Build.GetHost(), ) } - -// getPRNumberFromBuild is a helper function to -// extract the pull request number from a Build. -func getPRNumberFromBuild(b *library.Build) (int, error) { - // parse out pull request number from base ref - // - // pattern: refs/pull/1/head - var parts []string - if strings.HasPrefix(b.GetRef(), "refs/pull/") { - parts = strings.Split(b.GetRef(), "/") - } - - // just being safe to avoid out of range index errors - if len(parts) < 3 { - return 0, fmt.Errorf("invalid ref: %s", b.GetRef()) - } - - // return the results of converting number to string - return strconv.Atoi(parts[2]) -} diff --git a/api/build/enqueue.go b/api/build/enqueue.go new file mode 100644 index 000000000..be8cb2971 --- /dev/null +++ b/api/build/enqueue.go @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: Apache-2.0 + +package build + +import ( + "context" + "encoding/json" + "time" + + "github.com/go-vela/server/database" + "github.com/go-vela/server/queue" + "github.com/go-vela/types" + "github.com/sirupsen/logrus" +) + +// Enqueue is a helper function that pushes a queue item (build, repo, user) to the queue. +func Enqueue(ctx context.Context, queue queue.Service, db database.Interface, item *types.Item, route string) { + logrus.Infof("Converting queue item to json for build %d for %s", item.Build.GetNumber(), item.Repo.GetFullName()) + + byteItem, err := json.Marshal(item) + if err != nil { + logrus.Errorf("Failed to convert item to json for build %d for %s: %v", item.Build.GetNumber(), item.Repo.GetFullName(), err) + + // error out the build + CleanBuild(ctx, db, item.Build, nil, nil, err) + + return + } + + logrus.Infof("Pushing item for build %d for %s to queue route %s", item.Build.GetNumber(), item.Repo.GetFullName(), route) + + // push item on to the queue + err = queue.Push(context.Background(), route, byteItem) + if err != nil { + logrus.Errorf("Retrying; Failed to publish build %d for %s: %v", item.Build.GetNumber(), item.Repo.GetFullName(), err) + + err = queue.Push(context.Background(), route, byteItem) + if err != nil { + logrus.Errorf("Failed to publish build %d for %s: %v", item.Build.GetNumber(), item.Repo.GetFullName(), err) + + // error out the build + CleanBuild(ctx, db, item.Build, nil, nil, err) + + return + } + } + + // update fields in build object + item.Build.SetEnqueued(time.Now().UTC().Unix()) + + // update the build in the db to reflect the time it was enqueued + _, err = db.UpdateBuild(ctx, item.Build) + if err != nil { + logrus.Errorf("Failed to update build %d during publish to queue for %s: %v", item.Build.GetNumber(), item.Repo.GetFullName(), err) + } +} diff --git a/api/build/publish.go b/api/build/publish.go deleted file mode 100644 index f843b1461..000000000 --- a/api/build/publish.go +++ /dev/null @@ -1,62 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - -package build - -import ( - "context" - "encoding/json" - "time" - - "github.com/go-vela/server/database" - "github.com/go-vela/server/queue" - "github.com/go-vela/types" - "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" -) - -// PublishToQueue is a helper function that publishes a queue item (build, repo, user) to the queue. -func PublishToQueue(ctx context.Context, queue queue.Service, db database.Interface, b *library.Build, r *library.Repo, u *library.User, route string) { - // convert build, repo, and user into queue item - item := types.ToItem(b, r, u) - - logrus.Infof("Converting queue item to json for build %d for %s", b.GetNumber(), r.GetFullName()) - - byteItem, err := json.Marshal(item) - if err != nil { - logrus.Errorf("Failed to convert item to json for build %d for %s: %v", b.GetNumber(), r.GetFullName(), err) - - // error out the build - CleanBuild(ctx, db, b, nil, nil, err) - - return - } - - logrus.Infof("Establishing route for build %d for %s", b.GetNumber(), r.GetFullName()) - - logrus.Infof("Publishing item for build %d for %s to queue %s", b.GetNumber(), r.GetFullName(), route) - - // push item on to the queue - err = queue.Push(context.Background(), route, byteItem) - if err != nil { - logrus.Errorf("Retrying; Failed to publish build %d for %s: %v", b.GetNumber(), r.GetFullName(), err) - - err = queue.Push(context.Background(), route, byteItem) - if err != nil { - logrus.Errorf("Failed to publish build %d for %s: %v", b.GetNumber(), r.GetFullName(), err) - - // error out the build - CleanBuild(ctx, db, b, nil, nil, err) - - return - } - } - - // update fields in build object - b.SetEnqueued(time.Now().UTC().Unix()) - - // update the build in the db to reflect the time it was enqueued - _, err = db.UpdateBuild(ctx, b) - if err != nil { - logrus.Errorf("Failed to update build %d during publish to queue for %s: %v", b.GetNumber(), r.GetFullName(), err) - } -} diff --git a/api/build/restart.go b/api/build/restart.go index 1296d654a..aadc9b97e 100644 --- a/api/build/restart.go +++ b/api/build/restart.go @@ -6,7 +6,6 @@ import ( "fmt" "net/http" "strings" - "time" "github.com/gin-gonic/gin" "github.com/go-vela/server/compiler" @@ -21,8 +20,6 @@ import ( "github.com/go-vela/server/util" "github.com/go-vela/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" - "github.com/go-vela/types/pipeline" "github.com/sirupsen/logrus" ) @@ -74,8 +71,6 @@ import ( // "$ref": "#/definitions/Error" // RestartBuild represents the API handler to restart an existing build in the configured backend. -// -//nolint:funlen // ignore statement count func RestartBuild(c *gin.Context) { // capture middleware values m := c.MustGet("metadata").(*types.Metadata) @@ -98,6 +93,7 @@ func RestartBuild(c *gin.Context) { "user": u.GetName(), }) + // a build that is in a pending approval state cannot be restarted if strings.EqualFold(b.GetStatus(), constants.StatusPendingApproval) { retErr := fmt.Errorf("unable to restart build %s/%d: cannot restart a build pending approval", r.GetFullName(), b.GetNumber()) @@ -106,293 +102,45 @@ func RestartBuild(c *gin.Context) { return } - logger.Infof("restarting build %s", entry) - - // send API call to capture the repo owner - u, err := database.FromContext(c).GetUser(ctx, r.GetUserID()) - if err != nil { - retErr := fmt.Errorf("unable to get owner for %s: %w", r.GetFullName(), err) - - util.HandleError(c, http.StatusBadRequest, retErr) - - return - } - - // create SQL filters for querying pending and running builds for repo - filters := map[string]interface{}{ - "status": []string{constants.StatusPending, constants.StatusRunning}, - } - - // send API call to capture the number of pending or running builds for the repo - builds, err := database.FromContext(c).CountBuildsForRepo(ctx, r, filters) - if err != nil { - retErr := fmt.Errorf("unable to restart build: unable to get count of builds for repo %s", r.GetFullName()) - - util.HandleError(c, http.StatusBadRequest, retErr) - - return - } - - // check if the number of pending and running builds exceeds the limit for the repo - if builds >= r.GetBuildLimit() { - retErr := fmt.Errorf("unable to restart build: repo %s has exceeded the concurrent build limit of %d", r.GetFullName(), r.GetBuildLimit()) - - util.HandleError(c, http.StatusBadRequest, retErr) - - return - } - - // update fields in build object - b.SetID(0) - b.SetCreated(time.Now().UTC().Unix()) - b.SetEnqueued(0) - b.SetStarted(0) - b.SetFinished(0) - b.SetStatus(constants.StatusPending) - b.SetError("") - b.SetHost("") - b.SetRuntime("") - b.SetDistribution("") + // set sender to the user who initiated the restart and parent to the previous build b.SetSender(cl.Subject) - - // update the PR event action if action was never set - // for backwards compatibility with pre-0.14 releases. - if b.GetEvent() == constants.EventPull && b.GetEventAction() == "" { - // technically, the action could have been opened or synchronize. - // will not affect behavior of the pipeline since we did not - // support actions for builds where this would be the case. - b.SetEventAction(constants.ActionOpened) - } - - // set the parent equal to the restarted build number b.SetParent(b.GetNumber()) - // update the build numbers based off repo counter - inc := r.GetCounter() + 1 - r.SetCounter(inc) - b.SetNumber(inc) - - // populate the build link if a web address is provided - if len(m.Vela.WebAddress) > 0 { - b.SetLink( - fmt.Sprintf("%s/%s/%d", m.Vela.WebAddress, r.GetFullName(), b.GetNumber()), - ) - } - // variable to store changeset files - var files []string - // check if the build event is not issue_comment or pull_request - if !strings.EqualFold(b.GetEvent(), constants.EventComment) && - !strings.EqualFold(b.GetEvent(), constants.EventPull) { - // send API call to capture list of files changed for the commit - files, err = scm.FromContext(c).Changeset(ctx, u, r, b.GetCommit()) - if err != nil { - retErr := fmt.Errorf("unable to restart build: failed to get changeset for %s: %w", r.GetFullName(), err) + logger.Debugf("Generating queue items for build %s", entry) - util.HandleError(c, http.StatusInternalServerError, retErr) - - return - } + // restart form + config := CompileAndPublishConfig{ + Build: b, + Repo: r, + Metadata: m, + BaseErr: "unable to restart build", + Source: "restart", + Retries: 1, } - // check if the build event is a pull_request - if strings.EqualFold(b.GetEvent(), constants.EventPull) { - // capture number from build - number, err := getPRNumberFromBuild(b) - if err != nil { - retErr := fmt.Errorf("unable to restart build: failed to get pull_request number for %s: %w", r.GetFullName(), err) - - util.HandleError(c, http.StatusInternalServerError, retErr) - - return - } - - // send API call to capture list of files changed for the pull request - files, err = scm.FromContext(c).ChangesetPR(ctx, u, r, number) - if err != nil { - retErr := fmt.Errorf("unable to restart build: failed to get changeset for %s: %w", r.GetFullName(), err) - - util.HandleError(c, http.StatusInternalServerError, retErr) - - return - } - } - - // variables to store pipeline configuration - var ( - // variable to store the raw pipeline configuration - config []byte - // variable to store executable pipeline - p *pipeline.Build - // variable to store pipeline configuration - pipeline *library.Pipeline - // variable to store the pipeline type for the repository - pipelineType = r.GetPipelineType() + // generate queue items + _, _, item, err := CompileAndPublish( + c, + config, + database.FromContext(c), + scm.FromContext(c), + compiler.FromContext(c), + queue.FromContext(c), ) - // send API call to attempt to capture the pipeline - pipeline, err = database.FromContext(c).GetPipelineForRepo(ctx, b.GetCommit(), r) - if err != nil { // assume the pipeline doesn't exist in the database yet (before pipeline support was added) - // send API call to capture the pipeline configuration file - config, err = scm.FromContext(c).ConfigBackoff(ctx, u, r, b.GetCommit()) - if err != nil { - retErr := fmt.Errorf("unable to get pipeline configuration for %s: %w", r.GetFullName(), err) - - util.HandleError(c, http.StatusNotFound, retErr) - - return - } - } else { - config = pipeline.GetData() - } - - // ensure we use the expected pipeline type when compiling - // - // The pipeline type for a repo can change at any time which can break compiling - // existing pipelines in the system for that repo. To account for this, we update - // the repo pipeline type to match what was defined for the existing pipeline - // before compiling. After we're done compiling, we reset the pipeline type. - if len(pipeline.GetType()) > 0 { - r.SetPipelineType(pipeline.GetType()) - } - - var compiled *library.Pipeline - // parse and compile the pipeline configuration file - p, compiled, err = compiler.FromContext(c). - Duplicate(). - WithBuild(b). - WithCommit(b.GetCommit()). - WithFiles(files). - WithMetadata(m). - WithRepo(r). - WithUser(u). - Compile(config) - if err != nil { - retErr := fmt.Errorf("unable to compile pipeline configuration for %s: %w", entry, err) - - util.HandleError(c, http.StatusInternalServerError, retErr) - - return - } - // reset the pipeline type for the repo - // - // The pipeline type for a repo can change at any time which can break compiling - // existing pipelines in the system for that repo. To account for this, we update - // the repo pipeline type to match what was defined for the existing pipeline - // before compiling. After we're done compiling, we reset the pipeline type. - r.SetPipelineType(pipelineType) - - // skip the build if only the init or clone steps are found - skip := SkipEmptyBuild(p) - if skip != "" { - // set build to successful status - b.SetStatus(constants.StatusSkipped) - - // send API call to set the status on the commit - err = scm.FromContext(c).Status(ctx, u, b, r.GetOrg(), r.GetName()) - if err != nil { - logrus.Errorf("unable to set commit status for %s/%d: %v", r.GetFullName(), b.GetNumber(), err) - } - - c.JSON(http.StatusOK, skip) - - return - } - - // check if the pipeline did not already exist in the database - if pipeline == nil { - pipeline = compiled - pipeline.SetRepoID(r.GetID()) - pipeline.SetCommit(b.GetCommit()) - pipeline.SetRef(b.GetRef()) - - // send API call to create the pipeline - pipeline, err = database.FromContext(c).CreatePipeline(ctx, pipeline) - if err != nil { - retErr := fmt.Errorf("unable to create pipeline for %s: %w", r.GetFullName(), err) - - util.HandleError(c, http.StatusBadRequest, retErr) - - return - } - } - - b.SetPipelineID(pipeline.GetID()) - - // create the objects from the pipeline in the database - err = PlanBuild(ctx, database.FromContext(c), p, b, r) - if err != nil { - util.HandleError(c, http.StatusInternalServerError, err) - - return - } - - // send API call to update repo for ensuring counter is incremented - r, err = database.FromContext(c).UpdateRepo(ctx, r) + // error handling done in GenerateQueueItems if err != nil { - retErr := fmt.Errorf("unable to restart build: failed to update repo %s: %w", r.GetFullName(), err) - util.HandleError(c, http.StatusBadRequest, retErr) - return } - // send API call to capture the restarted build - b, _ = database.FromContext(c).GetBuildForRepo(ctx, r, b.GetNumber()) - - c.JSON(http.StatusCreated, b) - - // if the event is a deployment, update the build list - if strings.EqualFold(b.GetEvent(), constants.EventDeploy) { - d, err := database.FromContext(c).GetDeploymentForRepo(c, r, b.GetDeployNumber()) - if err != nil { - logger.Errorf("unable to set get deployment for build %s: %v", entry, err) - } - - build := append(d.GetBuilds(), b) - - d.SetBuilds(build) - - _, err = database.FromContext(c).UpdateDeployment(ctx, d) - if err != nil { - logger.Errorf("unable to set update deployment for build %s: %v", entry, err) - } - } - - // send API call to set the status on the commit - err = scm.FromContext(c).Status(ctx, u, b, r.GetOrg(), r.GetName()) - if err != nil { - logger.Errorf("unable to set commit status for build %s: %v", entry, err) - } - - // determine queue route - route, err := queue.FromContext(c).Route(&p.Worker) - if err != nil { - logrus.Errorf("unable to set route for build %d for %s: %v", b.GetNumber(), r.GetFullName(), err) - - // error out the build - CleanBuild(ctx, database.FromContext(c), b, nil, nil, err) - - return - } - - // temporarily set host to the route before it gets picked up by a worker - b.SetHost(route) - - err = PublishBuildExecutable(ctx, database.FromContext(c), p, b) - if err != nil { - retErr := fmt.Errorf("unable to publish build executable for %s/%d: %w", r.GetFullName(), b.GetNumber(), err) - util.HandleError(c, http.StatusInternalServerError, retErr) - - return - } + c.JSON(http.StatusCreated, item.Build) // publish the build to the queue - go PublishToQueue( + go Enqueue( ctx, queue.FromGinContext(c), database.FromContext(c), - b, - r, - u, - route, + item, + item.Build.GetHost(), ) } diff --git a/api/webhook/post.go b/api/webhook/post.go index 5fbf1327c..0746a4574 100644 --- a/api/webhook/post.go +++ b/api/webhook/post.go @@ -23,7 +23,6 @@ import ( "github.com/go-vela/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/go-vela/types/pipeline" "github.com/sirupsen/logrus" "gorm.io/gorm" ) @@ -273,399 +272,52 @@ func PostWebhook(c *gin.Context) { return } - // check if the repo has a valid owner - if repo.GetUserID() == 0 { - retErr := fmt.Errorf("%s: %s has no valid owner", baseErr, repo.GetFullName()) - util.HandleError(c, http.StatusBadRequest, retErr) - - h.SetStatus(constants.StatusFailure) - h.SetError(retErr.Error()) - - return - } - - // send API call to capture repo owner - logrus.Debugf("capturing owner of repository %s", repo.GetFullName()) - - u, err := database.FromContext(c).GetUser(ctx, repo.GetUserID()) - if err != nil { - retErr := fmt.Errorf("%s: failed to get owner for %s: %w", baseErr, repo.GetFullName(), err) - util.HandleError(c, http.StatusBadRequest, retErr) - - h.SetStatus(constants.StatusFailure) - h.SetError(retErr.Error()) - - return - } - - // confirm current repo owner has at least write access to repo (needed for status update later) - _, err = scm.FromContext(c).RepoAccess(ctx, u.GetName(), u.GetToken(), r.GetOrg(), r.GetName()) - if err != nil { - retErr := fmt.Errorf("unable to publish build to queue: repository owner %s no longer has write access to repository %s", u.GetName(), r.GetFullName()) - util.HandleError(c, http.StatusUnauthorized, retErr) - - h.SetStatus(constants.StatusFailure) - h.SetError(retErr.Error()) - - return - } - - // create SQL filters for querying pending and running builds for repo - filters := map[string]interface{}{ - "status": []string{constants.StatusPending, constants.StatusRunning}, - } - - // send API call to capture the number of pending or running builds for the repo - builds, err := database.FromContext(c).CountBuildsForRepo(ctx, repo, filters) - if err != nil { - retErr := fmt.Errorf("%s: unable to get count of builds for repo %s", baseErr, repo.GetFullName()) - util.HandleError(c, http.StatusBadRequest, retErr) - - h.SetStatus(constants.StatusFailure) - h.SetError(retErr.Error()) - - return - } - - logrus.Debugf("currently %d builds running on repo %s", builds, repo.GetFullName()) - - // check if the number of pending and running builds exceeds the limit for the repo - if builds >= repo.GetBuildLimit() { - retErr := fmt.Errorf("%s: repo %s has exceeded the concurrent build limit of %d", baseErr, repo.GetFullName(), repo.GetBuildLimit()) - util.HandleError(c, http.StatusBadRequest, retErr) - - h.SetStatus(constants.StatusFailure) - h.SetError(retErr.Error()) - - return - } - - // update fields in build object - logrus.Debugf("updating build number to %d", repo.GetCounter()) - b.SetNumber(repo.GetCounter()) - - logrus.Debug("updating status to pending") - b.SetStatus(constants.StatusPending) - - // if the event is issue_comment and the issue is a pull request, - // call SCM for more data not provided in webhook payload - if strings.EqualFold(b.GetEvent(), constants.EventComment) && webhook.PullRequest.Number > 0 { - commit, branch, baseref, headref, err := scm.FromContext(c).GetPullRequest(ctx, u, repo, webhook.PullRequest.Number) - if err != nil { - retErr := fmt.Errorf("%s: failed to get pull request info for %s: %w", baseErr, repo.GetFullName(), err) - util.HandleError(c, http.StatusInternalServerError, retErr) - - h.SetStatus(constants.StatusFailure) - h.SetError(retErr.Error()) - - return - } - - b.SetCommit(commit) - b.SetBranch(strings.ReplaceAll(branch, "refs/heads/", "")) - b.SetBaseRef(baseref) - b.SetHeadRef(headref) - } - - // variable to store changeset files - var files []string - - // check if the build event is not issue_comment or pull_request - if !strings.EqualFold(b.GetEvent(), constants.EventComment) && - !strings.EqualFold(b.GetEvent(), constants.EventPull) && - !strings.EqualFold(b.GetEvent(), constants.EventDelete) { - // send API call to capture list of files changed for the commit - files, err = scm.FromContext(c).Changeset(ctx, u, repo, b.GetCommit()) - if err != nil { - retErr := fmt.Errorf("%s: failed to get changeset for %s: %w", baseErr, repo.GetFullName(), err) - util.HandleError(c, http.StatusInternalServerError, retErr) - - h.SetStatus(constants.StatusFailure) - h.SetError(retErr.Error()) - - return - } + var prComment string + if strings.EqualFold(b.GetEvent(), constants.EventComment) { + prComment = webhook.PullRequest.Comment } - // check if the build event is a pull_request - if strings.EqualFold(b.GetEvent(), constants.EventPull) && webhook.PullRequest.Number > 0 { - // send API call to capture list of files changed for the pull request - files, err = scm.FromContext(c).ChangesetPR(ctx, u, repo, webhook.PullRequest.Number) - if err != nil { - retErr := fmt.Errorf("%s: failed to get changeset for %s: %w", baseErr, repo.GetFullName(), err) - util.HandleError(c, http.StatusInternalServerError, retErr) - - h.SetStatus(constants.StatusFailure) - h.SetError(retErr.Error()) - - return - } + // construct CompileAndPublishConfig + config := build.CompileAndPublishConfig{ + Build: b, + Repo: repo, + Metadata: m, + BaseErr: baseErr, + Source: "webhook", + Comment: prComment, + Retries: 3, } - var ( - // variable to store the raw pipeline configuration - config []byte - // variable to store executable pipeline - p *pipeline.Build - // variable to store pipeline configuration - pipeline *library.Pipeline - // variable to control number of times to retry processing pipeline - retryLimit = 3 - // variable to store the pipeline type for the repository - pipelineType = repo.GetPipelineType() + // generate the queue item + pushed, p, item, err := build.CompileAndPublish( + c, + config, + database.FromContext(c), + scm.FromContext(c), + compiler.FromContext(c), + queue.FromContext(c), ) - // implement a loop to process asynchronous operations with a retry limit - // - // Some operations taken during the webhook workflow can lead to race conditions - // failing to successfully process the request. This logic ensures we attempt our - // best efforts to handle these cases gracefully. - for i := 0; i < retryLimit; i++ { - logrus.Debugf("compilation loop - attempt %d", i+1) - // check if we're on the first iteration of the loop - if i > 0 { - // incrementally sleep in between retries - time.Sleep(time.Duration(i) * time.Second) - } - - // send database call to attempt to capture the pipeline if we already processed it before - pipeline, err = database.FromContext(c).GetPipelineForRepo(ctx, b.GetCommit(), repo) - if err != nil { // assume the pipeline doesn't exist in the database yet - // send API call to capture the pipeline configuration file - config, err = scm.FromContext(c).ConfigBackoff(ctx, u, repo, b.GetCommit()) - if err != nil { - retErr := fmt.Errorf("%s: unable to get pipeline configuration for %s: %w", baseErr, repo.GetFullName(), err) - - util.HandleError(c, http.StatusNotFound, retErr) - - h.SetStatus(constants.StatusFailure) - h.SetError(retErr.Error()) - - return - } - } else { - config = pipeline.GetData() - } - - // send API call to capture repo for the counter (grabbing repo again to ensure counter is correct) - repo, err = database.FromContext(c).GetRepoForOrg(ctx, repo.GetOrg(), repo.GetName()) - if err != nil { - retErr := fmt.Errorf("%s: unable to get repo %s: %w", baseErr, r.GetFullName(), err) - - // check if the retry limit has been exceeded - if i < retryLimit-1 { - logrus.WithError(retErr).Warningf("retrying #%d", i+1) - - // continue to the next iteration of the loop - continue - } - - util.HandleError(c, http.StatusBadRequest, retErr) - - h.SetStatus(constants.StatusFailure) - h.SetError(retErr.Error()) - - return - } - - // update DB record of repo (repo) with any changes captured from webhook payload (r) - repo.SetTopics(r.GetTopics()) - repo.SetBranch(r.GetBranch()) - - // update the build numbers based off repo counter - inc := repo.GetCounter() + 1 - repo.SetCounter(inc) - b.SetNumber(inc) - - // populate the build link if a web address is provided - if len(m.Vela.WebAddress) > 0 { - b.SetLink( - fmt.Sprintf("%s/%s/%d", m.Vela.WebAddress, repo.GetFullName(), b.GetNumber()), - ) - } - - // ensure we use the expected pipeline type when compiling - // - // The pipeline type for a repo can change at any time which can break compiling - // existing pipelines in the system for that repo. To account for this, we update - // the repo pipeline type to match what was defined for the existing pipeline - // before compiling. After we're done compiling, we reset the pipeline type. - if len(pipeline.GetType()) > 0 { - repo.SetPipelineType(pipeline.GetType()) - } - - var compiled *library.Pipeline - // parse and compile the pipeline configuration file - p, compiled, err = compiler.FromContext(c). - Duplicate(). - WithBuild(b). - WithComment(webhook.PullRequest.Comment). - WithCommit(b.GetCommit()). - WithFiles(files). - WithMetadata(m). - WithRepo(repo). - WithUser(u). - Compile(config) - if err != nil { - // format the error message with extra information - err = fmt.Errorf("unable to compile pipeline configuration for %s: %w", repo.GetFullName(), err) - - // log the error for traceability - logrus.Error(err.Error()) - - retErr := fmt.Errorf("%s: %w", baseErr, err) - util.HandleError(c, http.StatusInternalServerError, retErr) - - h.SetStatus(constants.StatusFailure) - h.SetError(retErr.Error()) - - return - } - - // reset the pipeline type for the repo - // - // The pipeline type for a repo can change at any time which can break compiling - // existing pipelines in the system for that repo. To account for this, we update - // the repo pipeline type to match what was defined for the existing pipeline - // before compiling. After we're done compiling, we reset the pipeline type. - repo.SetPipelineType(pipelineType) - - // skip the build if pipeline compiled to only the init and clone steps - skip := build.SkipEmptyBuild(p) - if skip != "" { - // set build to successful status - b.SetStatus(constants.StatusSkipped) - - // set hook status and message - h.SetStatus(constants.StatusSkipped) - h.SetError(skip) - - // send API call to set the status on the commit - err = scm.FromContext(c).Status(ctx, u, b, repo.GetOrg(), repo.GetName()) - if err != nil { - logrus.Errorf("unable to set commit status for %s/%d: %v", repo.GetFullName(), b.GetNumber(), err) - } - - c.JSON(http.StatusOK, skip) - - return - } - - // check if the pipeline did not already exist in the database - if pipeline == nil { - pipeline = compiled - pipeline.SetRepoID(repo.GetID()) - pipeline.SetCommit(b.GetCommit()) - pipeline.SetRef(b.GetRef()) - - // send API call to create the pipeline - pipeline, err = database.FromContext(c).CreatePipeline(ctx, pipeline) - if err != nil { - retErr := fmt.Errorf("%s: failed to create pipeline for %s: %w", baseErr, repo.GetFullName(), err) - - // check if the retry limit has been exceeded - if i < retryLimit-1 { - logrus.WithError(retErr).Warningf("retrying #%d", i+1) - - // continue to the next iteration of the loop - continue - } - - util.HandleError(c, http.StatusBadRequest, retErr) - - h.SetStatus(constants.StatusFailure) - h.SetError(retErr.Error()) - - return - } - } - - b.SetPipelineID(pipeline.GetID()) - - // create the objects from the pipeline in the database - // TODO: - // - if a build gets created and something else fails midway, - // the next loop will attempt to create the same build, - // using the same Number and thus create a constraint - // conflict; consider deleting the partially created - // build object in the database - err = build.PlanBuild(ctx, database.FromContext(c), p, b, repo) - if err != nil { - retErr := fmt.Errorf("%s: %w", baseErr, err) - - // check if the retry limit has been exceeded - if i < retryLimit-1 { - logrus.WithError(retErr).Warningf("retrying #%d", i+1) - - // reset fields set by cleanBuild for retry - b.SetError("") - b.SetStatus(constants.StatusPending) - b.SetFinished(0) - - // continue to the next iteration of the loop - continue - } - - util.HandleError(c, http.StatusInternalServerError, retErr) - - h.SetStatus(constants.StatusFailure) - h.SetError(retErr.Error()) - - return - } + // capture the build, repo, and user from the items + b, repo, u := item.Build, item.Repo, item.User - // break the loop because everything was successful - break - } // end of retry loop + // set hook build_id to the generated build id + h.SetBuildID(b.GetID()) - // send API call to update repo for ensuring counter is incremented - repo, err = database.FromContext(c).UpdateRepo(ctx, repo) if err != nil { - retErr := fmt.Errorf("%s: failed to update repo %s: %w", baseErr, repo.GetFullName(), err) - util.HandleError(c, http.StatusBadRequest, retErr) - - h.SetStatus(constants.StatusFailure) - h.SetError(retErr.Error()) - - return - } - - // return error if pipeline didn't get populated - if p == nil { - retErr := fmt.Errorf("%s: failed to set pipeline for %s: %w", baseErr, repo.GetFullName(), err) - util.HandleError(c, http.StatusBadRequest, retErr) - - h.SetStatus(constants.StatusFailure) - h.SetError(retErr.Error()) - - return - } - - // return error if build didn't get populated - if b == nil { - retErr := fmt.Errorf("%s: failed to set build for %s: %w", baseErr, repo.GetFullName(), err) - util.HandleError(c, http.StatusBadRequest, retErr) - h.SetStatus(constants.StatusFailure) - h.SetError(retErr.Error()) + h.SetError(err.Error()) return } - // send API call to capture the triggered build - b, err = database.FromContext(c).GetBuildForRepo(ctx, repo, b.GetNumber()) - if err != nil { - retErr := fmt.Errorf("%s: failed to get new build %s/%d: %w", baseErr, repo.GetFullName(), b.GetNumber(), err) - util.HandleError(c, http.StatusInternalServerError, retErr) - - h.SetStatus(constants.StatusFailure) - h.SetError(retErr.Error()) + if !pushed { + // if the build was not pushed to the queue, it was skipped + h.SetStatus(constants.StatusSkipped) return } - // set the BuildID field - h.SetBuildID(b.GetID()) // if event is deployment, update the deployment record to include this build if strings.EqualFold(b.GetEvent(), constants.EventDeploy) { d, err := database.FromContext(c).GetDeploymentForRepo(c, repo, webhook.Deployment.GetNumber()) @@ -713,29 +365,6 @@ func PostWebhook(c *gin.Context) { c.JSON(http.StatusOK, b) - // determine queue route - route, err := queue.FromContext(c).Route(&p.Worker) - if err != nil { - logrus.Errorf("unable to set route for build %d for %s: %v", b.GetNumber(), r.GetFullName(), err) - - // error out the build - build.CleanBuild(ctx, database.FromContext(c), b, nil, nil, err) - - return - } - - // temporarily set host to the route before it gets picked up by a worker - b.SetHost(route) - - // publish the pipeline.Build to the build_executables table to be requested by a worker - err = build.PublishBuildExecutable(ctx, database.FromContext(c), p, b) - if err != nil { - retErr := fmt.Errorf("unable to publish build executable for %s/%d: %w", repo.GetFullName(), b.GetNumber(), err) - util.HandleError(c, http.StatusInternalServerError, retErr) - - return - } - // regardless of whether the build is published to queue, we want to attempt to auto-cancel if no errors defer func() { if err == nil && build.ShouldAutoCancel(p.Metadata.AutoCancel, b, repo.GetBranch()) { @@ -819,14 +448,12 @@ func PostWebhook(c *gin.Context) { } // publish the build to the queue - go build.PublishToQueue( + go build.Enqueue( ctx, queue.FromGinContext(c), database.FromContext(c), - b, - repo, - u, - route, + item, + b.GetHost(), ) } diff --git a/cmd/vela-server/schedule.go b/cmd/vela-server/schedule.go index 2036306c4..acb5918f4 100644 --- a/cmd/vela-server/schedule.go +++ b/cmd/vela-server/schedule.go @@ -18,7 +18,6 @@ import ( "github.com/go-vela/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/go-vela/types/pipeline" "github.com/sirupsen/logrus" "k8s.io/apimachinery/pkg/util/wait" @@ -134,7 +133,7 @@ func processSchedules(ctx context.Context, start time.Time, compiler compiler.En return nil } -//nolint:funlen // ignore function length and number of statements +// processSchedule will, given a schedule, process it and trigger a new build. func processSchedule(ctx context.Context, s *library.Schedule, compiler compiler.Engine, database database.Interface, metadata *types.Metadata, queue queue.Service, scm scm.Service, allowList []string) error { // send API call to capture the repo for the schedule r, err := database.GetRepo(ctx, s.GetRepoID()) @@ -154,52 +153,12 @@ func processSchedule(ctx context.Context, s *library.Schedule, compiler compiler return fmt.Errorf("repo %s is not active", r.GetFullName()) } - // check if the repo has a valid owner - if r.GetUserID() == 0 { - return fmt.Errorf("repo %s does not have a valid owner", r.GetFullName()) - } - - // send API call to capture the owner for the repo - u, err := database.GetUser(ctx, r.GetUserID()) - if err != nil { - return fmt.Errorf("unable to get owner for repo %s: %w", r.GetFullName(), err) - } - - // send API call to confirm repo owner has at least write access to repo - _, err = scm.RepoAccess(ctx, u.GetName(), u.GetToken(), r.GetOrg(), r.GetName()) - if err != nil { - return fmt.Errorf("%s does not have at least write access for repo %s", u.GetName(), r.GetFullName()) - } - - // create SQL filters for querying pending and running builds for repo - filters := map[string]interface{}{ - "status": []string{constants.StatusPending, constants.StatusRunning}, - } - - // send API call to capture the number of pending or running builds for the repo - builds, err := database.CountBuildsForRepo(ctx, r, filters) - if err != nil { - return fmt.Errorf("unable to get count of builds for repo %s: %w", r.GetFullName(), err) - } - - // check if the number of pending and running builds exceeds the limit for the repo - if builds >= r.GetBuildLimit() { - return fmt.Errorf("repo %s has excceded the concurrent build limit of %d", r.GetFullName(), r.GetBuildLimit()) - } - - // send API call to capture the commit sha for the branch - _, commit, err := scm.GetBranch(ctx, u, r, s.GetBranch()) - if err != nil { - return fmt.Errorf("failed to get commit for repo %s on %s branch: %w", r.GetFullName(), r.GetBranch(), err) - } - url := strings.TrimSuffix(r.GetClone(), ".git") b := new(library.Build) b.SetAuthor(s.GetCreatedBy()) b.SetBranch(s.GetBranch()) b.SetClone(r.GetClone()) - b.SetCommit(commit) b.SetDeploy(s.GetName()) b.SetEvent(constants.EventSchedule) b.SetMessage(fmt.Sprintf("triggered for %s schedule with %s entry", s.GetName(), s.GetEntry())) @@ -210,216 +169,37 @@ func processSchedule(ctx context.Context, s *library.Schedule, compiler compiler b.SetStatus(constants.StatusPending) b.SetTitle(fmt.Sprintf("%s received from %s", constants.EventSchedule, url)) - // populate the build link if a web address is provided - if len(metadata.Vela.WebAddress) > 0 { - b.SetLink(fmt.Sprintf("%s/%s/%d", metadata.Vela.WebAddress, r.GetFullName(), b.GetNumber())) + // schedule form + config := build.CompileAndPublishConfig{ + Build: b, + Repo: r, + Metadata: metadata, + BaseErr: "unable to schedule build", + Source: "schedule", + Retries: 1, } - var ( - // variable to store the raw pipeline configuration - config []byte - // variable to store executable pipeline - p *pipeline.Build - // variable to store pipeline configuration - pipeline *library.Pipeline - // variable to control number of times to retry processing pipeline - retryLimit = 5 - // variable to store the pipeline type for the repository - pipelineType = r.GetPipelineType() + _, _, item, err := build.CompileAndPublish( + ctx, + config, + database, + scm, + compiler, + queue, ) - // implement a loop to process asynchronous operations with a retry limit - // - // Some operations taken during this workflow can lead to race conditions failing to successfully process - // the request. This logic ensures we attempt our best efforts to handle these cases gracefully. - for i := 0; i < retryLimit; i++ { - logrus.Debugf("compilation loop - attempt %d", i+1) - // check if we're on the first iteration of the loop - if i > 0 { - // incrementally sleep in between retries - time.Sleep(time.Duration(i) * time.Second) - } - - // send API call to attempt to capture the pipeline - pipeline, err = database.GetPipelineForRepo(ctx, b.GetCommit(), r) - if err != nil { // assume the pipeline doesn't exist in the database yet - // send API call to capture the pipeline configuration file - config, err = scm.ConfigBackoff(ctx, u, r, b.GetCommit()) - if err != nil { - return fmt.Errorf("unable to get pipeline config for %s/%s: %w", r.GetFullName(), b.GetCommit(), err) - } - } else { - config = pipeline.GetData() - } - - // send API call to capture repo for the counter (grabbing repo again to ensure counter is correct) - r, err = database.GetRepoForOrg(ctx, r.GetOrg(), r.GetName()) - if err != nil { - err = fmt.Errorf("unable to get repo %s: %w", r.GetFullName(), err) - - // check if the retry limit has been exceeded - if i < retryLimit-1 { - logrus.WithError(err).Warningf("retrying #%d", i+1) - - // continue to the next iteration of the loop - continue - } - - return err - } - - // set the build numbers based off repo counter - b.SetNumber(r.GetCounter() + 1) - // set the parent equal to the current repo counter - b.SetParent(r.GetCounter()) - // check if the parent is set to 0 - if b.GetParent() == 0 { - // parent should be "1" if it's the first build ran - b.SetParent(1) - } - - r.SetCounter(r.GetCounter() + 1) - - // set the build link if a web address is provided - if len(metadata.Vela.WebAddress) > 0 { - b.SetLink(fmt.Sprintf("%s/%s/%d", metadata.Vela.WebAddress, r.GetFullName(), b.GetNumber())) - } - - // ensure we use the expected pipeline type when compiling - // - // The pipeline type for a repo can change at any time which can break compiling - // existing pipelines in the system for that repo. To account for this, we update - // the repo pipeline type to match what was defined for the existing pipeline - // before compiling. After we're done compiling, we reset the pipeline type. - if len(pipeline.GetType()) > 0 { - r.SetPipelineType(pipeline.GetType()) - } - - var compiled *library.Pipeline - // parse and compile the pipeline configuration file - p, compiled, err = compiler. - Duplicate(). - WithBuild(b). - WithCommit(b.GetCommit()). - WithMetadata(metadata). - WithRepo(r). - WithUser(u). - Compile(config) - if err != nil { - return fmt.Errorf("unable to compile pipeline config for %s/%s: %w", r.GetFullName(), b.GetCommit(), err) - } - - // reset the pipeline type for the repo - // - // The pipeline type for a repo can change at any time which can break compiling - // existing pipelines in the system for that repo. To account for this, we update - // the repo pipeline type to match what was defined for the existing pipeline - // before compiling. After we're done compiling, we reset the pipeline type. - r.SetPipelineType(pipelineType) - - // skip the build if only the init or clone steps are found - skip := build.SkipEmptyBuild(p) - if skip != "" { - return nil - } - - // check if the pipeline did not already exist in the database - if pipeline == nil { - pipeline = compiled - pipeline.SetRepoID(r.GetID()) - pipeline.SetCommit(b.GetCommit()) - pipeline.SetRef(b.GetRef()) - - // send API call to create the pipeline - pipeline, err = database.CreatePipeline(ctx, pipeline) - if err != nil { - err = fmt.Errorf("failed to create pipeline for %s: %w", r.GetFullName(), err) - - // check if the retry limit has been exceeded - if i < retryLimit-1 { - logrus.WithError(err).Warningf("retrying #%d", i+1) - - // continue to the next iteration of the loop - continue - } - - return err - } - } - - b.SetPipelineID(pipeline.GetID()) - - // create the objects from the pipeline in the database - // TODO: - // - if a build gets created and something else fails midway, - // the next loop will attempt to create the same build, - // using the same Number and thus create a constraint - // conflict; consider deleting the partially created - // build object in the database - err = build.PlanBuild(ctx, database, p, b, r) - if err != nil { - // check if the retry limit has been exceeded - if i < retryLimit-1 { - logrus.WithError(err).Warningf("retrying #%d", i+1) - - // reset fields set by cleanBuild for retry - b.SetError("") - b.SetStatus(constants.StatusPending) - b.SetFinished(0) - - // continue to the next iteration of the loop - continue - } - - return err - } - - // break the loop because everything was successful - break - } // end of retry loop - - // send API call to update repo for ensuring counter is incremented - r, err = database.UpdateRepo(ctx, r) - if err != nil { - return fmt.Errorf("unable to update repo %s: %w", r.GetFullName(), err) - } - - // send API call to capture the triggered build - b, err = database.GetBuildForRepo(ctx, r, b.GetNumber()) - if err != nil { - return fmt.Errorf("unable to get new build %s/%d: %w", r.GetFullName(), b.GetNumber(), err) - } - - // determine queue route - route, err := queue.Route(&p.Worker) + // error handling done in GenerateQueueItems if err != nil { - logrus.Errorf("unable to set route for build %d for %s: %v", b.GetNumber(), r.GetFullName(), err) - - // error out the build - build.CleanBuild(ctx, database, b, nil, nil, err) - return err } - // temporarily set host to the route before it gets picked up by a worker - b.SetHost(route) - - err = build.PublishBuildExecutable(ctx, database, p, b) - if err != nil { - retErr := fmt.Errorf("unable to publish build executable for %s/%d: %w", r.GetFullName(), b.GetNumber(), err) - - return retErr - } - // publish the build to the queue - go build.PublishToQueue( + go build.Enqueue( ctx, queue, database, - b, - r, - u, - route, + item, + item.Build.GetHost(), ) return nil diff --git a/scm/github/webhook.go b/scm/github/webhook.go index 07b3fc163..7d8ac2015 100644 --- a/scm/github/webhook.go +++ b/scm/github/webhook.go @@ -437,8 +437,8 @@ func (c *client) processIssueCommentEvent(h *library.Hook, payload *github.Issue fmt.Sprintf("https://%s/%s/settings/hooks", h.GetHost(), payload.GetRepo().GetFullName()), ) - // skip if the comment action is deleted - if strings.EqualFold(payload.GetAction(), "deleted") { + // skip if the comment action is deleted or not part of a pull request + if strings.EqualFold(payload.GetAction(), "deleted") || !payload.GetIssue().IsPullRequest() { // return &types.Webhook{Hook: h}, nil return &types.Webhook{ Hook: h, @@ -470,22 +470,12 @@ func (c *client) processIssueCommentEvent(h *library.Hook, payload *github.Issue b.SetSender(payload.GetSender().GetLogin()) b.SetAuthor(payload.GetIssue().GetUser().GetLogin()) b.SetEmail(payload.GetIssue().GetUser().GetEmail()) - // treat as non-pull-request comment by default and - // set ref to default branch for the repo - b.SetRef(fmt.Sprintf("refs/heads/%s", r.GetBranch())) - - pr := 0 - // override ref and pull request number if this is - // a comment on a pull request - if payload.GetIssue().IsPullRequest() { - b.SetRef(fmt.Sprintf("refs/pull/%d/head", payload.GetIssue().GetNumber())) - pr = payload.GetIssue().GetNumber() - } + b.SetRef(fmt.Sprintf("refs/pull/%d/head", payload.GetIssue().GetNumber())) return &types.Webhook{ PullRequest: types.PullRequest{ Comment: payload.GetComment().GetBody(), - Number: pr, + Number: payload.GetIssue().GetNumber(), }, Hook: h, Repo: r, diff --git a/scm/github/webhook_test.go b/scm/github/webhook_test.go index 35f6581de..eab3cbc54 100644 --- a/scm/github/webhook_test.go +++ b/scm/github/webhook_test.go @@ -968,36 +968,8 @@ func TestGithub_ProcessWebhook_IssueComment_Created(t *testing.T) { wantHook.SetStatus(constants.StatusSuccess) wantHook.SetLink("https://github.com/Codertocat/Hello-World/settings/hooks") - wantRepo := new(library.Repo) - wantRepo.SetOrg("Codertocat") - wantRepo.SetName("Hello-World") - wantRepo.SetFullName("Codertocat/Hello-World") - wantRepo.SetLink("https://github.com/Codertocat/Hello-World") - wantRepo.SetClone("https://github.com/Codertocat/Hello-World.git") - wantRepo.SetBranch("main") - wantRepo.SetPrivate(false) - wantRepo.SetTopics(nil) - - wantBuild := new(library.Build) - wantBuild.SetEvent("comment") - wantBuild.SetEventAction("created") - wantBuild.SetClone("https://github.com/Codertocat/Hello-World.git") - wantBuild.SetSource("https://github.com/Codertocat/Hello-World/issues/1") - wantBuild.SetTitle("comment received from https://github.com/Codertocat/Hello-World") - wantBuild.SetMessage("Update the README with new information") - wantBuild.SetSender("Codertocat") - wantBuild.SetAuthor("Codertocat") - wantBuild.SetEmail("") - wantBuild.SetRef("refs/heads/main") - want := &types.Webhook{ - PullRequest: types.PullRequest{ - Comment: "ok to test", - Number: 0, - }, - Hook: wantHook, - Repo: wantRepo, - Build: wantBuild, + Hook: wantHook, } got, err := client.ProcessWebhook(context.TODO(), request) diff --git a/util/util.go b/util/util.go index 5d9ce644f..401c6a814 100644 --- a/util/util.go +++ b/util/util.go @@ -3,6 +3,7 @@ package util import ( + "context" "html" "net/url" "strings" @@ -15,11 +16,19 @@ import ( ) // HandleError appends the error to the handler chain for logging and outputs it. -func HandleError(c *gin.Context, status int, err error) { +func HandleError(c context.Context, status int, err error) { msg := err.Error() - //nolint:errcheck // ignore checking error - c.Error(err) - c.AbortWithStatusJSON(status, types.Error{Message: &msg}) + + switch ctx := c.(type) { + case *gin.Context: + //nolint:errcheck // ignore checking error + ctx.Error(err) + ctx.AbortWithStatusJSON(status, types.Error{Message: &msg}) + + return + default: + return + } } // MaxInt is a helper function to clamp the integer which From 5706d0f55c64a2aaab495e506bed643a0777376f Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Fri, 29 Mar 2024 10:12:36 -0400 Subject: [PATCH 17/71] feat!: step status reporting + fix pull request context overwrite bug (#1090) * init commit * add validation * bring in types and add some tests * fix hook skip and add some tests * address feedback * address feedback --- api/build/compile_publish.go | 54 +++++++-------- api/build/create.go | 11 ++- api/build/plan.go | 5 +- api/build/restart.go | 4 +- api/step/plan.go | 25 +++++-- api/step/update.go | 24 +++++++ api/webhook/post.go | 15 ++-- cmd/vela-server/schedule.go | 4 +- compiler/native/validate.go | 18 +++++ compiler/native/validate_test.go | 78 +++++++++++++++++++++ database/integration_test.go | 2 + database/step/create_test.go | 7 +- database/step/get_build_test.go | 10 +-- database/step/get_test.go | 4 +- database/step/list_build_test.go | 7 +- database/step/list_test.go | 6 +- database/step/step_test.go | 1 + database/step/table.go | 3 + database/step/update_test.go | 6 +- go.mod | 2 +- go.sum | 4 +- mock/server/step.go | 9 ++- router/middleware/step/step_test.go | 1 + scm/github/repo.go | 74 ++++++++++++++++++++ scm/github/repo_test.go | 102 ++++++++++++++++++++++++++++ scm/service.go | 3 + 26 files changed, 410 insertions(+), 69 deletions(-) diff --git a/api/build/compile_publish.go b/api/build/compile_publish.go index 114e121a5..ea908862f 100644 --- a/api/build/compile_publish.go +++ b/api/build/compile_publish.go @@ -4,6 +4,7 @@ package build import ( "context" + "errors" "fmt" "net/http" "strconv" @@ -45,7 +46,7 @@ func CompileAndPublish( scm scm.Service, compiler compiler.Engine, queue queue.Service, -) (bool, *pipeline.Build, *types.Item, error) { +) (*pipeline.Build, *types.Item, error) { logrus.Debugf("generating queue items for build %s/%d", cfg.Repo.GetFullName(), cfg.Build.GetNumber()) // assign variables from form for readibility @@ -61,7 +62,7 @@ func CompileAndPublish( retErr := fmt.Errorf("%s: failed to get owner for %s: %w", baseErr, r.GetFullName(), err) util.HandleError(c, http.StatusBadRequest, retErr) - return false, nil, nil, retErr + return nil, nil, retErr } // confirm current repo owner has at least write access to repo (needed for status update later) @@ -70,7 +71,7 @@ func CompileAndPublish( retErr := fmt.Errorf("unable to publish build to queue: repository owner %s no longer has write access to repository %s", u.GetName(), r.GetFullName()) util.HandleError(c, http.StatusUnauthorized, retErr) - return false, nil, nil, retErr + return nil, nil, retErr } // get pull request number from build if event is pull_request or issue_comment @@ -81,7 +82,7 @@ func CompileAndPublish( retErr := fmt.Errorf("%s: failed to get pull request number for %s: %w", baseErr, r.GetFullName(), err) util.HandleError(c, http.StatusBadRequest, retErr) - return false, nil, nil, retErr + return nil, nil, retErr } } @@ -92,7 +93,7 @@ func CompileAndPublish( retErr := fmt.Errorf("%s: failed to get pull request number for %s: %w", baseErr, r.GetFullName(), err) util.HandleError(c, http.StatusBadRequest, retErr) - return false, nil, nil, retErr + return nil, nil, retErr } commit, branch, baseref, headref, err := scm.GetPullRequest(c, u, r, prNum) @@ -100,7 +101,7 @@ func CompileAndPublish( retErr := fmt.Errorf("%s: failed to get pull request info for %s: %w", baseErr, r.GetFullName(), err) util.HandleError(c, http.StatusInternalServerError, retErr) - return false, nil, nil, retErr + return nil, nil, retErr } b.SetCommit(commit) @@ -117,7 +118,7 @@ func CompileAndPublish( retErr := fmt.Errorf("failed to get commit for repo %s on %s branch: %w", r.GetFullName(), r.GetBranch(), err) util.HandleError(c, http.StatusInternalServerError, retErr) - return false, nil, nil, retErr + return nil, nil, retErr } b.SetCommit(commit) @@ -134,7 +135,7 @@ func CompileAndPublish( retErr := fmt.Errorf("%s: unable to get count of builds for repo %s", baseErr, r.GetFullName()) util.HandleError(c, http.StatusBadRequest, retErr) - return false, nil, nil, retErr + return nil, nil, retErr } logrus.Debugf("currently %d builds running on repo %s", builds, r.GetFullName()) @@ -144,7 +145,7 @@ func CompileAndPublish( retErr := fmt.Errorf("%s: repo %s has exceeded the concurrent build limit of %d", baseErr, r.GetFullName(), r.GetBuildLimit()) util.HandleError(c, http.StatusBadRequest, retErr) - return false, nil, nil, retErr + return nil, nil, retErr } // update fields in build object @@ -173,7 +174,7 @@ func CompileAndPublish( retErr := fmt.Errorf("%s: failed to get changeset for %s: %w", baseErr, r.GetFullName(), err) util.HandleError(c, http.StatusInternalServerError, retErr) - return false, nil, nil, retErr + return nil, nil, retErr } } @@ -185,7 +186,7 @@ func CompileAndPublish( retErr := fmt.Errorf("%s: failed to get changeset for %s: %w", baseErr, r.GetFullName(), err) util.HandleError(c, http.StatusInternalServerError, retErr) - return false, nil, nil, retErr + return nil, nil, retErr } } @@ -225,7 +226,7 @@ func CompileAndPublish( util.HandleError(c, http.StatusNotFound, retErr) - return false, nil, nil, retErr + return nil, nil, retErr } } else { pipelineFile = pipeline.GetData() @@ -246,7 +247,7 @@ func CompileAndPublish( util.HandleError(c, http.StatusBadRequest, retErr) - return false, nil, nil, retErr + return nil, nil, retErr } // update DB record of repo (repo) with any changes captured from webhook payload (r) @@ -297,7 +298,7 @@ func CompileAndPublish( retErr := fmt.Errorf("%s: %w", baseErr, err) util.HandleError(c, http.StatusInternalServerError, retErr) - return false, nil, nil, retErr + return nil, nil, retErr } // reset the pipeline type for the repo @@ -320,12 +321,11 @@ func CompileAndPublish( logrus.Errorf("unable to set commit status for %s/%d: %v", repo.GetFullName(), b.GetNumber(), err) } - return false, - nil, + return nil, &types.Item{ Build: b, }, - nil + errors.New(skip) } // check if the pipeline did not already exist in the database @@ -350,7 +350,7 @@ func CompileAndPublish( util.HandleError(c, http.StatusBadRequest, retErr) - return false, nil, nil, retErr + return nil, nil, retErr } } @@ -363,7 +363,7 @@ func CompileAndPublish( // using the same Number and thus create a constraint // conflict; consider deleting the partially created // build object in the database - err = PlanBuild(c, database, p, b, repo) + err = PlanBuild(c, database, scm, p, b, repo) if err != nil { retErr := fmt.Errorf("%s: %w", baseErr, err) @@ -382,7 +382,7 @@ func CompileAndPublish( util.HandleError(c, http.StatusInternalServerError, retErr) - return false, nil, nil, retErr + return nil, nil, retErr } // break the loop because everything was successful @@ -395,7 +395,7 @@ func CompileAndPublish( retErr := fmt.Errorf("%s: failed to update repo %s: %w", baseErr, repo.GetFullName(), err) util.HandleError(c, http.StatusBadRequest, retErr) - return false, nil, nil, retErr + return nil, nil, retErr } // return error if pipeline didn't get populated @@ -403,7 +403,7 @@ func CompileAndPublish( retErr := fmt.Errorf("%s: failed to set pipeline for %s: %w", baseErr, repo.GetFullName(), err) util.HandleError(c, http.StatusBadRequest, retErr) - return false, nil, nil, retErr + return nil, nil, retErr } // return error if build didn't get populated @@ -411,7 +411,7 @@ func CompileAndPublish( retErr := fmt.Errorf("%s: failed to set build for %s: %w", baseErr, repo.GetFullName(), err) util.HandleError(c, http.StatusBadRequest, retErr) - return false, nil, nil, retErr + return nil, nil, retErr } // send API call to capture the triggered build @@ -420,7 +420,7 @@ func CompileAndPublish( retErr := fmt.Errorf("%s: failed to get new build %s/%d: %w", baseErr, repo.GetFullName(), b.GetNumber(), err) util.HandleError(c, http.StatusInternalServerError, retErr) - return false, nil, nil, retErr + return nil, nil, retErr } // determine queue route @@ -431,7 +431,7 @@ func CompileAndPublish( // error out the build CleanBuild(c, database, b, nil, nil, retErr) - return false, nil, nil, retErr + return nil, nil, retErr } // temporarily set host to the route before it gets picked up by a worker @@ -443,10 +443,10 @@ func CompileAndPublish( retErr := fmt.Errorf("unable to publish build executable for %s/%d: %w", repo.GetFullName(), b.GetNumber(), err) util.HandleError(c, http.StatusInternalServerError, retErr) - return false, nil, nil, retErr + return nil, nil, retErr } - return true, p, types.ToItem(b, repo, u), nil + return p, types.ToItem(b, repo, u), nil } // getPRNumberFromBuild is a helper function to diff --git a/api/build/create.go b/api/build/create.go index 09916d245..1f1463ba3 100644 --- a/api/build/create.go +++ b/api/build/create.go @@ -5,6 +5,7 @@ package build import ( "fmt" "net/http" + "strings" "github.com/gin-gonic/gin" "github.com/go-vela/server/compiler" @@ -16,6 +17,7 @@ import ( "github.com/go-vela/server/scm" "github.com/go-vela/server/util" "github.com/go-vela/types" + "github.com/go-vela/types/constants" "github.com/go-vela/types/library" "github.com/sirupsen/logrus" ) @@ -120,7 +122,7 @@ func CreateBuild(c *gin.Context) { Retries: 1, } - _, _, item, err := CompileAndPublish( + _, item, err := CompileAndPublish( c, config, database.FromContext(c), @@ -129,6 +131,13 @@ func CreateBuild(c *gin.Context) { queue.FromContext(c), ) + // check if build was skipped + if err != nil && strings.EqualFold(item.Build.GetStatus(), constants.StatusSkipped) { + c.JSON(http.StatusOK, err.Error()) + + return + } + // error handling done in CompileAndPublish if err != nil { return diff --git a/api/build/plan.go b/api/build/plan.go index 1c546e095..28f54e981 100644 --- a/api/build/plan.go +++ b/api/build/plan.go @@ -10,6 +10,7 @@ import ( "github.com/go-vela/server/api/service" "github.com/go-vela/server/api/step" "github.com/go-vela/server/database" + "github.com/go-vela/server/scm" "github.com/go-vela/types/library" "github.com/go-vela/types/pipeline" ) @@ -19,7 +20,7 @@ import ( // and services, for the build in the configured backend. // TODO: // - return build and error. -func PlanBuild(ctx context.Context, database database.Interface, p *pipeline.Build, b *library.Build, r *library.Repo) error { +func PlanBuild(ctx context.Context, database database.Interface, scm scm.Service, p *pipeline.Build, b *library.Build, r *library.Repo) error { // update fields in build object b.SetCreated(time.Now().UTC().Unix()) @@ -49,7 +50,7 @@ func PlanBuild(ctx context.Context, database database.Interface, p *pipeline.Bui } // plan all steps for the build - steps, err := step.PlanSteps(ctx, database, p, b) + steps, err := step.PlanSteps(ctx, database, scm, p, b, r) if err != nil { // clean up the objects from the pipeline in the database CleanBuild(ctx, database, b, services, steps, err) diff --git a/api/build/restart.go b/api/build/restart.go index aadc9b97e..8b32fdc56 100644 --- a/api/build/restart.go +++ b/api/build/restart.go @@ -119,7 +119,7 @@ func RestartBuild(c *gin.Context) { } // generate queue items - _, _, item, err := CompileAndPublish( + _, item, err := CompileAndPublish( c, config, database.FromContext(c), @@ -128,7 +128,7 @@ func RestartBuild(c *gin.Context) { queue.FromContext(c), ) - // error handling done in GenerateQueueItems + // error handling done in CompileAndPublish if err != nil { return } diff --git a/api/step/plan.go b/api/step/plan.go index 77f22adcb..58ecc98f5 100644 --- a/api/step/plan.go +++ b/api/step/plan.go @@ -8,15 +8,17 @@ import ( "time" "github.com/go-vela/server/database" + "github.com/go-vela/server/scm" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" "github.com/go-vela/types/pipeline" + "github.com/sirupsen/logrus" ) // PlanSteps is a helper function to plan all steps // in the build for execution. This creates the steps // for the build in the configured backend. -func PlanSteps(ctx context.Context, database database.Interface, p *pipeline.Build, b *library.Build) ([]*library.Step, error) { +func PlanSteps(ctx context.Context, database database.Interface, scm scm.Service, p *pipeline.Build, b *library.Build, repo *library.Repo) ([]*library.Step, error) { // variable to store planned steps steps := []*library.Step{} @@ -25,7 +27,7 @@ func PlanSteps(ctx context.Context, database database.Interface, p *pipeline.Bui // iterate through all steps for each pipeline stage for _, step := range stage.Steps { // create the step object - s, err := planStep(ctx, database, b, step, stage.Name) + s, err := planStep(ctx, database, scm, b, step, repo, stage.Name) if err != nil { return steps, err } @@ -36,7 +38,7 @@ func PlanSteps(ctx context.Context, database database.Interface, p *pipeline.Bui // iterate through all pipeline steps for _, step := range p.Steps { - s, err := planStep(ctx, database, b, step, "") + s, err := planStep(ctx, database, scm, b, step, repo, "") if err != nil { return steps, err } @@ -47,7 +49,7 @@ func PlanSteps(ctx context.Context, database database.Interface, p *pipeline.Bui return steps, nil } -func planStep(ctx context.Context, database database.Interface, b *library.Build, c *pipeline.Container, stage string) (*library.Step, error) { +func planStep(ctx context.Context, database database.Interface, scm scm.Service, b *library.Build, c *pipeline.Container, repo *library.Repo, stage string) (*library.Step, error) { // create the step object s := new(library.Step) s.SetBuildID(b.GetID()) @@ -57,6 +59,7 @@ func planStep(ctx context.Context, database database.Interface, b *library.Build s.SetImage(c.Image) s.SetStage(stage) s.SetStatus(constants.StatusPending) + s.SetReportAs(c.ReportAs) s.SetCreated(time.Now().UTC().Unix()) // send API call to create the step @@ -86,5 +89,19 @@ func planStep(ctx context.Context, database database.Interface, b *library.Build return nil, fmt.Errorf("unable to create logs for step %s: %w", s.GetName(), err) } + if len(s.GetReportAs()) > 0 { + // send API call to capture the repo owner + u, err := database.GetUser(ctx, repo.GetUserID()) + if err != nil { + logrus.Errorf("unable to get owner for build: %v", err) + } + + // send API call to set the status on the commit + err = scm.StepStatus(ctx, u, b, s, repo.GetOrg(), repo.GetName()) + if err != nil { + logrus.Errorf("unable to set commit status for build: %v", err) + } + } + return s, nil } diff --git a/api/step/update.go b/api/step/update.go index e049e0ad1..bdfedc8ee 100644 --- a/api/step/update.go +++ b/api/step/update.go @@ -13,7 +13,9 @@ import ( "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/step" "github.com/go-vela/server/router/middleware/user" + "github.com/go-vela/server/scm" "github.com/go-vela/server/util" + "github.com/go-vela/types/constants" "github.com/go-vela/types/library" "github.com/sirupsen/logrus" ) @@ -156,4 +158,26 @@ func UpdateStep(c *gin.Context) { } c.JSON(http.StatusOK, s) + + // check if the build is in a "final" state + // and if build is not a scheduled event + if (s.GetStatus() == constants.StatusSuccess || + s.GetStatus() == constants.StatusFailure || + s.GetStatus() == constants.StatusCanceled || + s.GetStatus() == constants.StatusKilled || + s.GetStatus() == constants.StatusError) && + (b.GetEvent() != constants.EventSchedule) && + (len(s.GetReportAs()) > 0) { + // send API call to capture the repo owner + u, err := database.FromContext(c).GetUser(ctx, r.GetUserID()) + if err != nil { + logrus.Errorf("unable to get owner for build %s: %v", entry, err) + } + + // send API call to set the status on the commit + err = scm.FromContext(c).StepStatus(ctx, u, b, s, r.GetOrg(), r.GetName()) + if err != nil { + logrus.Errorf("unable to set commit status for build %s: %v", entry, err) + } + } } diff --git a/api/webhook/post.go b/api/webhook/post.go index 0746a4574..8ebf0bf7f 100644 --- a/api/webhook/post.go +++ b/api/webhook/post.go @@ -289,7 +289,7 @@ func PostWebhook(c *gin.Context) { } // generate the queue item - pushed, p, item, err := build.CompileAndPublish( + p, item, err := build.CompileAndPublish( c, config, database.FromContext(c), @@ -304,16 +304,19 @@ func PostWebhook(c *gin.Context) { // set hook build_id to the generated build id h.SetBuildID(b.GetID()) - if err != nil { - h.SetStatus(constants.StatusFailure) + // check if build was skipped + if err != nil && strings.EqualFold(b.GetStatus(), constants.StatusSkipped) { + h.SetStatus(constants.StatusSkipped) h.SetError(err.Error()) + c.JSON(http.StatusOK, err.Error()) + return } - if !pushed { - // if the build was not pushed to the queue, it was skipped - h.SetStatus(constants.StatusSkipped) + if err != nil { + h.SetStatus(constants.StatusFailure) + h.SetError(err.Error()) return } diff --git a/cmd/vela-server/schedule.go b/cmd/vela-server/schedule.go index acb5918f4..3e4ef799f 100644 --- a/cmd/vela-server/schedule.go +++ b/cmd/vela-server/schedule.go @@ -179,7 +179,7 @@ func processSchedule(ctx context.Context, s *library.Schedule, compiler compiler Retries: 1, } - _, _, item, err := build.CompileAndPublish( + _, item, err := build.CompileAndPublish( ctx, config, database, @@ -188,7 +188,7 @@ func processSchedule(ctx context.Context, s *library.Schedule, compiler compiler queue, ) - // error handling done in GenerateQueueItems + // error handling done in CompileAndPublish if err != nil { return err } diff --git a/compiler/native/validate.go b/compiler/native/validate.go index e3c79d862..b220b34a7 100644 --- a/compiler/native/validate.go +++ b/compiler/native/validate.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/go-multierror" + "github.com/go-vela/types/constants" "github.com/go-vela/types/yaml" ) @@ -123,6 +124,10 @@ func validateStages(s yaml.StageSlice) error { // validateSteps is a helper function that verifies the // steps block in the yaml configuration is valid. func validateSteps(s yaml.StepSlice) error { + reportCount := 0 + + reportMap := make(map[string]string) + for _, step := range s { if len(step.Name) == 0 { return fmt.Errorf("no name provided for step") @@ -136,6 +141,15 @@ func validateSteps(s yaml.StepSlice) error { continue } + if s, ok := reportMap[step.ReportAs]; ok { + return fmt.Errorf("report_as to %s for step %s is already targeted by step %s", step.ReportAs, step.Name, s) + } + + if len(step.ReportAs) > 0 { + reportMap[step.ReportAs] = step.Name + reportCount++ + } + if len(step.Commands) == 0 && len(step.Environment) == 0 && len(step.Parameters) == 0 && len(step.Secrets) == 0 && len(step.Template.Name) == 0 && !step.Detach { @@ -143,5 +157,9 @@ func validateSteps(s yaml.StepSlice) error { } } + if reportCount > constants.ReportStepStatusLimit { + return fmt.Errorf("report_as is limited to %d steps, counted %d", constants.ReportStepStatusLimit, reportCount) + } + return nil } diff --git a/compiler/native/validate_test.go b/compiler/native/validate_test.go index 550bbd3ae..453af288a 100644 --- a/compiler/native/validate_test.go +++ b/compiler/native/validate_test.go @@ -4,6 +4,7 @@ package native import ( "flag" + "fmt" "testing" "github.com/go-vela/types/raw" @@ -528,3 +529,80 @@ func TestNative_Validate_Steps_NoCommands(t *testing.T) { t.Errorf("Validate should have returned err") } } + +func TestNative_Validate_Steps_ExceedReportAs(t *testing.T) { + // setup types + set := flag.NewFlagSet("test", 0) + c := cli.NewContext(nil, set, nil) + + str := "foo" + + reportSteps := yaml.StepSlice{} + + for i := 0; i < 12; i++ { + reportStep := &yaml.Step{ + Commands: raw.StringSlice{"echo hello"}, + Image: "alpine", + Name: fmt.Sprintf("%s-%d", str, i), + Pull: "always", + ReportAs: fmt.Sprintf("step-%d", i), + } + reportSteps = append(reportSteps, reportStep) + } + + p := &yaml.Build{ + Version: "v1", + Steps: reportSteps, + } + + // run test + compiler, err := New(c) + if err != nil { + t.Errorf("Unable to create new compiler: %v", err) + } + + err = compiler.Validate(p) + + if err == nil { + t.Errorf("Validate should have returned err") + } +} + +func TestNative_Validate_MultiReportAs(t *testing.T) { + // setup types + set := flag.NewFlagSet("test", 0) + c := cli.NewContext(nil, set, nil) + + str := "foo" + p := &yaml.Build{ + Version: "v1", + Steps: yaml.StepSlice{ + &yaml.Step{ + Commands: raw.StringSlice{"echo hello"}, + Image: "alpine", + Name: str, + Pull: "always", + ReportAs: "bar", + }, + &yaml.Step{ + Commands: raw.StringSlice{"echo hello"}, + Image: "alpine", + Name: str + "-2", + Pull: "always", + ReportAs: "bar", + }, + }, + } + + // run test + compiler, err := New(c) + if err != nil { + t.Errorf("Unable to create new compiler: %v", err) + } + + err = compiler.Validate(p) + + if err == nil { + t.Errorf("Validate should have returned err") + } +} diff --git a/database/integration_test.go b/database/integration_test.go index 29ac6774d..ce35d1ec8 100644 --- a/database/integration_test.go +++ b/database/integration_test.go @@ -2408,6 +2408,7 @@ func newResources() *Resources { stepOne.SetHost("example.company.com") stepOne.SetRuntime("docker") stepOne.SetDistribution("linux") + stepOne.SetReportAs("") stepTwo := new(library.Step) stepTwo.SetID(2) @@ -2426,6 +2427,7 @@ func newResources() *Resources { stepTwo.SetHost("example.company.com") stepTwo.SetRuntime("docker") stepTwo.SetDistribution("linux") + stepTwo.SetReportAs("test") userOne := new(library.User) userOne.SetID(1) diff --git a/database/step/create_test.go b/database/step/create_test.go index b7a494c06..987ffb5b1 100644 --- a/database/step/create_test.go +++ b/database/step/create_test.go @@ -19,6 +19,7 @@ func TestStep_Engine_CreateStep(t *testing.T) { _step.SetNumber(1) _step.SetName("foo") _step.SetImage("bar") + _step.SetReportAs("test") _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() @@ -28,9 +29,9 @@ func TestStep_Engine_CreateStep(t *testing.T) { // ensure the mock expects the query _mock.ExpectQuery(`INSERT INTO "steps" -("build_id","repo_id","number","name","image","stage","status","error","exit_code","created","started","finished","host","runtime","distribution","id") -VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16) RETURNING "id"`). - WithArgs(1, 1, 1, "foo", "bar", nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 1). +("build_id","repo_id","number","name","image","stage","status","error","exit_code","created","started","finished","host","runtime","distribution","report_as","id") +VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17) RETURNING "id"`). + WithArgs(1, 1, 1, "foo", "bar", nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, "test", 1). WillReturnRows(_rows) _sqlite := testSqlite(t) diff --git a/database/step/get_build_test.go b/database/step/get_build_test.go index 55669735c..b372a0c50 100644 --- a/database/step/get_build_test.go +++ b/database/step/get_build_test.go @@ -4,11 +4,11 @@ package step import ( "context" - "reflect" "testing" "github.com/DATA-DOG/go-sqlmock" "github.com/go-vela/types/library" + "github.com/google/go-cmp/cmp" ) func TestStep_Engine_GetStepForBuild(t *testing.T) { @@ -34,8 +34,8 @@ func TestStep_Engine_GetStepForBuild(t *testing.T) { // create expected result in mock _rows := sqlmock.NewRows( - []string{"id", "repo_id", "build_id", "number", "name", "image", "stage", "status", "error", "exit_code", "created", "started", "finished", "host", "runtime", "distribution"}). - AddRow(1, 1, 1, 1, "foo", "bar", "", "", "", 0, 0, 0, 0, "", "", "") + []string{"id", "repo_id", "build_id", "number", "name", "image", "stage", "status", "error", "exit_code", "created", "started", "finished", "host", "runtime", "distribution", "report_as"}). + AddRow(1, 1, 1, 1, "foo", "bar", "", "", "", 0, 0, 0, 0, "", "", "", "") // ensure the mock expects the query _mock.ExpectQuery(`SELECT * FROM "steps" WHERE build_id = $1 AND number = $2 LIMIT $3`).WithArgs(1, 1, 1).WillReturnRows(_rows) @@ -85,8 +85,8 @@ func TestStep_Engine_GetStepForBuild(t *testing.T) { t.Errorf("GetStepForBuild for %s returned err: %v", test.name, err) } - if !reflect.DeepEqual(got, test.want) { - t.Errorf("GetStepForBuild for %s is %v, want %v", test.name, got, test.want) + if diff := cmp.Diff(test.want, got); diff != "" { + t.Errorf("GetStepForBuild for %s is a mismatch (-want +got):\n%s", test.name, diff) } }) } diff --git a/database/step/get_test.go b/database/step/get_test.go index 762e69988..7e17a744c 100644 --- a/database/step/get_test.go +++ b/database/step/get_test.go @@ -27,8 +27,8 @@ func TestStep_Engine_GetStep(t *testing.T) { // create expected result in mock _rows := sqlmock.NewRows( - []string{"id", "repo_id", "build_id", "number", "name", "image", "stage", "status", "error", "exit_code", "created", "started", "finished", "host", "runtime", "distribution"}). - AddRow(1, 1, 1, 1, "foo", "bar", "", "", "", 0, 0, 0, 0, "", "", "") + []string{"id", "repo_id", "build_id", "number", "name", "image", "stage", "status", "error", "exit_code", "created", "started", "finished", "host", "runtime", "distribution", "report_as"}). + AddRow(1, 1, 1, 1, "foo", "bar", "", "", "", 0, 0, 0, 0, "", "", "", "") // ensure the mock expects the query _mock.ExpectQuery(`SELECT * FROM "steps" WHERE id = $1 LIMIT $2`).WithArgs(1, 1).WillReturnRows(_rows) diff --git a/database/step/list_build_test.go b/database/step/list_build_test.go index db53531c2..dbee0b395 100644 --- a/database/step/list_build_test.go +++ b/database/step/list_build_test.go @@ -33,6 +33,7 @@ func TestStep_Engine_ListStepsForBuild(t *testing.T) { _stepTwo.SetNumber(2) _stepTwo.SetName("foo") _stepTwo.SetImage("bar") + _stepTwo.SetReportAs("test") _postgres, _mock := testPostgres(t) @@ -47,9 +48,9 @@ func TestStep_Engine_ListStepsForBuild(t *testing.T) { // create expected result in mock _rows = sqlmock.NewRows( - []string{"id", "repo_id", "build_id", "number", "name", "image", "stage", "status", "error", "exit_code", "created", "started", "finished", "host", "runtime", "distribution"}). - AddRow(2, 1, 1, 2, "foo", "bar", "", "", "", 0, 0, 0, 0, "", "", ""). - AddRow(1, 1, 1, 1, "foo", "bar", "", "", "", 0, 0, 0, 0, "", "", "") + []string{"id", "repo_id", "build_id", "number", "name", "image", "stage", "status", "error", "exit_code", "created", "started", "finished", "host", "runtime", "distribution", "report_as"}). + AddRow(2, 1, 1, 2, "foo", "bar", "", "", "", 0, 0, 0, 0, "", "", "", "test"). + AddRow(1, 1, 1, 1, "foo", "bar", "", "", "", 0, 0, 0, 0, "", "", "", "") // ensure the mock expects the query _mock.ExpectQuery(`SELECT * FROM "steps" WHERE build_id = $1 ORDER BY id DESC LIMIT $2`).WithArgs(1, 10).WillReturnRows(_rows) diff --git a/database/step/list_test.go b/database/step/list_test.go index 284ae802f..2f8323faf 100644 --- a/database/step/list_test.go +++ b/database/step/list_test.go @@ -42,9 +42,9 @@ func TestStep_Engine_ListSteps(t *testing.T) { // create expected result in mock _rows = sqlmock.NewRows( - []string{"id", "repo_id", "build_id", "number", "name", "image", "stage", "status", "error", "exit_code", "created", "started", "finished", "host", "runtime", "distribution"}). - AddRow(1, 1, 1, 1, "foo", "bar", "", "", "", 0, 0, 0, 0, "", "", ""). - AddRow(2, 1, 2, 1, "bar", "foo", "", "", "", 0, 0, 0, 0, "", "", "") + []string{"id", "repo_id", "build_id", "number", "name", "image", "stage", "status", "error", "exit_code", "created", "started", "finished", "host", "runtime", "distribution", "report_as"}). + AddRow(1, 1, 1, 1, "foo", "bar", "", "", "", 0, 0, 0, 0, "", "", "", ""). + AddRow(2, 1, 2, 1, "bar", "foo", "", "", "", 0, 0, 0, 0, "", "", "", "") // ensure the mock expects the query _mock.ExpectQuery(`SELECT * FROM "steps"`).WillReturnRows(_rows) diff --git a/database/step/step_test.go b/database/step/step_test.go index bbd2a09da..e3101147d 100644 --- a/database/step/step_test.go +++ b/database/step/step_test.go @@ -221,6 +221,7 @@ func testStep() *library.Step { Host: new(string), Runtime: new(string), Distribution: new(string), + ReportAs: new(string), } } diff --git a/database/step/table.go b/database/step/table.go index 8cdde1b6e..a7cd7eb74 100644 --- a/database/step/table.go +++ b/database/step/table.go @@ -4,6 +4,7 @@ package step import ( "context" + "github.com/go-vela/types/constants" ) @@ -29,6 +30,7 @@ steps ( host VARCHAR(250), runtime VARCHAR(250), distribution VARCHAR(250), + report_as VARCHAR(250), UNIQUE(build_id, number) ); ` @@ -54,6 +56,7 @@ steps ( host TEXT, runtime TEXT, distribution TEXT, + report_as TEXT, UNIQUE(build_id, number) ); ` diff --git a/database/step/update_test.go b/database/step/update_test.go index 14ddf009c..d1b14dd2b 100644 --- a/database/step/update_test.go +++ b/database/step/update_test.go @@ -28,9 +28,9 @@ func TestStep_Engine_UpdateStep(t *testing.T) { // ensure the mock expects the query _mock.ExpectExec(`UPDATE "steps" -SET "build_id"=$1,"repo_id"=$2,"number"=$3,"name"=$4,"image"=$5,"stage"=$6,"status"=$7,"error"=$8,"exit_code"=$9,"created"=$10,"started"=$11,"finished"=$12,"host"=$13,"runtime"=$14,"distribution"=$15 -WHERE "id" = $16`). - WithArgs(1, 1, 1, "foo", "bar", nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 1). +SET "build_id"=$1,"repo_id"=$2,"number"=$3,"name"=$4,"image"=$5,"stage"=$6,"status"=$7,"error"=$8,"exit_code"=$9,"created"=$10,"started"=$11,"finished"=$12,"host"=$13,"runtime"=$14,"distribution"=$15,"report_as"=$16 +WHERE "id" = $17`). + WithArgs(1, 1, 1, "foo", "bar", nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 1). WillReturnResult(sqlmock.NewResult(1, 1)) _sqlite := testSqlite(t) diff --git a/go.mod b/go.mod index 7d043ce7f..eb4191a8d 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/drone/envsubst v1.0.3 github.com/gin-gonic/gin v1.9.1 github.com/go-playground/assert/v2 v2.2.0 - github.com/go-vela/types v0.23.2 + github.com/go-vela/types v0.23.4-0.20240326211542-476edfa844f0 github.com/golang-jwt/jwt/v5 v5.2.1 github.com/google/go-cmp v0.6.0 github.com/google/go-github/v59 v59.0.0 diff --git a/go.sum b/go.sum index 7493cb0e0..7e6377fa8 100644 --- a/go.sum +++ b/go.sum @@ -85,8 +85,8 @@ github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw= github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= -github.com/go-vela/types v0.23.2 h1:QDt2lta7FPEfN2RK/Bn++DkqyjGIB4H/Q4XkFAj3hXQ= -github.com/go-vela/types v0.23.2/go.mod h1:aTE6dzssqTGOvU6m2/vsI9NoSW/3hH/yLzf3cCSo0Zk= +github.com/go-vela/types v0.23.4-0.20240326211542-476edfa844f0 h1:CR/lM4nzDoQ1wKDa9aJGnlZHkx94m170t9NKyCjV9NA= +github.com/go-vela/types v0.23.4-0.20240326211542-476edfa844f0/go.mod h1:mEF9dLkk00rUXf/t39n2WvXZgJbxnPEEWy+DHqIlRUo= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= diff --git a/mock/server/step.go b/mock/server/step.go index e5694ab85..75fcdacf4 100644 --- a/mock/server/step.go +++ b/mock/server/step.go @@ -32,7 +32,8 @@ const ( "finished": 0, "host": "host.company.com", "runtime": "docker", - "distribution": "linux" + "distribution": "linux", + "report_as": "test" }` // StepsResp represents a JSON return for one to many steps. @@ -51,7 +52,8 @@ const ( "finished": 0, "host": "host.company.com", "runtime": "docker", - "distribution": "linux" + "distribution": "linux", + "report_as": "" }, { "id": 1, @@ -67,7 +69,8 @@ const ( "finished": 0, "host": "host.company.com", "runtime": "docker", - "distribution": "linux" + "distribution": "linux", + "report_as": "test" } ]` ) diff --git a/router/middleware/step/step_test.go b/router/middleware/step/step_test.go index 8d9e19271..e4432a14a 100644 --- a/router/middleware/step/step_test.go +++ b/router/middleware/step/step_test.go @@ -69,6 +69,7 @@ func TestStep_Establish(t *testing.T) { want.SetHost("") want.SetRuntime("") want.SetDistribution("") + want.SetReportAs("") got := new(library.Step) diff --git a/scm/github/repo.go b/scm/github/repo.go index d53bc8a87..ef22491f3 100644 --- a/scm/github/repo.go +++ b/scm/github/repo.go @@ -291,6 +291,12 @@ func (c *client) Status(ctx context.Context, u *library.User, b *library.Build, "user": u.GetName(), }).Tracef("setting commit status for %s/%s/%d @ %s", org, name, b.GetNumber(), b.GetCommit()) + // only report opened, synchronize, and reopened action types for pull_request events + if strings.EqualFold(b.GetEvent(), constants.EventPull) && !strings.EqualFold(b.GetEventAction(), constants.ActionOpened) && + !strings.EqualFold(b.GetEventAction(), constants.ActionSynchronize) && !strings.EqualFold(b.GetEventAction(), constants.ActionReopened) { + return nil + } + // create GitHub OAuth client with user's token client := c.newClientToken(*u.Token) @@ -387,6 +393,74 @@ func (c *client) Status(ctx context.Context, u *library.User, b *library.Build, return err } +// StepStatus sends the commit status for the given SHA to the GitHub repo with the step as the context. +func (c *client) StepStatus(ctx context.Context, u *library.User, b *library.Build, s *library.Step, org, name string) error { + c.Logger.WithFields(logrus.Fields{ + "build": b.GetNumber(), + "org": org, + "repo": name, + "user": u.GetName(), + }).Tracef("setting commit status for %s/%s/%d @ %s", org, name, b.GetNumber(), b.GetCommit()) + + // create GitHub OAuth client with user's token + client := c.newClientToken(*u.Token) + + context := fmt.Sprintf("%s/%s/%s", c.config.StatusContext, b.GetEvent(), s.GetReportAs()) + url := fmt.Sprintf("%s/%s/%s/%d#step:%d", c.config.WebUIAddress, org, name, b.GetNumber(), s.GetNumber()) + + var ( + state string + description string + ) + + // set the state and description for the status context + // depending on what the status of the build is + switch s.GetStatus() { + case constants.StatusRunning, constants.StatusPending: + state = "pending" + description = fmt.Sprintf("the step is %s", s.GetStatus()) + case constants.StatusPendingApproval: + state = "pending" + description = fmt.Sprintf("the step is %s", s.GetStatus()) + case constants.StatusSuccess: + state = "success" + description = "the step was successful" + case constants.StatusFailure: + //nolint:goconst // ignore making constant + state = "failure" + description = "the step has failed" + case constants.StatusCanceled: + state = "failure" + description = "the step was canceled" + case constants.StatusKilled: + state = "failure" + description = "the step was killed" + case constants.StatusSkipped: + state = "success" + description = "step was skipped as no steps/stages found" + default: + state = "error" + description = "there was an error" + } + + // create the status object to make the API call + status := &github.RepoStatus{ + Context: github.String(context), + Description: github.String(description), + State: github.String(state), + } + + // provide "Details" link in GitHub UI if server was configured with it + if len(c.config.WebUIAddress) > 0 && b.GetStatus() != constants.StatusSkipped { + status.TargetURL = github.String(url) + } + + // send API call to create the status context for the commit + _, _, err := client.Repositories.CreateStatus(ctx, org, name, b.GetCommit(), status) + + return err +} + // GetRepo gets repo information from Github. func (c *client) GetRepo(ctx context.Context, u *library.User, r *library.Repo) (*library.Repo, int, error) { c.Logger.WithFields(logrus.Fields{ diff --git a/scm/github/repo_test.go b/scm/github/repo_test.go index 997c793d6..6918c8a0d 100644 --- a/scm/github/repo_test.go +++ b/scm/github/repo_test.go @@ -908,6 +908,13 @@ func TestGithub_Status_Running(t *testing.T) { b.SetStatus(constants.StatusRunning) b.SetCommit("abcd1234") + step := new(library.Step) + step.SetID(1) + step.SetNumber(1) + step.SetName("test") + step.SetReportAs("test") + step.SetStatus(constants.StatusRunning) + client, _ := NewTest(s.URL) // run test @@ -920,6 +927,16 @@ func TestGithub_Status_Running(t *testing.T) { if err != nil { t.Errorf("Status returned err: %v", err) } + + err = client.StepStatus(context.TODO(), u, b, step, "foo", "bar") + + if resp.Code != http.StatusOK { + t.Errorf("Status returned %v, want %v", resp.Code, http.StatusOK) + } + + if err != nil { + t.Errorf("Status returned err: %v", err) + } } func TestGithub_Status_Success(t *testing.T) { @@ -952,6 +969,13 @@ func TestGithub_Status_Success(t *testing.T) { b.SetStatus(constants.StatusRunning) b.SetCommit("abcd1234") + step := new(library.Step) + step.SetID(1) + step.SetNumber(1) + step.SetName("test") + step.SetReportAs("test") + step.SetStatus(constants.StatusSuccess) + client, _ := NewTest(s.URL) // run test @@ -964,6 +988,16 @@ func TestGithub_Status_Success(t *testing.T) { if err != nil { t.Errorf("Status returned err: %v", err) } + + err = client.StepStatus(context.TODO(), u, b, step, "foo", "bar") + + if resp.Code != http.StatusOK { + t.Errorf("Status returned %v, want %v", resp.Code, http.StatusOK) + } + + if err != nil { + t.Errorf("Status returned err: %v", err) + } } func TestGithub_Status_Failure(t *testing.T) { @@ -996,6 +1030,13 @@ func TestGithub_Status_Failure(t *testing.T) { b.SetStatus(constants.StatusRunning) b.SetCommit("abcd1234") + step := new(library.Step) + step.SetID(1) + step.SetNumber(1) + step.SetName("test") + step.SetReportAs("test") + step.SetStatus(constants.StatusFailure) + client, _ := NewTest(s.URL) // run test @@ -1008,6 +1049,16 @@ func TestGithub_Status_Failure(t *testing.T) { if err != nil { t.Errorf("Status returned err: %v", err) } + + err = client.StepStatus(context.TODO(), u, b, step, "foo", "bar") + + if resp.Code != http.StatusOK { + t.Errorf("Status returned %v, want %v", resp.Code, http.StatusOK) + } + + if err != nil { + t.Errorf("Status returned err: %v", err) + } } func TestGithub_Status_Killed(t *testing.T) { @@ -1040,6 +1091,13 @@ func TestGithub_Status_Killed(t *testing.T) { b.SetStatus(constants.StatusRunning) b.SetCommit("abcd1234") + step := new(library.Step) + step.SetID(1) + step.SetNumber(1) + step.SetName("test") + step.SetReportAs("test") + step.SetStatus(constants.StatusKilled) + client, _ := NewTest(s.URL) // run test @@ -1052,6 +1110,16 @@ func TestGithub_Status_Killed(t *testing.T) { if err != nil { t.Errorf("Status returned err: %v", err) } + + err = client.StepStatus(context.TODO(), u, b, step, "foo", "bar") + + if resp.Code != http.StatusOK { + t.Errorf("Status returned %v, want %v", resp.Code, http.StatusOK) + } + + if err != nil { + t.Errorf("Status returned err: %v", err) + } } func TestGithub_Status_Skipped(t *testing.T) { @@ -1084,6 +1152,13 @@ func TestGithub_Status_Skipped(t *testing.T) { b.SetStatus(constants.StatusSkipped) b.SetCommit("abcd1234") + step := new(library.Step) + step.SetID(1) + step.SetNumber(1) + step.SetName("test") + step.SetReportAs("test") + step.SetStatus(constants.StatusSkipped) + client, _ := NewTest(s.URL) // run test @@ -1096,6 +1171,16 @@ func TestGithub_Status_Skipped(t *testing.T) { if err != nil { t.Errorf("Status returned err: %v", err) } + + err = client.StepStatus(context.TODO(), u, b, step, "foo", "bar") + + if resp.Code != http.StatusOK { + t.Errorf("Status returned %v, want %v", resp.Code, http.StatusOK) + } + + if err != nil { + t.Errorf("Status returned err: %v", err) + } } func TestGithub_Status_Error(t *testing.T) { @@ -1128,6 +1213,13 @@ func TestGithub_Status_Error(t *testing.T) { b.SetStatus(constants.StatusRunning) b.SetCommit("abcd1234") + step := new(library.Step) + step.SetID(1) + step.SetNumber(1) + step.SetName("test") + step.SetReportAs("test") + step.SetStatus(constants.StatusError) + client, _ := NewTest(s.URL) // run test @@ -1140,6 +1232,16 @@ func TestGithub_Status_Error(t *testing.T) { if err != nil { t.Errorf("Status returned err: %v", err) } + + err = client.StepStatus(context.TODO(), u, b, step, "foo", "bar") + + if resp.Code != http.StatusOK { + t.Errorf("Status returned %v, want %v", resp.Code, http.StatusOK) + } + + if err != nil { + t.Errorf("Status returned err: %v", err) + } } func TestGithub_GetRepo(t *testing.T) { diff --git a/scm/service.go b/scm/service.go index 074495cee..bc594af03 100644 --- a/scm/service.go +++ b/scm/service.go @@ -110,6 +110,9 @@ type Service interface { // Status defines a function that sends the // commit status for the given SHA from a repo. Status(context.Context, *library.User, *library.Build, string, string) error + // StepStatus defines a function that sends the + // commit status for the given SHA for a specified step context. + StepStatus(context.Context, *library.User, *library.Build, *library.Step, string, string) error // ListUserRepos defines a function that retrieves // all repos with admin rights for the user. ListUserRepos(context.Context, *library.User) ([]*library.Repo, error) From 5af11c245cc02edbef5f0b61bc89cefee777c286 Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Fri, 29 Mar 2024 10:28:44 -0400 Subject: [PATCH 18/71] enhance(templates): inject template name as variable (#1096) --- compiler/native/compile.go | 8 ++++ compiler/native/compile_test.go | 44 ++++++++++++---------- compiler/native/expand.go | 8 ++++ compiler/native/expand_test.go | 6 +-- compiler/native/testdata/long_template.yml | 1 + 5 files changed, 45 insertions(+), 22 deletions(-) diff --git a/compiler/native/compile.go b/compiler/native/compile.go index 9768d90bb..e72196c89 100644 --- a/compiler/native/compile.go +++ b/compiler/native/compile.go @@ -191,6 +191,14 @@ func (c *client) compileInline(p *yaml.Build, depth int) (*yaml.Build, error) { format = constants.PipelineTypeGo } + // initialize variable map if not parsed from config + if len(template.Variables) == 0 { + template.Variables = make(map[string]interface{}) + } + + // inject template name into variables + template.Variables["VELA_TEMPLATE_NAME"] = template.Name + parsed, _, err := c.Parse(bytes, format, template) if err != nil { return nil, err diff --git a/compiler/native/compile_test.go b/compiler/native/compile_test.go index e71956306..d00df4628 100644 --- a/compiler/native/compile_test.go +++ b/compiler/native/compile_test.go @@ -680,7 +680,7 @@ func TestNative_Compile_StagesPipelineTemplate(t *testing.T) { buildEnv["GRADLE_USER_HOME"] = ".gradle" buildEnv["HOME"] = "/root" buildEnv["SHELL"] = "/bin/sh" - buildEnv["VELA_BUILD_SCRIPT"] = generateScriptPosix([]string{"./gradlew build"}) + buildEnv["VELA_BUILD_SCRIPT"] = generateScriptPosix([]string{"./gradlew build", "echo gradle"}) buildEnv["bar"] = "test4" buildEnv["star"] = "test3" @@ -951,7 +951,7 @@ func TestNative_Compile_StepsPipelineTemplate(t *testing.T) { buildEnv["GRADLE_USER_HOME"] = ".gradle" buildEnv["HOME"] = "/root" buildEnv["SHELL"] = "/bin/sh" - buildEnv["VELA_BUILD_SCRIPT"] = generateScriptPosix([]string{"./gradlew build"}) + buildEnv["VELA_BUILD_SCRIPT"] = generateScriptPosix([]string{"./gradlew build", "echo gradle"}) buildEnv["bar"] = "test4" buildEnv["star"] = "test3" @@ -3230,17 +3230,21 @@ func Test_CompileLite(t *testing.T) { }, Templates: []*yaml.Template{ { - Name: "golang", - Source: "github.example.com/github/octocat/golang_inline_stages.yml", - Format: "golang", - Type: "github", - Variables: map[string]any{"image": string("golang:latest")}, + Name: "golang", + Source: "github.example.com/github/octocat/golang_inline_stages.yml", + Format: "golang", + Type: "github", + Variables: map[string]any{ + "image": string("golang:latest"), + "VELA_TEMPLATE_NAME": string("golang"), + }, }, { - Name: "starlark", - Source: "github.example.com/github/octocat/starlark_inline_stages.star", - Format: "starlark", - Type: "github", + Name: "starlark", + Source: "github.example.com/github/octocat/starlark_inline_stages.star", + Format: "starlark", + Type: "github", + Variables: map[string]any{"VELA_TEMPLATE_NAME": string("starlark")}, }, }, Environment: raw.StringSliceMap{}, @@ -3375,16 +3379,18 @@ func Test_CompileLite(t *testing.T) { Environment: raw.StringSliceMap{}, Templates: yaml.TemplateSlice{ { - Name: "golang", - Source: "github.example.com/github/octocat/golang_inline_steps.yml", - Format: "golang", - Type: "github", + Name: "golang", + Source: "github.example.com/github/octocat/golang_inline_steps.yml", + Format: "golang", + Type: "github", + Variables: map[string]any{"VELA_TEMPLATE_NAME": string("golang")}, }, { - Name: "starlark", - Source: "github.example.com/github/octocat/starlark_inline_steps.star", - Format: "starlark", - Type: "github", + Name: "starlark", + Source: "github.example.com/github/octocat/starlark_inline_steps.star", + Format: "starlark", + Type: "github", + Variables: map[string]any{"VELA_TEMPLATE_NAME": string("starlark")}, }, }, }, diff --git a/compiler/native/expand.go b/compiler/native/expand.go index 734c597e8..f3bac6edc 100644 --- a/compiler/native/expand.go +++ b/compiler/native/expand.go @@ -120,6 +120,14 @@ func (c *client) ExpandSteps(s *yaml.Build, tmpls map[string]*yaml.Template, r * return s, err } + // initialize variable map if not parsed from config + if len(step.Template.Variables) == 0 { + step.Template.Variables = make(map[string]interface{}) + } + + // inject template name into variables + step.Template.Variables["VELA_TEMPLATE_NAME"] = step.Template.Name + tmplBuild, err := c.mergeTemplate(bytes, tmpl, step) if err != nil { return s, err diff --git a/compiler/native/expand_test.go b/compiler/native/expand_test.go index 749bdccb2..df04741e3 100644 --- a/compiler/native/expand_test.go +++ b/compiler/native/expand_test.go @@ -98,7 +98,7 @@ func TestNative_ExpandStages(t *testing.T) { Pull: "always", }, &yaml.Step{ - Commands: []string{"./gradlew build"}, + Commands: []string{"./gradlew build", "echo gradle"}, Environment: raw.StringSliceMap{ "GRADLE_OPTS": "-Dorg.gradle.daemon=false -Dorg.gradle.workers.max=1 -Dorg.gradle.parallel=false", "GRADLE_USER_HOME": ".gradle", @@ -301,7 +301,7 @@ func TestNative_ExpandSteps(t *testing.T) { Pull: "always", }, &yaml.Step{ - Commands: []string{"./gradlew build"}, + Commands: []string{"./gradlew build", "echo gradle"}, Environment: raw.StringSliceMap{ "GRADLE_OPTS": "-Dorg.gradle.daemon=false -Dorg.gradle.workers.max=1 -Dorg.gradle.parallel=false", "GRADLE_USER_HOME": ".gradle", @@ -823,7 +823,7 @@ func TestNative_ExpandSteps_TemplateCallTemplate(t *testing.T) { Pull: "always", }, &yaml.Step{ - Commands: []string{"./gradlew build"}, + Commands: []string{"./gradlew build", "echo test"}, Environment: raw.StringSliceMap{ "GRADLE_OPTS": "-Dorg.gradle.daemon=false -Dorg.gradle.workers.max=1 -Dorg.gradle.parallel=false", "GRADLE_USER_HOME": ".gradle", diff --git a/compiler/native/testdata/long_template.yml b/compiler/native/testdata/long_template.yml index c9f92ee44..5cc78d9b7 100644 --- a/compiler/native/testdata/long_template.yml +++ b/compiler/native/testdata/long_template.yml @@ -23,6 +23,7 @@ steps: - name: build commands: - ./gradlew build + - echo {{ .VELA_TEMPLATE_NAME }} environment: {{ .environment }} image: {{ .image }} {{ .pull_policy }} From c5813f6040da4db95bc3a5263008a4e86c220f58 Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Fri, 29 Mar 2024 10:51:34 -0400 Subject: [PATCH 19/71] fix(scm): skipped map to failure for step status + remove deploy (#1097) --- scm/github/repo.go | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/scm/github/repo.go b/scm/github/repo.go index ef22491f3..1cd40d51c 100644 --- a/scm/github/repo.go +++ b/scm/github/repo.go @@ -312,12 +312,14 @@ func (c *client) Status(ctx context.Context, u *library.User, b *library.Build, // depending on what the status of the build is switch b.GetStatus() { case constants.StatusRunning, constants.StatusPending: + //nolint:goconst // ignore making constant state = "pending" description = fmt.Sprintf("the build is %s", b.GetStatus()) case constants.StatusPendingApproval: state = "pending" description = "build needs approval from repo admin to run" case constants.StatusSuccess: + //nolint:goconst // ignore making constant state = "success" description = "the build was successful" case constants.StatusFailure: @@ -402,6 +404,11 @@ func (c *client) StepStatus(ctx context.Context, u *library.User, b *library.Bui "user": u.GetName(), }).Tracef("setting commit status for %s/%s/%d @ %s", org, name, b.GetNumber(), b.GetCommit()) + // no commit statuses on deployments + if strings.EqualFold(b.GetEvent(), constants.EventDeploy) { + return nil + } + // create GitHub OAuth client with user's token client := c.newClientToken(*u.Token) @@ -414,19 +421,15 @@ func (c *client) StepStatus(ctx context.Context, u *library.User, b *library.Bui ) // set the state and description for the status context - // depending on what the status of the build is + // depending on what the status of the step is switch s.GetStatus() { - case constants.StatusRunning, constants.StatusPending: - state = "pending" - description = fmt.Sprintf("the step is %s", s.GetStatus()) - case constants.StatusPendingApproval: + case constants.StatusRunning, constants.StatusPending, constants.StatusPendingApproval: state = "pending" description = fmt.Sprintf("the step is %s", s.GetStatus()) case constants.StatusSuccess: state = "success" description = "the step was successful" case constants.StatusFailure: - //nolint:goconst // ignore making constant state = "failure" description = "the step has failed" case constants.StatusCanceled: @@ -436,8 +439,8 @@ func (c *client) StepStatus(ctx context.Context, u *library.User, b *library.Bui state = "failure" description = "the step was killed" case constants.StatusSkipped: - state = "success" - description = "step was skipped as no steps/stages found" + state = "failure" + description = "step was skipped or never ran" default: state = "error" description = "there was an error" From f591935d2fc9c29aaa8f60cb90cb37244657252e Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Mon, 1 Apr 2024 13:51:44 -0400 Subject: [PATCH 20/71] chore: remove legacy event code from repo and secret (#1098) --- api/repo/create.go | 34 +- api/repo/update.go | 45 -- api/secret/create.go | 5 - api/secret/update.go | 4 - compiler/native/environment_test.go | 648 ++++++++++++------------- database/build/build_test.go | 5 - database/deployment/deployment_test.go | 5 - database/hook/hook_test.go | 5 - database/integration_test.go | 13 - database/repo/create_test.go | 6 +- database/repo/get_org_test.go | 4 +- database/repo/get_test.go | 4 +- database/repo/list_org_test.go | 12 +- database/repo/list_test.go | 6 +- database/repo/list_user_test.go | 12 +- database/repo/repo_test.go | 5 - database/repo/table.go | 10 - database/repo/update_test.go | 6 +- database/schedule/schedule_test.go | 5 - database/secret/create_test.go | 18 +- database/secret/get_org_test.go | 4 +- database/secret/get_repo_test.go | 4 +- database/secret/get_team_test.go | 4 +- database/secret/get_test.go | 4 +- database/secret/list_org_test.go | 6 +- database/secret/list_repo_test.go | 6 +- database/secret/list_team_test.go | 14 +- database/secret/list_test.go | 6 +- database/secret/secret_test.go | 6 - database/secret/table.go | 2 - database/secret/update_test.go | 18 +- go.mod | 2 +- go.sum | 4 +- mock/server/repo.go | 17 +- mock/server/secret.go | 10 - queue/redis/redis_test.go | 28 +- router/middleware/org/org_test.go | 5 - router/middleware/repo/repo_test.go | 5 - scm/github/repo_test.go | 6 - secret/native/count_test.go | 1 - secret/native/create_test.go | 4 - secret/native/delete_test.go | 1 - secret/native/get_test.go | 1 - secret/native/list_test.go | 2 - secret/native/update.go | 5 - secret/native/update_test.go | 2 - secret/vault/create_test.go | 6 - secret/vault/get_test.go | 3 - secret/vault/list_test.go | 3 - secret/vault/update.go | 3 - secret/vault/update_test.go | 7 - secret/vault/vault.go | 21 +- secret/vault/vault_test.go | 4 - 53 files changed, 396 insertions(+), 670 deletions(-) diff --git a/api/repo/create.go b/api/repo/create.go index 9fe69dfad..59ccbf857 100644 --- a/api/repo/create.go +++ b/api/repo/create.go @@ -182,34 +182,6 @@ func CreateRepo(c *gin.Context) { r.SetAllowEvents(defaultAllowedEvents(defaultRepoEvents, defaultRepoEventsMask)) } - // -- DEPRECATED SECTION -- - // set default events if no events are passed in - if !input.GetAllowPull() && !input.GetAllowPush() && - !input.GetAllowDeploy() && !input.GetAllowTag() && - !input.GetAllowComment() { - for _, event := range defaultRepoEvents { - switch event { - case constants.EventPull: - r.SetAllowPull(true) - case constants.EventPush: - r.SetAllowPush(true) - case constants.EventDeploy: - r.SetAllowDeploy(true) - case constants.EventTag: - r.SetAllowTag(true) - case constants.EventComment: - r.SetAllowComment(true) - } - } - } else { - r.SetAllowComment(input.GetAllowComment()) - r.SetAllowDeploy(input.GetAllowDeploy()) - r.SetAllowPull(input.GetAllowPull()) - r.SetAllowPush(input.GetAllowPush()) - r.SetAllowTag(input.GetAllowTag()) - } - // -- END DEPRECATED SECTION -- - if len(input.GetPipelineType()) == 0 { r.SetPipelineType(constants.PipelineTypeYAML) } else { @@ -275,11 +247,7 @@ func CreateRepo(c *gin.Context) { // make sure our record of the repo allowed events matches what we send to SCM // what the dbRepo has should override default events on enable - r.SetAllowComment(dbRepo.GetAllowComment()) - r.SetAllowDeploy(dbRepo.GetAllowDeploy()) - r.SetAllowPull(dbRepo.GetAllowPull()) - r.SetAllowPush(dbRepo.GetAllowPush()) - r.SetAllowTag(dbRepo.GetAllowTag()) + r.SetAllowEvents(dbRepo.GetAllowEvents()) } // check if we should create the webhook diff --git a/api/repo/update.go b/api/repo/update.go index ba21996d3..efdb1a366 100644 --- a/api/repo/update.go +++ b/api/repo/update.go @@ -191,51 +191,6 @@ func UpdateRepo(c *gin.Context) { eventsChanged = true } - // -- DEPRECATED SECTION -- - if input.AllowPull != nil { - // update allow_pull if set - r.SetAllowPull(input.GetAllowPull()) - - eventsChanged = true - } - - if input.AllowPush != nil { - // update allow_push if set - r.SetAllowPush(input.GetAllowPush()) - - eventsChanged = true - } - - if input.AllowDeploy != nil { - // update allow_deploy if set - r.SetAllowDeploy(input.GetAllowDeploy()) - - eventsChanged = true - } - - if input.AllowTag != nil { - // update allow_tag if set - r.SetAllowTag(input.GetAllowTag()) - - eventsChanged = true - } - - if input.AllowComment != nil { - // update allow_comment if set - r.SetAllowComment(input.GetAllowComment()) - - eventsChanged = true - } - - // set default events if no events are enabled - if !r.GetAllowPull() && !r.GetAllowPush() && - !r.GetAllowDeploy() && !r.GetAllowTag() && - !r.GetAllowComment() { - r.SetAllowPull(true) - r.SetAllowPush(true) - } - // -- END DEPRECATED SECTION -- - // set default events if no events are enabled if r.GetAllowEvents().ToDatabase() == 0 { r.SetAllowEvents(defaultAllowedEvents(defaultRepoEvents, defaultRepoEventsMask)) diff --git a/api/secret/create.go b/api/secret/create.go index 3845f4b7c..e398647c6 100644 --- a/api/secret/create.go +++ b/api/secret/create.go @@ -225,11 +225,6 @@ func CreateSecret(c *gin.Context) { input.SetAllowEvents(e) } - if len(input.GetEvents()) == 0 { - // set default events to enable for the secret - input.SetEvents([]string{constants.EventPush, constants.EventTag, constants.EventDeploy}) - } - if input.AllowCommand == nil { input.SetAllowCommand(true) } diff --git a/api/secret/update.go b/api/secret/update.go index 98c78e031..aecadcc86 100644 --- a/api/secret/update.go +++ b/api/secret/update.go @@ -143,10 +143,6 @@ func UpdateSecret(c *gin.Context) { input.SetImages(util.Unique(input.GetImages())) } - if len(input.GetEvents()) > 0 { - input.SetEvents(util.Unique(input.GetEvents())) - } - if input.AllowCommand != nil { // update allow_command if set input.SetAllowCommand(input.GetAllowCommand()) diff --git a/compiler/native/environment_test.go b/compiler/native/environment_test.go index a6a598acc..01755972e 100644 --- a/compiler/native/environment_test.go +++ b/compiler/native/environment_test.go @@ -103,113 +103,103 @@ func TestNative_EnvironmentSteps(t *testing.T) { Name: str, Pull: "always", Environment: raw.StringSliceMap{ - "BUILD_AUTHOR": "", - "BUILD_AUTHOR_EMAIL": "", - "BUILD_BASE_REF": "", - "BUILD_BRANCH": "", - "BUILD_CHANNEL": "TODO", - "BUILD_CLONE": "", - "BUILD_COMMIT": "", - "BUILD_CREATED": "0", - "BUILD_ENQUEUED": "0", - "BUILD_EVENT": "", - "BUILD_HOST": "", - "BUILD_LINK": "", - "BUILD_MESSAGE": "", - "BUILD_NUMBER": "0", - "BUILD_PARENT": "0", - "BUILD_REF": "", - "BUILD_SENDER": "", - "BUILD_SOURCE": "", - "BUILD_STARTED": "0", - "BUILD_STATUS": "", - "BUILD_TITLE": "", - "BUILD_WORKSPACE": "/vela/src", - "CI": "true", - "REPOSITORY_ACTIVE": "false", - "REPOSITORY_ALLOW_COMMENT": "false", - "REPOSITORY_ALLOW_DEPLOY": "false", - "REPOSITORY_ALLOW_PULL": "false", - "REPOSITORY_ALLOW_PUSH": "false", - "REPOSITORY_ALLOW_TAG": "false", - "REPOSITORY_ALLOW_EVENTS": "", - "REPOSITORY_BRANCH": "", - "REPOSITORY_CLONE": "", - "REPOSITORY_FULL_NAME": "", - "REPOSITORY_LINK": "", - "REPOSITORY_NAME": "", - "REPOSITORY_ORG": "", - "REPOSITORY_PRIVATE": "false", - "REPOSITORY_TIMEOUT": "0", - "REPOSITORY_TRUSTED": "false", - "REPOSITORY_VISIBILITY": "", - "VELA": "true", - "VELA_ADDR": "TODO", - "VELA_BUILD_APPROVED_AT": "0", - "VELA_BUILD_APPROVED_BY": "", - "VELA_BUILD_AUTHOR": "", - "VELA_BUILD_AUTHOR_EMAIL": "", - "VELA_BUILD_BASE_REF": "", - "VELA_BUILD_BRANCH": "", - "VELA_BUILD_CHANNEL": "TODO", - "VELA_BUILD_CLONE": "", - "VELA_BUILD_COMMIT": "", - "VELA_BUILD_CREATED": "0", - "VELA_BUILD_DISTRIBUTION": "", - "VELA_BUILD_ENQUEUED": "0", - "VELA_BUILD_EVENT": "", - "VELA_BUILD_EVENT_ACTION": "", - "VELA_BUILD_HOST": "", - "VELA_BUILD_LINK": "", - "VELA_BUILD_MESSAGE": "", - "VELA_BUILD_NUMBER": "0", - "VELA_BUILD_PARENT": "0", - "VELA_BUILD_REF": "", - "VELA_BUILD_RUNTIME": "", - "VELA_BUILD_SENDER": "", - "VELA_BUILD_SOURCE": "", - "VELA_BUILD_STARTED": "0", - "VELA_BUILD_STATUS": "", - "VELA_BUILD_TITLE": "", - "VELA_BUILD_WORKSPACE": "/vela/src", - "VELA_CHANNEL": "TODO", - "VELA_DATABASE": "TODO", - "VELA_DISTRIBUTION": "TODO", - "VELA_HOST": "TODO", - "VELA_NETRC_MACHINE": "TODO", - "VELA_NETRC_PASSWORD": "", - "VELA_NETRC_USERNAME": "x-oauth-basic", - "VELA_QUEUE": "TODO", - "VELA_REPO_ACTIVE": "false", - "VELA_REPO_ALLOW_COMMENT": "false", - "VELA_REPO_ALLOW_DEPLOY": "false", - "VELA_REPO_ALLOW_PULL": "false", - "VELA_REPO_ALLOW_PUSH": "false", - "VELA_REPO_ALLOW_TAG": "false", - "VELA_REPO_ALLOW_EVENTS": "", - "VELA_REPO_APPROVE_BUILD": "", - "VELA_REPO_BRANCH": "", - "VELA_REPO_TOPICS": "", - "VELA_REPO_BUILD_LIMIT": "0", - "VELA_REPO_CLONE": "", - "VELA_REPO_FULL_NAME": "", - "VELA_REPO_LINK": "", - "VELA_REPO_NAME": "", - "VELA_REPO_ORG": "", - "VELA_REPO_PIPELINE_TYPE": "", - "VELA_REPO_PRIVATE": "false", - "VELA_REPO_TIMEOUT": "0", - "VELA_REPO_TRUSTED": "false", - "VELA_REPO_VISIBILITY": "", - "VELA_RUNTIME": "TODO", - "VELA_SOURCE": "TODO", - "VELA_USER_ACTIVE": "false", - "VELA_USER_ADMIN": "false", - "VELA_USER_FAVORITES": "[]", - "VELA_USER_NAME": "", - "VELA_VERSION": "TODO", - "VELA_WORKSPACE": "/vela/src", - "HELLO": "Hello, Stage Message", + "BUILD_AUTHOR": "", + "BUILD_AUTHOR_EMAIL": "", + "BUILD_BASE_REF": "", + "BUILD_BRANCH": "", + "BUILD_CHANNEL": "TODO", + "BUILD_CLONE": "", + "BUILD_COMMIT": "", + "BUILD_CREATED": "0", + "BUILD_ENQUEUED": "0", + "BUILD_EVENT": "", + "BUILD_HOST": "", + "BUILD_LINK": "", + "BUILD_MESSAGE": "", + "BUILD_NUMBER": "0", + "BUILD_PARENT": "0", + "BUILD_REF": "", + "BUILD_SENDER": "", + "BUILD_SOURCE": "", + "BUILD_STARTED": "0", + "BUILD_STATUS": "", + "BUILD_TITLE": "", + "BUILD_WORKSPACE": "/vela/src", + "CI": "true", + "REPOSITORY_ACTIVE": "false", + "REPOSITORY_ALLOW_EVENTS": "", + "REPOSITORY_BRANCH": "", + "REPOSITORY_CLONE": "", + "REPOSITORY_FULL_NAME": "", + "REPOSITORY_LINK": "", + "REPOSITORY_NAME": "", + "REPOSITORY_ORG": "", + "REPOSITORY_PRIVATE": "false", + "REPOSITORY_TIMEOUT": "0", + "REPOSITORY_TRUSTED": "false", + "REPOSITORY_VISIBILITY": "", + "VELA": "true", + "VELA_ADDR": "TODO", + "VELA_BUILD_APPROVED_AT": "0", + "VELA_BUILD_APPROVED_BY": "", + "VELA_BUILD_AUTHOR": "", + "VELA_BUILD_AUTHOR_EMAIL": "", + "VELA_BUILD_BASE_REF": "", + "VELA_BUILD_BRANCH": "", + "VELA_BUILD_CHANNEL": "TODO", + "VELA_BUILD_CLONE": "", + "VELA_BUILD_COMMIT": "", + "VELA_BUILD_CREATED": "0", + "VELA_BUILD_DISTRIBUTION": "", + "VELA_BUILD_ENQUEUED": "0", + "VELA_BUILD_EVENT": "", + "VELA_BUILD_EVENT_ACTION": "", + "VELA_BUILD_HOST": "", + "VELA_BUILD_LINK": "", + "VELA_BUILD_MESSAGE": "", + "VELA_BUILD_NUMBER": "0", + "VELA_BUILD_PARENT": "0", + "VELA_BUILD_REF": "", + "VELA_BUILD_RUNTIME": "", + "VELA_BUILD_SENDER": "", + "VELA_BUILD_SOURCE": "", + "VELA_BUILD_STARTED": "0", + "VELA_BUILD_STATUS": "", + "VELA_BUILD_TITLE": "", + "VELA_BUILD_WORKSPACE": "/vela/src", + "VELA_CHANNEL": "TODO", + "VELA_DATABASE": "TODO", + "VELA_DISTRIBUTION": "TODO", + "VELA_HOST": "TODO", + "VELA_NETRC_MACHINE": "TODO", + "VELA_NETRC_PASSWORD": "", + "VELA_NETRC_USERNAME": "x-oauth-basic", + "VELA_QUEUE": "TODO", + "VELA_REPO_ACTIVE": "false", + "VELA_REPO_ALLOW_EVENTS": "", + "VELA_REPO_APPROVE_BUILD": "", + "VELA_REPO_BRANCH": "", + "VELA_REPO_TOPICS": "", + "VELA_REPO_BUILD_LIMIT": "0", + "VELA_REPO_CLONE": "", + "VELA_REPO_FULL_NAME": "", + "VELA_REPO_LINK": "", + "VELA_REPO_NAME": "", + "VELA_REPO_ORG": "", + "VELA_REPO_PIPELINE_TYPE": "", + "VELA_REPO_PRIVATE": "false", + "VELA_REPO_TIMEOUT": "0", + "VELA_REPO_TRUSTED": "false", + "VELA_REPO_VISIBILITY": "", + "VELA_RUNTIME": "TODO", + "VELA_SOURCE": "TODO", + "VELA_USER_ACTIVE": "false", + "VELA_USER_ADMIN": "false", + "VELA_USER_FAVORITES": "[]", + "VELA_USER_NAME": "", + "VELA_VERSION": "TODO", + "VELA_WORKSPACE": "/vela/src", + "HELLO": "Hello, Stage Message", }, }, } @@ -287,113 +277,103 @@ func TestNative_EnvironmentServices(t *testing.T) { Name: str, Pull: "always", Environment: raw.StringSliceMap{ - "BUILD_AUTHOR": "", - "BUILD_AUTHOR_EMAIL": "", - "BUILD_BASE_REF": "", - "BUILD_BRANCH": "", - "BUILD_CHANNEL": "TODO", - "BUILD_CLONE": "", - "BUILD_COMMIT": "", - "BUILD_CREATED": "0", - "BUILD_ENQUEUED": "0", - "BUILD_EVENT": "", - "BUILD_HOST": "", - "BUILD_LINK": "", - "BUILD_MESSAGE": "", - "BUILD_NUMBER": "0", - "BUILD_PARENT": "0", - "BUILD_REF": "", - "BUILD_SENDER": "", - "BUILD_SOURCE": "", - "BUILD_STARTED": "0", - "BUILD_STATUS": "", - "BUILD_TITLE": "", - "BUILD_WORKSPACE": "/vela/src", - "CI": "true", - "REPOSITORY_ACTIVE": "false", - "REPOSITORY_ALLOW_COMMENT": "false", - "REPOSITORY_ALLOW_DEPLOY": "false", - "REPOSITORY_ALLOW_PULL": "false", - "REPOSITORY_ALLOW_PUSH": "false", - "REPOSITORY_ALLOW_TAG": "false", - "REPOSITORY_ALLOW_EVENTS": "", - "REPOSITORY_BRANCH": "", - "REPOSITORY_CLONE": "", - "REPOSITORY_FULL_NAME": "", - "REPOSITORY_LINK": "", - "REPOSITORY_NAME": "", - "REPOSITORY_ORG": "", - "REPOSITORY_PRIVATE": "false", - "REPOSITORY_TIMEOUT": "0", - "REPOSITORY_TRUSTED": "false", - "REPOSITORY_VISIBILITY": "", - "VELA": "true", - "VELA_ADDR": "TODO", - "VELA_BUILD_APPROVED_AT": "0", - "VELA_BUILD_APPROVED_BY": "", - "VELA_BUILD_AUTHOR": "", - "VELA_BUILD_AUTHOR_EMAIL": "", - "VELA_BUILD_BASE_REF": "", - "VELA_BUILD_BRANCH": "", - "VELA_BUILD_CHANNEL": "TODO", - "VELA_BUILD_CLONE": "", - "VELA_BUILD_COMMIT": "", - "VELA_BUILD_CREATED": "0", - "VELA_BUILD_DISTRIBUTION": "", - "VELA_BUILD_ENQUEUED": "0", - "VELA_BUILD_EVENT": "", - "VELA_BUILD_EVENT_ACTION": "", - "VELA_BUILD_HOST": "", - "VELA_BUILD_LINK": "", - "VELA_BUILD_MESSAGE": "", - "VELA_BUILD_NUMBER": "0", - "VELA_BUILD_PARENT": "0", - "VELA_BUILD_REF": "", - "VELA_BUILD_RUNTIME": "", - "VELA_BUILD_SENDER": "", - "VELA_BUILD_SOURCE": "", - "VELA_BUILD_STARTED": "0", - "VELA_BUILD_STATUS": "", - "VELA_BUILD_TITLE": "", - "VELA_BUILD_WORKSPACE": "/vela/src", - "VELA_CHANNEL": "TODO", - "VELA_DATABASE": "TODO", - "VELA_DISTRIBUTION": "TODO", - "VELA_HOST": "TODO", - "VELA_NETRC_MACHINE": "TODO", - "VELA_NETRC_PASSWORD": "", - "VELA_NETRC_USERNAME": "x-oauth-basic", - "VELA_QUEUE": "TODO", - "VELA_REPO_ACTIVE": "false", - "VELA_REPO_ALLOW_COMMENT": "false", - "VELA_REPO_ALLOW_DEPLOY": "false", - "VELA_REPO_ALLOW_PULL": "false", - "VELA_REPO_ALLOW_PUSH": "false", - "VELA_REPO_ALLOW_TAG": "false", - "VELA_REPO_ALLOW_EVENTS": "", - "VELA_REPO_APPROVE_BUILD": "", - "VELA_REPO_BRANCH": "", - "VELA_REPO_TOPICS": "", - "VELA_REPO_BUILD_LIMIT": "0", - "VELA_REPO_CLONE": "", - "VELA_REPO_FULL_NAME": "", - "VELA_REPO_LINK": "", - "VELA_REPO_NAME": "", - "VELA_REPO_ORG": "", - "VELA_REPO_PIPELINE_TYPE": "", - "VELA_REPO_PRIVATE": "false", - "VELA_REPO_TIMEOUT": "0", - "VELA_REPO_TRUSTED": "false", - "VELA_REPO_VISIBILITY": "", - "VELA_RUNTIME": "TODO", - "VELA_SOURCE": "TODO", - "VELA_USER_ACTIVE": "false", - "VELA_USER_ADMIN": "false", - "VELA_USER_FAVORITES": "[]", - "VELA_USER_NAME": "", - "VELA_VERSION": "TODO", - "VELA_WORKSPACE": "/vela/src", - "HELLO": "Hello, Global Message", + "BUILD_AUTHOR": "", + "BUILD_AUTHOR_EMAIL": "", + "BUILD_BASE_REF": "", + "BUILD_BRANCH": "", + "BUILD_CHANNEL": "TODO", + "BUILD_CLONE": "", + "BUILD_COMMIT": "", + "BUILD_CREATED": "0", + "BUILD_ENQUEUED": "0", + "BUILD_EVENT": "", + "BUILD_HOST": "", + "BUILD_LINK": "", + "BUILD_MESSAGE": "", + "BUILD_NUMBER": "0", + "BUILD_PARENT": "0", + "BUILD_REF": "", + "BUILD_SENDER": "", + "BUILD_SOURCE": "", + "BUILD_STARTED": "0", + "BUILD_STATUS": "", + "BUILD_TITLE": "", + "BUILD_WORKSPACE": "/vela/src", + "CI": "true", + "REPOSITORY_ACTIVE": "false", + "REPOSITORY_ALLOW_EVENTS": "", + "REPOSITORY_BRANCH": "", + "REPOSITORY_CLONE": "", + "REPOSITORY_FULL_NAME": "", + "REPOSITORY_LINK": "", + "REPOSITORY_NAME": "", + "REPOSITORY_ORG": "", + "REPOSITORY_PRIVATE": "false", + "REPOSITORY_TIMEOUT": "0", + "REPOSITORY_TRUSTED": "false", + "REPOSITORY_VISIBILITY": "", + "VELA": "true", + "VELA_ADDR": "TODO", + "VELA_BUILD_APPROVED_AT": "0", + "VELA_BUILD_APPROVED_BY": "", + "VELA_BUILD_AUTHOR": "", + "VELA_BUILD_AUTHOR_EMAIL": "", + "VELA_BUILD_BASE_REF": "", + "VELA_BUILD_BRANCH": "", + "VELA_BUILD_CHANNEL": "TODO", + "VELA_BUILD_CLONE": "", + "VELA_BUILD_COMMIT": "", + "VELA_BUILD_CREATED": "0", + "VELA_BUILD_DISTRIBUTION": "", + "VELA_BUILD_ENQUEUED": "0", + "VELA_BUILD_EVENT": "", + "VELA_BUILD_EVENT_ACTION": "", + "VELA_BUILD_HOST": "", + "VELA_BUILD_LINK": "", + "VELA_BUILD_MESSAGE": "", + "VELA_BUILD_NUMBER": "0", + "VELA_BUILD_PARENT": "0", + "VELA_BUILD_REF": "", + "VELA_BUILD_RUNTIME": "", + "VELA_BUILD_SENDER": "", + "VELA_BUILD_SOURCE": "", + "VELA_BUILD_STARTED": "0", + "VELA_BUILD_STATUS": "", + "VELA_BUILD_TITLE": "", + "VELA_BUILD_WORKSPACE": "/vela/src", + "VELA_CHANNEL": "TODO", + "VELA_DATABASE": "TODO", + "VELA_DISTRIBUTION": "TODO", + "VELA_HOST": "TODO", + "VELA_NETRC_MACHINE": "TODO", + "VELA_NETRC_PASSWORD": "", + "VELA_NETRC_USERNAME": "x-oauth-basic", + "VELA_QUEUE": "TODO", + "VELA_REPO_ACTIVE": "false", + "VELA_REPO_ALLOW_EVENTS": "", + "VELA_REPO_APPROVE_BUILD": "", + "VELA_REPO_BRANCH": "", + "VELA_REPO_TOPICS": "", + "VELA_REPO_BUILD_LIMIT": "0", + "VELA_REPO_CLONE": "", + "VELA_REPO_FULL_NAME": "", + "VELA_REPO_LINK": "", + "VELA_REPO_NAME": "", + "VELA_REPO_ORG": "", + "VELA_REPO_PIPELINE_TYPE": "", + "VELA_REPO_PRIVATE": "false", + "VELA_REPO_TIMEOUT": "0", + "VELA_REPO_TRUSTED": "false", + "VELA_REPO_VISIBILITY": "", + "VELA_RUNTIME": "TODO", + "VELA_SOURCE": "TODO", + "VELA_USER_ACTIVE": "false", + "VELA_USER_ADMIN": "false", + "VELA_USER_FAVORITES": "[]", + "VELA_USER_NAME": "", + "VELA_VERSION": "TODO", + "VELA_WORKSPACE": "/vela/src", + "HELLO": "Hello, Global Message", }, }, } @@ -452,114 +432,104 @@ func TestNative_EnvironmentSecrets(t *testing.T) { "foo": "bar", }, Environment: raw.StringSliceMap{ - "BUILD_AUTHOR": "", - "BUILD_AUTHOR_EMAIL": "", - "BUILD_BASE_REF": "", - "BUILD_BRANCH": "", - "BUILD_CHANNEL": "TODO", - "BUILD_CLONE": "", - "BUILD_COMMIT": "", - "BUILD_CREATED": "0", - "BUILD_ENQUEUED": "0", - "BUILD_EVENT": "", - "BUILD_HOST": "", - "BUILD_LINK": "", - "BUILD_MESSAGE": "", - "BUILD_NUMBER": "0", - "BUILD_PARENT": "0", - "BUILD_REF": "", - "BUILD_SENDER": "", - "BUILD_SOURCE": "", - "BUILD_STARTED": "0", - "BUILD_STATUS": "", - "BUILD_TITLE": "", - "BUILD_WORKSPACE": "/vela/src", - "CI": "true", - "PARAMETER_FOO": "bar", - "REPOSITORY_ACTIVE": "false", - "REPOSITORY_ALLOW_COMMENT": "false", - "REPOSITORY_ALLOW_DEPLOY": "false", - "REPOSITORY_ALLOW_PULL": "false", - "REPOSITORY_ALLOW_PUSH": "false", - "REPOSITORY_ALLOW_TAG": "false", - "REPOSITORY_ALLOW_EVENTS": "", - "REPOSITORY_BRANCH": "", - "REPOSITORY_CLONE": "", - "REPOSITORY_FULL_NAME": "", - "REPOSITORY_LINK": "", - "REPOSITORY_NAME": "", - "REPOSITORY_ORG": "", - "REPOSITORY_PRIVATE": "false", - "REPOSITORY_TIMEOUT": "0", - "REPOSITORY_TRUSTED": "false", - "REPOSITORY_VISIBILITY": "", - "VELA": "true", - "VELA_ADDR": "TODO", - "VELA_BUILD_APPROVED_AT": "0", - "VELA_BUILD_APPROVED_BY": "", - "VELA_BUILD_AUTHOR": "", - "VELA_BUILD_AUTHOR_EMAIL": "", - "VELA_BUILD_BASE_REF": "", - "VELA_BUILD_BRANCH": "", - "VELA_BUILD_CHANNEL": "TODO", - "VELA_BUILD_CLONE": "", - "VELA_BUILD_COMMIT": "", - "VELA_BUILD_CREATED": "0", - "VELA_BUILD_DISTRIBUTION": "", - "VELA_BUILD_ENQUEUED": "0", - "VELA_BUILD_EVENT": "", - "VELA_BUILD_EVENT_ACTION": "", - "VELA_BUILD_HOST": "", - "VELA_BUILD_LINK": "", - "VELA_BUILD_MESSAGE": "", - "VELA_BUILD_NUMBER": "0", - "VELA_BUILD_PARENT": "0", - "VELA_BUILD_REF": "", - "VELA_BUILD_RUNTIME": "", - "VELA_BUILD_SENDER": "", - "VELA_BUILD_SOURCE": "", - "VELA_BUILD_STARTED": "0", - "VELA_BUILD_STATUS": "", - "VELA_BUILD_TITLE": "", - "VELA_BUILD_WORKSPACE": "/vela/src", - "VELA_CHANNEL": "TODO", - "VELA_DATABASE": "TODO", - "VELA_DISTRIBUTION": "TODO", - "VELA_HOST": "TODO", - "VELA_NETRC_MACHINE": "TODO", - "VELA_NETRC_PASSWORD": "", - "VELA_NETRC_USERNAME": "x-oauth-basic", - "VELA_QUEUE": "TODO", - "VELA_REPO_ACTIVE": "false", - "VELA_REPO_ALLOW_COMMENT": "false", - "VELA_REPO_ALLOW_DEPLOY": "false", - "VELA_REPO_ALLOW_PULL": "false", - "VELA_REPO_ALLOW_PUSH": "false", - "VELA_REPO_ALLOW_TAG": "false", - "VELA_REPO_ALLOW_EVENTS": "", - "VELA_REPO_APPROVE_BUILD": "", - "VELA_REPO_BRANCH": "", - "VELA_REPO_TOPICS": "", - "VELA_REPO_BUILD_LIMIT": "0", - "VELA_REPO_CLONE": "", - "VELA_REPO_FULL_NAME": "", - "VELA_REPO_LINK": "", - "VELA_REPO_NAME": "", - "VELA_REPO_ORG": "", - "VELA_REPO_PIPELINE_TYPE": "", - "VELA_REPO_PRIVATE": "false", - "VELA_REPO_TIMEOUT": "0", - "VELA_REPO_TRUSTED": "false", - "VELA_REPO_VISIBILITY": "", - "VELA_RUNTIME": "TODO", - "VELA_SOURCE": "TODO", - "VELA_USER_ACTIVE": "false", - "VELA_USER_ADMIN": "false", - "VELA_USER_FAVORITES": "[]", - "VELA_USER_NAME": "", - "VELA_VERSION": "TODO", - "VELA_WORKSPACE": "/vela/src", - "HELLO": "Hello, Global Message", + "BUILD_AUTHOR": "", + "BUILD_AUTHOR_EMAIL": "", + "BUILD_BASE_REF": "", + "BUILD_BRANCH": "", + "BUILD_CHANNEL": "TODO", + "BUILD_CLONE": "", + "BUILD_COMMIT": "", + "BUILD_CREATED": "0", + "BUILD_ENQUEUED": "0", + "BUILD_EVENT": "", + "BUILD_HOST": "", + "BUILD_LINK": "", + "BUILD_MESSAGE": "", + "BUILD_NUMBER": "0", + "BUILD_PARENT": "0", + "BUILD_REF": "", + "BUILD_SENDER": "", + "BUILD_SOURCE": "", + "BUILD_STARTED": "0", + "BUILD_STATUS": "", + "BUILD_TITLE": "", + "BUILD_WORKSPACE": "/vela/src", + "CI": "true", + "PARAMETER_FOO": "bar", + "REPOSITORY_ACTIVE": "false", + "REPOSITORY_ALLOW_EVENTS": "", + "REPOSITORY_BRANCH": "", + "REPOSITORY_CLONE": "", + "REPOSITORY_FULL_NAME": "", + "REPOSITORY_LINK": "", + "REPOSITORY_NAME": "", + "REPOSITORY_ORG": "", + "REPOSITORY_PRIVATE": "false", + "REPOSITORY_TIMEOUT": "0", + "REPOSITORY_TRUSTED": "false", + "REPOSITORY_VISIBILITY": "", + "VELA": "true", + "VELA_ADDR": "TODO", + "VELA_BUILD_APPROVED_AT": "0", + "VELA_BUILD_APPROVED_BY": "", + "VELA_BUILD_AUTHOR": "", + "VELA_BUILD_AUTHOR_EMAIL": "", + "VELA_BUILD_BASE_REF": "", + "VELA_BUILD_BRANCH": "", + "VELA_BUILD_CHANNEL": "TODO", + "VELA_BUILD_CLONE": "", + "VELA_BUILD_COMMIT": "", + "VELA_BUILD_CREATED": "0", + "VELA_BUILD_DISTRIBUTION": "", + "VELA_BUILD_ENQUEUED": "0", + "VELA_BUILD_EVENT": "", + "VELA_BUILD_EVENT_ACTION": "", + "VELA_BUILD_HOST": "", + "VELA_BUILD_LINK": "", + "VELA_BUILD_MESSAGE": "", + "VELA_BUILD_NUMBER": "0", + "VELA_BUILD_PARENT": "0", + "VELA_BUILD_REF": "", + "VELA_BUILD_RUNTIME": "", + "VELA_BUILD_SENDER": "", + "VELA_BUILD_SOURCE": "", + "VELA_BUILD_STARTED": "0", + "VELA_BUILD_STATUS": "", + "VELA_BUILD_TITLE": "", + "VELA_BUILD_WORKSPACE": "/vela/src", + "VELA_CHANNEL": "TODO", + "VELA_DATABASE": "TODO", + "VELA_DISTRIBUTION": "TODO", + "VELA_HOST": "TODO", + "VELA_NETRC_MACHINE": "TODO", + "VELA_NETRC_PASSWORD": "", + "VELA_NETRC_USERNAME": "x-oauth-basic", + "VELA_QUEUE": "TODO", + "VELA_REPO_ACTIVE": "false", + "VELA_REPO_ALLOW_EVENTS": "", + "VELA_REPO_APPROVE_BUILD": "", + "VELA_REPO_BRANCH": "", + "VELA_REPO_TOPICS": "", + "VELA_REPO_BUILD_LIMIT": "0", + "VELA_REPO_CLONE": "", + "VELA_REPO_FULL_NAME": "", + "VELA_REPO_LINK": "", + "VELA_REPO_NAME": "", + "VELA_REPO_ORG": "", + "VELA_REPO_PIPELINE_TYPE": "", + "VELA_REPO_PRIVATE": "false", + "VELA_REPO_TIMEOUT": "0", + "VELA_REPO_TRUSTED": "false", + "VELA_REPO_VISIBILITY": "", + "VELA_RUNTIME": "TODO", + "VELA_SOURCE": "TODO", + "VELA_USER_ACTIVE": "false", + "VELA_USER_ADMIN": "false", + "VELA_USER_FAVORITES": "[]", + "VELA_USER_NAME": "", + "VELA_VERSION": "TODO", + "VELA_WORKSPACE": "/vela/src", + "HELLO": "Hello, Global Message", }, }, }, @@ -576,7 +546,7 @@ func TestNative_EnvironmentSecrets(t *testing.T) { t.Errorf("EnvironmentSecrets returned err: %v", err) } - if diff := cmp.Diff(got, want); diff != "" { + if diff := cmp.Diff(want, got); diff != "" { t.Errorf("EnvironmentSecrets mismatch (-want +got):\n%s", diff) } } @@ -615,36 +585,36 @@ func TestNative_environment(t *testing.T) { w: workspace, b: &library.Build{ID: &num64, RepoID: &num64, Number: &num, Parent: &num, Event: &push, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &str, BaseRef: &str}, m: &types.Metadata{Database: &types.Database{Driver: str, Host: str}, Queue: &types.Queue{Channel: str, Driver: str, Host: str}, Source: &types.Source{Driver: str, Host: str}, Vela: &types.Vela{Address: str, WebAddress: str}}, - r: &library.Repo{ID: &num64, UserID: &num64, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL, AllowPull: &booL, AllowPush: &booL, AllowDeploy: &booL, AllowTag: &booL, AllowComment: &booL}, + r: &library.Repo{ID: &num64, UserID: &num64, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, u: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, - want: map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "push", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "foo", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_COMMENT": "false", "REPOSITORY_ALLOW_DEPLOY": "false", "REPOSITORY_ALLOW_PULL": "false", "REPOSITORY_ALLOW_PUSH": "false", "REPOSITORY_ALLOW_TAG": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "push", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "foo", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_COMMENT": "false", "VELA_REPO_ALLOW_DEPLOY": "false", "VELA_REPO_ALLOW_PULL": "false", "VELA_REPO_ALLOW_PUSH": "false", "VELA_REPO_ALLOW_TAG": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, + want: map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "push", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "foo", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "push", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "foo", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, }, // tag { w: workspace, b: &library.Build{ID: &num64, RepoID: &num64, Number: &num, Parent: &num, Event: &tag, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &tagref, BaseRef: &str}, m: &types.Metadata{Database: &types.Database{Driver: str, Host: str}, Queue: &types.Queue{Channel: str, Driver: str, Host: str}, Source: &types.Source{Driver: str, Host: str}, Vela: &types.Vela{Address: str, WebAddress: str}}, - r: &library.Repo{ID: &num64, UserID: &num64, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL, AllowPull: &booL, AllowPush: &booL, AllowDeploy: &booL, AllowTag: &booL, AllowComment: &booL}, + r: &library.Repo{ID: &num64, UserID: &num64, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, u: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, - want: map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "tag", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "refs/tags/1", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TAG": "1", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_COMMENT": "false", "REPOSITORY_ALLOW_DEPLOY": "false", "REPOSITORY_ALLOW_PULL": "false", "REPOSITORY_ALLOW_PUSH": "false", "REPOSITORY_ALLOW_TAG": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "tag", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "refs/tags/1", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TAG": "1", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_COMMENT": "false", "VELA_REPO_ALLOW_DEPLOY": "false", "VELA_REPO_ALLOW_PULL": "false", "VELA_REPO_ALLOW_PUSH": "false", "VELA_REPO_ALLOW_TAG": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, + want: map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "tag", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "refs/tags/1", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TAG": "1", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "tag", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "refs/tags/1", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TAG": "1", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, }, // pull_request { w: workspace, b: &library.Build{ID: &num64, RepoID: &num64, Number: &num, Parent: &num, Event: &pull, EventAction: &pullact, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &pullref, BaseRef: &str}, m: &types.Metadata{Database: &types.Database{Driver: str, Host: str}, Queue: &types.Queue{Channel: str, Driver: str, Host: str}, Source: &types.Source{Driver: str, Host: str}, Vela: &types.Vela{Address: str, WebAddress: str}}, - r: &library.Repo{ID: &num64, UserID: &num64, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL, AllowPull: &booL, AllowPush: &booL, AllowDeploy: &booL, AllowTag: &booL, AllowComment: &booL}, + r: &library.Repo{ID: &num64, UserID: &num64, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, u: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, - want: map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "pull_request", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_PULL_REQUEST_NUMBER": "1", "BUILD_REF": "refs/pull/1/head", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_COMMENT": "false", "REPOSITORY_ALLOW_DEPLOY": "false", "REPOSITORY_ALLOW_PULL": "false", "REPOSITORY_ALLOW_PUSH": "false", "REPOSITORY_ALLOW_TAG": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "pull_request", "VELA_BUILD_EVENT_ACTION": "opened", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_PULL_REQUEST": "1", "VELA_BUILD_REF": "refs/pull/1/head", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_PULL_REQUEST": "1", "VELA_PULL_REQUEST_SOURCE": "", "VELA_PULL_REQUEST_TARGET": "foo", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_COMMENT": "false", "VELA_REPO_ALLOW_DEPLOY": "false", "VELA_REPO_ALLOW_PULL": "false", "VELA_REPO_ALLOW_PUSH": "false", "VELA_REPO_ALLOW_TAG": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, + want: map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "pull_request", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_PULL_REQUEST_NUMBER": "1", "BUILD_REF": "refs/pull/1/head", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "pull_request", "VELA_BUILD_EVENT_ACTION": "opened", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_PULL_REQUEST": "1", "VELA_BUILD_REF": "refs/pull/1/head", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_PULL_REQUEST": "1", "VELA_PULL_REQUEST_SOURCE": "", "VELA_PULL_REQUEST_TARGET": "foo", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, }, // deployment { w: workspace, b: &library.Build{ID: &num64, RepoID: &num64, Number: &num, Parent: &num, Event: &deploy, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &target, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &pullref, BaseRef: &str}, m: &types.Metadata{Database: &types.Database{Driver: str, Host: str}, Queue: &types.Queue{Channel: str, Driver: str, Host: str}, Source: &types.Source{Driver: str, Host: str}, Vela: &types.Vela{Address: str, WebAddress: str}}, - r: &library.Repo{ID: &num64, UserID: &num64, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL, AllowPull: &booL, AllowPush: &booL, AllowDeploy: &booL, AllowTag: &booL, AllowComment: &booL}, + r: &library.Repo{ID: &num64, UserID: &num64, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, u: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, - want: map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "deployment", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "refs/pull/1/head", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TARGET": "production", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_COMMENT": "false", "REPOSITORY_ALLOW_DEPLOY": "false", "REPOSITORY_ALLOW_PULL": "false", "REPOSITORY_ALLOW_PUSH": "false", "REPOSITORY_ALLOW_TAG": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "deployment", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "refs/pull/1/head", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TARGET": "production", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DEPLOYMENT": "production", "VELA_DEPLOYMENT_NUMBER": "0", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_COMMENT": "false", "VELA_REPO_ALLOW_DEPLOY": "false", "VELA_REPO_ALLOW_PULL": "false", "VELA_REPO_ALLOW_PUSH": "false", "VELA_REPO_ALLOW_TAG": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, + want: map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "deployment", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "refs/pull/1/head", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TARGET": "production", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "deployment", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "refs/pull/1/head", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TARGET": "production", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DEPLOYMENT": "production", "VELA_DEPLOYMENT_NUMBER": "0", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, }, } @@ -731,29 +701,29 @@ func Test_client_EnvironmentBuild(t *testing.T) { {"push", fields{ build: &library.Build{ID: &num64, RepoID: &num64, Number: &num, Parent: &num, Event: &push, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &str, BaseRef: &str}, metadata: &types.Metadata{Database: &types.Database{Driver: str, Host: str}, Queue: &types.Queue{Channel: str, Driver: str, Host: str}, Source: &types.Source{Driver: str, Host: str}, Vela: &types.Vela{Address: str, WebAddress: str}}, - repo: &library.Repo{ID: &num64, UserID: &num64, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL, AllowPull: &booL, AllowPush: &booL, AllowDeploy: &booL, AllowTag: &booL, AllowComment: &booL}, + repo: &library.Repo{ID: &num64, UserID: &num64, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, user: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, - }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "push", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "foo", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_COMMENT": "false", "REPOSITORY_ALLOW_DEPLOY": "false", "REPOSITORY_ALLOW_PULL": "false", "REPOSITORY_ALLOW_PUSH": "false", "REPOSITORY_ALLOW_TAG": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "push", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "foo", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_COMMENT": "false", "VELA_REPO_ALLOW_DEPLOY": "false", "VELA_REPO_ALLOW_PULL": "false", "VELA_REPO_ALLOW_PUSH": "false", "VELA_REPO_ALLOW_TAG": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}}, + }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "push", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "foo", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "push", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "foo", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}}, {"tag", fields{ build: &library.Build{ID: &num64, RepoID: &num64, Number: &num, Parent: &num, Event: &tag, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &tagref, BaseRef: &str}, metadata: &types.Metadata{Database: &types.Database{Driver: str, Host: str}, Queue: &types.Queue{Channel: str, Driver: str, Host: str}, Source: &types.Source{Driver: str, Host: str}, Vela: &types.Vela{Address: str, WebAddress: str}}, - repo: &library.Repo{ID: &num64, UserID: &num64, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL, AllowPull: &booL, AllowPush: &booL, AllowDeploy: &booL, AllowTag: &booL, AllowComment: &booL}, + repo: &library.Repo{ID: &num64, UserID: &num64, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, user: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, - }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "tag", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "refs/tags/1", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TAG": "1", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_COMMENT": "false", "REPOSITORY_ALLOW_DEPLOY": "false", "REPOSITORY_ALLOW_PULL": "false", "REPOSITORY_ALLOW_PUSH": "false", "REPOSITORY_ALLOW_TAG": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "tag", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "refs/tags/1", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TAG": "1", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_COMMENT": "false", "VELA_REPO_ALLOW_DEPLOY": "false", "VELA_REPO_ALLOW_PULL": "false", "VELA_REPO_ALLOW_PUSH": "false", "VELA_REPO_ALLOW_TAG": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, + }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "tag", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "refs/tags/1", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TAG": "1", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "tag", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "refs/tags/1", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TAG": "1", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, }, {"pull_request", fields{ build: &library.Build{ID: &num64, RepoID: &num64, Number: &num, Parent: &num, Event: &pull, EventAction: &pullact, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &pullref, BaseRef: &str}, metadata: &types.Metadata{Database: &types.Database{Driver: str, Host: str}, Queue: &types.Queue{Channel: str, Driver: str, Host: str}, Source: &types.Source{Driver: str, Host: str}, Vela: &types.Vela{Address: str, WebAddress: str}}, - repo: &library.Repo{ID: &num64, UserID: &num64, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL, AllowPull: &booL, AllowPush: &booL, AllowDeploy: &booL, AllowTag: &booL, AllowComment: &booL}, + repo: &library.Repo{ID: &num64, UserID: &num64, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, user: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, - }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "pull_request", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_PULL_REQUEST_NUMBER": "1", "BUILD_REF": "refs/pull/1/head", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_COMMENT": "false", "REPOSITORY_ALLOW_DEPLOY": "false", "REPOSITORY_ALLOW_PULL": "false", "REPOSITORY_ALLOW_PUSH": "false", "REPOSITORY_ALLOW_TAG": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "pull_request", "VELA_BUILD_EVENT_ACTION": "opened", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_PULL_REQUEST": "1", "VELA_BUILD_REF": "refs/pull/1/head", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_PULL_REQUEST": "1", "VELA_PULL_REQUEST_SOURCE": "", "VELA_PULL_REQUEST_TARGET": "foo", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_COMMENT": "false", "VELA_REPO_ALLOW_DEPLOY": "false", "VELA_REPO_ALLOW_PULL": "false", "VELA_REPO_ALLOW_PUSH": "false", "VELA_REPO_ALLOW_TAG": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, + }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "pull_request", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_PULL_REQUEST_NUMBER": "1", "BUILD_REF": "refs/pull/1/head", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "pull_request", "VELA_BUILD_EVENT_ACTION": "opened", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_PULL_REQUEST": "1", "VELA_BUILD_REF": "refs/pull/1/head", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_PULL_REQUEST": "1", "VELA_PULL_REQUEST_SOURCE": "", "VELA_PULL_REQUEST_TARGET": "foo", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, }, {"deployment", fields{ build: &library.Build{ID: &num64, RepoID: &num64, Number: &num, Parent: &num, Event: &deploy, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &target, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &pullref, BaseRef: &str}, metadata: &types.Metadata{Database: &types.Database{Driver: str, Host: str}, Queue: &types.Queue{Channel: str, Driver: str, Host: str}, Source: &types.Source{Driver: str, Host: str}, Vela: &types.Vela{Address: str, WebAddress: str}}, - repo: &library.Repo{ID: &num64, UserID: &num64, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL, AllowPull: &booL, AllowPush: &booL, AllowDeploy: &booL, AllowTag: &booL, AllowComment: &booL}, + repo: &library.Repo{ID: &num64, UserID: &num64, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, user: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, - }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "deployment", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "refs/pull/1/head", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TARGET": "production", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_COMMENT": "false", "REPOSITORY_ALLOW_DEPLOY": "false", "REPOSITORY_ALLOW_PULL": "false", "REPOSITORY_ALLOW_PUSH": "false", "REPOSITORY_ALLOW_TAG": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "deployment", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "refs/pull/1/head", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TARGET": "production", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DEPLOYMENT": "production", "VELA_DEPLOYMENT_NUMBER": "0", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_COMMENT": "false", "VELA_REPO_ALLOW_DEPLOY": "false", "VELA_REPO_ALLOW_PULL": "false", "VELA_REPO_ALLOW_PUSH": "false", "VELA_REPO_ALLOW_TAG": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, + }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "deployment", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "refs/pull/1/head", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TARGET": "production", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "deployment", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "refs/pull/1/head", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TARGET": "production", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DEPLOYMENT": "production", "VELA_DEPLOYMENT_NUMBER": "0", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, }, } for _, tt := range tests { diff --git a/database/build/build_test.go b/database/build/build_test.go index 2478b2ded..16910e5ac 100644 --- a/database/build/build_test.go +++ b/database/build/build_test.go @@ -261,11 +261,6 @@ func testRepo() *library.Repo { Private: new(bool), Trusted: new(bool), Active: new(bool), - AllowPull: new(bool), - AllowPush: new(bool), - AllowDeploy: new(bool), - AllowTag: new(bool), - AllowComment: new(bool), } } diff --git a/database/deployment/deployment_test.go b/database/deployment/deployment_test.go index 4421f4f9d..0184fbcce 100644 --- a/database/deployment/deployment_test.go +++ b/database/deployment/deployment_test.go @@ -208,10 +208,5 @@ func testRepo() *library.Repo { Private: new(bool), Trusted: new(bool), Active: new(bool), - AllowPull: new(bool), - AllowPush: new(bool), - AllowDeploy: new(bool), - AllowTag: new(bool), - AllowComment: new(bool), } } diff --git a/database/hook/hook_test.go b/database/hook/hook_test.go index 4aaeb6a93..fd358715f 100644 --- a/database/hook/hook_test.go +++ b/database/hook/hook_test.go @@ -207,10 +207,5 @@ func testRepo() *library.Repo { Private: new(bool), Trusted: new(bool), Active: new(bool), - AllowPull: new(bool), - AllowPush: new(bool), - AllowDeploy: new(bool), - AllowTag: new(bool), - AllowComment: new(bool), } } diff --git a/database/integration_test.go b/database/integration_test.go index ce35d1ec8..0bde55005 100644 --- a/database/integration_test.go +++ b/database/integration_test.go @@ -2239,11 +2239,6 @@ func newResources() *Resources { repoOne.SetPrivate(false) repoOne.SetTrusted(false) repoOne.SetActive(true) - repoOne.SetAllowPull(false) - repoOne.SetAllowPush(true) - repoOne.SetAllowDeploy(false) - repoOne.SetAllowTag(false) - repoOne.SetAllowComment(false) repoOne.SetPipelineType("") repoOne.SetPreviousName("") repoOne.SetApproveBuild(constants.ApproveNever) @@ -2267,11 +2262,6 @@ func newResources() *Resources { repoTwo.SetPrivate(false) repoTwo.SetTrusted(false) repoTwo.SetActive(true) - repoTwo.SetAllowPull(false) - repoTwo.SetAllowPush(true) - repoTwo.SetAllowDeploy(false) - repoTwo.SetAllowTag(false) - repoTwo.SetAllowComment(false) repoTwo.SetPipelineType("") repoTwo.SetPreviousName("") repoTwo.SetApproveBuild(constants.ApproveForkAlways) @@ -2312,7 +2302,6 @@ func newResources() *Resources { secretOrg.SetValue("bar") secretOrg.SetType("org") secretOrg.SetImages([]string{"alpine"}) - secretOrg.SetEvents([]string{"push", "tag", "deployment"}) secretOrg.SetAllowEvents(library.NewEventsFromMask(1)) secretOrg.SetAllowCommand(true) secretOrg.SetAllowSubstitution(true) @@ -2330,7 +2319,6 @@ func newResources() *Resources { secretRepo.SetValue("bar") secretRepo.SetType("repo") secretRepo.SetImages([]string{"alpine"}) - secretRepo.SetEvents([]string{"push", "tag", "deployment"}) secretRepo.SetAllowEvents(library.NewEventsFromMask(1)) secretRepo.SetAllowCommand(true) secretRepo.SetAllowSubstitution(true) @@ -2348,7 +2336,6 @@ func newResources() *Resources { secretShared.SetValue("bar") secretShared.SetType("shared") secretShared.SetImages([]string{"alpine"}) - secretShared.SetEvents([]string{"push", "tag", "deployment"}) secretShared.SetAllowCommand(true) secretShared.SetAllowSubstitution(true) secretShared.SetAllowEvents(library.NewEventsFromMask(1)) diff --git a/database/repo/create_test.go b/database/repo/create_test.go index 189622744..1a523b563 100644 --- a/database/repo/create_test.go +++ b/database/repo/create_test.go @@ -32,9 +32,9 @@ func TestRepo_Engine_CreateRepo(t *testing.T) { // ensure the mock expects the query _mock.ExpectQuery(`INSERT INTO "repos" -("user_id","hash","org","name","full_name","link","clone","branch","topics","build_limit","timeout","counter","visibility","private","trusted","active","allow_pull","allow_push","allow_deploy","allow_tag","allow_comment","allow_events","pipeline_type","previous_name","approve_build","id") -VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26) RETURNING "id"`). - WithArgs(1, AnyArgument{}, "foo", "bar", "foo/bar", nil, nil, nil, AnyArgument{}, AnyArgument{}, AnyArgument{}, AnyArgument{}, "public", false, false, false, false, false, false, false, false, nil, "yaml", "oldName", nil, 1). +("user_id","hash","org","name","full_name","link","clone","branch","topics","build_limit","timeout","counter","visibility","private","trusted","active","allow_events","pipeline_type","previous_name","approve_build","id") +VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21) RETURNING "id"`). + WithArgs(1, AnyArgument{}, "foo", "bar", "foo/bar", nil, nil, nil, AnyArgument{}, AnyArgument{}, AnyArgument{}, AnyArgument{}, "public", false, false, false, nil, "yaml", "oldName", nil, 1). WillReturnRows(_rows) _sqlite := testSqlite(t) diff --git a/database/repo/get_org_test.go b/database/repo/get_org_test.go index 95e6d6a32..db5b36314 100644 --- a/database/repo/get_org_test.go +++ b/database/repo/get_org_test.go @@ -30,8 +30,8 @@ func TestRepo_Engine_GetRepoForOrg(t *testing.T) { // create expected result in mock _rows := sqlmock.NewRows( - []string{"id", "user_id", "hash", "org", "name", "full_name", "link", "clone", "branch", "topics", "build_limit", "timeout", "counter", "visibility", "private", "trusted", "active", "allow_pull", "allow_push", "allow_deploy", "allow_tag", "allow_comment", "allow_events", "pipeline_type", "previous_name", "approve_build"}). - AddRow(1, 1, "baz", "foo", "bar", "foo/bar", "", "", "", "{}", 0, 0, 0, "public", false, false, false, false, false, false, false, false, 1, "yaml", "", "") + []string{"id", "user_id", "hash", "org", "name", "full_name", "link", "clone", "branch", "topics", "build_limit", "timeout", "counter", "visibility", "private", "trusted", "active", "allow_events", "pipeline_type", "previous_name", "approve_build"}). + AddRow(1, 1, "baz", "foo", "bar", "foo/bar", "", "", "", "{}", 0, 0, 0, "public", false, false, false, 1, "yaml", "", "") // ensure the mock expects the query _mock.ExpectQuery(`SELECT * FROM "repos" WHERE org = $1 AND name = $2 LIMIT $3`).WithArgs("foo", "bar", 1).WillReturnRows(_rows) diff --git a/database/repo/get_test.go b/database/repo/get_test.go index 7a4fcdba8..3957975d2 100644 --- a/database/repo/get_test.go +++ b/database/repo/get_test.go @@ -30,8 +30,8 @@ func TestRepo_Engine_GetRepo(t *testing.T) { // create expected result in mock _rows := sqlmock.NewRows( - []string{"id", "user_id", "hash", "org", "name", "full_name", "link", "clone", "branch", "topics", "build_limit", "timeout", "counter", "visibility", "private", "trusted", "active", "allow_pull", "allow_push", "allow_deploy", "allow_tag", "allow_comment", "allow_events", "pipeline_type", "previous_name", "approve_build"}). - AddRow(1, 1, "baz", "foo", "bar", "foo/bar", "", "", "", "{}", 0, 0, 0, "public", false, false, false, false, false, false, false, false, 1, "yaml", "", "") + []string{"id", "user_id", "hash", "org", "name", "full_name", "link", "clone", "branch", "topics", "build_limit", "timeout", "counter", "visibility", "private", "trusted", "active", "allow_events", "pipeline_type", "previous_name", "approve_build"}). + AddRow(1, 1, "baz", "foo", "bar", "foo/bar", "", "", "", "{}", 0, 0, 0, "public", false, false, false, 1, "yaml", "", "") // ensure the mock expects the query _mock.ExpectQuery(`SELECT * FROM "repos" WHERE id = $1 LIMIT $2`).WithArgs(1, 1).WillReturnRows(_rows) diff --git a/database/repo/list_org_test.go b/database/repo/list_org_test.go index 5d6bfb99f..e59e29d49 100644 --- a/database/repo/list_org_test.go +++ b/database/repo/list_org_test.go @@ -63,9 +63,9 @@ func TestRepo_Engine_ListReposForOrg(t *testing.T) { // create expected name query result in mock _rows = sqlmock.NewRows( - []string{"id", "user_id", "hash", "org", "name", "full_name", "link", "clone", "branch", "topics", "timeout", "counter", "visibility", "private", "trusted", "active", "allow_pull", "allow_push", "allow_deploy", "allow_tag", "allow_comment", "allow_events", "pipeline_type", "previous_name", "approve_build"}). - AddRow(1, 1, "baz", "foo", "bar", "foo/bar", "", "", "", "{}", 0, 0, "public", false, false, false, false, false, false, false, false, 1, "yaml", nil, nil). - AddRow(2, 1, "bar", "foo", "baz", "foo/baz", "", "", "", "{}", 0, 0, "public", false, false, false, false, false, false, false, false, 1, "yaml", nil, nil) + []string{"id", "user_id", "hash", "org", "name", "full_name", "link", "clone", "branch", "topics", "timeout", "counter", "visibility", "private", "trusted", "active", "allow_events", "pipeline_type", "previous_name", "approve_build"}). + AddRow(1, 1, "baz", "foo", "bar", "foo/bar", "", "", "", "{}", 0, 0, "public", false, false, false, 1, "yaml", nil, nil). + AddRow(2, 1, "bar", "foo", "baz", "foo/baz", "", "", "", "{}", 0, 0, "public", false, false, false, 1, "yaml", nil, nil) // ensure the mock expects the name query _mock.ExpectQuery(`SELECT * FROM "repos" WHERE org = $1 ORDER BY name LIMIT $2`).WithArgs("foo", 10).WillReturnRows(_rows) @@ -78,9 +78,9 @@ func TestRepo_Engine_ListReposForOrg(t *testing.T) { // create expected latest query result in mock _rows = sqlmock.NewRows( - []string{"id", "user_id", "hash", "org", "name", "full_name", "link", "clone", "branch", "topics", "timeout", "counter", "visibility", "private", "trusted", "active", "allow_pull", "allow_push", "allow_deploy", "allow_tag", "allow_comment", "allow_events", "pipeline_type", "previous_name", "approve_build"}). - AddRow(1, 1, "baz", "foo", "bar", "foo/bar", "", "", "", "{}", 0, 0, "public", false, false, false, false, false, false, false, false, 1, "yaml", nil, nil). - AddRow(2, 1, "bar", "foo", "baz", "foo/baz", "", "", "", "{}", 0, 0, "public", false, false, false, false, false, false, false, false, 1, "yaml", nil, nil) + []string{"id", "user_id", "hash", "org", "name", "full_name", "link", "clone", "branch", "topics", "timeout", "counter", "visibility", "private", "trusted", "active", "allow_events", "pipeline_type", "previous_name", "approve_build"}). + AddRow(1, 1, "baz", "foo", "bar", "foo/bar", "", "", "", "{}", 0, 0, "public", false, false, false, 1, "yaml", nil, nil). + AddRow(2, 1, "bar", "foo", "baz", "foo/baz", "", "", "", "{}", 0, 0, "public", false, false, false, 1, "yaml", nil, nil) // ensure the mock expects the latest query _mock.ExpectQuery(`SELECT repos.* FROM "repos" LEFT JOIN (SELECT repos.id, MAX(builds.created) AS latest_build FROM "builds" INNER JOIN repos repos ON builds.repo_id = repos.id WHERE repos.org = $1 GROUP BY "repos"."id") t on repos.id = t.id ORDER BY latest_build DESC NULLS LAST LIMIT $2`).WithArgs("foo", 10).WillReturnRows(_rows) diff --git a/database/repo/list_test.go b/database/repo/list_test.go index 793123257..7b3a5ff5e 100644 --- a/database/repo/list_test.go +++ b/database/repo/list_test.go @@ -48,9 +48,9 @@ func TestRepo_Engine_ListRepos(t *testing.T) { // create expected result in mock _rows = sqlmock.NewRows( - []string{"id", "user_id", "hash", "org", "name", "full_name", "link", "clone", "branch", "topics", "timeout", "counter", "visibility", "private", "trusted", "active", "allow_pull", "allow_push", "allow_deploy", "allow_tag", "allow_comment", "allow_events", "pipeline_type", "previous_name", "approve_build"}). - AddRow(1, 1, "baz", "foo", "bar", "foo/bar", "", "", "", "{}", 0, 0, "public", false, false, false, false, false, false, false, false, 1, "yaml", nil, nil). - AddRow(2, 1, "baz", "bar", "foo", "bar/foo", "", "", "", "{}", 0, 0, "public", false, false, false, false, false, false, false, false, 1, "yaml", nil, nil) + []string{"id", "user_id", "hash", "org", "name", "full_name", "link", "clone", "branch", "topics", "timeout", "counter", "visibility", "private", "trusted", "active", "allow_events", "pipeline_type", "previous_name", "approve_build"}). + AddRow(1, 1, "baz", "foo", "bar", "foo/bar", "", "", "", "{}", 0, 0, "public", false, false, false, 1, "yaml", nil, nil). + AddRow(2, 1, "baz", "bar", "foo", "bar/foo", "", "", "", "{}", 0, 0, "public", false, false, false, 1, "yaml", nil, nil) // ensure the mock expects the query _mock.ExpectQuery(`SELECT * FROM "repos"`).WillReturnRows(_rows) diff --git a/database/repo/list_user_test.go b/database/repo/list_user_test.go index a387c4e5a..30f6bc3b1 100644 --- a/database/repo/list_user_test.go +++ b/database/repo/list_user_test.go @@ -68,9 +68,9 @@ func TestRepo_Engine_ListReposForUser(t *testing.T) { // create expected name query result in mock _rows = sqlmock.NewRows( - []string{"id", "user_id", "hash", "org", "name", "full_name", "link", "clone", "branch", "topics", "timeout", "counter", "visibility", "private", "trusted", "active", "allow_pull", "allow_push", "allow_deploy", "allow_tag", "allow_comment", "allow_events", "pipeline_type", "previous_name", "approve_build"}). - AddRow(1, 1, "baz", "foo", "bar", "foo/bar", "", "", "", "{}", 0, 0, "public", false, false, false, false, false, false, false, false, 1, "yaml", nil, nil). - AddRow(2, 1, "baz", "bar", "foo", "bar/foo", "", "", "", "{}", 0, 0, "public", false, false, false, false, false, false, false, false, 1, "yaml", nil, nil) + []string{"id", "user_id", "hash", "org", "name", "full_name", "link", "clone", "branch", "topics", "timeout", "counter", "visibility", "private", "trusted", "active", "allow_events", "pipeline_type", "previous_name", "approve_build"}). + AddRow(1, 1, "baz", "foo", "bar", "foo/bar", "", "", "", "{}", 0, 0, "public", false, false, false, 1, "yaml", nil, nil). + AddRow(2, 1, "baz", "bar", "foo", "bar/foo", "", "", "", "{}", 0, 0, "public", false, false, false, 1, "yaml", nil, nil) // ensure the mock expects the name query _mock.ExpectQuery(`SELECT * FROM "repos" WHERE user_id = $1 ORDER BY name LIMIT $2`).WithArgs(1, 10).WillReturnRows(_rows) @@ -83,9 +83,9 @@ func TestRepo_Engine_ListReposForUser(t *testing.T) { // create expected latest query result in mock _rows = sqlmock.NewRows( - []string{"id", "user_id", "hash", "org", "name", "full_name", "link", "clone", "branch", "topics", "timeout", "counter", "visibility", "private", "trusted", "active", "allow_pull", "allow_push", "allow_deploy", "allow_tag", "allow_comment", "allow_events", "pipeline_type", "previous_name", "approve_build"}). - AddRow(1, 1, "baz", "foo", "bar", "foo/bar", "", "", "", "{}", 0, 0, "public", false, false, false, false, false, false, false, false, 1, "yaml", nil, nil). - AddRow(2, 1, "baz", "bar", "foo", "bar/foo", "", "", "", "{}", 0, 0, "public", false, false, false, false, false, false, false, false, 1, "yaml", nil, nil) + []string{"id", "user_id", "hash", "org", "name", "full_name", "link", "clone", "branch", "topics", "timeout", "counter", "visibility", "private", "trusted", "active", "allow_events", "pipeline_type", "previous_name", "approve_build"}). + AddRow(1, 1, "baz", "foo", "bar", "foo/bar", "", "", "", "{}", 0, 0, "public", false, false, false, 1, "yaml", nil, nil). + AddRow(2, 1, "baz", "bar", "foo", "bar/foo", "", "", "", "{}", 0, 0, "public", false, false, false, 1, "yaml", nil, nil) // ensure the mock expects the latest query _mock.ExpectQuery(`SELECT repos.* FROM "repos" LEFT JOIN (SELECT repos.id, MAX(builds.created) AS latest_build FROM "builds" INNER JOIN repos repos ON builds.repo_id = repos.id WHERE repos.user_id = $1 GROUP BY "repos"."id") t on repos.id = t.id ORDER BY latest_build DESC NULLS LAST LIMIT $2`).WithArgs(1, 10).WillReturnRows(_rows) diff --git a/database/repo/repo_test.go b/database/repo/repo_test.go index 597ef1623..325732a56 100644 --- a/database/repo/repo_test.go +++ b/database/repo/repo_test.go @@ -194,11 +194,6 @@ func testRepo() *library.Repo { Private: new(bool), Trusted: new(bool), Active: new(bool), - AllowPull: new(bool), - AllowPush: new(bool), - AllowDeploy: new(bool), - AllowTag: new(bool), - AllowComment: new(bool), AllowEvents: testEvents(), } } diff --git a/database/repo/table.go b/database/repo/table.go index e0f26a6c3..a7877d280 100644 --- a/database/repo/table.go +++ b/database/repo/table.go @@ -31,11 +31,6 @@ repos ( private BOOLEAN, trusted BOOLEAN, active BOOLEAN, - allow_pull BOOLEAN, - allow_push BOOLEAN, - allow_deploy BOOLEAN, - allow_tag BOOLEAN, - allow_comment BOOLEAN, allow_events INTEGER, pipeline_type TEXT, previous_name VARCHAR(100), @@ -66,11 +61,6 @@ repos ( private BOOLEAN, trusted BOOLEAN, active BOOLEAN, - allow_pull BOOLEAN, - allow_push BOOLEAN, - allow_deploy BOOLEAN, - allow_tag BOOLEAN, - allow_comment BOOLEAN, allow_events INTEGER, pipeline_type TEXT, previous_name TEXT, diff --git a/database/repo/update_test.go b/database/repo/update_test.go index bf791a30d..c7bca1d15 100644 --- a/database/repo/update_test.go +++ b/database/repo/update_test.go @@ -33,9 +33,9 @@ func TestRepo_Engine_UpdateRepo(t *testing.T) { // ensure the mock expects the query _mock.ExpectExec(`UPDATE "repos" -SET "user_id"=$1,"hash"=$2,"org"=$3,"name"=$4,"full_name"=$5,"link"=$6,"clone"=$7,"branch"=$8,"topics"=$9,"build_limit"=$10,"timeout"=$11,"counter"=$12,"visibility"=$13,"private"=$14,"trusted"=$15,"active"=$16,"allow_pull"=$17,"allow_push"=$18,"allow_deploy"=$19,"allow_tag"=$20,"allow_comment"=$21,"allow_events"=$22,"pipeline_type"=$23,"previous_name"=$24,"approve_build"=$25 -WHERE "id" = $26`). - WithArgs(1, AnyArgument{}, "foo", "bar", "foo/bar", nil, nil, nil, AnyArgument{}, AnyArgument{}, AnyArgument{}, AnyArgument{}, "public", false, false, false, false, false, false, false, false, 1, "yaml", "oldName", constants.ApproveForkAlways, 1). +SET "user_id"=$1,"hash"=$2,"org"=$3,"name"=$4,"full_name"=$5,"link"=$6,"clone"=$7,"branch"=$8,"topics"=$9,"build_limit"=$10,"timeout"=$11,"counter"=$12,"visibility"=$13,"private"=$14,"trusted"=$15,"active"=$16,"allow_events"=$17,"pipeline_type"=$18,"previous_name"=$19,"approve_build"=$20 +WHERE "id" = $21`). + WithArgs(1, AnyArgument{}, "foo", "bar", "foo/bar", nil, nil, nil, AnyArgument{}, AnyArgument{}, AnyArgument{}, AnyArgument{}, "public", false, false, false, 1, "yaml", "oldName", constants.ApproveForkAlways, 1). WillReturnResult(sqlmock.NewResult(1, 1)) _sqlite := testSqlite(t) diff --git a/database/schedule/schedule_test.go b/database/schedule/schedule_test.go index d676223a1..723c40aaa 100644 --- a/database/schedule/schedule_test.go +++ b/database/schedule/schedule_test.go @@ -210,11 +210,6 @@ func testRepo() *library.Repo { Private: new(bool), Trusted: new(bool), Active: new(bool), - AllowPull: new(bool), - AllowPush: new(bool), - AllowDeploy: new(bool), - AllowTag: new(bool), - AllowComment: new(bool), } } diff --git a/database/secret/create_test.go b/database/secret/create_test.go index eeec4c363..210a57b99 100644 --- a/database/secret/create_test.go +++ b/database/secret/create_test.go @@ -60,23 +60,23 @@ func TestSecret_Engine_CreateSecret(t *testing.T) { // ensure the mock expects the repo secrets query _mock.ExpectQuery(`INSERT INTO "secrets" -("org","repo","team","name","value","type","images","events","allow_events","allow_command","allow_substitution","created_at","created_by","updated_at","updated_by","id") -VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16) RETURNING "id"`). - WithArgs("foo", "bar", nil, "baz", AnyArgument{}, "repo", nil, nil, 1, false, false, 1, "user", 1, "user2", 1). +("org","repo","team","name","value","type","images","allow_events","allow_command","allow_substitution","created_at","created_by","updated_at","updated_by","id") +VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15) RETURNING "id"`). + WithArgs("foo", "bar", nil, "baz", AnyArgument{}, "repo", nil, 1, false, false, 1, "user", 1, "user2", 1). WillReturnRows(_rows) // ensure the mock expects the org secrets query _mock.ExpectQuery(`INSERT INTO "secrets" -("org","repo","team","name","value","type","images","events","allow_events","allow_command","allow_substitution","created_at","created_by","updated_at","updated_by","id") -VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16) RETURNING "id"`). - WithArgs("foo", "*", nil, "bar", AnyArgument{}, "org", nil, nil, 3, false, false, 1, "user", 1, "user2", 2). +("org","repo","team","name","value","type","images","allow_events","allow_command","allow_substitution","created_at","created_by","updated_at","updated_by","id") +VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15) RETURNING "id"`). + WithArgs("foo", "*", nil, "bar", AnyArgument{}, "org", nil, 3, false, false, 1, "user", 1, "user2", 2). WillReturnRows(_rows) // ensure the mock expects the shared secrets query _mock.ExpectQuery(`INSERT INTO "secrets" -("org","repo","team","name","value","type","images","events","allow_events","allow_command","allow_substitution","created_at","created_by","updated_at","updated_by","id") -VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16) RETURNING "id"`). - WithArgs("foo", nil, "bar", "baz", AnyArgument{}, "shared", nil, nil, 1, false, false, 1, "user", 1, "user2", 3). +("org","repo","team","name","value","type","images","allow_events","allow_command","allow_substitution","created_at","created_by","updated_at","updated_by","id") +VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15) RETURNING "id"`). + WithArgs("foo", nil, "bar", "baz", AnyArgument{}, "shared", nil, 1, false, false, 1, "user", 1, "user2", 3). WillReturnRows(_rows) _sqlite := testSqlite(t) diff --git a/database/secret/get_org_test.go b/database/secret/get_org_test.go index 840fa2f91..51ca298d2 100644 --- a/database/secret/get_org_test.go +++ b/database/secret/get_org_test.go @@ -32,8 +32,8 @@ func TestSecret_Engine_GetSecretForOrg(t *testing.T) { // create expected result in mock _rows := sqlmock.NewRows( - []string{"id", "type", "org", "repo", "team", "name", "value", "images", "events", "allow_events", "allow_command", "allow_substitution", "created_at", "created_by", "updated_at", "updated_by"}). - AddRow(1, "org", "foo", "*", "", "baz", "bar", nil, nil, 1, false, false, 1, "user", 1, "user2") + []string{"id", "type", "org", "repo", "team", "name", "value", "images", "allow_events", "allow_command", "allow_substitution", "created_at", "created_by", "updated_at", "updated_by"}). + AddRow(1, "org", "foo", "*", "", "baz", "bar", nil, 1, false, false, 1, "user", 1, "user2") // ensure the mock expects the query _mock.ExpectQuery(`SELECT * FROM "secrets" WHERE type = $1 AND org = $2 AND name = $3 LIMIT $4`). diff --git a/database/secret/get_repo_test.go b/database/secret/get_repo_test.go index c4ed2c472..d32f81cc0 100644 --- a/database/secret/get_repo_test.go +++ b/database/secret/get_repo_test.go @@ -42,8 +42,8 @@ func TestSecret_Engine_GetSecretForRepo(t *testing.T) { // create expected result in mock _rows := sqlmock.NewRows( - []string{"id", "type", "org", "repo", "team", "name", "value", "images", "events", "allow_events", "allow_command", "allow_substitution", "created_at", "created_by", "updated_at", "updated_by"}). - AddRow(1, "repo", "foo", "bar", "", "baz", "foob", nil, nil, 1, false, false, 1, "user", 1, "user2") + []string{"id", "type", "org", "repo", "team", "name", "value", "images", "allow_events", "allow_command", "allow_substitution", "created_at", "created_by", "updated_at", "updated_by"}). + AddRow(1, "repo", "foo", "bar", "", "baz", "foob", nil, 1, false, false, 1, "user", 1, "user2") // ensure the mock expects the query _mock.ExpectQuery(`SELECT * FROM "secrets" WHERE type = $1 AND org = $2 AND repo = $3 AND name = $4 LIMIT $5`). diff --git a/database/secret/get_team_test.go b/database/secret/get_team_test.go index a39012c26..f34e6f2b6 100644 --- a/database/secret/get_team_test.go +++ b/database/secret/get_team_test.go @@ -32,8 +32,8 @@ func TestSecret_Engine_GetSecretForTeam(t *testing.T) { // create expected result in mock _rows := sqlmock.NewRows( - []string{"id", "type", "org", "repo", "team", "name", "value", "images", "events", "allow_events", "allow_command", "allow_substitution", "created_at", "created_by", "updated_at", "updated_by"}). - AddRow(1, "shared", "foo", "", "bar", "baz", "foob", nil, nil, 1, false, false, 1, "user", 1, "user2") + []string{"id", "type", "org", "repo", "team", "name", "value", "images", "allow_events", "allow_command", "allow_substitution", "created_at", "created_by", "updated_at", "updated_by"}). + AddRow(1, "shared", "foo", "", "bar", "baz", "foob", nil, 1, false, false, 1, "user", 1, "user2") // ensure the mock expects the query _mock.ExpectQuery(`SELECT * FROM "secrets" WHERE type = $1 AND org = $2 AND team = $3 AND name = $4 LIMIT $5`). diff --git a/database/secret/get_test.go b/database/secret/get_test.go index 8b8d4d9c5..16e456c12 100644 --- a/database/secret/get_test.go +++ b/database/secret/get_test.go @@ -31,8 +31,8 @@ func TestSecret_Engine_GetSecret(t *testing.T) { // create expected result in mock _rows := sqlmock.NewRows( - []string{"id", "type", "org", "repo", "team", "name", "value", "images", "events", "allow_events", "allow_command", "allow_substitution", "created_at", "created_by", "updated_at", "updated_by"}). - AddRow(1, "repo", "foo", "bar", "", "baz", "foob", nil, nil, 1, false, false, 1, "user", 1, "user2") + []string{"id", "type", "org", "repo", "team", "name", "value", "images", "allow_events", "allow_command", "allow_substitution", "created_at", "created_by", "updated_at", "updated_by"}). + AddRow(1, "repo", "foo", "bar", "", "baz", "foob", nil, 1, false, false, 1, "user", 1, "user2") // ensure the mock expects the query _mock.ExpectQuery(`SELECT * FROM "secrets" WHERE id = $1 LIMIT $2`).WithArgs(1, 1).WillReturnRows(_rows) diff --git a/database/secret/list_org_test.go b/database/secret/list_org_test.go index 024d7a05a..14493ef38 100644 --- a/database/secret/list_org_test.go +++ b/database/secret/list_org_test.go @@ -52,9 +52,9 @@ func TestSecret_Engine_ListSecretsForOrg(t *testing.T) { // create expected name query result in mock _rows = sqlmock.NewRows( - []string{"id", "type", "org", "repo", "team", "name", "value", "images", "events", "allow_events", "allow_command", "allow_substitution", "created_at", "created_by", "updated_at", "updated_by"}). - AddRow(2, "org", "foo", "*", "", "bar", "baz", nil, nil, 1, false, false, 1, "user", 1, "user2"). - AddRow(1, "org", "foo", "*", "", "baz", "bar", nil, nil, 1, false, false, 1, "user", 1, "user2") + []string{"id", "type", "org", "repo", "team", "name", "value", "images", "allow_events", "allow_command", "allow_substitution", "created_at", "created_by", "updated_at", "updated_by"}). + AddRow(2, "org", "foo", "*", "", "bar", "baz", nil, 1, false, false, 1, "user", 1, "user2"). + AddRow(1, "org", "foo", "*", "", "baz", "bar", nil, 1, false, false, 1, "user", 1, "user2") // ensure the mock expects the name query _mock.ExpectQuery(`SELECT * FROM "secrets" WHERE type = $1 AND org = $2 ORDER BY id DESC LIMIT $3`). diff --git a/database/secret/list_repo_test.go b/database/secret/list_repo_test.go index eb97e4c52..9fc76e7bf 100644 --- a/database/secret/list_repo_test.go +++ b/database/secret/list_repo_test.go @@ -63,9 +63,9 @@ func TestSecret_Engine_ListSecretsForRepo(t *testing.T) { // create expected name query result in mock _rows = sqlmock.NewRows( - []string{"id", "type", "org", "repo", "team", "name", "value", "images", "events", "allow_events", "allow_command", "allow_substitution", "created_at", "created_by", "updated_at", "updated_by"}). - AddRow(2, "repo", "foo", "bar", "", "foob", "baz", nil, nil, 1, false, false, 1, "user", 1, "user2"). - AddRow(1, "repo", "foo", "bar", "", "baz", "foob", nil, nil, 1, false, false, 1, "user", 1, "user2") + []string{"id", "type", "org", "repo", "team", "name", "value", "images", "allow_events", "allow_command", "allow_substitution", "created_at", "created_by", "updated_at", "updated_by"}). + AddRow(2, "repo", "foo", "bar", "", "foob", "baz", nil, 1, false, false, 1, "user", 1, "user2"). + AddRow(1, "repo", "foo", "bar", "", "baz", "foob", nil, 1, false, false, 1, "user", 1, "user2") // ensure the mock expects the name query _mock.ExpectQuery(`SELECT * FROM "secrets" WHERE type = $1 AND org = $2 AND repo = $3 ORDER BY id DESC LIMIT $4`). diff --git a/database/secret/list_team_test.go b/database/secret/list_team_test.go index fd925935e..89b40b237 100644 --- a/database/secret/list_team_test.go +++ b/database/secret/list_team_test.go @@ -53,9 +53,9 @@ func TestSecret_Engine_ListSecretsForTeam(t *testing.T) { // create expected name query result in mock _rows = sqlmock.NewRows( - []string{"id", "type", "org", "repo", "team", "name", "value", "images", "events", "allow_events", "allow_command", "allow_substitution", "created_at", "created_by", "updated_at", "updated_by"}). - AddRow(2, "shared", "foo", "", "bar", "foob", "baz", nil, nil, 1, false, false, 1, "user", 1, "user2"). - AddRow(1, "shared", "foo", "", "bar", "baz", "foob", nil, nil, 1, false, false, 1, "user", 1, "user2") + []string{"id", "type", "org", "repo", "team", "name", "value", "images", "allow_events", "allow_command", "allow_substitution", "created_at", "created_by", "updated_at", "updated_by"}). + AddRow(2, "shared", "foo", "", "bar", "foob", "baz", nil, 1, false, false, 1, "user", 1, "user2"). + AddRow(1, "shared", "foo", "", "bar", "baz", "foob", nil, 1, false, false, 1, "user", 1, "user2") // ensure the mock expects the name query _mock.ExpectQuery(`SELECT * FROM "secrets" WHERE type = $1 AND org = $2 AND team = $3 ORDER BY id DESC LIMIT $4`). @@ -134,6 +134,7 @@ func TestSecret_Engine_ListSecretsForTeams(t *testing.T) { _secretOne.SetCreatedBy("user") _secretOne.SetUpdatedAt(1) _secretOne.SetUpdatedBy("user2") + _secretOne.SetAllowEvents(library.NewEventsFromMask(1)) _secretTwo := testSecret() _secretTwo.SetID(2) @@ -146,6 +147,7 @@ func TestSecret_Engine_ListSecretsForTeams(t *testing.T) { _secretTwo.SetCreatedBy("user") _secretTwo.SetUpdatedAt(1) _secretTwo.SetUpdatedBy("user2") + _secretTwo.SetAllowEvents(library.NewEventsFromMask(1)) _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() @@ -159,9 +161,9 @@ func TestSecret_Engine_ListSecretsForTeams(t *testing.T) { // create expected name query result in mock _rows = sqlmock.NewRows( - []string{"id", "type", "org", "repo", "team", "name", "value", "images", "events", "allow_command", "created_at", "created_by", "updated_at", "updated_by"}). - AddRow(2, "shared", "foo", "", "bar", "foob", "baz", nil, nil, false, 1, "user", 1, "user2"). - AddRow(1, "shared", "foo", "", "bar", "baz", "foob", nil, nil, false, 1, "user", 1, "user2") + []string{"id", "type", "org", "repo", "team", "name", "value", "images", "allow_events", "allow_command", "created_at", "created_by", "updated_at", "updated_by"}). + AddRow(2, "shared", "foo", "", "bar", "foob", "baz", nil, 1, false, 1, "user", 1, "user2"). + AddRow(1, "shared", "foo", "", "bar", "baz", "foob", nil, 1, false, 1, "user", 1, "user2") // ensure the mock expects the name query _mock.ExpectQuery(`SELECT * FROM "secrets" WHERE type = $1 AND org = $2 AND LOWER(team) IN ($3,$4) ORDER BY id DESC LIMIT $5`). diff --git a/database/secret/list_test.go b/database/secret/list_test.go index a1a0e9e38..c050d452d 100644 --- a/database/secret/list_test.go +++ b/database/secret/list_test.go @@ -50,9 +50,9 @@ func TestSecret_Engine_ListSecrets(t *testing.T) { // create expected result in mock _rows = sqlmock.NewRows( - []string{"id", "type", "org", "repo", "team", "name", "value", "images", "events", "allow_events", "allow_command", "allow_substitution", "created_at", "created_by", "updated_at", "updated_by"}). - AddRow(1, "repo", "foo", "bar", "", "baz", "foob", nil, nil, 1, false, false, 1, "user", 1, "user2"). - AddRow(2, "repo", "foo", "bar", "", "foob", "baz", nil, nil, 1, false, false, 1, "user", 1, "user2") + []string{"id", "type", "org", "repo", "team", "name", "value", "images", "allow_events", "allow_command", "allow_substitution", "created_at", "created_by", "updated_at", "updated_by"}). + AddRow(1, "repo", "foo", "bar", "", "baz", "foob", nil, 1, false, false, 1, "user", 1, "user2"). + AddRow(2, "repo", "foo", "bar", "", "foob", "baz", nil, 1, false, false, 1, "user", 1, "user2") // ensure the mock expects the query _mock.ExpectQuery(`SELECT * FROM "secrets"`).WillReturnRows(_rows) diff --git a/database/secret/secret_test.go b/database/secret/secret_test.go index e4b74ec9a..160f208cb 100644 --- a/database/secret/secret_test.go +++ b/database/secret/secret_test.go @@ -198,11 +198,6 @@ func testRepo() *library.Repo { Private: new(bool), Trusted: new(bool), Active: new(bool), - AllowPull: new(bool), - AllowPush: new(bool), - AllowDeploy: new(bool), - AllowTag: new(bool), - AllowComment: new(bool), } } @@ -218,7 +213,6 @@ func testSecret() *library.Secret { Value: new(string), Type: new(string), Images: new([]string), - Events: new([]string), AllowEvents: testEvents(), AllowCommand: new(bool), AllowSubstitution: new(bool), diff --git a/database/secret/table.go b/database/secret/table.go index 67fd6b8b9..07b84fee8 100644 --- a/database/secret/table.go +++ b/database/secret/table.go @@ -22,7 +22,6 @@ secrets ( name VARCHAR(250), value BYTEA, images VARCHAR(1000), - events VARCHAR(1000), allow_events INTEGER, allow_command BOOLEAN, allow_substitution BOOLEAN, @@ -48,7 +47,6 @@ secrets ( name TEXT, value TEXT, images TEXT, - events TEXT, allow_events INTEGER, allow_command BOOLEAN, allow_substitution BOOLEAN, diff --git a/database/secret/update_test.go b/database/secret/update_test.go index 5797471f2..0502de911 100644 --- a/database/secret/update_test.go +++ b/database/secret/update_test.go @@ -57,23 +57,23 @@ func TestSecret_Engine_UpdateSecret(t *testing.T) { // ensure the mock expects the repo query _mock.ExpectExec(`UPDATE "secrets" -SET "org"=$1,"repo"=$2,"team"=$3,"name"=$4,"value"=$5,"type"=$6,"images"=$7,"events"=$8,"allow_events"=$9,"allow_command"=$10,"allow_substitution"=$11,"created_at"=$12,"created_by"=$13,"updated_at"=$14,"updated_by"=$15 -WHERE "id" = $16`). - WithArgs("foo", "bar", nil, "baz", AnyArgument{}, "repo", nil, nil, 1, false, false, 1, "user", AnyArgument{}, "user2", 1). +SET "org"=$1,"repo"=$2,"team"=$3,"name"=$4,"value"=$5,"type"=$6,"images"=$7,"allow_events"=$8,"allow_command"=$9,"allow_substitution"=$10,"created_at"=$11,"created_by"=$12,"updated_at"=$13,"updated_by"=$14 +WHERE "id" = $15`). + WithArgs("foo", "bar", nil, "baz", AnyArgument{}, "repo", nil, 1, false, false, 1, "user", AnyArgument{}, "user2", 1). WillReturnResult(sqlmock.NewResult(1, 1)) // ensure the mock expects the org query _mock.ExpectExec(`UPDATE "secrets" -SET "org"=$1,"repo"=$2,"team"=$3,"name"=$4,"value"=$5,"type"=$6,"images"=$7,"events"=$8,"allow_events"=$9,"allow_command"=$10,"allow_substitution"=$11,"created_at"=$12,"created_by"=$13,"updated_at"=$14,"updated_by"=$15 -WHERE "id" = $16`). - WithArgs("foo", "*", nil, "bar", AnyArgument{}, "org", nil, nil, 1, false, false, 1, "user", AnyArgument{}, "user2", 2). +SET "org"=$1,"repo"=$2,"team"=$3,"name"=$4,"value"=$5,"type"=$6,"images"=$7,"allow_events"=$8,"allow_command"=$9,"allow_substitution"=$10,"created_at"=$11,"created_by"=$12,"updated_at"=$13,"updated_by"=$14 +WHERE "id" = $15`). + WithArgs("foo", "*", nil, "bar", AnyArgument{}, "org", nil, 1, false, false, 1, "user", AnyArgument{}, "user2", 2). WillReturnResult(sqlmock.NewResult(1, 1)) // ensure the mock expects the shared query _mock.ExpectExec(`UPDATE "secrets" -SET "org"=$1,"repo"=$2,"team"=$3,"name"=$4,"value"=$5,"type"=$6,"images"=$7,"events"=$8,"allow_events"=$9,"allow_command"=$10,"allow_substitution"=$11,"created_at"=$12,"created_by"=$13,"updated_at"=$14,"updated_by"=$15 -WHERE "id" = $16`). - WithArgs("foo", nil, "bar", "baz", AnyArgument{}, "shared", nil, nil, 1, false, false, 1, "user", NowTimestamp{}, "user2", 3). +SET "org"=$1,"repo"=$2,"team"=$3,"name"=$4,"value"=$5,"type"=$6,"images"=$7,"allow_events"=$8,"allow_command"=$9,"allow_substitution"=$10,"created_at"=$11,"created_by"=$12,"updated_at"=$13,"updated_by"=$14 +WHERE "id" = $15`). + WithArgs("foo", nil, "bar", "baz", AnyArgument{}, "shared", nil, 1, false, false, 1, "user", NowTimestamp{}, "user2", 3). WillReturnResult(sqlmock.NewResult(1, 1)) _sqlite := testSqlite(t) diff --git a/go.mod b/go.mod index eb4191a8d..681104cdc 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/drone/envsubst v1.0.3 github.com/gin-gonic/gin v1.9.1 github.com/go-playground/assert/v2 v2.2.0 - github.com/go-vela/types v0.23.4-0.20240326211542-476edfa844f0 + github.com/go-vela/types v0.23.4-0.20240401132228-9b43c701ab32 github.com/golang-jwt/jwt/v5 v5.2.1 github.com/google/go-cmp v0.6.0 github.com/google/go-github/v59 v59.0.0 diff --git a/go.sum b/go.sum index 7e6377fa8..a956a83fd 100644 --- a/go.sum +++ b/go.sum @@ -85,8 +85,8 @@ github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw= github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= -github.com/go-vela/types v0.23.4-0.20240326211542-476edfa844f0 h1:CR/lM4nzDoQ1wKDa9aJGnlZHkx94m170t9NKyCjV9NA= -github.com/go-vela/types v0.23.4-0.20240326211542-476edfa844f0/go.mod h1:mEF9dLkk00rUXf/t39n2WvXZgJbxnPEEWy+DHqIlRUo= +github.com/go-vela/types v0.23.4-0.20240401132228-9b43c701ab32 h1:fqmNnM1LdH3Zg1zCADfgR7a51EOSZvLFAB2Em4CG+Pg= +github.com/go-vela/types v0.23.4-0.20240401132228-9b43c701ab32/go.mod h1:mEF9dLkk00rUXf/t39n2WvXZgJbxnPEEWy+DHqIlRUo= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= diff --git a/mock/server/repo.go b/mock/server/repo.go index cc480b289..88b4d4715 100644 --- a/mock/server/repo.go +++ b/mock/server/repo.go @@ -33,11 +33,6 @@ const ( "pipeline_type": "yaml", "topics": [], "active": true, - "allow_pull": false, - "allow_push": true, - "allow_deploy": false, - "allow_tag": false, - "allow_comment": false, "allow_events": { "push": { "branch": true, @@ -77,11 +72,7 @@ const ( "visibility": "public", "private": false, "trusted": true, - "active": true, - "allow_pr": false, - "allow_push": true, - "allow_deploy": false, - "allow_tag": false + "active": true }, { "id": 2, @@ -97,11 +88,7 @@ const ( "visibility": "public", "private": false, "trusted": true, - "active": true, - "allow_pr": false, - "allow_push": true, - "allow_deploy": false, - "allow_tag": false + "active": true } ]` ) diff --git a/mock/server/secret.go b/mock/server/secret.go index 34fcd4b76..5030ce3cd 100644 --- a/mock/server/secret.go +++ b/mock/server/secret.go @@ -28,7 +28,6 @@ const ( "images": [ "alpine" ], - "events": [], "allow_events": { "push": { "branch": true, @@ -68,9 +67,6 @@ const ( "type": "repo", "images": [ "alpine" - ], - "events": [ - "push" ] }, { @@ -83,9 +79,6 @@ const ( "type": "org", "images": [ "alpine" - ], - "events": [ - "push" ] }, { @@ -98,9 +91,6 @@ const ( "type": "shared", "images": [ "alpine" - ], - "events": [ - "push" ] } ]` diff --git a/queue/redis/redis_test.go b/queue/redis/redis_test.go index 919892976..3f632b129 100644 --- a/queue/redis/redis_test.go +++ b/queue/redis/redis_test.go @@ -74,22 +74,18 @@ var ( } _repo = &library.Repo{ - ID: Int64(1), - Org: String("github"), - Name: String("octocat"), - FullName: String("github/octocat"), - Link: String("https://github.com/github/octocat"), - Clone: String("https://github.com/github/octocat.git"), - Branch: String("main"), - Timeout: Int64(60), - Visibility: String("public"), - Private: Bool(false), - Trusted: Bool(false), - Active: Bool(true), - AllowPull: Bool(false), - AllowPush: Bool(true), - AllowDeploy: Bool(false), - AllowTag: Bool(false), + ID: Int64(1), + Org: String("github"), + Name: String("octocat"), + FullName: String("github/octocat"), + Link: String("https://github.com/github/octocat"), + Clone: String("https://github.com/github/octocat.git"), + Branch: String("main"), + Timeout: Int64(60), + Visibility: String("public"), + Private: Bool(false), + Trusted: Bool(false), + Active: Bool(true), } _steps = &pipeline.Build{ diff --git a/router/middleware/org/org_test.go b/router/middleware/org/org_test.go index 27021222f..8b217f5f8 100644 --- a/router/middleware/org/org_test.go +++ b/router/middleware/org/org_test.go @@ -48,11 +48,6 @@ func TestOrg_Establish(t *testing.T) { r.SetPrivate(false) r.SetTrusted(false) r.SetActive(false) - r.SetAllowPull(false) - r.SetAllowPush(false) - r.SetAllowDeploy(false) - r.SetAllowTag(false) - r.SetAllowComment(false) want := "foo" got := "" diff --git a/router/middleware/repo/repo_test.go b/router/middleware/repo/repo_test.go index 9ae835eae..488bcac8d 100644 --- a/router/middleware/repo/repo_test.go +++ b/router/middleware/repo/repo_test.go @@ -54,11 +54,6 @@ func TestRepo_Establish(t *testing.T) { want.SetPrivate(false) want.SetTrusted(false) want.SetActive(false) - want.SetAllowPull(false) - want.SetAllowPush(false) - want.SetAllowDeploy(false) - want.SetAllowTag(false) - want.SetAllowComment(false) want.SetAllowEvents(library.NewEventsFromMask(1)) want.SetPipelineType("yaml") want.SetPreviousName("") diff --git a/scm/github/repo_test.go b/scm/github/repo_test.go index 6918c8a0d..b34e704ac 100644 --- a/scm/github/repo_test.go +++ b/scm/github/repo_test.go @@ -690,9 +690,6 @@ func TestGithub_Enable(t *testing.T) { r.SetName("bar") r.SetOrg("foo") r.SetHash("secret") - r.SetAllowPush(true) - r.SetAllowPull(true) - r.SetAllowDeploy(true) client, _ := NewTest(s.URL) @@ -739,9 +736,6 @@ func TestGithub_Update(t *testing.T) { r.SetName("bar") r.SetOrg("foo") r.SetHash("secret") - r.SetAllowPush(true) - r.SetAllowPull(true) - r.SetAllowDeploy(true) hookID := int64(1) diff --git a/secret/native/count_test.go b/secret/native/count_test.go index 33ab448be..e080ec03a 100644 --- a/secret/native/count_test.go +++ b/secret/native/count_test.go @@ -20,7 +20,6 @@ func TestNative_Count(t *testing.T) { sec.SetValue("foob") sec.SetType("repo") sec.SetImages([]string{"foo", "bar"}) - sec.SetEvents([]string{"foo", "bar"}) sec.SetCreatedAt(1) sec.SetUpdatedAt(1) diff --git a/secret/native/create_test.go b/secret/native/create_test.go index 02a114976..c7c44c22d 100644 --- a/secret/native/create_test.go +++ b/secret/native/create_test.go @@ -22,7 +22,6 @@ func TestNative_Create_Org(t *testing.T) { want.SetValue("baz") want.SetType("org") want.SetImages([]string{"foo", "bar"}) - want.SetEvents([]string{"foo", "bar"}) want.SetAllowEvents(library.NewEventsFromMask(1)) want.SetAllowCommand(false) want.SetAllowSubstitution(false) @@ -71,7 +70,6 @@ func TestNative_Create_Repo(t *testing.T) { want.SetValue("foob") want.SetType("repo") want.SetImages([]string{"foo", "bar"}) - want.SetEvents([]string{"foo", "bar"}) want.SetAllowEvents(library.NewEventsFromMask(1)) want.SetAllowCommand(false) want.SetAllowSubstitution(false) @@ -120,7 +118,6 @@ func TestNative_Create_Shared(t *testing.T) { want.SetValue("foob") want.SetType("shared") want.SetImages([]string{"foo", "bar"}) - want.SetEvents([]string{"foo", "bar"}) want.SetAllowEvents(library.NewEventsFromMask(1)) want.SetAllowCommand(false) want.SetAllowSubstitution(false) @@ -169,7 +166,6 @@ func TestNative_Create_Invalid(t *testing.T) { sec.SetValue("foob") sec.SetType("invalid") sec.SetImages([]string{"foo", "bar"}) - sec.SetEvents([]string{"foo", "bar"}) sec.SetAllowEvents(library.NewEventsFromMask(1)) sec.SetAllowCommand(false) sec.SetAllowSubstitution(false) diff --git a/secret/native/delete_test.go b/secret/native/delete_test.go index 96838d575..ad486b2a1 100644 --- a/secret/native/delete_test.go +++ b/secret/native/delete_test.go @@ -21,7 +21,6 @@ func TestNative_Delete(t *testing.T) { sec.SetValue("foob") sec.SetType("repo") sec.SetImages([]string{"foo", "bar"}) - sec.SetEvents([]string{"foo", "bar"}) sec.SetAllowCommand(false) sec.SetCreatedAt(1) sec.SetUpdatedAt(1) diff --git a/secret/native/get_test.go b/secret/native/get_test.go index b9b56e51e..f20dcdf5b 100644 --- a/secret/native/get_test.go +++ b/secret/native/get_test.go @@ -22,7 +22,6 @@ func TestNative_Get(t *testing.T) { want.SetValue("foob") want.SetType("repo") want.SetImages([]string{"foo", "bar"}) - want.SetEvents([]string{"foo", "bar"}) want.SetAllowEvents(library.NewEventsFromMask(1)) want.SetAllowCommand(false) want.SetAllowSubstitution(false) diff --git a/secret/native/list_test.go b/secret/native/list_test.go index b01e3a546..b201eda73 100644 --- a/secret/native/list_test.go +++ b/secret/native/list_test.go @@ -22,7 +22,6 @@ func TestNative_List(t *testing.T) { sOne.SetValue("foob") sOne.SetType("repo") sOne.SetImages([]string{"foo", "bar"}) - sOne.SetEvents([]string{"foo", "bar"}) sOne.SetAllowEvents(library.NewEventsFromMask(1)) sOne.SetAllowCommand(false) sOne.SetAllowSubstitution(false) @@ -40,7 +39,6 @@ func TestNative_List(t *testing.T) { sTwo.SetValue("baz") sTwo.SetType("repo") sTwo.SetImages([]string{"foo", "bar"}) - sTwo.SetEvents([]string{"foo", "bar"}) sTwo.SetAllowEvents(library.NewEventsFromMask(1)) sTwo.SetAllowCommand(false) sTwo.SetAllowSubstitution(false) diff --git a/secret/native/update.go b/secret/native/update.go index 7e2c92d0c..bce00e936 100644 --- a/secret/native/update.go +++ b/secret/native/update.go @@ -19,11 +19,6 @@ func (c *client) Update(ctx context.Context, sType, org, name string, s *library return nil, err } - // update the events if set - if len(s.GetEvents()) > 0 { - secret.SetEvents(s.GetEvents()) - } - // update allow events if set if s.GetAllowEvents().ToDatabase() > 0 { secret.SetAllowEvents(s.GetAllowEvents()) diff --git a/secret/native/update_test.go b/secret/native/update_test.go index 38d7a3b5b..1ec2d597a 100644 --- a/secret/native/update_test.go +++ b/secret/native/update_test.go @@ -23,7 +23,6 @@ func TestNative_Update(t *testing.T) { original.SetValue("secretValue") original.SetType("repo") original.SetImages([]string{"foo", "baz"}) - original.SetEvents([]string{"foob", "bar"}) original.SetAllowEvents(library.NewEventsFromMask(1)) original.SetAllowCommand(true) original.SetAllowSubstitution(true) @@ -41,7 +40,6 @@ func TestNative_Update(t *testing.T) { want.SetValue("foob") want.SetType("repo") want.SetImages([]string{"foo", "bar"}) - want.SetEvents([]string{"foo", "bar"}) want.SetAllowEvents(library.NewEventsFromMask(3)) want.SetAllowCommand(false) want.SetAllowSubstitution(false) diff --git a/secret/vault/create_test.go b/secret/vault/create_test.go index 129b0e487..dc0d5226f 100644 --- a/secret/vault/create_test.go +++ b/secret/vault/create_test.go @@ -51,7 +51,6 @@ func TestVault_Create_Org(t *testing.T) { sec.SetValue("baz") sec.SetType("org") sec.SetImages([]string{"foo", "bar"}) - sec.SetEvents([]string{"foo", "bar"}) sec.SetAllowCommand(true) sec.SetAllowSubstitution(true) sec.SetAllowEvents(library.NewEventsFromMask(1)) @@ -142,7 +141,6 @@ func TestVault_Create_Repo(t *testing.T) { sec.SetValue("foob") sec.SetType("repo") sec.SetImages([]string{"foo", "bar"}) - sec.SetEvents([]string{"foo", "bar"}) sec.SetAllowCommand(true) sec.SetAllowSubstitution(true) sec.SetAllowEvents(library.NewEventsFromMask(3)) @@ -234,7 +232,6 @@ func TestVault_Create_Shared(t *testing.T) { sec.SetValue("foob") sec.SetType("shared") sec.SetImages([]string{"foo", "bar"}) - sec.SetEvents([]string{"foo", "bar"}) sec.SetAllowCommand(false) sec.SetAllowSubstitution(false) sec.SetAllowEvents(library.NewEventsFromMask(1)) @@ -321,7 +318,6 @@ func TestVault_Create_InvalidSecret(t *testing.T) { sec.SetValue("") sec.SetType("repo") sec.SetImages([]string{"foo", "bar"}) - sec.SetEvents([]string{"foo", "bar"}) sec.SetAllowCommand(false) type args struct { @@ -376,7 +372,6 @@ func TestVault_Create_InvalidType(t *testing.T) { sec.SetValue("foob") sec.SetType("invalid") sec.SetImages([]string{"foo", "bar"}) - sec.SetEvents([]string{"foo", "bar"}) sec.SetAllowCommand(false) // setup mock server @@ -430,7 +425,6 @@ func TestVault_Create_ClosedServer(t *testing.T) { sec.SetValue("foob") sec.SetType("repo") sec.SetImages([]string{"foo", "bar"}) - sec.SetEvents([]string{"foo", "bar"}) sec.SetAllowCommand(false) // setup mock server diff --git a/secret/vault/get_test.go b/secret/vault/get_test.go index 2c811e9fd..5af08f22a 100644 --- a/secret/vault/get_test.go +++ b/secret/vault/get_test.go @@ -51,7 +51,6 @@ func TestVault_Get_Org(t *testing.T) { want.SetValue("baz") want.SetType("org") want.SetImages([]string{"foo", "bar"}) - want.SetEvents([]string{"foo", "bar"}) want.SetAllowCommand(true) want.SetAllowSubstitution(true) want.SetAllowEvents(library.NewEventsFromMask(1)) @@ -142,7 +141,6 @@ func TestVault_Get_Repo(t *testing.T) { want.SetValue("foob") want.SetType("repo") want.SetImages([]string{"foo", "bar"}) - want.SetEvents([]string{"foo", "bar"}) want.SetAllowCommand(true) want.SetAllowSubstitution(true) want.SetAllowEvents(library.NewEventsFromMask(3)) @@ -233,7 +231,6 @@ func TestVault_Get_Shared(t *testing.T) { want.SetValue("foob") want.SetType("shared") want.SetImages([]string{"foo", "bar"}) - want.SetEvents([]string{"foo", "bar"}) want.SetAllowCommand(false) want.SetAllowSubstitution(false) want.SetAllowEvents(library.NewEventsFromMask(1)) diff --git a/secret/vault/list_test.go b/secret/vault/list_test.go index 3a6c2ab60..9a6eb352e 100644 --- a/secret/vault/list_test.go +++ b/secret/vault/list_test.go @@ -66,7 +66,6 @@ func TestVault_List_Org(t *testing.T) { sec.SetValue("baz") sec.SetType("org") sec.SetImages([]string{"foo", "bar"}) - sec.SetEvents([]string{"foo", "bar"}) sec.SetAllowCommand(true) sec.SetAllowSubstitution(true) sec.SetAllowEvents(library.NewEventsFromMask(1)) @@ -204,7 +203,6 @@ func TestVault_List_Repo(t *testing.T) { sec.SetValue("foob") sec.SetType("repo") sec.SetImages([]string{"foo", "bar"}) - sec.SetEvents([]string{"foo", "bar"}) sec.SetAllowCommand(true) sec.SetAllowSubstitution(true) sec.SetAllowEvents(library.NewEventsFromMask(3)) @@ -327,7 +325,6 @@ func TestVault_List_Shared(t *testing.T) { sec.SetValue("foob") sec.SetType("shared") sec.SetImages([]string{"foo", "bar"}) - sec.SetEvents([]string{"foo", "bar"}) sec.SetAllowCommand(false) sec.SetAllowSubstitution(false) sec.SetAllowEvents(library.NewEventsFromMask(1)) diff --git a/secret/vault/update.go b/secret/vault/update.go index 5655dcb9d..a269bd8f3 100644 --- a/secret/vault/update.go +++ b/secret/vault/update.go @@ -45,9 +45,6 @@ func (c *client) Update(ctx context.Context, sType, org, name string, s *library // convert the Vault secret our secret vault := vaultFromSecret(sec) - if len(s.GetEvents()) > 0 { - vault.Data["events"] = s.GetEvents() - } if s.GetAllowEvents().ToDatabase() != 0 { vault.Data["allow_events"] = s.GetAllowEvents().ToDatabase() diff --git a/secret/vault/update_test.go b/secret/vault/update_test.go index 94f247c7e..4a525c1ab 100644 --- a/secret/vault/update_test.go +++ b/secret/vault/update_test.go @@ -66,7 +66,6 @@ func TestVault_Update_Org(t *testing.T) { sec.SetValue("baz") sec.SetType("org") sec.SetImages([]string{"foo", "bar"}) - sec.SetEvents([]string{"foo", "bar"}) sec.SetAllowCommand(true) sec.SetAllowSubstitution(true) sec.SetAllowEvents(library.NewEventsFromMask(1)) @@ -173,7 +172,6 @@ func TestVault_Update_Repo(t *testing.T) { sec.SetValue("foob") sec.SetType("repo") sec.SetImages([]string{"foo", "bar"}) - sec.SetEvents([]string{"foo", "bar"}) sec.SetAllowCommand(true) sec.SetAllowSubstitution(true) sec.SetAllowEvents(library.NewEventsFromMask(3)) @@ -280,7 +278,6 @@ func TestVault_Update_Shared(t *testing.T) { sec.SetValue("foob") sec.SetType("shared") sec.SetImages([]string{"foo", "bar"}) - sec.SetEvents([]string{"foo", "bar"}) sec.SetAllowCommand(false) sec.SetAllowSubstitution(false) sec.SetAllowEvents(library.NewEventsFromMask(1)) @@ -372,7 +369,6 @@ func TestVault_Update_InvalidSecret(t *testing.T) { sec.SetValue("") sec.SetType("repo") sec.SetImages([]string{"foo", "bar"}) - sec.SetEvents([]string{"foo", "bar"}) sec.SetAllowCommand(false) type args struct { @@ -426,7 +422,6 @@ func TestVault_Update_InvalidType(t *testing.T) { sec.SetValue("foob") sec.SetType("invalid") sec.SetImages([]string{"foo", "bar"}) - sec.SetEvents([]string{"foo", "bar"}) // setup mock server fake := httptest.NewServer(http.NotFoundHandler()) @@ -478,7 +473,6 @@ func TestVault_Update_ClosedServer(t *testing.T) { sec.SetValue("foob") sec.SetType("repo") sec.SetImages([]string{"foo", "bar"}) - sec.SetEvents([]string{"foo", "bar"}) // setup mock server fake := httptest.NewServer(http.NotFoundHandler()) @@ -552,7 +546,6 @@ func TestVault_Update_NoWrite(t *testing.T) { sec.SetValue("foob") sec.SetType("repo") sec.SetImages([]string{"foo", "bar"}) - sec.SetEvents([]string{"foo", "bar"}) type args struct { version string diff --git a/secret/vault/vault.go b/secret/vault/vault.go index d9f3d79b5..2cbf34b34 100644 --- a/secret/vault/vault.go +++ b/secret/vault/vault.go @@ -144,22 +144,8 @@ func secretFromVault(vault *api.Secret) *library.Secret { data = vault.Data } - // set events if found in Vault secret - v, ok := data["events"] - if ok { - events, ok := v.([]interface{}) - if ok { - for _, element := range events { - event, ok := element.(string) - if ok { - s.SetEvents(append(s.GetEvents(), event)) - } - } - } - } - // set allow_events if found in Vault secret - v, ok = data["allow_events"] + v, ok := data["allow_events"] if ok { maskJSON, ok := v.(json.Number) if ok { @@ -345,11 +331,6 @@ func vaultFromSecret(s *library.Secret) *api.Secret { vault := new(api.Secret) vault.Data = data - // set events if found in Vela secret - if len(s.GetEvents()) > 0 { - vault.Data["events"] = s.GetEvents() - } - // set allow events to mask if s.GetAllowEvents().ToDatabase() != 0 { vault.Data["allow_events"] = s.GetAllowEvents().ToDatabase() diff --git a/secret/vault/vault_test.go b/secret/vault/vault_test.go index cec5d02c8..2bbb666bb 100644 --- a/secret/vault/vault_test.go +++ b/secret/vault/vault_test.go @@ -133,7 +133,6 @@ func TestVault_secretFromVault(t *testing.T) { want.SetName("bar") want.SetValue("baz") want.SetType("org") - want.SetEvents([]string{"push", "tag", "deployment"}) want.SetAllowEvents(library.NewEventsFromMask(8195)) want.SetImages([]string{"foo", "bar"}) want.SetAllowCommand(true) @@ -176,7 +175,6 @@ func TestVault_vaultFromSecret(t *testing.T) { s.SetName("bar") s.SetValue("baz") s.SetType("org") - s.SetEvents([]string{"foo", "bar"}) s.SetAllowEvents(library.NewEventsFromMask(1)) s.SetImages([]string{"foo", "bar"}) s.SetAllowCommand(true) @@ -188,7 +186,6 @@ func TestVault_vaultFromSecret(t *testing.T) { want := &api.Secret{ Data: map[string]interface{}{ - "events": []string{"foo", "bar"}, "allow_events": int64(1), "images": []string{"foo", "bar"}, "name": "bar", @@ -243,7 +240,6 @@ func TestVault_AccurateSecretFields(t *testing.T) { // helper function to return a test Vault secret data. func testVaultSecretData() map[string]interface{} { return map[string]interface{}{ - "events": []interface{}{"push", "tag", "deployment"}, "allow_events": json.Number("8195"), "images": []interface{}{"foo", "bar"}, "name": "bar", From 0d08fc330017480edd689fb981d09a98cba22c0c Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Fri, 5 Apr 2024 10:03:27 -0500 Subject: [PATCH 21/71] enhance(compiler): add ruledata option to CompileLite (#1076) * enhance(compiler): add ruledata option to CompileLite * remove template length check as it is unnecessary * fix tests from latest merges to main --------- Co-authored-by: Kelly Merrick --- api/pipeline/compile.go | 58 +- api/pipeline/expand.go | 4 +- api/pipeline/validate.go | 4 +- compiler/engine.go | 2 +- compiler/native/compile.go | 73 +- compiler/native/compile_test.go | 691 +++++++++++++----- .../native/testdata/golang_inline_stages.yml | 3 + .../native/testdata/inline_with_stages.yml | 9 +- .../native/testdata/inline_with_steps.yml | 15 +- .../testdata/steps_pipeline_template.yml | 11 + 10 files changed, 674 insertions(+), 196 deletions(-) diff --git a/api/pipeline/compile.go b/api/pipeline/compile.go index d829ab755..b47d243e8 100644 --- a/api/pipeline/compile.go +++ b/api/pipeline/compile.go @@ -6,15 +6,17 @@ package pipeline import ( "fmt" "net/http" + "strings" "github.com/gin-gonic/gin" "github.com/go-vela/server/compiler" "github.com/go-vela/server/router/middleware/org" - "github.com/go-vela/server/router/middleware/pipeline" + pMiddleware "github.com/go-vela/server/router/middleware/pipeline" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types" + "github.com/go-vela/types/pipeline" "github.com/sirupsen/logrus" ) @@ -72,7 +74,7 @@ func CompilePipeline(c *gin.Context) { // capture middleware values m := c.MustGet("metadata").(*types.Metadata) o := org.Retrieve(c) - p := pipeline.Retrieve(c) + p := pMiddleware.Retrieve(c) r := repo.Retrieve(c) u := user.Retrieve(c) @@ -94,8 +96,10 @@ func CompilePipeline(c *gin.Context) { // create the compiler object compiler := compiler.FromContext(c).Duplicate().WithCommit(p.GetCommit()).WithMetadata(m).WithRepo(r).WithUser(u) + ruleData := prepareRuleData(c) + // compile the pipeline - pipeline, _, err := compiler.CompileLite(p.GetData(), true) + pipeline, _, err := compiler.CompileLite(p.GetData(), ruleData, true) if err != nil { retErr := fmt.Errorf("unable to compile pipeline %s: %w", entry, err) @@ -106,3 +110,51 @@ func CompilePipeline(c *gin.Context) { writeOutput(c, pipeline) } + +// prepareRuleData is a helper function to prepare the rule data from the query parameters. +func prepareRuleData(c *gin.Context) *pipeline.RuleData { + // capture the branch name parameter + branch := c.Query("branch") + // capture the comment parameter + comment := c.Query("comment") + // capture the event type parameter + event := c.Query("event") + // capture the repo parameter + ruleDataRepo := c.Query("repo") + // capture the status type parameter + status := c.Query("status") + // capture the tag parameter + tag := c.Query("tag") + // capture the target parameter + target := c.Query("target") + + var pathSet []string + // capture the path parameter + path := c.Query("path") + if len(path) > 0 { + pathSet = strings.Split(path, ",") + } + + // if any ruledata query params were provided, create ruledata struct + if len(branch) > 0 || + len(comment) > 0 || + len(event) > 0 || + len(path) > 0 || + len(ruleDataRepo) > 0 || + len(status) > 0 || + len(tag) > 0 || + len(target) > 0 { + return &pipeline.RuleData{ + Branch: branch, + Comment: comment, + Event: event, + Path: pathSet, + Repo: ruleDataRepo, + Status: status, + Tag: tag, + Target: target, + } + } + + return nil +} diff --git a/api/pipeline/expand.go b/api/pipeline/expand.go index 8fb19303f..948dcf1fd 100644 --- a/api/pipeline/expand.go +++ b/api/pipeline/expand.go @@ -95,8 +95,10 @@ func ExpandPipeline(c *gin.Context) { // create the compiler object compiler := compiler.FromContext(c).Duplicate().WithCommit(p.GetCommit()).WithMetadata(m).WithRepo(r).WithUser(u) + ruleData := prepareRuleData(c) + // expand the templates in the pipeline - pipeline, _, err := compiler.CompileLite(p.GetData(), false) + pipeline, _, err := compiler.CompileLite(p.GetData(), ruleData, false) if err != nil { retErr := fmt.Errorf("unable to expand pipeline %s: %w", entry, err) diff --git a/api/pipeline/validate.go b/api/pipeline/validate.go index 333e7f0d6..fbaf1116b 100644 --- a/api/pipeline/validate.go +++ b/api/pipeline/validate.go @@ -93,8 +93,10 @@ func ValidatePipeline(c *gin.Context) { // create the compiler object compiler := compiler.FromContext(c).Duplicate().WithCommit(p.GetCommit()).WithMetadata(m).WithRepo(r).WithUser(u) + ruleData := prepareRuleData(c) + // validate the pipeline - pipeline, _, err := compiler.CompileLite(p.GetData(), false) + pipeline, _, err := compiler.CompileLite(p.GetData(), ruleData, false) if err != nil { retErr := fmt.Errorf("unable to validate pipeline %s: %w", entry, err) diff --git a/compiler/engine.go b/compiler/engine.go index 69812a519..b0a5c032f 100644 --- a/compiler/engine.go +++ b/compiler/engine.go @@ -23,7 +23,7 @@ type Engine interface { // CompileLite defines a function that produces an light executable // representation of a pipeline from an object. This calls // Parse internally to convert the object to a yaml configuration. - CompileLite(interface{}, bool) (*yaml.Build, *library.Pipeline, error) + CompileLite(interface{}, *pipeline.RuleData, bool) (*yaml.Build, *library.Pipeline, error) // Duplicate defines a function that // creates a clone of the Engine. diff --git a/compiler/native/compile.go b/compiler/native/compile.go index e72196c89..423d3cecf 100644 --- a/compiler/native/compile.go +++ b/compiler/native/compile.go @@ -97,7 +97,7 @@ func (c *client) Compile(v interface{}) (*pipeline.Build, *library.Pipeline, err } // CompileLite produces a partial of an executable pipeline from a yaml configuration. -func (c *client) CompileLite(v interface{}, substitute bool) (*yaml.Build, *library.Pipeline, error) { +func (c *client) CompileLite(v interface{}, ruleData *pipeline.RuleData, substitute bool) (*yaml.Build, *library.Pipeline, error) { p, data, err := c.Parse(v, c.repo.GetPipelineType(), new(yaml.Template)) if err != nil { return nil, nil, err @@ -125,36 +125,71 @@ func (c *client) CompileLite(v interface{}, substitute bool) (*yaml.Build, *libr // create map of templates for easy lookup templates := mapFromTemplates(p.Templates) - if len(templates) > 0 { - switch { - case len(p.Stages) > 0: - // inject the templates into the steps - p, err = c.ExpandStages(p, templates, nil) + switch { + case len(p.Stages) > 0: + // inject the templates into the steps + p, err = c.ExpandStages(p, templates, ruleData) + if err != nil { + return nil, _pipeline, err + } + + if substitute { + // inject the substituted environment variables into the steps + p.Stages, err = c.SubstituteStages(p.Stages) if err != nil { return nil, _pipeline, err } + } + + if ruleData != nil { + purgedStages := new(yaml.StageSlice) - if substitute { - // inject the substituted environment variables into the steps - p.Stages, err = c.SubstituteStages(p.Stages) - if err != nil { - return nil, _pipeline, err + for _, stg := range p.Stages { + purgedSteps := new(yaml.StepSlice) + + for _, s := range stg.Steps { + cRuleset := s.Ruleset.ToPipeline() + if match, err := cRuleset.Match(ruleData); err == nil && match { + *purgedSteps = append(*purgedSteps, s) + } + } + + stg.Steps = *purgedSteps + + if len(stg.Steps) > 0 { + *purgedStages = append(*purgedStages, stg) } } - case len(p.Steps) > 0: - // inject the templates into the steps - p, err = c.ExpandSteps(p, templates, nil, c.TemplateDepth) + + p.Stages = *purgedStages + } + + case len(p.Steps) > 0: + // inject the templates into the steps + p, err = c.ExpandSteps(p, templates, ruleData, c.TemplateDepth) + if err != nil { + return nil, _pipeline, err + } + + if substitute { + // inject the substituted environment variables into the steps + p.Steps, err = c.SubstituteSteps(p.Steps) if err != nil { return nil, _pipeline, err } + } - if substitute { - // inject the substituted environment variables into the steps - p.Steps, err = c.SubstituteSteps(p.Steps) - if err != nil { - return nil, _pipeline, err + if ruleData != nil { + purgedSteps := new(yaml.StepSlice) + + for _, s := range p.Steps { + cRuleset := s.Ruleset.ToPipeline() + if match, err := cRuleset.Match(ruleData); err == nil && match { + *purgedSteps = append(*purgedSteps, s) } } + + p.Steps = *purgedSteps } } diff --git a/compiler/native/compile_test.go b/compiler/native/compile_test.go index d00df4628..b1e31c00c 100644 --- a/compiler/native/compile_test.go +++ b/compiler/native/compile_test.go @@ -2308,60 +2308,6 @@ func Test_Compile_Inline(t *testing.T) { }, }, }, - { - Name: "golang_foo", - Needs: []string{"clone"}, - Environment: initEnv, - Steps: []*pipeline.Container{ - { - ID: "__0_golang_foo_golang_foo", - Commands: []string{"echo $VELA_BUILD_SCRIPT | base64 -d | /bin/sh -e"}, - Directory: "/vela/src/foo//", - Entrypoint: []string{"/bin/sh", "-c"}, - Environment: generateTestEnv("echo hello from foo", m, ""), - Image: "golang:latest", - Name: "golang_foo", - Pull: "not_present", - Number: 4, - }, - }, - }, - { - Name: "golang_bar", - Needs: []string{"clone"}, - Environment: initEnv, - Steps: []*pipeline.Container{ - { - ID: "__0_golang_bar_golang_bar", - Commands: []string{"echo $VELA_BUILD_SCRIPT | base64 -d | /bin/sh -e"}, - Directory: "/vela/src/foo//", - Entrypoint: []string{"/bin/sh", "-c"}, - Environment: generateTestEnv("echo hello from bar", m, ""), - Image: "golang:latest", - Name: "golang_bar", - Pull: "not_present", - Number: 5, - }, - }, - }, - { - Name: "golang_star", - Needs: []string{"clone"}, - Environment: initEnv, - Steps: []*pipeline.Container{ - { - ID: "__0_golang_star_golang_star", - Commands: []string{"echo $VELA_BUILD_SCRIPT | base64 -d | /bin/sh -e"}, - Directory: "/vela/src/foo//", - Entrypoint: []string{"/bin/sh", "-c"}, - Environment: generateTestEnv("echo hello from star", m, ""), - Image: "golang:latest", - Name: "golang_star", - Pull: "not_present", - Number: 6, - }, - }, - }, { Name: "starlark_foo", Needs: []string{"clone"}, @@ -2376,7 +2322,7 @@ func Test_Compile_Inline(t *testing.T) { Image: "alpine", Name: "starlark_build_foo", Pull: "not_present", - Number: 7, + Number: 4, }, }, }, @@ -2394,7 +2340,7 @@ func Test_Compile_Inline(t *testing.T) { Image: "alpine", Name: "starlark_build_bar", Pull: "not_present", - Number: 8, + Number: 5, }, }, }, @@ -2482,60 +2428,6 @@ func Test_Compile_Inline(t *testing.T) { }, }, }, - { - Name: "nested_golang_foo", - Needs: []string{"clone"}, - Environment: initEnv, - Steps: []*pipeline.Container{ - { - ID: "__0_nested_golang_foo_nested_golang_foo", - Commands: []string{"echo $VELA_BUILD_SCRIPT | base64 -d | /bin/sh -e"}, - Directory: "/vela/src/foo//", - Entrypoint: []string{"/bin/sh", "-c"}, - Environment: generateTestEnv("echo hello from foo", m, ""), - Image: "golang:latest", - Name: "nested_golang_foo", - Pull: "not_present", - Number: 5, - }, - }, - }, - { - Name: "nested_golang_bar", - Needs: []string{"clone"}, - Environment: initEnv, - Steps: []*pipeline.Container{ - { - ID: "__0_nested_golang_bar_nested_golang_bar", - Commands: []string{"echo $VELA_BUILD_SCRIPT | base64 -d | /bin/sh -e"}, - Directory: "/vela/src/foo//", - Entrypoint: []string{"/bin/sh", "-c"}, - Environment: generateTestEnv("echo hello from bar", m, ""), - Image: "golang:latest", - Name: "nested_golang_bar", - Pull: "not_present", - Number: 6, - }, - }, - }, - { - Name: "nested_golang_star", - Needs: []string{"clone"}, - Environment: initEnv, - Steps: []*pipeline.Container{ - { - ID: "__0_nested_golang_star_nested_golang_star", - Commands: []string{"echo $VELA_BUILD_SCRIPT | base64 -d | /bin/sh -e"}, - Directory: "/vela/src/foo//", - Entrypoint: []string{"/bin/sh", "-c"}, - Environment: generateTestEnv("echo hello from star", m, ""), - Image: "golang:latest", - Name: "nested_golang_star", - Pull: "not_present", - Number: 7, - }, - }, - }, { Name: "nested_starlark_foo", Needs: []string{"clone"}, @@ -2550,7 +2442,7 @@ func Test_Compile_Inline(t *testing.T) { Image: "alpine", Name: "nested_starlark_build_foo", Pull: "not_present", - Number: 8, + Number: 5, }, }, }, @@ -2568,7 +2460,7 @@ func Test_Compile_Inline(t *testing.T) { Image: "alpine", Name: "nested_starlark_build_bar", Pull: "not_present", - Number: 9, + Number: 6, }, }, }, @@ -3017,60 +2909,6 @@ func Test_Compile_Inline(t *testing.T) { }, }, }, - { - Name: "golang_foo", - Needs: []string{"clone"}, - Environment: golangEnv, - Steps: []*pipeline.Container{ - { - ID: "__0_golang_foo_golang_foo", - Commands: []string{"echo $VELA_BUILD_SCRIPT | base64 -d | /bin/sh -e"}, - Directory: "/vela/src/foo//", - Entrypoint: []string{"/bin/sh", "-c"}, - Environment: generateTestEnv("echo hello from foo", m, constants.PipelineTypeGo), - Image: "golang:latest", - Name: "golang_foo", - Pull: "not_present", - Number: 6, - }, - }, - }, - { - Name: "golang_bar", - Needs: []string{"clone"}, - Environment: golangEnv, - Steps: []*pipeline.Container{ - { - ID: "__0_golang_bar_golang_bar", - Commands: []string{"echo $VELA_BUILD_SCRIPT | base64 -d | /bin/sh -e"}, - Directory: "/vela/src/foo//", - Entrypoint: []string{"/bin/sh", "-c"}, - Environment: generateTestEnv("echo hello from bar", m, constants.PipelineTypeGo), - Image: "golang:latest", - Name: "golang_bar", - Pull: "not_present", - Number: 7, - }, - }, - }, - { - Name: "golang_star", - Needs: []string{"clone"}, - Environment: golangEnv, - Steps: []*pipeline.Container{ - { - ID: "__0_golang_star_golang_star", - Commands: []string{"echo $VELA_BUILD_SCRIPT | base64 -d | /bin/sh -e"}, - Directory: "/vela/src/foo//", - Entrypoint: []string{"/bin/sh", "-c"}, - Environment: generateTestEnv("echo hello from star", m, constants.PipelineTypeGo), - Image: "golang:latest", - Name: "golang_star", - Pull: "not_present", - Number: 8, - }, - }, - }, { Name: "starlark_foo", Needs: []string{"clone"}, @@ -3085,7 +2923,7 @@ func Test_Compile_Inline(t *testing.T) { Image: "alpine", Name: "starlark_build_foo", Pull: "not_present", - Number: 9, + Number: 6, }, }, }, @@ -3103,7 +2941,7 @@ func Test_Compile_Inline(t *testing.T) { Image: "alpine", Name: "starlark_build_bar", Pull: "not_present", - Number: 10, + Number: 7, }, }, }, @@ -3207,6 +3045,7 @@ func Test_CompileLite(t *testing.T) { file string pipelineType string substitute bool + ruleData *pipeline.RuleData } tests := []struct { @@ -3259,6 +3098,20 @@ func Test_CompileLite(t *testing.T) { Name: "test", Pull: "not_present", }, + { + Commands: raw.StringSlice{"echo from inline ruleset"}, + Image: "alpine", + Name: "ruleset", + Pull: "not_present", + Ruleset: yaml.Ruleset{ + If: yaml.Rules{ + Event: []string{"push"}, + Branch: []string{"main"}, + }, + Matcher: "filepath", + Operator: "and", + }, + }, }, }, { @@ -3270,6 +3123,14 @@ func Test_CompileLite(t *testing.T) { Image: "golang:latest", Name: "golang_foo", Pull: "not_present", + Ruleset: yaml.Ruleset{ + If: yaml.Rules{ + Event: []string{"tag"}, + Tag: []string{"v*"}, + }, + Matcher: "filepath", + Operator: "and", + }, }, }, }, @@ -3282,6 +3143,14 @@ func Test_CompileLite(t *testing.T) { Image: "golang:latest", Name: "golang_bar", Pull: "not_present", + Ruleset: yaml.Ruleset{ + If: yaml.Rules{ + Event: []string{"tag"}, + Tag: []string{"v*"}, + }, + Matcher: "filepath", + Operator: "and", + }, }, }, }, @@ -3294,6 +3163,14 @@ func Test_CompileLite(t *testing.T) { Image: "golang:latest", Name: "golang_star", Pull: "not_present", + Ruleset: yaml.Ruleset{ + If: yaml.Rules{ + Event: []string{"tag"}, + Tag: []string{"v*"}, + }, + Matcher: "filepath", + Operator: "and", + }, }, }, }, @@ -3325,6 +3202,97 @@ func Test_CompileLite(t *testing.T) { }, wantErr: false, }, + { + name: "render_inline with stages - ruleset", + args: args{ + file: "testdata/inline_with_stages.yml", + pipelineType: "", + substitute: true, + ruleData: &pipeline.RuleData{ + Event: "push", + Branch: "main", + }, + }, + want: &yaml.Build{ + Version: "1", + Metadata: yaml.Metadata{ + RenderInline: true, + Environment: []string{"steps", "services", "secrets"}, + }, + Templates: []*yaml.Template{ + { + Name: "golang", + Source: "github.example.com/github/octocat/golang_inline_stages.yml", + Format: "golang", + Type: "github", + Variables: map[string]any{ + "image": string("golang:latest"), + "VELA_TEMPLATE_NAME": string("golang"), + }, + }, + { + Name: "starlark", + Source: "github.example.com/github/octocat/starlark_inline_stages.star", + Format: "starlark", + Type: "github", + Variables: map[string]any{"VELA_TEMPLATE_NAME": string("starlark")}, + }, + }, + Environment: raw.StringSliceMap{}, + Stages: []*yaml.Stage{ + { + Name: "test", + Needs: []string{"clone"}, + Steps: []*yaml.Step{ + { + Commands: raw.StringSlice{"echo from inline"}, + Image: "alpine", + Name: "test", + Pull: "not_present", + }, + { + Commands: raw.StringSlice{"echo from inline ruleset"}, + Image: "alpine", + Name: "ruleset", + Pull: "not_present", + Ruleset: yaml.Ruleset{ + If: yaml.Rules{ + Event: []string{"push"}, + Branch: []string{"main"}, + }, + Matcher: "filepath", + Operator: "and", + }, + }, + }, + }, + { + Name: "starlark_foo", + Needs: []string{"clone"}, + Steps: []*yaml.Step{ + { + Commands: raw.StringSlice{"echo hello from foo"}, + Image: "alpine", + Name: "starlark_build_foo", + Pull: "not_present", + }, + }, + }, + { + Name: "starlark_bar", + Needs: []string{"clone"}, + Steps: []*yaml.Step{ + { + Commands: raw.StringSlice{"echo hello from bar"}, + Image: "alpine", + Name: "starlark_build_bar", + Pull: "not_present", + }, + }, + }, + }, + }, + }, { name: "render_inline with steps", args: args{ @@ -3345,6 +3313,34 @@ func Test_CompileLite(t *testing.T) { Name: "test", Pull: "not_present", }, + { + Commands: raw.StringSlice{"echo from inline ruleset"}, + Image: "alpine", + Name: "ruleset", + Pull: "not_present", + Ruleset: yaml.Ruleset{ + If: yaml.Rules{ + Event: []string{"deployment"}, + Target: []string{"production"}, + }, + Matcher: "filepath", + Operator: "and", + }, + }, + { + Commands: raw.StringSlice{"echo from inline ruleset"}, + Image: "alpine", + Name: "other ruleset", + Pull: "not_present", + Ruleset: yaml.Ruleset{ + If: yaml.Rules{ + Path: []string{"src/*", "test/*"}, + Event: []string{}, + }, + Matcher: "filepath", + Operator: "and", + }, + }, { Commands: raw.StringSlice{"echo hello from foo"}, Image: "alpine", @@ -3396,6 +3392,339 @@ func Test_CompileLite(t *testing.T) { }, wantErr: false, }, + { + name: "render_inline with steps - ruleset", + args: args{ + file: "testdata/inline_with_steps.yml", + pipelineType: "", + substitute: true, + ruleData: &pipeline.RuleData{ + Event: "deployment", + Target: "production", + Path: []string{"README.md"}, + }, + }, + want: &yaml.Build{ + Version: "1", + Metadata: yaml.Metadata{ + RenderInline: true, + Environment: []string{"steps", "services", "secrets"}, + }, + Steps: yaml.StepSlice{ + { + Commands: raw.StringSlice{"echo from inline"}, + Image: "alpine", + Name: "test", + Pull: "not_present", + }, + { + Commands: raw.StringSlice{"echo from inline ruleset"}, + Image: "alpine", + Name: "ruleset", + Pull: "not_present", + Ruleset: yaml.Ruleset{ + If: yaml.Rules{ + Event: []string{"deployment"}, + Target: []string{"production"}, + }, + Matcher: "filepath", + Operator: "and", + }, + }, + { + Commands: raw.StringSlice{"echo hello from foo"}, + Image: "alpine", + Name: "golang_foo", + Pull: "not_present", + }, + { + Commands: raw.StringSlice{"echo hello from bar"}, + Image: "alpine", + Name: "golang_bar", + Pull: "not_present", + }, + { + Commands: raw.StringSlice{"echo hello from star"}, + Image: "alpine", + Name: "golang_star", + Pull: "not_present", + }, + { + Commands: raw.StringSlice{"echo hello from foo"}, + Image: "alpine", + Name: "starlark_build_foo", + Pull: "not_present", + }, + { + Commands: raw.StringSlice{"echo hello from bar"}, + Image: "alpine", + Name: "starlark_build_bar", + Pull: "not_present", + }, + }, + Environment: raw.StringSliceMap{}, + Templates: yaml.TemplateSlice{ + { + Name: "golang", + Source: "github.example.com/github/octocat/golang_inline_steps.yml", + Format: "golang", + Type: "github", + Variables: map[string]any{"VELA_TEMPLATE_NAME": string("golang")}, + }, + { + Name: "starlark", + Source: "github.example.com/github/octocat/starlark_inline_steps.star", + Format: "starlark", + Type: "github", + Variables: map[string]any{"VELA_TEMPLATE_NAME": string("starlark")}, + }, + }, + }, + }, + { + name: "call template with ruleset", + args: args{ + file: "testdata/steps_pipeline_template.yml", + pipelineType: "", + substitute: true, + ruleData: &pipeline.RuleData{ + Event: "push", + }, + }, + want: &yaml.Build{ + Version: "1", + Metadata: yaml.Metadata{ + Environment: []string{"steps", "services", "secrets"}, + }, + Environment: raw.StringSliceMap{ + "bar": "test4", + "star": "test3", + }, + Secrets: yaml.SecretSlice{ + { + Name: "docker_username", + Key: "org/repo/docker/username", + Engine: "native", + Type: "repo", + Pull: "build_start", + }, + { + Name: "docker_password", + Key: "org/repo/docker/password", + Engine: "vault", + Type: "repo", + Pull: "build_start", + }, + { + Name: "foo_password", + Key: "org/repo/foo/password", + Engine: "vault", + Type: "repo", + Pull: "build_start", + }, + }, + Services: yaml.ServiceSlice{ + { + Image: "postgres:12", + Name: "postgres", + Pull: "not_present", + }, + }, + Steps: yaml.StepSlice{ + { + Commands: raw.StringSlice{"./gradlew downloadDependencies"}, + Image: "openjdk:latest", + Name: "sample_install", + Pull: "always", + Environment: raw.StringSliceMap{ + "GRADLE_OPTS": "-Dorg.gradle.daemon=false -Dorg.gradle.workers.max=1 -Dorg.gradle.parallel=false", + "GRADLE_USER_HOME": ".gradle", + }, + }, + { + Commands: raw.StringSlice{"./gradlew check"}, + Image: "openjdk:latest", + Name: "sample_test", + Pull: "always", + Environment: raw.StringSliceMap{ + "GRADLE_OPTS": "-Dorg.gradle.daemon=false -Dorg.gradle.workers.max=1 -Dorg.gradle.parallel=false", + "GRADLE_USER_HOME": ".gradle", + }, + }, + { + Commands: raw.StringSlice{"./gradlew build", "echo gradle"}, + Image: "openjdk:latest", + Name: "sample_build", + Pull: "always", + Environment: raw.StringSliceMap{ + "GRADLE_OPTS": "-Dorg.gradle.daemon=false -Dorg.gradle.workers.max=1 -Dorg.gradle.parallel=false", + "GRADLE_USER_HOME": ".gradle", + }, + }, + { + Commands: raw.StringSlice{"echo hello from foo"}, + Image: "alpine", + Name: "starlark_build_foo", + Pull: "not_present", + }, + { + Commands: raw.StringSlice{"echo hello from bar"}, + Image: "alpine", + Name: "starlark_build_bar", + Pull: "not_present", + }, + { + Secrets: yaml.StepSecretSlice{ + { + Source: "docker_username", + Target: "registry_username", + }, + { + Source: "docker_password", + Target: "registry_password", + }, + }, + Image: "plugins/docker:18.09", + Name: "docker", + Pull: "always", + Parameters: map[string]any{ + "registry": string("index.docker.io"), + "repo": string("github/octocat"), + "tags": []any{string("latest"), string("dev")}, + }, + }, + }, + Templates: yaml.TemplateSlice{ + { + Name: "gradle", + Source: "github.example.com/foo/bar/long_template.yml", + Type: "github", + }, + { + Name: "starlark", + Source: "github.example.com/github/octocat/starlark_inline_steps.star", + Format: "starlark", + Type: "github", + }, + }, + }, + }, + { + name: "call template with ruleset - no match", + args: args{ + file: "testdata/steps_pipeline_template.yml", + pipelineType: "", + substitute: true, + ruleData: &pipeline.RuleData{ + Event: "pull_request", + }, + }, + want: &yaml.Build{ + Version: "1", + Metadata: yaml.Metadata{ + Environment: []string{"steps", "services", "secrets"}, + }, + Environment: raw.StringSliceMap{ + "bar": "test4", + "star": "test3", + }, + Secrets: yaml.SecretSlice{ + { + Name: "docker_username", + Key: "org/repo/docker/username", + Engine: "native", + Type: "repo", + Pull: "build_start", + }, + { + Name: "docker_password", + Key: "org/repo/docker/password", + Engine: "vault", + Type: "repo", + Pull: "build_start", + }, + { + Name: "foo_password", + Key: "org/repo/foo/password", + Engine: "vault", + Type: "repo", + Pull: "build_start", + }, + }, + Services: yaml.ServiceSlice{ + { + Image: "postgres:12", + Name: "postgres", + Pull: "not_present", + }, + }, + Steps: yaml.StepSlice{ + { + Commands: raw.StringSlice{"./gradlew downloadDependencies"}, + Image: "openjdk:latest", + Name: "sample_install", + Pull: "always", + Environment: raw.StringSliceMap{ + "GRADLE_OPTS": "-Dorg.gradle.daemon=false -Dorg.gradle.workers.max=1 -Dorg.gradle.parallel=false", + "GRADLE_USER_HOME": ".gradle", + }, + }, + { + Commands: raw.StringSlice{"./gradlew check"}, + Image: "openjdk:latest", + Name: "sample_test", + Pull: "always", + Environment: raw.StringSliceMap{ + "GRADLE_OPTS": "-Dorg.gradle.daemon=false -Dorg.gradle.workers.max=1 -Dorg.gradle.parallel=false", + "GRADLE_USER_HOME": ".gradle", + }, + }, + { + Commands: raw.StringSlice{"./gradlew build", "echo gradle"}, + Image: "openjdk:latest", + Name: "sample_build", + Pull: "always", + Environment: raw.StringSliceMap{ + "GRADLE_OPTS": "-Dorg.gradle.daemon=false -Dorg.gradle.workers.max=1 -Dorg.gradle.parallel=false", + "GRADLE_USER_HOME": ".gradle", + }, + }, + { + Secrets: yaml.StepSecretSlice{ + { + Source: "docker_username", + Target: "registry_username", + }, + { + Source: "docker_password", + Target: "registry_password", + }, + }, + Image: "plugins/docker:18.09", + Name: "docker", + Pull: "always", + Parameters: map[string]any{ + "registry": string("index.docker.io"), + "repo": string("github/octocat"), + "tags": []any{string("latest"), string("dev")}, + }, + }, + }, + Templates: yaml.TemplateSlice{ + { + Name: "gradle", + Source: "github.example.com/foo/bar/long_template.yml", + Type: "github", + }, + { + Name: "starlark", + Source: "github.example.com/github/octocat/starlark_inline_steps.star", + Format: "starlark", + Type: "github", + }, + }, + }, + }, { name: "golang", args: args{ @@ -3418,6 +3747,14 @@ func Test_CompileLite(t *testing.T) { Image: "alpine", Name: "foo", Pull: "not_present", + Ruleset: yaml.Ruleset{ + If: yaml.Rules{ + Event: []string{"tag"}, + Tag: []string{"v*"}, + }, + Matcher: "filepath", + Operator: "and", + }, }, }, }, @@ -3430,6 +3767,14 @@ func Test_CompileLite(t *testing.T) { Image: "alpine", Name: "bar", Pull: "not_present", + Ruleset: yaml.Ruleset{ + If: yaml.Rules{ + Event: []string{"tag"}, + Tag: []string{"v*"}, + }, + Matcher: "filepath", + Operator: "and", + }, }, }, }, @@ -3442,6 +3787,14 @@ func Test_CompileLite(t *testing.T) { Image: "alpine", Name: "star", Pull: "not_present", + Ruleset: yaml.Ruleset{ + If: yaml.Rules{ + Event: []string{"tag"}, + Tag: []string{"v*"}, + }, + Matcher: "filepath", + Operator: "and", + }, }, }, }, @@ -3488,7 +3841,7 @@ func Test_CompileLite(t *testing.T) { t.Errorf("Reading yaml file return err: %v", err) } - got, _, err := compiler.CompileLite(yaml, tt.args.substitute) + got, _, err := compiler.CompileLite(yaml, tt.args.ruleData, tt.args.substitute) if (err != nil) != tt.wantErr { t.Errorf("CompileLite() error = %v, wantErr %v", err, tt.wantErr) return diff --git a/compiler/native/testdata/golang_inline_stages.yml b/compiler/native/testdata/golang_inline_stages.yml index 59b390d47..f8ca4d849 100644 --- a/compiler/native/testdata/golang_inline_stages.yml +++ b/compiler/native/testdata/golang_inline_stages.yml @@ -8,6 +8,9 @@ stages: steps: - name: {{ $stage }} image: {{ default "alpine" $.image }} + ruleset: + event: tag + tag: v* commands: - echo hello from {{ $stage }} {{ end }} \ No newline at end of file diff --git a/compiler/native/testdata/inline_with_stages.yml b/compiler/native/testdata/inline_with_stages.yml index 89d79b5e3..0834b976d 100644 --- a/compiler/native/testdata/inline_with_stages.yml +++ b/compiler/native/testdata/inline_with_stages.yml @@ -21,4 +21,11 @@ stages: - name: test image: alpine commands: - - echo from inline \ No newline at end of file + - echo from inline + - name: ruleset + image: alpine + ruleset: + event: push + branch: main + commands: + - echo from inline ruleset \ No newline at end of file diff --git a/compiler/native/testdata/inline_with_steps.yml b/compiler/native/testdata/inline_with_steps.yml index 28348cf8d..7bee378dd 100644 --- a/compiler/native/testdata/inline_with_steps.yml +++ b/compiler/native/testdata/inline_with_steps.yml @@ -17,4 +17,17 @@ steps: - name: test image: alpine commands: - - echo from inline \ No newline at end of file + - echo from inline + - name: ruleset + image: alpine + ruleset: + event: deployment + target: production + commands: + - echo from inline ruleset + - name: other ruleset + image: alpine + ruleset: + path: [ "src/*", "test/*" ] + commands: + - echo from inline ruleset \ No newline at end of file diff --git a/compiler/native/testdata/steps_pipeline_template.yml b/compiler/native/testdata/steps_pipeline_template.yml index 7d8e8db28..beaca0fb8 100644 --- a/compiler/native/testdata/steps_pipeline_template.yml +++ b/compiler/native/testdata/steps_pipeline_template.yml @@ -8,6 +8,11 @@ templates: source: github.example.com/foo/bar/long_template.yml type: github + - name: starlark + source: github.example.com/github/octocat/starlark_inline_steps.star + format: starlark + type: github + steps: # would execute the following steps: # 1. sample_get_dependencies @@ -21,6 +26,12 @@ steps: environment: "{ GRADLE_USER_HOME: .gradle, GRADLE_OPTS: -Dorg.gradle.daemon=false -Dorg.gradle.workers.max=1 -Dorg.gradle.parallel=false }" pull_policy: "pull: true" + - name: starlark + ruleset: + event: push + template: + name: starlark + - name: docker image: plugins/docker:18.09 parameters: From fb31ea5a6e965c31441a517cdda1fbfdfce0492a Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Fri, 5 Apr 2024 12:09:33 -0400 Subject: [PATCH 22/71] fix(api/pipeline): correct type for path query param + add testing (#1100) --- api/pipeline/compile.go | 10 +--- api/pipeline/compile_test.go | 93 ++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 8 deletions(-) create mode 100644 api/pipeline/compile_test.go diff --git a/api/pipeline/compile.go b/api/pipeline/compile.go index b47d243e8..2b5782fe7 100644 --- a/api/pipeline/compile.go +++ b/api/pipeline/compile.go @@ -6,7 +6,6 @@ package pipeline import ( "fmt" "net/http" - "strings" "github.com/gin-gonic/gin" "github.com/go-vela/server/compiler" @@ -127,19 +126,14 @@ func prepareRuleData(c *gin.Context) *pipeline.RuleData { tag := c.Query("tag") // capture the target parameter target := c.Query("target") - - var pathSet []string // capture the path parameter - path := c.Query("path") - if len(path) > 0 { - pathSet = strings.Split(path, ",") - } + pathSet := c.QueryArray("path") // if any ruledata query params were provided, create ruledata struct if len(branch) > 0 || len(comment) > 0 || len(event) > 0 || - len(path) > 0 || + len(pathSet) > 0 || len(ruleDataRepo) > 0 || len(status) > 0 || len(tag) > 0 || diff --git a/api/pipeline/compile_test.go b/api/pipeline/compile_test.go new file mode 100644 index 000000000..c65ce1d0b --- /dev/null +++ b/api/pipeline/compile_test.go @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: Apache-2.0 + +package pipeline + +import ( + "net/http" + "net/http/httptest" + "strings" + "testing" + + "github.com/gin-gonic/gin" + "github.com/go-vela/types/pipeline" + "github.com/google/go-cmp/cmp" +) + +// TestPrepareRuleData tests the prepareRuleData function. +func TestPrepareRuleData(t *testing.T) { + gin.SetMode(gin.TestMode) + + tests := []struct { + name string + parameters map[string]string + want *pipeline.RuleData + }{ + { + name: "all params provided", + parameters: map[string]string{ + "branch": "main", + "comment": "Test comment", + "event": "push", + "repo": "my-repo", + "status": "success", + "tag": "v1.0.0", + "target": "production", + "path": "README.md", + }, + want: &pipeline.RuleData{ + Branch: "main", + Comment: "Test comment", + Event: "push", + Repo: "my-repo", + Status: "success", + Tag: "v1.0.0", + Target: "production", + Path: []string{"README.md"}, + }, + }, + { + name: "multiple path params", + parameters: map[string]string{ + "path": "README.md", + "branch": "main", + }, + want: &pipeline.RuleData{ + Branch: "main", + Path: []string{"README.md", "src/main.go"}, + }, + }, + { + name: "no params provided", + parameters: map[string]string{}, + want: nil, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + w := httptest.NewRecorder() + req, _ := http.NewRequest("GET", "/", nil) + + q := req.URL.Query() + for key, value := range tt.parameters { + q.Add(key, value) + } + + // add additional path parameter for multiple path test + if strings.EqualFold(tt.name, "multiple path params") { + q.Add("path", "src/main.go") + } + + req.URL.RawQuery = q.Encode() + + ctx, _ := gin.CreateTestContext(w) + ctx.Request = req + + got := prepareRuleData(ctx) + + if diff := cmp.Diff(tt.want, got); diff != "" { + t.Errorf("prepareRuleData() mismatch (-want +got):\n%s", diff) + } + }) + } +} From e7917a8b4085db4da7a363c7974f534d505cf950 Mon Sep 17 00:00:00 2001 From: Win San Date: Fri, 5 Apr 2024 14:42:45 -0500 Subject: [PATCH 23/71] feat(rulesets): add support for PR labeled events (#1081) * Process PR label event 1. Add API changes for updating repos to leverage label events 2. Process PR label events in scm package 3. Update compiler to use label value in its purging process * Add labeled event to PR struct * Merge branch 'main' into feat/pr-labeled-action * Add support for PR unlabeled event 1. Update process PR event helper function 2. Update tests * chore: remove legacy event code from repo and secret * Extend label rule to include other PR events * Update go.mod * Fix linter warnings * Add tests for webhook and native compiler * Update test for webhook --------- Co-authored-by: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Co-authored-by: ecrupper Co-authored-by: Tim Huynh --- api/build/compile_publish.go | 2 + api/webhook/post.go | 11 +- compiler/engine.go | 3 + compiler/native/compile.go | 1 + compiler/native/expand_test.go | 2 + compiler/native/native.go | 10 + compiler/native/native_test.go | 20 + database/repo/repo_test.go | 2 + database/secret/secret_test.go | 2 + go.mod | 2 +- go.sum | 4 +- .../pull_request_edited_while_labeled.json | 466 ++++++++++++++++++ .../testdata/hooks/pull_request_labeled.json | 451 +++++++++++++++++ .../hooks/pull_request_unlabeled.json | 451 +++++++++++++++++ scm/github/webhook.go | 18 +- scm/github/webhook_test.go | 90 ++++ 16 files changed, 1529 insertions(+), 6 deletions(-) create mode 100644 scm/github/testdata/hooks/pull_request_edited_while_labeled.json create mode 100644 scm/github/testdata/hooks/pull_request_labeled.json create mode 100644 scm/github/testdata/hooks/pull_request_unlabeled.json diff --git a/api/build/compile_publish.go b/api/build/compile_publish.go index ea908862f..f60dcaa56 100644 --- a/api/build/compile_publish.go +++ b/api/build/compile_publish.go @@ -31,6 +31,7 @@ type CompileAndPublishConfig struct { BaseErr string Source string Comment string + Labels []string Retries int } @@ -287,6 +288,7 @@ func CompileAndPublish( WithMetadata(cfg.Metadata). WithRepo(repo). WithUser(u). + WithLabels(cfg.Labels). Compile(pipelineFile) if err != nil { // format the error message with extra information diff --git a/api/webhook/post.go b/api/webhook/post.go index 8ebf0bf7f..d33a201e9 100644 --- a/api/webhook/post.go +++ b/api/webhook/post.go @@ -272,11 +272,19 @@ func PostWebhook(c *gin.Context) { return } - var prComment string + var ( + prComment string + prLabels []string + ) + if strings.EqualFold(b.GetEvent(), constants.EventComment) { prComment = webhook.PullRequest.Comment } + if strings.EqualFold(b.GetEvent(), constants.EventPull) { + prLabels = webhook.PullRequest.Labels + } + // construct CompileAndPublishConfig config := build.CompileAndPublishConfig{ Build: b, @@ -285,6 +293,7 @@ func PostWebhook(c *gin.Context) { BaseErr: baseErr, Source: "webhook", Comment: prComment, + Labels: prLabels, Retries: 3, } diff --git a/compiler/engine.go b/compiler/engine.go index b0a5c032f..566696b91 100644 --- a/compiler/engine.go +++ b/compiler/engine.go @@ -140,6 +140,9 @@ type Engine interface { // WithUser defines a function that sets // the library user type in the Engine. WithUser(*library.User) Engine + // WithLabel defines a function that sets + // the label(s) in the Engine. + WithLabels([]string) Engine // WithUser defines a function that sets // the private github client in the Engine. WithPrivateGitHub(string, string) Engine diff --git a/compiler/native/compile.go b/compiler/native/compile.go index 423d3cecf..1c02e4d7a 100644 --- a/compiler/native/compile.go +++ b/compiler/native/compile.go @@ -70,6 +70,7 @@ func (c *client) Compile(v interface{}) (*pipeline.Build, *library.Pipeline, err Repo: c.repo.GetFullName(), Tag: strings.TrimPrefix(c.build.GetRef(), "refs/tags/"), Target: c.build.GetDeploy(), + Label: c.labels, } switch { diff --git a/compiler/native/expand_test.go b/compiler/native/expand_test.go index df04741e3..6d9479a53 100644 --- a/compiler/native/expand_test.go +++ b/compiler/native/expand_test.go @@ -450,6 +450,7 @@ func TestNative_ExpandStepsMulti(t *testing.T) { If: yaml.Rules{ Branch: []string{"main"}, }, + Operator: "and", }, }, &yaml.Step{ @@ -466,6 +467,7 @@ func TestNative_ExpandStepsMulti(t *testing.T) { If: yaml.Rules{ Branch: []string{"dev"}, }, + Operator: "and", }, }, } diff --git a/compiler/native/native.go b/compiler/native/native.go index a93c6fd50..048f22307 100644 --- a/compiler/native/native.go +++ b/compiler/native/native.go @@ -42,6 +42,7 @@ type client struct { metadata *types.Metadata repo *library.Repo user *library.User + labels []string } // New returns a Pipeline implementation that integrates with the supported registries. @@ -210,3 +211,12 @@ func (c *client) WithUser(u *library.User) compiler.Engine { return c } + +// WithLabels sets the label(s) in the Engine. +func (c *client) WithLabels(labels []string) compiler.Engine { + if len(labels) != 0 { + c.labels = labels + } + + return c +} diff --git a/compiler/native/native_test.go b/compiler/native/native_test.go index 36be98195..489288ee7 100644 --- a/compiler/native/native_test.go +++ b/compiler/native/native_test.go @@ -328,3 +328,23 @@ func TestNative_WithUser(t *testing.T) { t.Errorf("WithUser is %v, want %v", got, want) } } + +func TestNative_WithLabels(t *testing.T) { + // setup types + set := flag.NewFlagSet("test", 0) + c := cli.NewContext(nil, set, nil) + + labels := []string{"documentation", "enhancement"} + want, _ := New(c) + want.labels = []string{"documentation", "enhancement"} + + // run test + got, err := New(c) + if err != nil { + t.Errorf("Unable to create new compiler: %v", err) + } + + if !reflect.DeepEqual(got.WithLabels(labels), want) { + t.Errorf("WithLocalTemplates is %v, want %v", got, want) + } +} diff --git a/database/repo/repo_test.go b/database/repo/repo_test.go index 325732a56..7abb255d6 100644 --- a/database/repo/repo_test.go +++ b/database/repo/repo_test.go @@ -211,6 +211,8 @@ func testEvents() *library.Events { Edited: new(bool), Synchronize: new(bool), Reopened: new(bool), + Labeled: new(bool), + Unlabeled: new(bool), }, Deployment: &actions.Deploy{ Created: new(bool), diff --git a/database/secret/secret_test.go b/database/secret/secret_test.go index 160f208cb..5382c054b 100644 --- a/database/secret/secret_test.go +++ b/database/secret/secret_test.go @@ -236,6 +236,8 @@ func testEvents() *library.Events { Edited: new(bool), Synchronize: new(bool), Reopened: new(bool), + Labeled: new(bool), + Unlabeled: new(bool), }, Deployment: &actions.Deploy{ Created: new(bool), diff --git a/go.mod b/go.mod index 681104cdc..5a52e83a0 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/drone/envsubst v1.0.3 github.com/gin-gonic/gin v1.9.1 github.com/go-playground/assert/v2 v2.2.0 - github.com/go-vela/types v0.23.4-0.20240401132228-9b43c701ab32 + github.com/go-vela/types v0.23.4-0.20240402153726-f16c3e4cb5fb github.com/golang-jwt/jwt/v5 v5.2.1 github.com/google/go-cmp v0.6.0 github.com/google/go-github/v59 v59.0.0 diff --git a/go.sum b/go.sum index a956a83fd..9c4e1259a 100644 --- a/go.sum +++ b/go.sum @@ -85,8 +85,8 @@ github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw= github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= -github.com/go-vela/types v0.23.4-0.20240401132228-9b43c701ab32 h1:fqmNnM1LdH3Zg1zCADfgR7a51EOSZvLFAB2Em4CG+Pg= -github.com/go-vela/types v0.23.4-0.20240401132228-9b43c701ab32/go.mod h1:mEF9dLkk00rUXf/t39n2WvXZgJbxnPEEWy+DHqIlRUo= +github.com/go-vela/types v0.23.4-0.20240402153726-f16c3e4cb5fb h1:jHao/NNRswInMLEb0m1OJ84d1m/LGWMCmaeRqSDnWQY= +github.com/go-vela/types v0.23.4-0.20240402153726-f16c3e4cb5fb/go.mod h1:mEF9dLkk00rUXf/t39n2WvXZgJbxnPEEWy+DHqIlRUo= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= diff --git a/scm/github/testdata/hooks/pull_request_edited_while_labeled.json b/scm/github/testdata/hooks/pull_request_edited_while_labeled.json new file mode 100644 index 000000000..55471932e --- /dev/null +++ b/scm/github/testdata/hooks/pull_request_edited_while_labeled.json @@ -0,0 +1,466 @@ +{ + "action": "edited", + "number": 1, + "pull_request": { + "url": "https://api.github.com/repos/Codertocat/Hello-World/pulls/1", + "id": 191568743, + "node_id": "MDExOlB1bGxSZXF1ZXN0MTkxNTY4NzQz", + "html_url": "https://github.com/Codertocat/Hello-World/pull/1", + "diff_url": "https://github.com/Codertocat/Hello-World/pull/1.diff", + "patch_url": "https://github.com/Codertocat/Hello-World/pull/1.patch", + "issue_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/1", + "number": 1, + "state": "open", + "locked": false, + "title": "Update the README with new information", + "user": { + "login": "Codertocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Codertocat", + "html_url": "https://github.com/Codertocat", + "followers_url": "https://api.github.com/users/Codertocat/followers", + "following_url": "https://api.github.com/users/Codertocat/following{/other_user}", + "gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions", + "organizations_url": "https://api.github.com/users/Codertocat/orgs", + "repos_url": "https://api.github.com/users/Codertocat/repos", + "events_url": "https://api.github.com/users/Codertocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/Codertocat/received_events", + "type": "User", + "site_admin": false + }, + "body": "This is a pretty simple change that we need to pull into main.", + "created_at": "2018-05-30T20:18:30Z", + "updated_at": "2018-05-30T20:18:50Z", + "closed_at": "2018-05-30T20:18:50Z", + "merged_at": null, + "merge_commit_sha": "414cb0069601a32b00bd122a2380cd283626a8e5", + "assignee": null, + "assignees": [], + "requested_reviewers": [], + "requested_teams": [], + "labels": [ + { + "id": 3768735, + "node_id": "MDU6TGFiZWwzNzY4NzM1", + "url": "https://git.target.com/api/v3/repos/WinSan/vela-sandbox/labels/documentation", + "name": "documentation", + "color": "0075ca", + "default": true, + "description": "Improvements or additions to documentation" + }, + { + "id": 3768737, + "node_id": "MDU6TGFiZWwzNzY4NzM3", + "url": "https://git.target.com/api/v3/repos/WinSan/vela-sandbox/labels/enhancement", + "name": "enhancement", + "color": "a2eeef", + "default": true, + "description": "New feature or request" + } + ], + "milestone": null, + "commits_url": "https://api.github.com/repos/Codertocat/Hello-World/pulls/1/commits", + "review_comments_url": "https://api.github.com/repos/Codertocat/Hello-World/pulls/1/comments", + "review_comment_url": "https://api.github.com/repos/Codertocat/Hello-World/pulls/comments{/number}", + "comments_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/1/comments", + "statuses_url": "https://api.github.com/repos/Codertocat/Hello-World/statuses/34c5c7793cb3b279e22454cb6750c80560547b3a", + "head": { + "label": "Codertocat:changes", + "ref": "changes", + "sha": "34c5c7793cb3b279e22454cb6750c80560547b3a", + "user": { + "login": "Codertocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Codertocat", + "html_url": "https://github.com/Codertocat", + "followers_url": "https://api.github.com/users/Codertocat/followers", + "following_url": "https://api.github.com/users/Codertocat/following{/other_user}", + "gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions", + "organizations_url": "https://api.github.com/users/Codertocat/orgs", + "repos_url": "https://api.github.com/users/Codertocat/repos", + "events_url": "https://api.github.com/users/Codertocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/Codertocat/received_events", + "type": "User", + "site_admin": false + }, + "repo": { + "id": 135493233, + "node_id": "MDEwOlJlcG9zaXRvcnkxMzU0OTMyMzM=", + "name": "Hello-World", + "full_name": "Codertocat/Hello-World", + "owner": { + "login": "Codertocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Codertocat", + "html_url": "https://github.com/Codertocat", + "followers_url": "https://api.github.com/users/Codertocat/followers", + "following_url": "https://api.github.com/users/Codertocat/following{/other_user}", + "gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions", + "organizations_url": "https://api.github.com/users/Codertocat/orgs", + "repos_url": "https://api.github.com/users/Codertocat/repos", + "events_url": "https://api.github.com/users/Codertocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/Codertocat/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/Codertocat/Hello-World", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/Codertocat/Hello-World", + "forks_url": "https://api.github.com/repos/Codertocat/Hello-World/forks", + "keys_url": "https://api.github.com/repos/Codertocat/Hello-World/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/Codertocat/Hello-World/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/Codertocat/Hello-World/teams", + "hooks_url": "https://api.github.com/repos/Codertocat/Hello-World/hooks", + "issue_events_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/events{/number}", + "events_url": "https://api.github.com/repos/Codertocat/Hello-World/events", + "assignees_url": "https://api.github.com/repos/Codertocat/Hello-World/assignees{/user}", + "branches_url": "https://api.github.com/repos/Codertocat/Hello-World/branches{/branch}", + "tags_url": "https://api.github.com/repos/Codertocat/Hello-World/tags", + "blobs_url": "https://api.github.com/repos/Codertocat/Hello-World/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/Codertocat/Hello-World/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/Codertocat/Hello-World/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/Codertocat/Hello-World/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/Codertocat/Hello-World/statuses/{sha}", + "languages_url": "https://api.github.com/repos/Codertocat/Hello-World/languages", + "stargazers_url": "https://api.github.com/repos/Codertocat/Hello-World/stargazers", + "contributors_url": "https://api.github.com/repos/Codertocat/Hello-World/contributors", + "subscribers_url": "https://api.github.com/repos/Codertocat/Hello-World/subscribers", + "subscription_url": "https://api.github.com/repos/Codertocat/Hello-World/subscription", + "commits_url": "https://api.github.com/repos/Codertocat/Hello-World/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/Codertocat/Hello-World/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/Codertocat/Hello-World/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/Codertocat/Hello-World/contents/{+path}", + "compare_url": "https://api.github.com/repos/Codertocat/Hello-World/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/Codertocat/Hello-World/merges", + "archive_url": "https://api.github.com/repos/Codertocat/Hello-World/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/Codertocat/Hello-World/downloads", + "issues_url": "https://api.github.com/repos/Codertocat/Hello-World/issues{/number}", + "pulls_url": "https://api.github.com/repos/Codertocat/Hello-World/pulls{/number}", + "milestones_url": "https://api.github.com/repos/Codertocat/Hello-World/milestones{/number}", + "notifications_url": "https://api.github.com/repos/Codertocat/Hello-World/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/Codertocat/Hello-World/labels{/name}", + "releases_url": "https://api.github.com/repos/Codertocat/Hello-World/releases{/id}", + "deployments_url": "https://api.github.com/repos/Codertocat/Hello-World/deployments", + "created_at": "2018-05-30T20:18:04Z", + "updated_at": "2018-05-30T20:18:50Z", + "pushed_at": "2018-05-30T20:18:48Z", + "git_url": "git://github.com/Codertocat/Hello-World.git", + "ssh_url": "git@github.com:Codertocat/Hello-World.git", + "clone_url": "https://github.com/Codertocat/Hello-World.git", + "svn_url": "https://github.com/Codertocat/Hello-World", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "open_issues_count": 1, + "license": null, + "forks": 0, + "open_issues": 1, + "watchers": 0, + "default_branch": "main" + } + }, + "base": { + "label": "Codertocat:main", + "ref": "main", + "sha": "a10867b14bb761a232cd80139fbd4c0d33264240", + "user": { + "login": "Codertocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Codertocat", + "html_url": "https://github.com/Codertocat", + "followers_url": "https://api.github.com/users/Codertocat/followers", + "following_url": "https://api.github.com/users/Codertocat/following{/other_user}", + "gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions", + "organizations_url": "https://api.github.com/users/Codertocat/orgs", + "repos_url": "https://api.github.com/users/Codertocat/repos", + "events_url": "https://api.github.com/users/Codertocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/Codertocat/received_events", + "type": "User", + "site_admin": false + }, + "repo": { + "id": 135493233, + "node_id": "MDEwOlJlcG9zaXRvcnkxMzU0OTMyMzM=", + "name": "Hello-World", + "full_name": "Codertocat/Hello-World", + "owner": { + "login": "Codertocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Codertocat", + "html_url": "https://github.com/Codertocat", + "followers_url": "https://api.github.com/users/Codertocat/followers", + "following_url": "https://api.github.com/users/Codertocat/following{/other_user}", + "gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions", + "organizations_url": "https://api.github.com/users/Codertocat/orgs", + "repos_url": "https://api.github.com/users/Codertocat/repos", + "events_url": "https://api.github.com/users/Codertocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/Codertocat/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/Codertocat/Hello-World", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/Codertocat/Hello-World", + "forks_url": "https://api.github.com/repos/Codertocat/Hello-World/forks", + "keys_url": "https://api.github.com/repos/Codertocat/Hello-World/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/Codertocat/Hello-World/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/Codertocat/Hello-World/teams", + "hooks_url": "https://api.github.com/repos/Codertocat/Hello-World/hooks", + "issue_events_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/events{/number}", + "events_url": "https://api.github.com/repos/Codertocat/Hello-World/events", + "assignees_url": "https://api.github.com/repos/Codertocat/Hello-World/assignees{/user}", + "branches_url": "https://api.github.com/repos/Codertocat/Hello-World/branches{/branch}", + "tags_url": "https://api.github.com/repos/Codertocat/Hello-World/tags", + "blobs_url": "https://api.github.com/repos/Codertocat/Hello-World/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/Codertocat/Hello-World/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/Codertocat/Hello-World/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/Codertocat/Hello-World/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/Codertocat/Hello-World/statuses/{sha}", + "languages_url": "https://api.github.com/repos/Codertocat/Hello-World/languages", + "stargazers_url": "https://api.github.com/repos/Codertocat/Hello-World/stargazers", + "contributors_url": "https://api.github.com/repos/Codertocat/Hello-World/contributors", + "subscribers_url": "https://api.github.com/repos/Codertocat/Hello-World/subscribers", + "subscription_url": "https://api.github.com/repos/Codertocat/Hello-World/subscription", + "commits_url": "https://api.github.com/repos/Codertocat/Hello-World/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/Codertocat/Hello-World/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/Codertocat/Hello-World/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/Codertocat/Hello-World/contents/{+path}", + "compare_url": "https://api.github.com/repos/Codertocat/Hello-World/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/Codertocat/Hello-World/merges", + "archive_url": "https://api.github.com/repos/Codertocat/Hello-World/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/Codertocat/Hello-World/downloads", + "issues_url": "https://api.github.com/repos/Codertocat/Hello-World/issues{/number}", + "pulls_url": "https://api.github.com/repos/Codertocat/Hello-World/pulls{/number}", + "milestones_url": "https://api.github.com/repos/Codertocat/Hello-World/milestones{/number}", + "notifications_url": "https://api.github.com/repos/Codertocat/Hello-World/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/Codertocat/Hello-World/labels{/name}", + "releases_url": "https://api.github.com/repos/Codertocat/Hello-World/releases{/id}", + "deployments_url": "https://api.github.com/repos/Codertocat/Hello-World/deployments", + "created_at": "2018-05-30T20:18:04Z", + "updated_at": "2018-05-30T20:18:50Z", + "pushed_at": "2018-05-30T20:18:48Z", + "git_url": "git://github.com/Codertocat/Hello-World.git", + "ssh_url": "git@github.com:Codertocat/Hello-World.git", + "clone_url": "https://github.com/Codertocat/Hello-World.git", + "svn_url": "https://github.com/Codertocat/Hello-World", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "open_issues_count": 1, + "license": null, + "forks": 0, + "open_issues": 1, + "watchers": 0, + "default_branch": "main" + } + }, + "_links": { + "self": { + "href": "https://api.github.com/repos/Codertocat/Hello-World/pulls/1" + }, + "html": { + "href": "https://github.com/Codertocat/Hello-World/pull/1" + }, + "issue": { + "href": "https://api.github.com/repos/Codertocat/Hello-World/issues/1" + }, + "comments": { + "href": "https://api.github.com/repos/Codertocat/Hello-World/issues/1/comments" + }, + "review_comments": { + "href": "https://api.github.com/repos/Codertocat/Hello-World/pulls/1/comments" + }, + "review_comment": { + "href": "https://api.github.com/repos/Codertocat/Hello-World/pulls/comments{/number}" + }, + "commits": { + "href": "https://api.github.com/repos/Codertocat/Hello-World/pulls/1/commits" + }, + "statuses": { + "href": "https://api.github.com/repos/Codertocat/Hello-World/statuses/34c5c7793cb3b279e22454cb6750c80560547b3a" + } + }, + "author_association": "OWNER", + "merged": false, + "mergeable": true, + "rebaseable": true, + "mergeable_state": "clean", + "merged_by": null, + "comments": 0, + "review_comments": 1, + "maintainer_can_modify": false, + "commits": 1, + "additions": 1, + "deletions": 1, + "changed_files": 1 + }, + "changes": { + "title": { + "from": "Update README.md." + } + }, + "repository": { + "id": 135493233, + "node_id": "MDEwOlJlcG9zaXRvcnkxMzU0OTMyMzM=", + "name": "Hello-World", + "full_name": "Codertocat/Hello-World", + "owner": { + "login": "Codertocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Codertocat", + "html_url": "https://github.com/Codertocat", + "followers_url": "https://api.github.com/users/Codertocat/followers", + "following_url": "https://api.github.com/users/Codertocat/following{/other_user}", + "gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions", + "organizations_url": "https://api.github.com/users/Codertocat/orgs", + "repos_url": "https://api.github.com/users/Codertocat/repos", + "events_url": "https://api.github.com/users/Codertocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/Codertocat/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/Codertocat/Hello-World", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/Codertocat/Hello-World", + "forks_url": "https://api.github.com/repos/Codertocat/Hello-World/forks", + "keys_url": "https://api.github.com/repos/Codertocat/Hello-World/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/Codertocat/Hello-World/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/Codertocat/Hello-World/teams", + "hooks_url": "https://api.github.com/repos/Codertocat/Hello-World/hooks", + "issue_events_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/events{/number}", + "events_url": "https://api.github.com/repos/Codertocat/Hello-World/events", + "assignees_url": "https://api.github.com/repos/Codertocat/Hello-World/assignees{/user}", + "branches_url": "https://api.github.com/repos/Codertocat/Hello-World/branches{/branch}", + "tags_url": "https://api.github.com/repos/Codertocat/Hello-World/tags", + "blobs_url": "https://api.github.com/repos/Codertocat/Hello-World/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/Codertocat/Hello-World/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/Codertocat/Hello-World/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/Codertocat/Hello-World/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/Codertocat/Hello-World/statuses/{sha}", + "languages_url": "https://api.github.com/repos/Codertocat/Hello-World/languages", + "stargazers_url": "https://api.github.com/repos/Codertocat/Hello-World/stargazers", + "contributors_url": "https://api.github.com/repos/Codertocat/Hello-World/contributors", + "subscribers_url": "https://api.github.com/repos/Codertocat/Hello-World/subscribers", + "subscription_url": "https://api.github.com/repos/Codertocat/Hello-World/subscription", + "commits_url": "https://api.github.com/repos/Codertocat/Hello-World/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/Codertocat/Hello-World/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/Codertocat/Hello-World/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/Codertocat/Hello-World/contents/{+path}", + "compare_url": "https://api.github.com/repos/Codertocat/Hello-World/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/Codertocat/Hello-World/merges", + "archive_url": "https://api.github.com/repos/Codertocat/Hello-World/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/Codertocat/Hello-World/downloads", + "issues_url": "https://api.github.com/repos/Codertocat/Hello-World/issues{/number}", + "pulls_url": "https://api.github.com/repos/Codertocat/Hello-World/pulls{/number}", + "milestones_url": "https://api.github.com/repos/Codertocat/Hello-World/milestones{/number}", + "notifications_url": "https://api.github.com/repos/Codertocat/Hello-World/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/Codertocat/Hello-World/labels{/name}", + "releases_url": "https://api.github.com/repos/Codertocat/Hello-World/releases{/id}", + "deployments_url": "https://api.github.com/repos/Codertocat/Hello-World/deployments", + "created_at": "2018-05-30T20:18:04Z", + "updated_at": "2018-05-30T20:18:50Z", + "pushed_at": "2018-05-30T20:18:48Z", + "git_url": "git://github.com/Codertocat/Hello-World.git", + "ssh_url": "git@github.com:Codertocat/Hello-World.git", + "clone_url": "https://github.com/Codertocat/Hello-World.git", + "svn_url": "https://github.com/Codertocat/Hello-World", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "open_issues_count": 1, + "license": null, + "forks": 0, + "open_issues": 1, + "watchers": 0, + "default_branch": "main" + }, + "sender": { + "login": "Codertocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Codertocat", + "html_url": "https://github.com/Codertocat", + "followers_url": "https://api.github.com/users/Codertocat/followers", + "following_url": "https://api.github.com/users/Codertocat/following{/other_user}", + "gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions", + "organizations_url": "https://api.github.com/users/Codertocat/orgs", + "repos_url": "https://api.github.com/users/Codertocat/repos", + "events_url": "https://api.github.com/users/Codertocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/Codertocat/received_events", + "type": "User", + "site_admin": false + } +} \ No newline at end of file diff --git a/scm/github/testdata/hooks/pull_request_labeled.json b/scm/github/testdata/hooks/pull_request_labeled.json new file mode 100644 index 000000000..5d2cbd6eb --- /dev/null +++ b/scm/github/testdata/hooks/pull_request_labeled.json @@ -0,0 +1,451 @@ +{ + "action": "labeled", + "number": 1, + "pull_request": { + "url": "https://api.github.com/repos/Codertocat/Hello-World/pulls/1", + "id": 191568743, + "node_id": "MDExOlB1bGxSZXF1ZXN0MTkxNTY4NzQz", + "html_url": "https://github.com/Codertocat/Hello-World/pull/1", + "diff_url": "https://github.com/Codertocat/Hello-World/pull/1.diff", + "patch_url": "https://github.com/Codertocat/Hello-World/pull/1.patch", + "issue_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/1", + "number": 1, + "state": "open", + "locked": false, + "title": "Update the README with new information", + "user": { + "login": "Codertocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Codertocat", + "html_url": "https://github.com/Codertocat", + "followers_url": "https://api.github.com/users/Codertocat/followers", + "following_url": "https://api.github.com/users/Codertocat/following{/other_user}", + "gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions", + "organizations_url": "https://api.github.com/users/Codertocat/orgs", + "repos_url": "https://api.github.com/users/Codertocat/repos", + "events_url": "https://api.github.com/users/Codertocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/Codertocat/received_events", + "type": "User", + "site_admin": false + }, + "body": "This is a pretty simple change that we need to pull into main.", + "created_at": "2018-05-30T20:18:30Z", + "updated_at": "2018-05-30T20:18:50Z", + "closed_at": "2018-05-30T20:18:50Z", + "merged_at": null, + "merge_commit_sha": "414cb0069601a32b00bd122a2380cd283626a8e5", + "assignee": null, + "assignees": [], + "requested_reviewers": [], + "requested_teams": [], + "labels": [], + "milestone": null, + "commits_url": "https://api.github.com/repos/Codertocat/Hello-World/pulls/1/commits", + "review_comments_url": "https://api.github.com/repos/Codertocat/Hello-World/pulls/1/comments", + "review_comment_url": "https://api.github.com/repos/Codertocat/Hello-World/pulls/comments{/number}", + "comments_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/1/comments", + "statuses_url": "https://api.github.com/repos/Codertocat/Hello-World/statuses/34c5c7793cb3b279e22454cb6750c80560547b3a", + "head": { + "label": "Codertocat:changes", + "ref": "changes", + "sha": "34c5c7793cb3b279e22454cb6750c80560547b3a", + "user": { + "login": "Codertocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Codertocat", + "html_url": "https://github.com/Codertocat", + "followers_url": "https://api.github.com/users/Codertocat/followers", + "following_url": "https://api.github.com/users/Codertocat/following{/other_user}", + "gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions", + "organizations_url": "https://api.github.com/users/Codertocat/orgs", + "repos_url": "https://api.github.com/users/Codertocat/repos", + "events_url": "https://api.github.com/users/Codertocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/Codertocat/received_events", + "type": "User", + "site_admin": false + }, + "repo": { + "id": 135493233, + "node_id": "MDEwOlJlcG9zaXRvcnkxMzU0OTMyMzM=", + "name": "Hello-World", + "full_name": "Codertocat/Hello-World", + "owner": { + "login": "Codertocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Codertocat", + "html_url": "https://github.com/Codertocat", + "followers_url": "https://api.github.com/users/Codertocat/followers", + "following_url": "https://api.github.com/users/Codertocat/following{/other_user}", + "gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions", + "organizations_url": "https://api.github.com/users/Codertocat/orgs", + "repos_url": "https://api.github.com/users/Codertocat/repos", + "events_url": "https://api.github.com/users/Codertocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/Codertocat/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/Codertocat/Hello-World", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/Codertocat/Hello-World", + "forks_url": "https://api.github.com/repos/Codertocat/Hello-World/forks", + "keys_url": "https://api.github.com/repos/Codertocat/Hello-World/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/Codertocat/Hello-World/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/Codertocat/Hello-World/teams", + "hooks_url": "https://api.github.com/repos/Codertocat/Hello-World/hooks", + "issue_events_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/events{/number}", + "events_url": "https://api.github.com/repos/Codertocat/Hello-World/events", + "assignees_url": "https://api.github.com/repos/Codertocat/Hello-World/assignees{/user}", + "branches_url": "https://api.github.com/repos/Codertocat/Hello-World/branches{/branch}", + "tags_url": "https://api.github.com/repos/Codertocat/Hello-World/tags", + "blobs_url": "https://api.github.com/repos/Codertocat/Hello-World/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/Codertocat/Hello-World/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/Codertocat/Hello-World/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/Codertocat/Hello-World/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/Codertocat/Hello-World/statuses/{sha}", + "languages_url": "https://api.github.com/repos/Codertocat/Hello-World/languages", + "stargazers_url": "https://api.github.com/repos/Codertocat/Hello-World/stargazers", + "contributors_url": "https://api.github.com/repos/Codertocat/Hello-World/contributors", + "subscribers_url": "https://api.github.com/repos/Codertocat/Hello-World/subscribers", + "subscription_url": "https://api.github.com/repos/Codertocat/Hello-World/subscription", + "commits_url": "https://api.github.com/repos/Codertocat/Hello-World/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/Codertocat/Hello-World/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/Codertocat/Hello-World/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/Codertocat/Hello-World/contents/{+path}", + "compare_url": "https://api.github.com/repos/Codertocat/Hello-World/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/Codertocat/Hello-World/merges", + "archive_url": "https://api.github.com/repos/Codertocat/Hello-World/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/Codertocat/Hello-World/downloads", + "issues_url": "https://api.github.com/repos/Codertocat/Hello-World/issues{/number}", + "pulls_url": "https://api.github.com/repos/Codertocat/Hello-World/pulls{/number}", + "milestones_url": "https://api.github.com/repos/Codertocat/Hello-World/milestones{/number}", + "notifications_url": "https://api.github.com/repos/Codertocat/Hello-World/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/Codertocat/Hello-World/labels{/name}", + "releases_url": "https://api.github.com/repos/Codertocat/Hello-World/releases{/id}", + "deployments_url": "https://api.github.com/repos/Codertocat/Hello-World/deployments", + "created_at": "2018-05-30T20:18:04Z", + "updated_at": "2018-05-30T20:18:50Z", + "pushed_at": "2018-05-30T20:18:48Z", + "git_url": "git://github.com/Codertocat/Hello-World.git", + "ssh_url": "git@github.com:Codertocat/Hello-World.git", + "clone_url": "https://github.com/Codertocat/Hello-World.git", + "svn_url": "https://github.com/Codertocat/Hello-World", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "open_issues_count": 1, + "license": null, + "forks": 0, + "open_issues": 1, + "watchers": 0, + "default_branch": "main" + } + }, + "base": { + "label": "Codertocat:main", + "ref": "main", + "sha": "a10867b14bb761a232cd80139fbd4c0d33264240", + "user": { + "login": "Codertocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Codertocat", + "html_url": "https://github.com/Codertocat", + "followers_url": "https://api.github.com/users/Codertocat/followers", + "following_url": "https://api.github.com/users/Codertocat/following{/other_user}", + "gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions", + "organizations_url": "https://api.github.com/users/Codertocat/orgs", + "repos_url": "https://api.github.com/users/Codertocat/repos", + "events_url": "https://api.github.com/users/Codertocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/Codertocat/received_events", + "type": "User", + "site_admin": false + }, + "repo": { + "id": 135493233, + "node_id": "MDEwOlJlcG9zaXRvcnkxMzU0OTMyMzM=", + "name": "Hello-World", + "full_name": "Codertocat/Hello-World", + "owner": { + "login": "Codertocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Codertocat", + "html_url": "https://github.com/Codertocat", + "followers_url": "https://api.github.com/users/Codertocat/followers", + "following_url": "https://api.github.com/users/Codertocat/following{/other_user}", + "gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions", + "organizations_url": "https://api.github.com/users/Codertocat/orgs", + "repos_url": "https://api.github.com/users/Codertocat/repos", + "events_url": "https://api.github.com/users/Codertocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/Codertocat/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/Codertocat/Hello-World", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/Codertocat/Hello-World", + "forks_url": "https://api.github.com/repos/Codertocat/Hello-World/forks", + "keys_url": "https://api.github.com/repos/Codertocat/Hello-World/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/Codertocat/Hello-World/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/Codertocat/Hello-World/teams", + "hooks_url": "https://api.github.com/repos/Codertocat/Hello-World/hooks", + "issue_events_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/events{/number}", + "events_url": "https://api.github.com/repos/Codertocat/Hello-World/events", + "assignees_url": "https://api.github.com/repos/Codertocat/Hello-World/assignees{/user}", + "branches_url": "https://api.github.com/repos/Codertocat/Hello-World/branches{/branch}", + "tags_url": "https://api.github.com/repos/Codertocat/Hello-World/tags", + "blobs_url": "https://api.github.com/repos/Codertocat/Hello-World/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/Codertocat/Hello-World/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/Codertocat/Hello-World/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/Codertocat/Hello-World/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/Codertocat/Hello-World/statuses/{sha}", + "languages_url": "https://api.github.com/repos/Codertocat/Hello-World/languages", + "stargazers_url": "https://api.github.com/repos/Codertocat/Hello-World/stargazers", + "contributors_url": "https://api.github.com/repos/Codertocat/Hello-World/contributors", + "subscribers_url": "https://api.github.com/repos/Codertocat/Hello-World/subscribers", + "subscription_url": "https://api.github.com/repos/Codertocat/Hello-World/subscription", + "commits_url": "https://api.github.com/repos/Codertocat/Hello-World/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/Codertocat/Hello-World/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/Codertocat/Hello-World/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/Codertocat/Hello-World/contents/{+path}", + "compare_url": "https://api.github.com/repos/Codertocat/Hello-World/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/Codertocat/Hello-World/merges", + "archive_url": "https://api.github.com/repos/Codertocat/Hello-World/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/Codertocat/Hello-World/downloads", + "issues_url": "https://api.github.com/repos/Codertocat/Hello-World/issues{/number}", + "pulls_url": "https://api.github.com/repos/Codertocat/Hello-World/pulls{/number}", + "milestones_url": "https://api.github.com/repos/Codertocat/Hello-World/milestones{/number}", + "notifications_url": "https://api.github.com/repos/Codertocat/Hello-World/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/Codertocat/Hello-World/labels{/name}", + "releases_url": "https://api.github.com/repos/Codertocat/Hello-World/releases{/id}", + "deployments_url": "https://api.github.com/repos/Codertocat/Hello-World/deployments", + "created_at": "2018-05-30T20:18:04Z", + "updated_at": "2018-05-30T20:18:50Z", + "pushed_at": "2018-05-30T20:18:48Z", + "git_url": "git://github.com/Codertocat/Hello-World.git", + "ssh_url": "git@github.com:Codertocat/Hello-World.git", + "clone_url": "https://github.com/Codertocat/Hello-World.git", + "svn_url": "https://github.com/Codertocat/Hello-World", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "open_issues_count": 1, + "license": null, + "forks": 0, + "open_issues": 1, + "watchers": 0, + "default_branch": "main" + } + }, + "_links": { + "self": { + "href": "https://api.github.com/repos/Codertocat/Hello-World/pulls/1" + }, + "html": { + "href": "https://github.com/Codertocat/Hello-World/pull/1" + }, + "issue": { + "href": "https://api.github.com/repos/Codertocat/Hello-World/issues/1" + }, + "comments": { + "href": "https://api.github.com/repos/Codertocat/Hello-World/issues/1/comments" + }, + "review_comments": { + "href": "https://api.github.com/repos/Codertocat/Hello-World/pulls/1/comments" + }, + "review_comment": { + "href": "https://api.github.com/repos/Codertocat/Hello-World/pulls/comments{/number}" + }, + "commits": { + "href": "https://api.github.com/repos/Codertocat/Hello-World/pulls/1/commits" + }, + "statuses": { + "href": "https://api.github.com/repos/Codertocat/Hello-World/statuses/34c5c7793cb3b279e22454cb6750c80560547b3a" + } + }, + "author_association": "OWNER", + "merged": false, + "mergeable": true, + "rebaseable": true, + "mergeable_state": "clean", + "merged_by": null, + "comments": 0, + "review_comments": 1, + "maintainer_can_modify": false, + "commits": 1, + "additions": 1, + "deletions": 1, + "changed_files": 1 + }, + "label": { + "id": 3768735, + "node_id": "MDU6TGFiZWwzNzY4NzM1", + "url": "https://github.com/Codertocat/Hello-World/labels/documentation", + "name": "documentation", + "color": "0075ca", + "default": true, + "description": "Improvements or additions to documentation" + }, + "repository": { + "id": 135493233, + "node_id": "MDEwOlJlcG9zaXRvcnkxMzU0OTMyMzM=", + "name": "Hello-World", + "full_name": "Codertocat/Hello-World", + "owner": { + "login": "Codertocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Codertocat", + "html_url": "https://github.com/Codertocat", + "followers_url": "https://api.github.com/users/Codertocat/followers", + "following_url": "https://api.github.com/users/Codertocat/following{/other_user}", + "gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions", + "organizations_url": "https://api.github.com/users/Codertocat/orgs", + "repos_url": "https://api.github.com/users/Codertocat/repos", + "events_url": "https://api.github.com/users/Codertocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/Codertocat/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/Codertocat/Hello-World", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/Codertocat/Hello-World", + "forks_url": "https://api.github.com/repos/Codertocat/Hello-World/forks", + "keys_url": "https://api.github.com/repos/Codertocat/Hello-World/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/Codertocat/Hello-World/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/Codertocat/Hello-World/teams", + "hooks_url": "https://api.github.com/repos/Codertocat/Hello-World/hooks", + "issue_events_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/events{/number}", + "events_url": "https://api.github.com/repos/Codertocat/Hello-World/events", + "assignees_url": "https://api.github.com/repos/Codertocat/Hello-World/assignees{/user}", + "branches_url": "https://api.github.com/repos/Codertocat/Hello-World/branches{/branch}", + "tags_url": "https://api.github.com/repos/Codertocat/Hello-World/tags", + "blobs_url": "https://api.github.com/repos/Codertocat/Hello-World/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/Codertocat/Hello-World/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/Codertocat/Hello-World/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/Codertocat/Hello-World/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/Codertocat/Hello-World/statuses/{sha}", + "languages_url": "https://api.github.com/repos/Codertocat/Hello-World/languages", + "stargazers_url": "https://api.github.com/repos/Codertocat/Hello-World/stargazers", + "contributors_url": "https://api.github.com/repos/Codertocat/Hello-World/contributors", + "subscribers_url": "https://api.github.com/repos/Codertocat/Hello-World/subscribers", + "subscription_url": "https://api.github.com/repos/Codertocat/Hello-World/subscription", + "commits_url": "https://api.github.com/repos/Codertocat/Hello-World/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/Codertocat/Hello-World/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/Codertocat/Hello-World/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/Codertocat/Hello-World/contents/{+path}", + "compare_url": "https://api.github.com/repos/Codertocat/Hello-World/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/Codertocat/Hello-World/merges", + "archive_url": "https://api.github.com/repos/Codertocat/Hello-World/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/Codertocat/Hello-World/downloads", + "issues_url": "https://api.github.com/repos/Codertocat/Hello-World/issues{/number}", + "pulls_url": "https://api.github.com/repos/Codertocat/Hello-World/pulls{/number}", + "milestones_url": "https://api.github.com/repos/Codertocat/Hello-World/milestones{/number}", + "notifications_url": "https://api.github.com/repos/Codertocat/Hello-World/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/Codertocat/Hello-World/labels{/name}", + "releases_url": "https://api.github.com/repos/Codertocat/Hello-World/releases{/id}", + "deployments_url": "https://api.github.com/repos/Codertocat/Hello-World/deployments", + "created_at": "2018-05-30T20:18:04Z", + "updated_at": "2018-05-30T20:18:50Z", + "pushed_at": "2018-05-30T20:18:48Z", + "git_url": "git://github.com/Codertocat/Hello-World.git", + "ssh_url": "git@github.com:Codertocat/Hello-World.git", + "clone_url": "https://github.com/Codertocat/Hello-World.git", + "svn_url": "https://github.com/Codertocat/Hello-World", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "open_issues_count": 1, + "license": null, + "forks": 0, + "open_issues": 1, + "watchers": 0, + "default_branch": "main" + }, + "sender": { + "login": "Codertocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Codertocat", + "html_url": "https://github.com/Codertocat", + "followers_url": "https://api.github.com/users/Codertocat/followers", + "following_url": "https://api.github.com/users/Codertocat/following{/other_user}", + "gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions", + "organizations_url": "https://api.github.com/users/Codertocat/orgs", + "repos_url": "https://api.github.com/users/Codertocat/repos", + "events_url": "https://api.github.com/users/Codertocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/Codertocat/received_events", + "type": "User", + "site_admin": false + } +} \ No newline at end of file diff --git a/scm/github/testdata/hooks/pull_request_unlabeled.json b/scm/github/testdata/hooks/pull_request_unlabeled.json new file mode 100644 index 000000000..adf48f380 --- /dev/null +++ b/scm/github/testdata/hooks/pull_request_unlabeled.json @@ -0,0 +1,451 @@ +{ + "action": "unlabeled", + "number": 1, + "pull_request": { + "url": "https://api.github.com/repos/Codertocat/Hello-World/pulls/1", + "id": 191568743, + "node_id": "MDExOlB1bGxSZXF1ZXN0MTkxNTY4NzQz", + "html_url": "https://github.com/Codertocat/Hello-World/pull/1", + "diff_url": "https://github.com/Codertocat/Hello-World/pull/1.diff", + "patch_url": "https://github.com/Codertocat/Hello-World/pull/1.patch", + "issue_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/1", + "number": 1, + "state": "open", + "locked": false, + "title": "Update the README with new information", + "user": { + "login": "Codertocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Codertocat", + "html_url": "https://github.com/Codertocat", + "followers_url": "https://api.github.com/users/Codertocat/followers", + "following_url": "https://api.github.com/users/Codertocat/following{/other_user}", + "gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions", + "organizations_url": "https://api.github.com/users/Codertocat/orgs", + "repos_url": "https://api.github.com/users/Codertocat/repos", + "events_url": "https://api.github.com/users/Codertocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/Codertocat/received_events", + "type": "User", + "site_admin": false + }, + "body": "This is a pretty simple change that we need to pull into main.", + "created_at": "2018-05-30T20:18:30Z", + "updated_at": "2018-05-30T20:18:50Z", + "closed_at": "2018-05-30T20:18:50Z", + "merged_at": null, + "merge_commit_sha": "414cb0069601a32b00bd122a2380cd283626a8e5", + "assignee": null, + "assignees": [], + "requested_reviewers": [], + "requested_teams": [], + "labels": [], + "milestone": null, + "commits_url": "https://api.github.com/repos/Codertocat/Hello-World/pulls/1/commits", + "review_comments_url": "https://api.github.com/repos/Codertocat/Hello-World/pulls/1/comments", + "review_comment_url": "https://api.github.com/repos/Codertocat/Hello-World/pulls/comments{/number}", + "comments_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/1/comments", + "statuses_url": "https://api.github.com/repos/Codertocat/Hello-World/statuses/34c5c7793cb3b279e22454cb6750c80560547b3a", + "head": { + "label": "Codertocat:changes", + "ref": "changes", + "sha": "34c5c7793cb3b279e22454cb6750c80560547b3a", + "user": { + "login": "Codertocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Codertocat", + "html_url": "https://github.com/Codertocat", + "followers_url": "https://api.github.com/users/Codertocat/followers", + "following_url": "https://api.github.com/users/Codertocat/following{/other_user}", + "gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions", + "organizations_url": "https://api.github.com/users/Codertocat/orgs", + "repos_url": "https://api.github.com/users/Codertocat/repos", + "events_url": "https://api.github.com/users/Codertocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/Codertocat/received_events", + "type": "User", + "site_admin": false + }, + "repo": { + "id": 135493233, + "node_id": "MDEwOlJlcG9zaXRvcnkxMzU0OTMyMzM=", + "name": "Hello-World", + "full_name": "Codertocat/Hello-World", + "owner": { + "login": "Codertocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Codertocat", + "html_url": "https://github.com/Codertocat", + "followers_url": "https://api.github.com/users/Codertocat/followers", + "following_url": "https://api.github.com/users/Codertocat/following{/other_user}", + "gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions", + "organizations_url": "https://api.github.com/users/Codertocat/orgs", + "repos_url": "https://api.github.com/users/Codertocat/repos", + "events_url": "https://api.github.com/users/Codertocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/Codertocat/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/Codertocat/Hello-World", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/Codertocat/Hello-World", + "forks_url": "https://api.github.com/repos/Codertocat/Hello-World/forks", + "keys_url": "https://api.github.com/repos/Codertocat/Hello-World/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/Codertocat/Hello-World/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/Codertocat/Hello-World/teams", + "hooks_url": "https://api.github.com/repos/Codertocat/Hello-World/hooks", + "issue_events_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/events{/number}", + "events_url": "https://api.github.com/repos/Codertocat/Hello-World/events", + "assignees_url": "https://api.github.com/repos/Codertocat/Hello-World/assignees{/user}", + "branches_url": "https://api.github.com/repos/Codertocat/Hello-World/branches{/branch}", + "tags_url": "https://api.github.com/repos/Codertocat/Hello-World/tags", + "blobs_url": "https://api.github.com/repos/Codertocat/Hello-World/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/Codertocat/Hello-World/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/Codertocat/Hello-World/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/Codertocat/Hello-World/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/Codertocat/Hello-World/statuses/{sha}", + "languages_url": "https://api.github.com/repos/Codertocat/Hello-World/languages", + "stargazers_url": "https://api.github.com/repos/Codertocat/Hello-World/stargazers", + "contributors_url": "https://api.github.com/repos/Codertocat/Hello-World/contributors", + "subscribers_url": "https://api.github.com/repos/Codertocat/Hello-World/subscribers", + "subscription_url": "https://api.github.com/repos/Codertocat/Hello-World/subscription", + "commits_url": "https://api.github.com/repos/Codertocat/Hello-World/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/Codertocat/Hello-World/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/Codertocat/Hello-World/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/Codertocat/Hello-World/contents/{+path}", + "compare_url": "https://api.github.com/repos/Codertocat/Hello-World/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/Codertocat/Hello-World/merges", + "archive_url": "https://api.github.com/repos/Codertocat/Hello-World/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/Codertocat/Hello-World/downloads", + "issues_url": "https://api.github.com/repos/Codertocat/Hello-World/issues{/number}", + "pulls_url": "https://api.github.com/repos/Codertocat/Hello-World/pulls{/number}", + "milestones_url": "https://api.github.com/repos/Codertocat/Hello-World/milestones{/number}", + "notifications_url": "https://api.github.com/repos/Codertocat/Hello-World/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/Codertocat/Hello-World/labels{/name}", + "releases_url": "https://api.github.com/repos/Codertocat/Hello-World/releases{/id}", + "deployments_url": "https://api.github.com/repos/Codertocat/Hello-World/deployments", + "created_at": "2018-05-30T20:18:04Z", + "updated_at": "2018-05-30T20:18:50Z", + "pushed_at": "2018-05-30T20:18:48Z", + "git_url": "git://github.com/Codertocat/Hello-World.git", + "ssh_url": "git@github.com:Codertocat/Hello-World.git", + "clone_url": "https://github.com/Codertocat/Hello-World.git", + "svn_url": "https://github.com/Codertocat/Hello-World", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "open_issues_count": 1, + "license": null, + "forks": 0, + "open_issues": 1, + "watchers": 0, + "default_branch": "main" + } + }, + "base": { + "label": "Codertocat:main", + "ref": "main", + "sha": "a10867b14bb761a232cd80139fbd4c0d33264240", + "user": { + "login": "Codertocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Codertocat", + "html_url": "https://github.com/Codertocat", + "followers_url": "https://api.github.com/users/Codertocat/followers", + "following_url": "https://api.github.com/users/Codertocat/following{/other_user}", + "gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions", + "organizations_url": "https://api.github.com/users/Codertocat/orgs", + "repos_url": "https://api.github.com/users/Codertocat/repos", + "events_url": "https://api.github.com/users/Codertocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/Codertocat/received_events", + "type": "User", + "site_admin": false + }, + "repo": { + "id": 135493233, + "node_id": "MDEwOlJlcG9zaXRvcnkxMzU0OTMyMzM=", + "name": "Hello-World", + "full_name": "Codertocat/Hello-World", + "owner": { + "login": "Codertocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Codertocat", + "html_url": "https://github.com/Codertocat", + "followers_url": "https://api.github.com/users/Codertocat/followers", + "following_url": "https://api.github.com/users/Codertocat/following{/other_user}", + "gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions", + "organizations_url": "https://api.github.com/users/Codertocat/orgs", + "repos_url": "https://api.github.com/users/Codertocat/repos", + "events_url": "https://api.github.com/users/Codertocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/Codertocat/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/Codertocat/Hello-World", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/Codertocat/Hello-World", + "forks_url": "https://api.github.com/repos/Codertocat/Hello-World/forks", + "keys_url": "https://api.github.com/repos/Codertocat/Hello-World/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/Codertocat/Hello-World/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/Codertocat/Hello-World/teams", + "hooks_url": "https://api.github.com/repos/Codertocat/Hello-World/hooks", + "issue_events_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/events{/number}", + "events_url": "https://api.github.com/repos/Codertocat/Hello-World/events", + "assignees_url": "https://api.github.com/repos/Codertocat/Hello-World/assignees{/user}", + "branches_url": "https://api.github.com/repos/Codertocat/Hello-World/branches{/branch}", + "tags_url": "https://api.github.com/repos/Codertocat/Hello-World/tags", + "blobs_url": "https://api.github.com/repos/Codertocat/Hello-World/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/Codertocat/Hello-World/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/Codertocat/Hello-World/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/Codertocat/Hello-World/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/Codertocat/Hello-World/statuses/{sha}", + "languages_url": "https://api.github.com/repos/Codertocat/Hello-World/languages", + "stargazers_url": "https://api.github.com/repos/Codertocat/Hello-World/stargazers", + "contributors_url": "https://api.github.com/repos/Codertocat/Hello-World/contributors", + "subscribers_url": "https://api.github.com/repos/Codertocat/Hello-World/subscribers", + "subscription_url": "https://api.github.com/repos/Codertocat/Hello-World/subscription", + "commits_url": "https://api.github.com/repos/Codertocat/Hello-World/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/Codertocat/Hello-World/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/Codertocat/Hello-World/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/Codertocat/Hello-World/contents/{+path}", + "compare_url": "https://api.github.com/repos/Codertocat/Hello-World/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/Codertocat/Hello-World/merges", + "archive_url": "https://api.github.com/repos/Codertocat/Hello-World/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/Codertocat/Hello-World/downloads", + "issues_url": "https://api.github.com/repos/Codertocat/Hello-World/issues{/number}", + "pulls_url": "https://api.github.com/repos/Codertocat/Hello-World/pulls{/number}", + "milestones_url": "https://api.github.com/repos/Codertocat/Hello-World/milestones{/number}", + "notifications_url": "https://api.github.com/repos/Codertocat/Hello-World/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/Codertocat/Hello-World/labels{/name}", + "releases_url": "https://api.github.com/repos/Codertocat/Hello-World/releases{/id}", + "deployments_url": "https://api.github.com/repos/Codertocat/Hello-World/deployments", + "created_at": "2018-05-30T20:18:04Z", + "updated_at": "2018-05-30T20:18:50Z", + "pushed_at": "2018-05-30T20:18:48Z", + "git_url": "git://github.com/Codertocat/Hello-World.git", + "ssh_url": "git@github.com:Codertocat/Hello-World.git", + "clone_url": "https://github.com/Codertocat/Hello-World.git", + "svn_url": "https://github.com/Codertocat/Hello-World", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "open_issues_count": 1, + "license": null, + "forks": 0, + "open_issues": 1, + "watchers": 0, + "default_branch": "main" + } + }, + "_links": { + "self": { + "href": "https://api.github.com/repos/Codertocat/Hello-World/pulls/1" + }, + "html": { + "href": "https://github.com/Codertocat/Hello-World/pull/1" + }, + "issue": { + "href": "https://api.github.com/repos/Codertocat/Hello-World/issues/1" + }, + "comments": { + "href": "https://api.github.com/repos/Codertocat/Hello-World/issues/1/comments" + }, + "review_comments": { + "href": "https://api.github.com/repos/Codertocat/Hello-World/pulls/1/comments" + }, + "review_comment": { + "href": "https://api.github.com/repos/Codertocat/Hello-World/pulls/comments{/number}" + }, + "commits": { + "href": "https://api.github.com/repos/Codertocat/Hello-World/pulls/1/commits" + }, + "statuses": { + "href": "https://api.github.com/repos/Codertocat/Hello-World/statuses/34c5c7793cb3b279e22454cb6750c80560547b3a" + } + }, + "author_association": "OWNER", + "merged": false, + "mergeable": true, + "rebaseable": true, + "mergeable_state": "clean", + "merged_by": null, + "comments": 0, + "review_comments": 1, + "maintainer_can_modify": false, + "commits": 1, + "additions": 1, + "deletions": 1, + "changed_files": 1 + }, + "label": { + "id": 3768735, + "node_id": "MDU6TGFiZWwzNzY4NzM1", + "url": "https://github.com/Codertocat/Hello-World/labels/documentation", + "name": "documentation", + "color": "0075ca", + "default": true, + "description": "Improvements or additions to documentation" + }, + "repository": { + "id": 135493233, + "node_id": "MDEwOlJlcG9zaXRvcnkxMzU0OTMyMzM=", + "name": "Hello-World", + "full_name": "Codertocat/Hello-World", + "owner": { + "login": "Codertocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Codertocat", + "html_url": "https://github.com/Codertocat", + "followers_url": "https://api.github.com/users/Codertocat/followers", + "following_url": "https://api.github.com/users/Codertocat/following{/other_user}", + "gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions", + "organizations_url": "https://api.github.com/users/Codertocat/orgs", + "repos_url": "https://api.github.com/users/Codertocat/repos", + "events_url": "https://api.github.com/users/Codertocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/Codertocat/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/Codertocat/Hello-World", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/Codertocat/Hello-World", + "forks_url": "https://api.github.com/repos/Codertocat/Hello-World/forks", + "keys_url": "https://api.github.com/repos/Codertocat/Hello-World/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/Codertocat/Hello-World/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/Codertocat/Hello-World/teams", + "hooks_url": "https://api.github.com/repos/Codertocat/Hello-World/hooks", + "issue_events_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/events{/number}", + "events_url": "https://api.github.com/repos/Codertocat/Hello-World/events", + "assignees_url": "https://api.github.com/repos/Codertocat/Hello-World/assignees{/user}", + "branches_url": "https://api.github.com/repos/Codertocat/Hello-World/branches{/branch}", + "tags_url": "https://api.github.com/repos/Codertocat/Hello-World/tags", + "blobs_url": "https://api.github.com/repos/Codertocat/Hello-World/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/Codertocat/Hello-World/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/Codertocat/Hello-World/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/Codertocat/Hello-World/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/Codertocat/Hello-World/statuses/{sha}", + "languages_url": "https://api.github.com/repos/Codertocat/Hello-World/languages", + "stargazers_url": "https://api.github.com/repos/Codertocat/Hello-World/stargazers", + "contributors_url": "https://api.github.com/repos/Codertocat/Hello-World/contributors", + "subscribers_url": "https://api.github.com/repos/Codertocat/Hello-World/subscribers", + "subscription_url": "https://api.github.com/repos/Codertocat/Hello-World/subscription", + "commits_url": "https://api.github.com/repos/Codertocat/Hello-World/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/Codertocat/Hello-World/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/Codertocat/Hello-World/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/Codertocat/Hello-World/contents/{+path}", + "compare_url": "https://api.github.com/repos/Codertocat/Hello-World/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/Codertocat/Hello-World/merges", + "archive_url": "https://api.github.com/repos/Codertocat/Hello-World/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/Codertocat/Hello-World/downloads", + "issues_url": "https://api.github.com/repos/Codertocat/Hello-World/issues{/number}", + "pulls_url": "https://api.github.com/repos/Codertocat/Hello-World/pulls{/number}", + "milestones_url": "https://api.github.com/repos/Codertocat/Hello-World/milestones{/number}", + "notifications_url": "https://api.github.com/repos/Codertocat/Hello-World/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/Codertocat/Hello-World/labels{/name}", + "releases_url": "https://api.github.com/repos/Codertocat/Hello-World/releases{/id}", + "deployments_url": "https://api.github.com/repos/Codertocat/Hello-World/deployments", + "created_at": "2018-05-30T20:18:04Z", + "updated_at": "2018-05-30T20:18:50Z", + "pushed_at": "2018-05-30T20:18:48Z", + "git_url": "git://github.com/Codertocat/Hello-World.git", + "ssh_url": "git@github.com:Codertocat/Hello-World.git", + "clone_url": "https://github.com/Codertocat/Hello-World.git", + "svn_url": "https://github.com/Codertocat/Hello-World", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "open_issues_count": 1, + "license": null, + "forks": 0, + "open_issues": 1, + "watchers": 0, + "default_branch": "main" + }, + "sender": { + "login": "Codertocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Codertocat", + "html_url": "https://github.com/Codertocat", + "followers_url": "https://api.github.com/users/Codertocat/followers", + "following_url": "https://api.github.com/users/Codertocat/following{/other_user}", + "gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions", + "organizations_url": "https://api.github.com/users/Codertocat/orgs", + "repos_url": "https://api.github.com/users/Codertocat/repos", + "events_url": "https://api.github.com/users/Codertocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/Codertocat/received_events", + "type": "User", + "site_admin": false + } +} \ No newline at end of file diff --git a/scm/github/webhook.go b/scm/github/webhook.go index 7d8ac2015..08ce41464 100644 --- a/scm/github/webhook.go +++ b/scm/github/webhook.go @@ -250,11 +250,13 @@ func (c *client) processPREvent(h *library.Hook, payload *github.PullRequestEven return &types.Webhook{Hook: h}, nil } - // skip if the pull request action is not opened, synchronize, reopened, or edited + // skip if the pull request action is not opened, synchronize, reopened, edited, labeled, or unlabeled if !strings.EqualFold(payload.GetAction(), "opened") && !strings.EqualFold(payload.GetAction(), "synchronize") && !strings.EqualFold(payload.GetAction(), "reopened") && - !strings.EqualFold(payload.GetAction(), "edited") { + !strings.EqualFold(payload.GetAction(), "edited") && + !strings.EqualFold(payload.GetAction(), "labeled") && + !strings.EqualFold(payload.GetAction(), "unlabeled") { return &types.Webhook{Hook: h}, nil } @@ -309,6 +311,17 @@ func (c *client) processPREvent(h *library.Hook, payload *github.PullRequestEven b.SetEmail(payload.GetPullRequest().GetHead().GetUser().GetEmail()) } + var prLabels []string + if strings.EqualFold(payload.GetAction(), "labeled") || + strings.EqualFold(payload.GetAction(), "unlabeled") { + prLabels = append(prLabels, payload.GetLabel().GetName()) + } else { + labels := payload.GetPullRequest().Labels + for _, label := range labels { + prLabels = append(prLabels, label.GetName()) + } + } + // determine if pull request head is a fork and does not match the repo name of base fromFork := payload.GetPullRequest().GetHead().GetRepo().GetFork() && !strings.EqualFold(payload.GetPullRequest().GetBase().GetRepo().GetFullName(), payload.GetPullRequest().GetHead().GetRepo().GetFullName()) @@ -317,6 +330,7 @@ func (c *client) processPREvent(h *library.Hook, payload *github.PullRequestEven PullRequest: types.PullRequest{ Number: payload.GetNumber(), IsFromFork: fromFork, + Labels: prLabels, }, Hook: h, Repo: r, diff --git a/scm/github/webhook_test.go b/scm/github/webhook_test.go index eab3cbc54..3bf0415f9 100644 --- a/scm/github/webhook_test.go +++ b/scm/github/webhook_test.go @@ -372,6 +372,54 @@ func TestGithub_ProcessWebhook_PullRequest(t *testing.T) { wantBuild.SetBaseRef("main") wantBuild.SetHeadRef("changes") + wantBuild2 := new(library.Build) + wantBuild2.SetEvent("pull_request") + wantBuild2.SetEventAction("labeled") + wantBuild2.SetClone("https://github.com/Codertocat/Hello-World.git") + wantBuild2.SetSource("https://github.com/Codertocat/Hello-World/pull/1") + wantBuild2.SetTitle("pull_request received from https://github.com/Codertocat/Hello-World") + wantBuild2.SetMessage("Update the README with new information") + wantBuild2.SetCommit("34c5c7793cb3b279e22454cb6750c80560547b3a") + wantBuild2.SetSender("Codertocat") + wantBuild2.SetAuthor("Codertocat") + wantBuild2.SetEmail("") + wantBuild2.SetBranch("main") + wantBuild2.SetRef("refs/pull/1/head") + wantBuild2.SetBaseRef("main") + wantBuild2.SetHeadRef("changes") + + wantBuild3 := new(library.Build) + wantBuild3.SetEvent("pull_request") + wantBuild3.SetEventAction("unlabeled") + wantBuild3.SetClone("https://github.com/Codertocat/Hello-World.git") + wantBuild3.SetSource("https://github.com/Codertocat/Hello-World/pull/1") + wantBuild3.SetTitle("pull_request received from https://github.com/Codertocat/Hello-World") + wantBuild3.SetMessage("Update the README with new information") + wantBuild3.SetCommit("34c5c7793cb3b279e22454cb6750c80560547b3a") + wantBuild3.SetSender("Codertocat") + wantBuild3.SetAuthor("Codertocat") + wantBuild3.SetEmail("") + wantBuild3.SetBranch("main") + wantBuild3.SetRef("refs/pull/1/head") + wantBuild3.SetBaseRef("main") + wantBuild3.SetHeadRef("changes") + + wantBuild4 := new(library.Build) + wantBuild4.SetEvent("pull_request") + wantBuild4.SetEventAction("edited") + wantBuild4.SetClone("https://github.com/Codertocat/Hello-World.git") + wantBuild4.SetSource("https://github.com/Codertocat/Hello-World/pull/1") + wantBuild4.SetTitle("pull_request received from https://github.com/Codertocat/Hello-World") + wantBuild4.SetMessage("Update the README with new information") + wantBuild4.SetCommit("34c5c7793cb3b279e22454cb6750c80560547b3a") + wantBuild4.SetSender("Codertocat") + wantBuild4.SetAuthor("Codertocat") + wantBuild4.SetEmail("") + wantBuild4.SetBranch("main") + wantBuild4.SetRef("refs/pull/1/head") + wantBuild4.SetBaseRef("main") + wantBuild4.SetHeadRef("changes") + tests := []struct { name string testData string @@ -435,6 +483,48 @@ func TestGithub_ProcessWebhook_PullRequest(t *testing.T) { Build: nil, }, }, + { + name: "labeled documentation", + testData: "testdata/hooks/pull_request_labeled.json", + want: &types.Webhook{ + PullRequest: types.PullRequest{ + Number: wantHook.GetNumber(), + IsFromFork: false, + Labels: []string{"documentation"}, + }, + Hook: wantHook, + Repo: wantRepo, + Build: wantBuild2, + }, + }, + { + name: "unlabeled documentation", + testData: "testdata/hooks/pull_request_unlabeled.json", + want: &types.Webhook{ + PullRequest: types.PullRequest{ + Number: wantHook.GetNumber(), + IsFromFork: false, + Labels: []string{"documentation"}, + }, + Hook: wantHook, + Repo: wantRepo, + Build: wantBuild3, + }, + }, + { + name: "edited while labeled documentation", + testData: "testdata/hooks/pull_request_edited_while_labeled.json", + want: &types.Webhook{ + PullRequest: types.PullRequest{ + Number: wantHook.GetNumber(), + IsFromFork: false, + Labels: []string{"documentation", "enhancement"}, + }, + Hook: wantHook, + Repo: wantRepo, + Build: wantBuild4, + }, + }, } for _, tt := range tests { From b889656a0a4eeac459824a81f3c310369a00da94 Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Tue, 9 Apr 2024 13:21:04 -0400 Subject: [PATCH 24/71] chore(deps): upgrade go-github to v61 (#1102) --- compiler/native/compile_test.go | 2 +- compiler/registry/github/github.go | 2 +- compiler/registry/github/github_test.go | 2 +- compiler/registry/github/template.go | 2 +- go.mod | 2 +- go.sum | 4 ++-- scm/github/access.go | 2 +- scm/github/authentication.go | 2 +- scm/github/changeset.go | 2 +- scm/github/deployment.go | 2 +- scm/github/github.go | 2 +- scm/github/github_test.go | 2 +- scm/github/repo.go | 23 ++++++++++------------- scm/github/webhook.go | 2 +- 14 files changed, 24 insertions(+), 27 deletions(-) diff --git a/compiler/native/compile_test.go b/compiler/native/compile_test.go index b1e31c00c..4fb45b2dd 100644 --- a/compiler/native/compile_test.go +++ b/compiler/native/compile_test.go @@ -13,7 +13,7 @@ import ( "github.com/go-vela/types/constants" "github.com/go-vela/types/raw" - "github.com/google/go-github/v59/github" + "github.com/google/go-github/v61/github" "testing" "time" diff --git a/compiler/registry/github/github.go b/compiler/registry/github/github.go index 5988f891d..d617d2c50 100644 --- a/compiler/registry/github/github.go +++ b/compiler/registry/github/github.go @@ -7,7 +7,7 @@ import ( "net/url" "strings" - "github.com/google/go-github/v59/github" + "github.com/google/go-github/v61/github" "golang.org/x/oauth2" ) diff --git a/compiler/registry/github/github_test.go b/compiler/registry/github/github_test.go index 688d7948c..0ad0f2f55 100644 --- a/compiler/registry/github/github_test.go +++ b/compiler/registry/github/github_test.go @@ -10,7 +10,7 @@ import ( "reflect" "testing" - "github.com/google/go-github/v59/github" + "github.com/google/go-github/v61/github" "golang.org/x/oauth2" ) diff --git a/compiler/registry/github/template.go b/compiler/registry/github/template.go index 03d503b82..b375c151f 100644 --- a/compiler/registry/github/template.go +++ b/compiler/registry/github/template.go @@ -11,7 +11,7 @@ import ( "github.com/go-vela/types/library" - "github.com/google/go-github/v59/github" + "github.com/google/go-github/v61/github" ) // Template captures the templated pipeline configuration from the GitHub repo. diff --git a/go.mod b/go.mod index 5a52e83a0..2b2c83713 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/go-vela/types v0.23.4-0.20240402153726-f16c3e4cb5fb github.com/golang-jwt/jwt/v5 v5.2.1 github.com/google/go-cmp v0.6.0 - github.com/google/go-github/v59 v59.0.0 + github.com/google/go-github/v61 v61.0.0 github.com/google/uuid v1.6.0 github.com/goware/urlx v0.3.2 github.com/hashicorp/go-cleanhttp v0.5.2 diff --git a/go.sum b/go.sum index 9c4e1259a..f3bc883ef 100644 --- a/go.sum +++ b/go.sum @@ -106,8 +106,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 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/google/go-github/v59 v59.0.0 h1:7h6bgpF5as0YQLLkEiVqpgtJqjimMYhBkD4jT5aN3VA= -github.com/google/go-github/v59 v59.0.0/go.mod h1:rJU4R0rQHFVFDOkqGWxfLNo6vEk4dv40oDjhV/gH6wM= +github.com/google/go-github/v61 v61.0.0 h1:VwQCBwhyE9JclCI+22/7mLB1PuU9eowCXKY5pNlu1go= +github.com/google/go-github/v61 v61.0.0/go.mod h1:0WR+KmsWX75G2EbpyGsGmradjo3IiciuI4BmdVCobQY= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= diff --git a/scm/github/access.go b/scm/github/access.go index ea2445a3b..f6b185356 100644 --- a/scm/github/access.go +++ b/scm/github/access.go @@ -9,7 +9,7 @@ import ( "github.com/sirupsen/logrus" "github.com/go-vela/types/library" - "github.com/google/go-github/v59/github" + "github.com/google/go-github/v61/github" ) // OrgAccess captures the user's access level for an org. diff --git a/scm/github/authentication.go b/scm/github/authentication.go index 609790c77..d41cd5a8c 100644 --- a/scm/github/authentication.go +++ b/scm/github/authentication.go @@ -12,7 +12,7 @@ import ( "github.com/go-vela/server/random" "github.com/go-vela/types/library" - "github.com/google/go-github/v59/github" + "github.com/google/go-github/v61/github" ) // Authorize uses the given access token to authorize the user. diff --git a/scm/github/changeset.go b/scm/github/changeset.go index a3ba3113b..de97c22d4 100644 --- a/scm/github/changeset.go +++ b/scm/github/changeset.go @@ -9,7 +9,7 @@ import ( "github.com/sirupsen/logrus" "github.com/go-vela/types/library" - "github.com/google/go-github/v59/github" + "github.com/google/go-github/v61/github" ) // Changeset captures the list of files changed for a commit. diff --git a/scm/github/deployment.go b/scm/github/deployment.go index 675503800..835ad851a 100644 --- a/scm/github/deployment.go +++ b/scm/github/deployment.go @@ -10,7 +10,7 @@ import ( "github.com/go-vela/types/library" "github.com/go-vela/types/raw" - "github.com/google/go-github/v59/github" + "github.com/google/go-github/v61/github" ) // GetDeployment gets a deployment from the GitHub repo. diff --git a/scm/github/github.go b/scm/github/github.go index d588f1795..4c9910653 100644 --- a/scm/github/github.go +++ b/scm/github/github.go @@ -7,7 +7,7 @@ import ( "fmt" "net/url" - "github.com/google/go-github/v59/github" + "github.com/google/go-github/v61/github" "github.com/sirupsen/logrus" "golang.org/x/oauth2" diff --git a/scm/github/github_test.go b/scm/github/github_test.go index 14a8ba15c..bfc70ac75 100644 --- a/scm/github/github_test.go +++ b/scm/github/github_test.go @@ -10,7 +10,7 @@ import ( "reflect" "testing" - "github.com/google/go-github/v59/github" + "github.com/google/go-github/v61/github" "golang.org/x/oauth2" ) diff --git a/scm/github/repo.go b/scm/github/repo.go index 1cd40d51c..df90e5cb1 100644 --- a/scm/github/repo.go +++ b/scm/github/repo.go @@ -14,7 +14,7 @@ import ( "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/google/go-github/v59/github" + "github.com/google/go-github/v61/github" ) // ConfigBackoff is a wrapper for Config that will retry five times if the function @@ -122,11 +122,8 @@ func (c *client) Disable(ctx context.Context, u *library.User, org, name string) continue } - // cast url from hook configuration to string - hookURL := hook.Config["url"].(string) - // capture hook ID if the hook url matches - if hookURL == fmt.Sprintf("%s/webhook", c.config.ServerWebhookAddress) { + if strings.EqualFold(hook.GetConfig().GetURL(), fmt.Sprintf("%s/webhook", c.config.ServerWebhookAddress)) { ids = append(ids, hook.GetID()) } } @@ -192,10 +189,10 @@ func (c *client) Enable(ctx context.Context, u *library.User, r *library.Repo, h // create the hook object to make the API call hook := &github.Hook{ Events: events, - Config: map[string]interface{}{ - "url": fmt.Sprintf("%s/webhook", c.config.ServerWebhookAddress), - "content_type": "form", - "secret": r.GetHash(), + Config: &github.HookConfig{ + URL: github.String(fmt.Sprintf("%s/webhook", c.config.ServerWebhookAddress)), + ContentType: github.String("form"), + Secret: github.String(r.GetHash()), }, Active: github.Bool(true), } @@ -266,10 +263,10 @@ func (c *client) Update(ctx context.Context, u *library.User, r *library.Repo, h // create the hook object to make the API call hook := &github.Hook{ Events: events, - Config: map[string]interface{}{ - "url": fmt.Sprintf("%s/webhook", c.config.ServerWebhookAddress), - "content_type": "form", - "secret": r.GetHash(), + Config: &github.HookConfig{ + URL: github.String(fmt.Sprintf("%s/webhook", c.config.ServerWebhookAddress)), + ContentType: github.String("form"), + Secret: github.String(r.GetHash()), }, Active: github.Bool(true), } diff --git a/scm/github/webhook.go b/scm/github/webhook.go index 08ce41464..3e2e5badd 100644 --- a/scm/github/webhook.go +++ b/scm/github/webhook.go @@ -18,7 +18,7 @@ import ( "github.com/go-vela/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/google/go-github/v59/github" + "github.com/google/go-github/v61/github" ) // ProcessWebhook parses the webhook from a repo. From 1058d9696961cb393755774dd424f9d703214bce Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Wed, 10 Apr 2024 12:46:28 -0400 Subject: [PATCH 25/71] refactor(repo)!: nested repository with migration from types (#1095) --- api/admin/repo.go | 5 +- api/auth/login.go | 4 +- api/auth/logout.go | 4 +- api/auth/redirect.go | 4 +- api/build/approve.go | 16 +- api/build/auto_cancel.go | 7 +- api/build/compile_publish.go | 38 +- api/build/create.go | 4 +- api/build/enqueue.go | 4 +- api/build/get_id.go | 3 +- api/build/graph.go | 6 +- api/build/plan.go | 3 +- api/build/restart.go | 4 +- api/build/update.go | 8 +- api/pipeline/compile.go | 4 +- api/pipeline/expand.go | 4 +- api/pipeline/template.go | 15 +- api/pipeline/validate.go | 4 +- api/repo/chown.go | 2 +- api/repo/create.go | 13 +- api/repo/repair.go | 7 +- api/repo/update.go | 17 +- api/scm/sync_org.go | 6 +- api/step/plan.go | 13 +- api/step/update.go | 8 +- api/types/actions/comment.go | 83 +++ api/types/actions/comment_test.go | 108 +++ api/types/actions/deploy.go | 54 ++ api/types/actions/deploy_test.go | 98 +++ api/types/actions/pull.go | 203 ++++++ api/types/actions/pull_test.go | 148 ++++ api/types/actions/push.go | 143 ++++ api/types/actions/push_test.go | 136 ++++ api/types/actions/schedule.go | 54 ++ api/types/actions/schedule_test.go | 98 +++ api/types/events.go | 338 +++++++++ api/types/events_test.go | 424 +++++++++++ api/types/executor.go | 227 ++++++ api/types/executor_test.go | 241 +++++++ api/types/repo.go | 668 ++++++++++++++++++ api/types/repo_test.go | 371 ++++++++++ api/types/string.go | 90 +++ api/types/string_test.go | 57 ++ api/types/worker_test.go | 2 +- api/user/get_source.go | 8 +- api/webhook/post.go | 29 +- cmd/vela-server/metadata.go | 22 +- cmd/vela-server/schedule.go | 6 +- compiler/engine.go | 7 +- compiler/native/compile.go | 3 +- compiler/native/compile_test.go | 175 ++--- compiler/native/environment.go | 5 +- compiler/native/environment_test.go | 62 +- compiler/native/expand_test.go | 9 +- compiler/native/native.go | 11 +- compiler/native/native_test.go | 15 +- compiler/native/parse_test.go | 10 +- compiler/native/transform_test.go | 22 +- database/build/build_test.go | 6 +- database/build/count_org_test.go | 9 +- database/build/count_repo.go | 4 +- database/build/count_repo_test.go | 2 +- database/build/get_repo.go | 3 +- database/build/get_repo_test.go | 2 +- database/build/interface.go | 11 +- database/build/last_repo.go | 3 +- database/build/last_repo_test.go | 2 +- database/build/list_org_test.go | 9 +- database/build/list_pending_running_repo.go | 3 +- .../build/list_pending_running_repo_test.go | 9 +- database/build/list_pending_running_test.go | 5 +- database/build/list_repo.go | 3 +- database/build/list_repo_test.go | 2 +- database/deployment/count_repo.go | 4 +- database/deployment/count_repo_test.go | 2 +- database/deployment/deployment_test.go | 6 +- database/deployment/get_repo.go | 3 +- database/deployment/get_repo_test.go | 2 +- database/deployment/interface.go | 7 +- database/deployment/list_repo.go | 3 +- database/hook/count_repo.go | 4 +- database/hook/count_repo_test.go | 2 +- database/hook/get_repo.go | 3 +- database/hook/get_repo_test.go | 2 +- database/hook/hook_test.go | 6 +- database/hook/interface.go | 9 +- database/hook/last_repo.go | 3 +- database/hook/last_repo_test.go | 2 +- database/hook/list_repo.go | 3 +- database/hook/list_repo_test.go | 2 +- database/integration_test.go | 72 +- database/pipeline/count_repo.go | 4 +- database/pipeline/count_repo_test.go | 4 +- database/pipeline/get_repo.go | 3 +- database/pipeline/get_repo_test.go | 3 +- database/pipeline/interface.go | 7 +- database/pipeline/list_repo.go | 3 +- database/pipeline/list_repo_test.go | 3 +- database/repo/count_org_test.go | 4 +- database/repo/count_test.go | 4 +- database/repo/count_user_test.go | 4 +- database/repo/create.go | 21 +- database/repo/create_test.go | 4 +- database/repo/delete.go | 9 +- database/repo/delete_test.go | 2 +- database/repo/get.go | 21 +- database/repo/get_org.go | 27 +- database/repo/get_org_test.go | 38 +- database/repo/get_test.go | 32 +- database/repo/interface.go | 17 +- database/repo/list.go | 22 +- database/repo/list_org.go | 25 +- database/repo/list_org_test.go | 52 +- database/repo/list_test.go | 40 +- database/repo/list_user.go | 22 +- database/repo/list_user_test.go | 53 +- database/repo/repo.go | 328 +++++++++ database/repo/repo_test.go | 26 +- database/repo/update.go | 21 +- database/repo/update_test.go | 6 +- database/schedule/count_repo.go | 5 +- database/schedule/get_repo.go | 4 +- database/schedule/interface.go | 7 +- database/schedule/list_repo.go | 4 +- database/schedule/schedule_test.go | 6 +- database/secret/count_repo.go | 4 +- database/secret/count_repo_test.go | 2 +- database/secret/count_team_test.go | 2 +- database/secret/get_repo.go | 3 +- database/secret/get_repo_test.go | 2 +- database/secret/interface.go | 7 +- database/secret/list_repo.go | 3 +- database/secret/list_repo_test.go | 2 +- database/secret/secret_test.go | 6 +- go.mod | 4 +- go.sum | 4 +- internal/metadata.go | 44 ++ internal/token/compose.go | 4 +- internal/token/compose_test.go | 6 +- internal/webhook.go | 70 ++ internal/webhook_test.go | 111 +++ mock/server/repo.go | 18 +- mock/server/repo_test.go | 4 +- queue/models/item.go | 31 + queue/models/item_test.go | 123 ++++ queue/redis/length_test.go | 5 +- queue/redis/pop.go | 6 +- queue/redis/pop_test.go | 13 +- queue/redis/push_test.go | 5 +- queue/redis/redis_test.go | 70 +- queue/service.go | 4 +- router/middleware/build/build_test.go | 26 +- router/middleware/executors/context.go | 8 +- router/middleware/executors/context_test.go | 11 +- router/middleware/executors/executor_test.go | 7 +- router/middleware/executors/executors.go | 6 +- router/middleware/header.go | 6 +- router/middleware/header_test.go | 14 +- router/middleware/logger_test.go | 8 +- router/middleware/metadata.go | 5 +- router/middleware/metadata_test.go | 9 +- router/middleware/org/org_test.go | 6 +- router/middleware/perm/perm.go | 34 +- router/middleware/perm/perm_test.go | 141 ++-- router/middleware/pipeline/pipeline.go | 4 +- router/middleware/pipeline/pipeline_test.go | 34 +- router/middleware/repo/context.go | 8 +- router/middleware/repo/context_test.go | 7 +- router/middleware/repo/repo.go | 4 +- router/middleware/repo/repo_test.go | 25 +- router/middleware/service/service_test.go | 30 +- router/middleware/step/step_test.go | 36 +- scm/github/changeset.go | 14 +- scm/github/changeset_test.go | 11 +- scm/github/deployment.go | 9 +- scm/github/deployment_test.go | 3 +- scm/github/repo.go | 31 +- scm/github/repo_test.go | 49 +- scm/github/webhook.go | 61 +- scm/github/webhook_test.go | 103 +-- scm/service.go | 37 +- secret/native/count.go | 4 +- secret/native/get.go | 3 +- secret/native/list.go | 3 +- util/encryption.go | 96 +++ util/encryption_test.go | 99 +++ util/util.go | 4 +- 187 files changed, 5673 insertions(+), 1005 deletions(-) create mode 100644 api/types/actions/comment.go create mode 100644 api/types/actions/comment_test.go create mode 100644 api/types/actions/deploy.go create mode 100644 api/types/actions/deploy_test.go create mode 100644 api/types/actions/pull.go create mode 100644 api/types/actions/pull_test.go create mode 100644 api/types/actions/push.go create mode 100644 api/types/actions/push_test.go create mode 100644 api/types/actions/schedule.go create mode 100644 api/types/actions/schedule_test.go create mode 100644 api/types/events.go create mode 100644 api/types/events_test.go create mode 100644 api/types/executor.go create mode 100644 api/types/executor_test.go create mode 100644 api/types/repo.go create mode 100644 api/types/repo_test.go create mode 100644 api/types/string.go create mode 100644 api/types/string_test.go create mode 100644 internal/metadata.go create mode 100644 internal/webhook.go create mode 100644 internal/webhook_test.go create mode 100644 queue/models/item.go create mode 100644 queue/models/item_test.go create mode 100644 util/encryption.go create mode 100644 util/encryption_test.go diff --git a/api/admin/repo.go b/api/admin/repo.go index 11814a8a0..46eb3ccc2 100644 --- a/api/admin/repo.go +++ b/api/admin/repo.go @@ -7,11 +7,10 @@ import ( "fmt" "net/http" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/util" - "github.com/go-vela/types/library" - "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" ) @@ -55,7 +54,7 @@ func UpdateRepo(c *gin.Context) { ctx := c.Request.Context() // capture body from API request - input := new(library.Repo) + input := new(types.Repo) err := c.Bind(input) if err != nil { diff --git a/api/auth/login.go b/api/auth/login.go index 041d844f3..a6e026fc2 100644 --- a/api/auth/login.go +++ b/api/auth/login.go @@ -8,8 +8,8 @@ import ( "net/url" "github.com/gin-gonic/gin" + "github.com/go-vela/server/internal" "github.com/go-vela/server/util" - "github.com/go-vela/types" "github.com/sirupsen/logrus" ) @@ -38,7 +38,7 @@ import ( // process a user logging in to Vela. func Login(c *gin.Context) { // load the metadata - m := c.MustGet("metadata").(*types.Metadata) + m := c.MustGet("metadata").(*internal.Metadata) // capture query params t := util.FormParameter(c, "type") diff --git a/api/auth/logout.go b/api/auth/logout.go index 454d2b9ed..2c1cf9a33 100644 --- a/api/auth/logout.go +++ b/api/auth/logout.go @@ -8,10 +8,10 @@ import ( "net/url" "github.com/go-vela/server/database" + "github.com/go-vela/server/internal" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/go-vela/types" "github.com/go-vela/types/constants" "github.com/gin-gonic/gin" @@ -41,7 +41,7 @@ import ( // refresh token cookie. func Logout(c *gin.Context) { // grab the metadata to help deal with the cookie - m := c.MustGet("metadata").(*types.Metadata) + m := c.MustGet("metadata").(*internal.Metadata) // capture middleware values u := user.Retrieve(c) ctx := c.Request.Context() diff --git a/api/auth/redirect.go b/api/auth/redirect.go index 473c7a612..2e96b3482 100644 --- a/api/auth/redirect.go +++ b/api/auth/redirect.go @@ -7,8 +7,8 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/go-vela/server/internal" "github.com/go-vela/server/util" - "github.com/go-vela/types" "github.com/sirupsen/logrus" ) @@ -68,7 +68,7 @@ import ( // This will only handle non-headless flows (ie. web or cli). func GetAuthRedirect(c *gin.Context) { // load the metadata - m := c.MustGet("metadata").(*types.Metadata) + m := c.MustGet("metadata").(*internal.Metadata) logrus.Info("redirecting for final auth flow destination") diff --git a/api/build/approve.go b/api/build/approve.go index 5b41616b5..30006ab1c 100644 --- a/api/build/approve.go +++ b/api/build/approve.go @@ -11,12 +11,12 @@ import ( "github.com/gin-gonic/gin" "github.com/go-vela/server/database" "github.com/go-vela/server/queue" + "github.com/go-vela/server/queue/models" "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/go-vela/types" "github.com/go-vela/types/constants" "github.com/sirupsen/logrus" ) @@ -105,23 +105,13 @@ func ApproveBuild(c *gin.Context) { logger.Debugf("user %s approved build %s/%d for execution", u.GetName(), r.GetFullName(), b.GetNumber()) - // send API call to capture the repo owner - owner, err := database.FromContext(c).GetUser(ctx, r.GetUserID()) - if err != nil { - retErr := fmt.Errorf("unable to get owner for %s: %w", r.GetFullName(), err) - - util.HandleError(c, http.StatusBadRequest, retErr) - - return - } - // set fields b.SetStatus(constants.StatusPending) b.SetApprovedAt(time.Now().Unix()) b.SetApprovedBy(u.GetName()) // update the build in the db - _, err = database.FromContext(c).UpdateBuild(ctx, b) + _, err := database.FromContext(c).UpdateBuild(ctx, b) if err != nil { logrus.Errorf("Failed to update build %d during publish to queue for %s: %v", b.GetNumber(), r.GetFullName(), err) } @@ -131,7 +121,7 @@ func ApproveBuild(c *gin.Context) { ctx, queue.FromGinContext(c), database.FromContext(c), - types.ToItem(b, r, owner), + models.ToItem(b, r), b.GetHost(), ) diff --git a/api/build/auto_cancel.go b/api/build/auto_cancel.go index 0f200498c..53dc1b3eb 100644 --- a/api/build/auto_cancel.go +++ b/api/build/auto_cancel.go @@ -12,6 +12,7 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/internal/token" "github.com/go-vela/types/constants" @@ -21,7 +22,7 @@ import ( // AutoCancel is a helper function that checks to see if any pending or running // builds for the repo can be replaced by the current build. -func AutoCancel(c *gin.Context, b *library.Build, rB *library.Build, r *library.Repo, cancelOpts *pipeline.CancelOptions) (bool, error) { +func AutoCancel(c *gin.Context, b *library.Build, rB *library.Build, r *types.Repo, cancelOpts *pipeline.CancelOptions) (bool, error) { // if build is the current build, continue if rB.GetID() == b.GetID() { return false, nil @@ -73,8 +74,8 @@ func AutoCancel(c *gin.Context, b *library.Build, rB *library.Build, r *library. // cancelRunning is a helper function that determines the executor currently running a build and sends an API call // to that executor's worker to cancel the build. -func cancelRunning(c *gin.Context, b *library.Build, r *library.Repo) error { - e := new([]library.Executor) +func cancelRunning(c *gin.Context, b *library.Build, r *types.Repo) error { + e := new([]types.Executor) // retrieve the worker w, err := database.FromContext(c).GetWorkerForHostname(c, b.GetHost()) if err != nil { diff --git a/api/build/compile_publish.go b/api/build/compile_publish.go index f60dcaa56..e23e6d8b3 100644 --- a/api/build/compile_publish.go +++ b/api/build/compile_publish.go @@ -11,12 +11,14 @@ import ( "strings" "time" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/compiler" "github.com/go-vela/server/database" + "github.com/go-vela/server/internal" "github.com/go-vela/server/queue" + "github.com/go-vela/server/queue/models" "github.com/go-vela/server/scm" "github.com/go-vela/server/util" - "github.com/go-vela/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" "github.com/go-vela/types/pipeline" @@ -26,8 +28,8 @@ import ( // CompileAndPublishConfig is a struct that contains information for the CompileAndPublish function. type CompileAndPublishConfig struct { Build *library.Build - Repo *library.Repo - Metadata *types.Metadata + Repo *types.Repo + Metadata *internal.Metadata BaseErr string Source string Comment string @@ -47,27 +49,17 @@ func CompileAndPublish( scm scm.Service, compiler compiler.Engine, queue queue.Service, -) (*pipeline.Build, *types.Item, error) { +) (*pipeline.Build, *models.Item, error) { logrus.Debugf("generating queue items for build %s/%d", cfg.Repo.GetFullName(), cfg.Build.GetNumber()) // assign variables from form for readibility r := cfg.Repo + u := cfg.Repo.GetOwner() b := cfg.Build baseErr := cfg.BaseErr - // send API call to capture repo owner - logrus.Debugf("capturing owner of repository %s", cfg.Repo.GetFullName()) - - u, err := database.GetUser(c, r.GetUserID()) - if err != nil { - retErr := fmt.Errorf("%s: failed to get owner for %s: %w", baseErr, r.GetFullName(), err) - util.HandleError(c, http.StatusBadRequest, retErr) - - return nil, nil, retErr - } - // confirm current repo owner has at least write access to repo (needed for status update later) - _, err = scm.RepoAccess(c, u.GetName(), u.GetToken(), r.GetOrg(), r.GetName()) + _, err := scm.RepoAccess(c, u.GetName(), u.GetToken(), r.GetOrg(), r.GetName()) if err != nil { retErr := fmt.Errorf("unable to publish build to queue: repository owner %s no longer has write access to repository %s", u.GetName(), r.GetFullName()) util.HandleError(c, http.StatusUnauthorized, retErr) @@ -97,7 +89,7 @@ func CompileAndPublish( return nil, nil, retErr } - commit, branch, baseref, headref, err := scm.GetPullRequest(c, u, r, prNum) + commit, branch, baseref, headref, err := scm.GetPullRequest(c, r, prNum) if err != nil { retErr := fmt.Errorf("%s: failed to get pull request info for %s: %w", baseErr, r.GetFullName(), err) util.HandleError(c, http.StatusInternalServerError, retErr) @@ -114,7 +106,7 @@ func CompileAndPublish( // if the source is from a schedule, fetch the commit sha from schedule branch (same as build branch at this moment) if strings.EqualFold(cfg.Source, "schedule") { // send API call to capture the commit sha for the branch - _, commit, err := scm.GetBranch(c, u, r, b.GetBranch()) + _, commit, err := scm.GetBranch(c, r, b.GetBranch()) if err != nil { retErr := fmt.Errorf("failed to get commit for repo %s on %s branch: %w", r.GetFullName(), r.GetBranch(), err) util.HandleError(c, http.StatusInternalServerError, retErr) @@ -170,7 +162,7 @@ func CompileAndPublish( !strings.EqualFold(b.GetEvent(), constants.EventPull) && !strings.EqualFold(b.GetEvent(), constants.EventDelete) { // send API call to capture list of files changed for the commit - files, err = scm.Changeset(c, u, r, b.GetCommit()) + files, err = scm.Changeset(c, r, b.GetCommit()) if err != nil { retErr := fmt.Errorf("%s: failed to get changeset for %s: %w", baseErr, r.GetFullName(), err) util.HandleError(c, http.StatusInternalServerError, retErr) @@ -182,7 +174,7 @@ func CompileAndPublish( // check if the build event is a pull_request if strings.EqualFold(b.GetEvent(), constants.EventPull) && prNum > 0 { // send API call to capture list of files changed for the pull request - files, err = scm.ChangesetPR(c, u, r, prNum) + files, err = scm.ChangesetPR(c, r, prNum) if err != nil { retErr := fmt.Errorf("%s: failed to get changeset for %s: %w", baseErr, r.GetFullName(), err) util.HandleError(c, http.StatusInternalServerError, retErr) @@ -201,7 +193,7 @@ func CompileAndPublish( // variable to store the pipeline type for the repository pipelineType = r.GetPipelineType() // variable to store updated repository record - repo *library.Repo + repo *types.Repo ) // implement a loop to process asynchronous operations with a retry limit @@ -324,7 +316,7 @@ func CompileAndPublish( } return nil, - &types.Item{ + &models.Item{ Build: b, }, errors.New(skip) @@ -448,7 +440,7 @@ func CompileAndPublish( return nil, nil, retErr } - return p, types.ToItem(b, repo, u), nil + return p, models.ToItem(b, repo), nil } // getPRNumberFromBuild is a helper function to diff --git a/api/build/create.go b/api/build/create.go index 1f1463ba3..08027545e 100644 --- a/api/build/create.go +++ b/api/build/create.go @@ -10,13 +10,13 @@ import ( "github.com/gin-gonic/gin" "github.com/go-vela/server/compiler" "github.com/go-vela/server/database" + "github.com/go-vela/server/internal" "github.com/go-vela/server/queue" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" "github.com/go-vela/server/util" - "github.com/go-vela/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" "github.com/sirupsen/logrus" @@ -74,7 +74,7 @@ import ( // CreateBuild represents the API handler to create a build in the configured backend. func CreateBuild(c *gin.Context) { // capture middleware values - m := c.MustGet("metadata").(*types.Metadata) + m := c.MustGet("metadata").(*internal.Metadata) o := org.Retrieve(c) r := repo.Retrieve(c) u := user.Retrieve(c) diff --git a/api/build/enqueue.go b/api/build/enqueue.go index be8cb2971..4edce866c 100644 --- a/api/build/enqueue.go +++ b/api/build/enqueue.go @@ -9,12 +9,12 @@ import ( "github.com/go-vela/server/database" "github.com/go-vela/server/queue" - "github.com/go-vela/types" + "github.com/go-vela/server/queue/models" "github.com/sirupsen/logrus" ) // Enqueue is a helper function that pushes a queue item (build, repo, user) to the queue. -func Enqueue(ctx context.Context, queue queue.Service, db database.Interface, item *types.Item, route string) { +func Enqueue(ctx context.Context, queue queue.Service, db database.Interface, item *models.Item, route string) { logrus.Infof("Converting queue item to json for build %d for %s", item.Build.GetNumber(), item.Repo.GetFullName()) byteItem, err := json.Marshal(item) diff --git a/api/build/get_id.go b/api/build/get_id.go index 44cfbdbea..b3adbea95 100644 --- a/api/build/get_id.go +++ b/api/build/get_id.go @@ -8,6 +8,7 @@ import ( "strconv" "github.com/gin-gonic/gin" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" @@ -51,7 +52,7 @@ func GetBuildByID(c *gin.Context) { // Variables that will hold the library types of the build and repo var ( b *library.Build - r *library.Repo + r *types.Repo ) // Capture user from middleware diff --git a/api/build/graph.go b/api/build/graph.go index dde6e5343..fe6c9cf0d 100644 --- a/api/build/graph.go +++ b/api/build/graph.go @@ -11,13 +11,13 @@ import ( "github.com/gin-gonic/gin" "github.com/go-vela/server/compiler" "github.com/go-vela/server/database" + "github.com/go-vela/server/internal" "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" "github.com/go-vela/server/util" - "github.com/go-vela/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" "github.com/go-vela/types/pipeline" @@ -142,7 +142,7 @@ func GetBuildGraph(c *gin.Context) { o := org.Retrieve(c) r := repo.Retrieve(c) u := user.Retrieve(c) - m := c.MustGet("metadata").(*types.Metadata) + m := c.MustGet("metadata").(*internal.Metadata) ctx := c.Request.Context() // update engine logger with API metadata @@ -194,7 +194,7 @@ func GetBuildGraph(c *gin.Context) { // check if the build event is not pull_request if !strings.EqualFold(b.GetEvent(), constants.EventPull) { // send API call to capture list of files changed for the commit - files, err = scm.FromContext(c).Changeset(ctx, u, r, b.GetCommit()) + files, err = scm.FromContext(c).Changeset(ctx, r, b.GetCommit()) if err != nil { retErr := fmt.Errorf("%s: failed to get changeset for %s: %w", baseErr, r.GetFullName(), err) diff --git a/api/build/plan.go b/api/build/plan.go index 28f54e981..d34a776ff 100644 --- a/api/build/plan.go +++ b/api/build/plan.go @@ -9,6 +9,7 @@ import ( "github.com/go-vela/server/api/service" "github.com/go-vela/server/api/step" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/scm" "github.com/go-vela/types/library" @@ -20,7 +21,7 @@ import ( // and services, for the build in the configured backend. // TODO: // - return build and error. -func PlanBuild(ctx context.Context, database database.Interface, scm scm.Service, p *pipeline.Build, b *library.Build, r *library.Repo) error { +func PlanBuild(ctx context.Context, database database.Interface, scm scm.Service, p *pipeline.Build, b *library.Build, r *types.Repo) error { // update fields in build object b.SetCreated(time.Now().UTC().Unix()) diff --git a/api/build/restart.go b/api/build/restart.go index 8b32fdc56..6043b4fde 100644 --- a/api/build/restart.go +++ b/api/build/restart.go @@ -10,6 +10,7 @@ import ( "github.com/gin-gonic/gin" "github.com/go-vela/server/compiler" "github.com/go-vela/server/database" + "github.com/go-vela/server/internal" "github.com/go-vela/server/queue" "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/claims" @@ -18,7 +19,6 @@ import ( "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" "github.com/go-vela/server/util" - "github.com/go-vela/types" "github.com/go-vela/types/constants" "github.com/sirupsen/logrus" ) @@ -73,7 +73,7 @@ import ( // RestartBuild represents the API handler to restart an existing build in the configured backend. func RestartBuild(c *gin.Context) { // capture middleware values - m := c.MustGet("metadata").(*types.Metadata) + m := c.MustGet("metadata").(*internal.Metadata) cl := claims.Retrieve(c) b := build.Retrieve(c) o := org.Retrieve(c) diff --git a/api/build/update.go b/api/build/update.go index c9fb30aa8..6a09e397f 100644 --- a/api/build/update.go +++ b/api/build/update.go @@ -168,14 +168,8 @@ func UpdateBuild(c *gin.Context) { b.GetStatus() == constants.StatusCanceled || b.GetStatus() == constants.StatusKilled || b.GetStatus() == constants.StatusError) && b.GetEvent() != constants.EventSchedule { - // send API call to capture the repo owner - u, err := database.FromContext(c).GetUser(ctx, r.GetUserID()) - if err != nil { - logrus.Errorf("unable to get owner for build %s: %v", entry, err) - } - // send API call to set the status on the commit - err = scm.FromContext(c).Status(ctx, u, b, r.GetOrg(), r.GetName()) + err = scm.FromContext(c).Status(ctx, r.GetOwner(), b, r.GetOrg(), r.GetName()) if err != nil { logrus.Errorf("unable to set commit status for build %s: %v", entry, err) } diff --git a/api/pipeline/compile.go b/api/pipeline/compile.go index 2b5782fe7..c3027edcf 100644 --- a/api/pipeline/compile.go +++ b/api/pipeline/compile.go @@ -9,12 +9,12 @@ import ( "github.com/gin-gonic/gin" "github.com/go-vela/server/compiler" + "github.com/go-vela/server/internal" "github.com/go-vela/server/router/middleware/org" pMiddleware "github.com/go-vela/server/router/middleware/pipeline" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/go-vela/types" "github.com/go-vela/types/pipeline" "github.com/sirupsen/logrus" ) @@ -71,7 +71,7 @@ import ( // expand and compile a pipeline configuration. func CompilePipeline(c *gin.Context) { // capture middleware values - m := c.MustGet("metadata").(*types.Metadata) + m := c.MustGet("metadata").(*internal.Metadata) o := org.Retrieve(c) p := pMiddleware.Retrieve(c) r := repo.Retrieve(c) diff --git a/api/pipeline/expand.go b/api/pipeline/expand.go index 948dcf1fd..a47ca84d6 100644 --- a/api/pipeline/expand.go +++ b/api/pipeline/expand.go @@ -9,12 +9,12 @@ import ( "github.com/gin-gonic/gin" "github.com/go-vela/server/compiler" + "github.com/go-vela/server/internal" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/pipeline" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/go-vela/types" "github.com/sirupsen/logrus" ) @@ -71,7 +71,7 @@ import ( // expand a pipeline configuration. func ExpandPipeline(c *gin.Context) { // capture middleware values - m := c.MustGet("metadata").(*types.Metadata) + m := c.MustGet("metadata").(*internal.Metadata) o := org.Retrieve(c) p := pipeline.Retrieve(c) r := repo.Retrieve(c) diff --git a/api/pipeline/template.go b/api/pipeline/template.go index 9716b6328..8114d7f72 100644 --- a/api/pipeline/template.go +++ b/api/pipeline/template.go @@ -10,14 +10,13 @@ import ( "github.com/gin-gonic/gin" "github.com/go-vela/server/compiler" "github.com/go-vela/server/compiler/registry/github" - "github.com/go-vela/server/database" + "github.com/go-vela/server/internal" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/pipeline" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" "github.com/go-vela/server/util" - "github.com/go-vela/types" "github.com/go-vela/types/library" "github.com/go-vela/types/yaml" "github.com/sirupsen/logrus" @@ -75,7 +74,7 @@ import ( // map of templates utilized by a pipeline configuration. func GetTemplates(c *gin.Context) { // capture middleware values - m := c.MustGet("metadata").(*types.Metadata) + m := c.MustGet("metadata").(*internal.Metadata) o := org.Retrieve(c) p := pipeline.Retrieve(c) r := repo.Retrieve(c) @@ -105,14 +104,6 @@ func GetTemplates(c *gin.Context) { return } - // send API call to capture the repo owner - user, err := database.FromContext(c).GetUser(ctx, r.GetUserID()) - if err != nil { - util.HandleError(c, http.StatusBadRequest, fmt.Errorf("unable to get owner for %s: %w", r.GetFullName(), err)) - - return - } - baseErr := fmt.Sprintf("unable to set template links for %s", entry) templates := make(map[string]*library.Template) @@ -144,7 +135,7 @@ func GetTemplates(c *gin.Context) { } // retrieve link to template file from github - link, err := scm.FromContext(c).GetHTMLURL(ctx, user, src.Org, src.Repo, src.Name, src.Ref) + link, err := scm.FromContext(c).GetHTMLURL(ctx, r.GetOwner(), src.Org, src.Repo, src.Name, src.Ref) if err != nil { util.HandleError(c, http.StatusBadRequest, fmt.Errorf("%s: unable to get html url for %s/%s/%s/@%s: %w", baseErr, src.Org, src.Repo, src.Name, src.Ref, err)) diff --git a/api/pipeline/validate.go b/api/pipeline/validate.go index fbaf1116b..2754b24c9 100644 --- a/api/pipeline/validate.go +++ b/api/pipeline/validate.go @@ -8,12 +8,12 @@ import ( "github.com/gin-gonic/gin" "github.com/go-vela/server/compiler" + "github.com/go-vela/server/internal" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/pipeline" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/go-vela/types" "github.com/sirupsen/logrus" ) @@ -69,7 +69,7 @@ import ( // expand and validate a pipeline configuration. func ValidatePipeline(c *gin.Context) { // capture middleware values - m := c.MustGet("metadata").(*types.Metadata) + m := c.MustGet("metadata").(*internal.Metadata) o := org.Retrieve(c) p := pipeline.Retrieve(c) r := repo.Retrieve(c) diff --git a/api/repo/chown.go b/api/repo/chown.go index 8061b2de6..9e1bf98ab 100644 --- a/api/repo/chown.go +++ b/api/repo/chown.go @@ -64,7 +64,7 @@ func ChownRepo(c *gin.Context) { }).Infof("changing owner of repo %s to %s", r.GetFullName(), u.GetName()) // update repo owner - r.SetUserID(u.GetID()) + r.SetOwner(u) // send API call to update the repo _, err := database.FromContext(c).UpdateRepo(ctx, r) diff --git a/api/repo/create.go b/api/repo/create.go index 59ccbf857..bc0c1103d 100644 --- a/api/repo/create.go +++ b/api/repo/create.go @@ -9,6 +9,7 @@ import ( "strings" "github.com/gin-gonic/gin" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" @@ -80,7 +81,7 @@ func CreateRepo(c *gin.Context) { ctx := c.Request.Context() // capture body from API request - input := new(library.Repo) + input := new(types.Repo) err := c.Bind(input) if err != nil { @@ -111,7 +112,7 @@ func CreateRepo(c *gin.Context) { } // update fields in repo object - r.SetUserID(u.GetID()) + r.SetOwner(u) // set the active field based off the input provided if input.Active == nil { @@ -275,7 +276,7 @@ func CreateRepo(c *gin.Context) { // if the repo exists but is inactive if len(dbRepo.GetOrg()) > 0 && !dbRepo.GetActive() { // update the repo owner - dbRepo.SetUserID(u.GetID()) + dbRepo.SetOwner(u) // update the default branch dbRepo.SetBranch(r.GetBranch()) // activate the repo @@ -323,12 +324,12 @@ func CreateRepo(c *gin.Context) { // defaultAllowedEvents is a helper function that generates an Events struct that results // from an admin-provided `sliceDefaults` or an admin-provided `maskDefaults`. If the admin // supplies a mask, that will be the default. Otherwise, it will be the legacy event list. -func defaultAllowedEvents(sliceDefaults []string, maskDefaults int64) *library.Events { +func defaultAllowedEvents(sliceDefaults []string, maskDefaults int64) *types.Events { if maskDefaults > 0 { - return library.NewEventsFromMask(maskDefaults) + return types.NewEventsFromMask(maskDefaults) } - events := new(library.Events) + events := new(types.Events) for _, event := range sliceDefaults { switch event { diff --git a/api/repo/repair.go b/api/repo/repair.go index 4a792283d..9d6e99b32 100644 --- a/api/repo/repair.go +++ b/api/repo/repair.go @@ -4,17 +4,18 @@ package repo import ( "fmt" + "net/http" + "github.com/gin-gonic/gin" wh "github.com/go-vela/server/api/webhook" "github.com/go-vela/server/database" + "github.com/go-vela/server/internal" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" "github.com/go-vela/server/util" - "github.com/go-vela/types" "github.com/sirupsen/logrus" - "net/http" ) // swagger:operation PATCH /api/v1/repos/{org}/{repo}/repair repos RepairRepo @@ -56,7 +57,7 @@ func RepairRepo(c *gin.Context) { u := user.Retrieve(c) ctx := c.Request.Context() // capture middleware values - m := c.MustGet("metadata").(*types.Metadata) + m := c.MustGet("metadata").(*internal.Metadata) // update engine logger with API metadata // diff --git a/api/repo/update.go b/api/repo/update.go index efdb1a366..db179371a 100644 --- a/api/repo/update.go +++ b/api/repo/update.go @@ -9,6 +9,7 @@ import ( "strings" "github.com/gin-gonic/gin" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" @@ -16,7 +17,6 @@ import ( "github.com/go-vela/server/scm" "github.com/go-vela/server/util" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" "github.com/google/uuid" "github.com/sirupsen/logrus" ) @@ -89,7 +89,7 @@ func UpdateRepo(c *gin.Context) { }).Infof("updating repo %s", r.GetFullName()) // capture body from API request - input := new(library.Repo) + input := new(types.Repo) err := c.Bind(input) if err != nil { @@ -249,26 +249,19 @@ func UpdateRepo(c *gin.Context) { return } - // if user is platform admin, fetch the repo owner token to make changes to webhook + // if user is platform admin, use repo owner token to make changes to webhook if u.GetAdmin() { // capture admin name for logging admn := u.GetName() - u, err = database.FromContext(c).GetUser(ctx, r.GetUserID()) - if err != nil { - retErr := fmt.Errorf("unable to get repo owner of %s for platform admin webhook update: %w", r.GetFullName(), err) - - util.HandleError(c, http.StatusInternalServerError, retErr) - - return - } - // log admin override update repo hook logrus.WithFields(logrus.Fields{ "org": o, "repo": r.GetName(), "user": u.GetName(), }).Infof("platform admin %s updating repo webhook events for repo %s", admn, r.GetFullName()) + + u = r.GetOwner() } // update webhook with new events _, err = scm.FromContext(c).Update(ctx, u, r, lastHook.GetWebhookID()) diff --git a/api/scm/sync_org.go b/api/scm/sync_org.go index fb0c425f3..0c5628bef 100644 --- a/api/scm/sync_org.go +++ b/api/scm/sync_org.go @@ -7,12 +7,12 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" "github.com/go-vela/server/util" - "github.com/go-vela/types/library" "github.com/sirupsen/logrus" ) @@ -99,7 +99,7 @@ func SyncReposForOrg(c *gin.Context) { return } - repos := []*library.Repo{} + repos := []*types.Repo{} page := 0 // capture all repos belonging to a certain org in database for orgRepos := int64(0); orgRepos < t; orgRepos += 100 { @@ -117,7 +117,7 @@ func SyncReposForOrg(c *gin.Context) { page++ } - var results []*library.Repo + var results []*types.Repo // iterate through captured repos and check if they are in GitHub for _, repo := range repos { diff --git a/api/step/plan.go b/api/step/plan.go index 58ecc98f5..eb7d9dda9 100644 --- a/api/step/plan.go +++ b/api/step/plan.go @@ -7,6 +7,7 @@ import ( "fmt" "time" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/scm" "github.com/go-vela/types/constants" @@ -18,7 +19,7 @@ import ( // PlanSteps is a helper function to plan all steps // in the build for execution. This creates the steps // for the build in the configured backend. -func PlanSteps(ctx context.Context, database database.Interface, scm scm.Service, p *pipeline.Build, b *library.Build, repo *library.Repo) ([]*library.Step, error) { +func PlanSteps(ctx context.Context, database database.Interface, scm scm.Service, p *pipeline.Build, b *library.Build, repo *types.Repo) ([]*library.Step, error) { // variable to store planned steps steps := []*library.Step{} @@ -49,7 +50,7 @@ func PlanSteps(ctx context.Context, database database.Interface, scm scm.Service return steps, nil } -func planStep(ctx context.Context, database database.Interface, scm scm.Service, b *library.Build, c *pipeline.Container, repo *library.Repo, stage string) (*library.Step, error) { +func planStep(ctx context.Context, database database.Interface, scm scm.Service, b *library.Build, c *pipeline.Container, repo *types.Repo, stage string) (*library.Step, error) { // create the step object s := new(library.Step) s.SetBuildID(b.GetID()) @@ -90,14 +91,8 @@ func planStep(ctx context.Context, database database.Interface, scm scm.Service, } if len(s.GetReportAs()) > 0 { - // send API call to capture the repo owner - u, err := database.GetUser(ctx, repo.GetUserID()) - if err != nil { - logrus.Errorf("unable to get owner for build: %v", err) - } - // send API call to set the status on the commit - err = scm.StepStatus(ctx, u, b, s, repo.GetOrg(), repo.GetName()) + err = scm.StepStatus(ctx, repo.GetOwner(), b, s, repo.GetOrg(), repo.GetName()) if err != nil { logrus.Errorf("unable to set commit status for build: %v", err) } diff --git a/api/step/update.go b/api/step/update.go index bdfedc8ee..7dc97efac 100644 --- a/api/step/update.go +++ b/api/step/update.go @@ -168,14 +168,8 @@ func UpdateStep(c *gin.Context) { s.GetStatus() == constants.StatusError) && (b.GetEvent() != constants.EventSchedule) && (len(s.GetReportAs()) > 0) { - // send API call to capture the repo owner - u, err := database.FromContext(c).GetUser(ctx, r.GetUserID()) - if err != nil { - logrus.Errorf("unable to get owner for build %s: %v", entry, err) - } - // send API call to set the status on the commit - err = scm.FromContext(c).StepStatus(ctx, u, b, s, r.GetOrg(), r.GetName()) + err = scm.FromContext(c).StepStatus(ctx, r.GetOwner(), b, s, r.GetOrg(), r.GetName()) if err != nil { logrus.Errorf("unable to set commit status for build %s: %v", entry, err) } diff --git a/api/types/actions/comment.go b/api/types/actions/comment.go new file mode 100644 index 000000000..552aa3800 --- /dev/null +++ b/api/types/actions/comment.go @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: Apache-2.0 + +package actions + +import "github.com/go-vela/types/constants" + +// Comment is the API representation of the various actions associated +// with the comment event webhook from the SCM. +type Comment struct { + Created *bool `json:"created"` + Edited *bool `json:"edited"` +} + +// FromMask returns the Comment type resulting from the provided integer mask. +func (a *Comment) FromMask(mask int64) *Comment { + a.SetCreated(mask&constants.AllowCommentCreate > 0) + a.SetEdited(mask&constants.AllowCommentEdit > 0) + + return a +} + +// ToMask returns the integer mask of the values for the Comment set. +func (a *Comment) ToMask() int64 { + mask := int64(0) + + if a.GetCreated() { + mask = mask | constants.AllowCommentCreate + } + + if a.GetEdited() { + mask = mask | constants.AllowCommentEdit + } + + return mask +} + +// GetCreated returns the Created field from the provided Comment. If the object is nil, +// or the field within the object is nil, it returns the zero value instead. +func (a *Comment) GetCreated() bool { + // return zero value if Events type or Created field is nil + if a == nil || a.Created == nil { + return false + } + + return *a.Created +} + +// GetEdited returns the Edited field from the provided Comment. If the object is nil, +// or the field within the object is nil, it returns the zero value instead. +func (a *Comment) GetEdited() bool { + // return zero value if Events type or Edited field is nil + if a == nil || a.Edited == nil { + return false + } + + return *a.Edited +} + +// SetCreated sets the Comment Created field. +// +// When the provided Events type is nil, it +// will set nothing and immediately return. +func (a *Comment) SetCreated(v bool) { + // return if Events type is nil + if a == nil { + return + } + + a.Created = &v +} + +// SetEdited sets the Comment Edited field. +// +// When the provided Events type is nil, it +// will set nothing and immediately return. +func (a *Comment) SetEdited(v bool) { + // return if Events type is nil + if a == nil { + return + } + + a.Edited = &v +} diff --git a/api/types/actions/comment_test.go b/api/types/actions/comment_test.go new file mode 100644 index 000000000..1ffc465b8 --- /dev/null +++ b/api/types/actions/comment_test.go @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: Apache-2.0 + +package actions + +import ( + "reflect" + "testing" + + "github.com/go-vela/types/constants" +) + +func TestTypes_Comment_Getters(t *testing.T) { + // setup tests + tests := []struct { + actions *Comment + want *Comment + }{ + { + actions: testComment(), + want: testComment(), + }, + { + actions: new(Comment), + want: new(Comment), + }, + } + + // run tests + for _, test := range tests { + if test.actions.GetCreated() != test.want.GetCreated() { + t.Errorf("GetCreated is %v, want %v", test.actions.GetCreated(), test.want.GetCreated()) + } + + if test.actions.GetEdited() != test.want.GetEdited() { + t.Errorf("GetEdited is %v, want %v", test.actions.GetEdited(), test.want.GetEdited()) + } + } +} + +func TestTypes_Comment_Setters(t *testing.T) { + // setup types + var a *Comment + + // setup tests + tests := []struct { + actions *Comment + want *Comment + }{ + { + actions: testComment(), + want: testComment(), + }, + { + actions: a, + want: new(Comment), + }, + } + + // run tests + for _, test := range tests { + test.actions.SetCreated(test.want.GetCreated()) + test.actions.SetEdited(test.want.GetEdited()) + + if test.actions.GetCreated() != test.want.GetCreated() { + t.Errorf("SetCreated is %v, want %v", test.actions.GetCreated(), test.want.GetCreated()) + } + + if test.actions.GetEdited() != test.want.GetEdited() { + t.Errorf("SetEdited is %v, want %v", test.actions.GetEdited(), test.want.GetEdited()) + } + } +} + +func TestTypes_Comment_FromMask(t *testing.T) { + // setup types + mask := testMask() + + want := testComment() + + // run test + got := new(Comment).FromMask(mask) + + if !reflect.DeepEqual(got, want) { + t.Errorf("FromMask is %v, want %v", got, want) + } +} + +func TestTypes_Comment_ToMask(t *testing.T) { + // setup types + actions := testComment() + + want := int64(constants.AllowCommentCreate) + + // run test + got := actions.ToMask() + + if want != got { + t.Errorf("ToMask is %v, want %v", got, want) + } +} + +func testComment() *Comment { + comment := new(Comment) + comment.SetCreated(true) + comment.SetEdited(false) + + return comment +} diff --git a/api/types/actions/deploy.go b/api/types/actions/deploy.go new file mode 100644 index 000000000..5dd7a4242 --- /dev/null +++ b/api/types/actions/deploy.go @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: Apache-2.0 +// +//nolint:dupl // similar code to schedule.go +package actions + +import "github.com/go-vela/types/constants" + +// Deploy is the API representation of the various actions associated +// with the deploy event webhook from the SCM. +type Deploy struct { + Created *bool `json:"created"` +} + +// FromMask returns the Deploy type resulting from the provided integer mask. +func (a *Deploy) FromMask(mask int64) *Deploy { + a.SetCreated(mask&constants.AllowDeployCreate > 0) + + return a +} + +// ToMask returns the integer mask of the values for the Deploy set. +func (a *Deploy) ToMask() int64 { + mask := int64(0) + + if a.GetCreated() { + mask = mask | constants.AllowDeployCreate + } + + return mask +} + +// GetCreated returns the Created field from the provided Deploy. If the object is nil, +// or the field within the object is nil, it returns the zero value instead. +func (a *Deploy) GetCreated() bool { + // return zero value if Deploy type or Created field is nil + if a == nil || a.Created == nil { + return false + } + + return *a.Created +} + +// SetCreated sets the Deploy Created field. +// +// When the provided Deploy type is nil, it +// will set nothing and immediately return. +func (a *Deploy) SetCreated(v bool) { + // return if Deploy type is nil + if a == nil { + return + } + + a.Created = &v +} diff --git a/api/types/actions/deploy_test.go b/api/types/actions/deploy_test.go new file mode 100644 index 000000000..373407c7f --- /dev/null +++ b/api/types/actions/deploy_test.go @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: Apache-2.0 + +package actions + +import ( + "reflect" + "testing" + + "github.com/go-vela/types/constants" +) + +func TestTypes_Deploy_Getters(t *testing.T) { + // setup tests + tests := []struct { + actions *Deploy + want *Deploy + }{ + { + actions: testDeploy(), + want: testDeploy(), + }, + { + actions: new(Deploy), + want: new(Deploy), + }, + } + + // run tests + for _, test := range tests { + if test.actions.GetCreated() != test.want.GetCreated() { + t.Errorf("GetCreated is %v, want %v", test.actions.GetCreated(), test.want.GetCreated()) + } + } +} + +func TestTypes_Deploy_Setters(t *testing.T) { + // setup types + var a *Deploy + + // setup tests + tests := []struct { + actions *Deploy + want *Deploy + }{ + { + actions: testDeploy(), + want: testDeploy(), + }, + { + actions: a, + want: new(Deploy), + }, + } + + // run tests + for _, test := range tests { + test.actions.SetCreated(test.want.GetCreated()) + + if test.actions.GetCreated() != test.want.GetCreated() { + t.Errorf("SetCreated is %v, want %v", test.actions.GetCreated(), test.want.GetCreated()) + } + } +} + +func TestTypes_Deploy_FromMask(t *testing.T) { + // setup types + mask := testMask() + + want := testDeploy() + + // run test + got := new(Deploy).FromMask(mask) + + if !reflect.DeepEqual(got, want) { + t.Errorf("FromMask is %v, want %v", got, want) + } +} + +func TestTypes_Deploy_ToMask(t *testing.T) { + // setup types + actions := testDeploy() + + want := int64(constants.AllowDeployCreate) + + // run test + got := actions.ToMask() + + if want != got { + t.Errorf("ToMask is %v, want %v", got, want) + } +} + +func testDeploy() *Deploy { + deploy := new(Deploy) + deploy.SetCreated(true) + + return deploy +} diff --git a/api/types/actions/pull.go b/api/types/actions/pull.go new file mode 100644 index 000000000..fd35fe7eb --- /dev/null +++ b/api/types/actions/pull.go @@ -0,0 +1,203 @@ +// SPDX-License-Identifier: Apache-2.0 + +package actions + +import "github.com/go-vela/types/constants" + +// Pull is the API representation of the various actions associated +// with the pull_request event webhook from the SCM. +type Pull struct { + Opened *bool `json:"opened"` + Edited *bool `json:"edited"` + Synchronize *bool `json:"synchronize"` + Reopened *bool `json:"reopened"` + Labeled *bool `json:"labeled"` + Unlabeled *bool `json:"unlabeled"` +} + +// FromMask returns the Pull type resulting from the provided integer mask. +func (a *Pull) FromMask(mask int64) *Pull { + a.SetOpened(mask&constants.AllowPullOpen > 0) + a.SetSynchronize(mask&constants.AllowPullSync > 0) + a.SetEdited(mask&constants.AllowPullEdit > 0) + a.SetReopened(mask&constants.AllowPullReopen > 0) + a.SetLabeled(mask&constants.AllowPullLabel > 0) + a.SetUnlabeled(mask&constants.AllowPullUnlabel > 0) + + return a +} + +// ToMask returns the integer mask of the values for the Pull set. +func (a *Pull) ToMask() int64 { + mask := int64(0) + + if a.GetOpened() { + mask = mask | constants.AllowPullOpen + } + + if a.GetSynchronize() { + mask = mask | constants.AllowPullSync + } + + if a.GetEdited() { + mask = mask | constants.AllowPullEdit + } + + if a.GetReopened() { + mask = mask | constants.AllowPullReopen + } + + if a.GetLabeled() { + mask = mask | constants.AllowPullLabel + } + + if a.GetUnlabeled() { + mask = mask | constants.AllowPullUnlabel + } + + return mask +} + +// GetOpened returns the Opened field from the provided Pull. If the object is nil, +// or the field within the object is nil, it returns the zero value instead. +func (a *Pull) GetOpened() bool { + // return zero value if Pull type or Opened field is nil + if a == nil || a.Opened == nil { + return false + } + + return *a.Opened +} + +// GetSynchronize returns the Synchronize field from the provided Pull. If the object is nil, +// or the field within the object is nil, it returns the zero value instead. +func (a *Pull) GetSynchronize() bool { + // return zero value if Pull type or Synchronize field is nil + if a == nil || a.Synchronize == nil { + return false + } + + return *a.Synchronize +} + +// GetEdited returns the Edited field from the provided Pull. If the object is nil, +// or the field within the object is nil, it returns the zero value instead. +func (a *Pull) GetEdited() bool { + // return zero value if Pull type or Edited field is nil + if a == nil || a.Edited == nil { + return false + } + + return *a.Edited +} + +// GetReopened returns the Reopened field from the provided Pull. If the object is nil, +// or the field within the object is nil, it returns the zero value instead. +func (a *Pull) GetReopened() bool { + // return zero value if Pull type or Reopened field is nil + if a == nil || a.Reopened == nil { + return false + } + + return *a.Reopened +} + +// GetLabeled returns the Labeled field from the provided Pull. If the object is nil, +// or the field within the object is nil, it returns the zero value instead. +func (a *Pull) GetLabeled() bool { + // return zero value if Pull type or Labeled field is nil + if a == nil || a.Labeled == nil { + return false + } + + return *a.Labeled +} + +// GetUnlabeled returns the Unlabeled field from the provided Pull. If the object is nil, +// or the field within the object is nil, it returns the zero value instead. +func (a *Pull) GetUnlabeled() bool { + // return zero value if Pull type or Unlabeled field is nil + if a == nil || a.Unlabeled == nil { + return false + } + + return *a.Unlabeled +} + +// SetOpened sets the Pull Opened field. +// +// When the provided Pull type is nil, it +// will set nothing and immediately return. +func (a *Pull) SetOpened(v bool) { + // return if Pull type is nil + if a == nil { + return + } + + a.Opened = &v +} + +// SetSynchronize sets the Pull Synchronize field. +// +// When the provided Pull type is nil, it +// will set nothing and immediately return. +func (a *Pull) SetSynchronize(v bool) { + // return if Pull type is nil + if a == nil { + return + } + + a.Synchronize = &v +} + +// SetEdited sets the Pull Edited field. +// +// When the provided Pull type is nil, it +// will set nothing and immediately return. +func (a *Pull) SetEdited(v bool) { + // return if Pull type is nil + if a == nil { + return + } + + a.Edited = &v +} + +// SetReopened sets the Pull Reopened field. +// +// When the provided Pull type is nil, it +// will set nothing and immediately return. +func (a *Pull) SetReopened(v bool) { + // return if Pull type is nil + if a == nil { + return + } + + a.Reopened = &v +} + +// SetLabeled sets the Pull Labeled field. +// +// When the provided Pull type is nil, it +// will set nothing and immediately return. +func (a *Pull) SetLabeled(v bool) { + // return if Pull type is nil + if a == nil { + return + } + + a.Labeled = &v +} + +// SetUnlabeled sets the Pull Unlabeled field. +// +// When the provided Pull type is nil, it +// will set nothing and immediately return. +func (a *Pull) SetUnlabeled(v bool) { + // return if Pull type is nil + if a == nil { + return + } + + a.Unlabeled = &v +} diff --git a/api/types/actions/pull_test.go b/api/types/actions/pull_test.go new file mode 100644 index 000000000..0ff17d6ad --- /dev/null +++ b/api/types/actions/pull_test.go @@ -0,0 +1,148 @@ +// SPDX-License-Identifier: Apache-2.0 + +package actions + +import ( + "reflect" + "testing" + + "github.com/go-vela/types/constants" +) + +func TestActions_Pull_Getters(t *testing.T) { + // setup tests + tests := []struct { + actions *Pull + want *Pull + }{ + { + actions: testPull(), + want: testPull(), + }, + { + actions: new(Pull), + want: new(Pull), + }, + } + + // run tests + for _, test := range tests { + if test.actions.GetOpened() != test.want.GetOpened() { + t.Errorf("GetOpened is %v, want %v", test.actions.GetOpened(), test.want.GetOpened()) + } + + if test.actions.GetSynchronize() != test.want.GetSynchronize() { + t.Errorf("GetSynchronize is %v, want %v", test.actions.GetSynchronize(), test.want.GetSynchronize()) + } + + if test.actions.GetEdited() != test.want.GetEdited() { + t.Errorf("GetEdited is %v, want %v", test.actions.GetEdited(), test.want.GetEdited()) + } + + if test.actions.GetReopened() != test.want.GetReopened() { + t.Errorf("GetReopened is %v, want %v", test.actions.GetReopened(), test.want.GetReopened()) + } + + if test.actions.GetLabeled() != test.want.GetLabeled() { + t.Errorf("GetLabeled is %v, want %v", test.actions.GetLabeled(), test.want.GetLabeled()) + } + + if test.actions.GetUnlabeled() != test.want.GetUnlabeled() { + t.Errorf("GetUnlabeled is %v, want %v", test.actions.GetUnlabeled(), test.want.GetUnlabeled()) + } + } +} + +func TestActions_Pull_Setters(t *testing.T) { + // setup types + var a *Pull + + // setup tests + tests := []struct { + actions *Pull + want *Pull + }{ + { + actions: testPull(), + want: testPull(), + }, + { + actions: a, + want: new(Pull), + }, + } + + // run tests + for _, test := range tests { + test.actions.SetOpened(test.want.GetOpened()) + test.actions.SetSynchronize(test.want.GetSynchronize()) + test.actions.SetEdited(test.want.GetEdited()) + test.actions.SetReopened(test.want.GetReopened()) + test.actions.SetLabeled(test.want.GetLabeled()) + test.actions.SetUnlabeled(test.want.GetUnlabeled()) + + if test.actions.GetOpened() != test.want.GetOpened() { + t.Errorf("SetOpened is %v, want %v", test.actions.GetOpened(), test.want.GetOpened()) + } + + if test.actions.GetSynchronize() != test.want.GetSynchronize() { + t.Errorf("SetSynchronize is %v, want %v", test.actions.GetSynchronize(), test.want.GetSynchronize()) + } + + if test.actions.GetEdited() != test.want.GetEdited() { + t.Errorf("SetEdited is %v, want %v", test.actions.GetEdited(), test.want.GetEdited()) + } + + if test.actions.GetReopened() != test.want.GetReopened() { + t.Errorf("SetReopened is %v, want %v", test.actions.GetReopened(), test.want.GetReopened()) + } + + if test.actions.GetLabeled() != test.want.GetLabeled() { + t.Errorf("SetLabeled is %v, want %v", test.actions.GetLabeled(), test.want.GetLabeled()) + } + + if test.actions.GetUnlabeled() != test.want.GetUnlabeled() { + t.Errorf("SetUnlabeled is %v, want %v", test.actions.GetUnlabeled(), test.want.GetUnlabeled()) + } + } +} + +func TestActions_Pull_FromMask(t *testing.T) { + // setup types + mask := testMask() + + want := testPull() + + // run test + got := new(Pull).FromMask(mask) + + if !reflect.DeepEqual(got, want) { + t.Errorf("FromMask is %v, want %v", got, want) + } +} + +func TestActions_Pull_ToMask(t *testing.T) { + // setup types + actions := testPull() + + want := int64(constants.AllowPullOpen | constants.AllowPullSync | constants.AllowPullReopen | constants.AllowPullUnlabel) + + // run test + got := actions.ToMask() + + if want != got { + t.Errorf("ToMask is %v, want %v", got, want) + } +} + +func testPull() *Pull { + pr := new(Pull) + pr.SetOpened(true) + pr.SetSynchronize(true) + pr.SetEdited(false) + pr.SetReopened(true) + pr.SetLabeled(false) + pr.SetUnlabeled(true) + + return pr +} diff --git a/api/types/actions/push.go b/api/types/actions/push.go new file mode 100644 index 000000000..6d5b24a6f --- /dev/null +++ b/api/types/actions/push.go @@ -0,0 +1,143 @@ +// SPDX-License-Identifier: Apache-2.0 + +package actions + +import "github.com/go-vela/types/constants" + +// Push is the API 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"` + 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 +} + +// ToMask returns the integer mask of the values for the Push set. +func (a *Push) ToMask() int64 { + mask := int64(0) + + if a.GetBranch() { + mask = mask | constants.AllowPushBranch + } + + if a.GetTag() { + mask = mask | constants.AllowPushTag + } + + if a.GetDeleteBranch() { + mask = mask | constants.AllowPushDeleteBranch + } + + if a.GetDeleteTag() { + mask = mask | constants.AllowPushDeleteTag + } + + return mask +} + +// GetBranch returns the Branch 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) GetBranch() bool { + // return zero value if Push 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 Push. If the object is nil, +// or the field within the object is nil, it returns the zero value instead. +func (a *Push) GetTag() bool { + // return zero value if Push type or Tag field is nil + if a == nil || a.Tag == nil { + return false + } + + 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 +// will set nothing and immediately return. +func (a *Push) SetBranch(v bool) { + // return if Events type is nil + if a == nil { + return + } + + a.Branch = &v +} + +// SetTag sets the Push Tag field. +// +// When the provided Push type is nil, it +// will set nothing and immediately return. +func (a *Push) SetTag(v bool) { + // return if Events type is nil + if a == nil { + return + } + + 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/api/types/actions/push_test.go b/api/types/actions/push_test.go new file mode 100644 index 000000000..259f7db2b --- /dev/null +++ b/api/types/actions/push_test.go @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: Apache-2.0 + +package actions + +import ( + "reflect" + "testing" + + "github.com/go-vela/types/constants" +) + +func TestTypes_Push_Getters(t *testing.T) { + // setup tests + tests := []struct { + actions *Push + want *Push + }{ + { + actions: testPush(), + want: testPush(), + }, + { + actions: new(Push), + want: new(Push), + }, + } + + // 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 TestTypes_Push_Setters(t *testing.T) { + // setup types + var a *Push + + // setup tests + tests := []struct { + actions *Push + want *Push + }{ + { + actions: testPush(), + want: testPush(), + }, + { + actions: a, + want: new(Push), + }, + } + + // run tests + 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()) + } + + 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()) + } + } +} + +func TestTypes_Push_FromMask(t *testing.T) { + // setup types + mask := testMask() + + want := testPush() + + // run test + got := new(Push).FromMask(mask) + + if !reflect.DeepEqual(got, want) { + t.Errorf("FromMask is %v, want %v", got, want) + } +} + +func TestTypes_Push_ToMask(t *testing.T) { + // setup types + actions := testPush() + + want := int64(constants.AllowPushBranch | constants.AllowPushTag | constants.AllowPushDeleteBranch | constants.AllowPushDeleteTag) + + // run test + got := actions.ToMask() + + if want != got { + t.Errorf("ToMask is %v, want %v", got, want) + } +} + +func testPush() *Push { + push := new(Push) + push.SetBranch(true) + push.SetTag(true) + push.SetDeleteBranch(true) + push.SetDeleteTag(true) + + return push +} + +func testMask() int64 { + return int64( + constants.AllowPushBranch | + constants.AllowPushTag | + constants.AllowPushDeleteBranch | + constants.AllowPushDeleteTag | + constants.AllowPullOpen | + constants.AllowPullSync | + constants.AllowPullReopen | + constants.AllowPullUnlabel | + constants.AllowDeployCreate | + constants.AllowCommentCreate | + constants.AllowSchedule, + ) +} diff --git a/api/types/actions/schedule.go b/api/types/actions/schedule.go new file mode 100644 index 000000000..bc4588d2f --- /dev/null +++ b/api/types/actions/schedule.go @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: Apache-2.0 +// +//nolint:dupl // similar code to deploy.go +package actions + +import "github.com/go-vela/types/constants" + +// Schedule is the API 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/api/types/actions/schedule_test.go b/api/types/actions/schedule_test.go new file mode 100644 index 000000000..8a06b0d75 --- /dev/null +++ b/api/types/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 TestTypes_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 TestTypes_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 TestTypes_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 TestTypes_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/api/types/events.go b/api/types/events.go new file mode 100644 index 000000000..9c4885667 --- /dev/null +++ b/api/types/events.go @@ -0,0 +1,338 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "fmt" + + "github.com/go-vela/types/constants" + "github.com/go-vela/types/library/actions" +) + +// 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"` + Schedule *actions.Schedule `json:"schedule"` +} + +// NewEventsFromMask is an instatiation function for the Events type that +// takes in an event mask integer value and populates the nested Events struct. +func NewEventsFromMask(mask int64) *Events { + pushActions := new(actions.Push).FromMask(mask) + 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) + + e.SetPush(pushActions) + e.SetPullRequest(pullActions) + e.SetDeployment(deployActions) + e.SetComment(commentActions) + e.SetSchedule(scheduleActions) + + return e +} + +// NewEventsFromSlice is an instantiation function for the Events type that +// takes in a slice of event strings and populates the nested Events struct. +func NewEventsFromSlice(events []string) (*Events, error) { + mask := int64(0) + + // iterate through all events provided + for _, event := range events { + switch event { + // push actions + case constants.EventPush, constants.EventPush + ":branch": + mask = mask | constants.AllowPushBranch + case constants.EventTag, constants.EventPush + ":" + constants.EventTag: + mask = mask | constants.AllowPushTag + case constants.EventDelete + ":" + constants.ActionBranch: + mask = mask | constants.AllowPushDeleteBranch + case constants.EventDelete + ":" + constants.ActionTag: + mask = mask | constants.AllowPushDeleteTag + case constants.EventDelete: + mask = mask | constants.AllowPushDeleteBranch | constants.AllowPushDeleteTag + + // pull_request actions + case constants.EventPull, constants.EventPullAlternate: + mask = mask | constants.AllowPullOpen | constants.AllowPullSync | constants.AllowPullReopen + case constants.EventPull + ":" + constants.ActionOpened: + mask = mask | constants.AllowPullOpen + case constants.EventPull + ":" + constants.ActionEdited: + mask = mask | constants.AllowPullEdit + case constants.EventPull + ":" + constants.ActionSynchronize: + mask = mask | constants.AllowPullSync + case constants.EventPull + ":" + constants.ActionReopened: + mask = mask | constants.AllowPullReopen + case constants.EventPull + ":" + constants.ActionLabeled: + mask = mask | constants.AllowPullLabel + case constants.EventPull + ":" + constants.ActionUnlabeled: + mask = mask | constants.AllowPullUnlabel + + // deployment actions + case constants.EventDeploy, constants.EventDeployAlternate, constants.EventDeploy + ":" + constants.ActionCreated: + mask = mask | constants.AllowDeployCreate + + // comment actions + case constants.EventComment: + mask = mask | constants.AllowCommentCreate | constants.AllowCommentEdit + case constants.EventComment + ":" + constants.ActionCreated: + mask = mask | constants.AllowCommentCreate + case constants.EventComment + ":" + constants.ActionEdited: + mask = mask | constants.AllowCommentEdit + + // schedule actions + case constants.EventSchedule, constants.EventSchedule + ":" + constants.ActionRun: + mask = mask | constants.AllowSchedule + + default: + return nil, fmt.Errorf("invalid event provided: %s", event) + } + } + + return NewEventsFromMask(mask), nil +} + +// 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 + } + + 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.EventPull + ":" + constants.ActionReopened: + allowed = e.GetPullRequest().GetReopened() + case constants.EventPull + ":" + constants.ActionLabeled: + allowed = e.GetPullRequest().GetLabeled() + case constants.EventPull + ":" + constants.ActionUnlabeled: + allowed = e.GetPullRequest().GetUnlabeled() + 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() + case constants.EventDelete + ":" + constants.ActionBranch: + allowed = e.GetPush().GetDeleteBranch() + case constants.EventDelete + ":" + constants.ActionTag: + allowed = e.GetPush().GetDeleteTag() + } + + 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 { + eventSlice := []string{} + + if e.GetPush().GetBranch() { + eventSlice = append(eventSlice, constants.EventPush) + } + + if e.GetPullRequest().GetOpened() { + eventSlice = append(eventSlice, constants.EventPull+":"+constants.ActionOpened) + } + + if e.GetPullRequest().GetSynchronize() { + eventSlice = append(eventSlice, constants.EventPull+":"+constants.ActionSynchronize) + } + + if e.GetPullRequest().GetEdited() { + eventSlice = append(eventSlice, constants.EventPull+":"+constants.ActionEdited) + } + + if e.GetPullRequest().GetReopened() { + eventSlice = append(eventSlice, constants.EventPull+":"+constants.ActionReopened) + } + + if e.GetPullRequest().GetLabeled() { + eventSlice = append(eventSlice, constants.EventPull+":"+constants.ActionLabeled) + } + + if e.GetPullRequest().GetUnlabeled() { + eventSlice = append(eventSlice, constants.EventPull+":"+constants.ActionUnlabeled) + } + + if e.GetPush().GetTag() { + eventSlice = append(eventSlice, constants.EventTag) + } + + if e.GetDeployment().GetCreated() { + eventSlice = append(eventSlice, constants.EventDeploy) + } + + if e.GetComment().GetCreated() { + eventSlice = append(eventSlice, constants.EventComment+":"+constants.ActionCreated) + } + + if e.GetComment().GetEdited() { + eventSlice = append(eventSlice, constants.EventComment+":"+constants.ActionEdited) + } + + if e.GetSchedule().GetRun() { + eventSlice = append(eventSlice, constants.EventSchedule) + } + + if e.GetPush().GetDeleteBranch() { + eventSlice = append(eventSlice, constants.EventDelete+":"+constants.ActionBranch) + } + + if e.GetPush().GetDeleteTag() { + 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() | + e.GetSchedule().ToMask() +} + +// GetPush returns the Push 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) GetPush() *actions.Push { + // return zero value if Events type or Push field is nil + if e == nil || e.Push == nil { + return new(actions.Push) + } + + return e.Push +} + +// GetPullRequest returns the PullRequest 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) GetPullRequest() *actions.Pull { + // return zero value if Events type or PullRequest field is nil + if e == nil || e.PullRequest == nil { + return new(actions.Pull) + } + + return e.PullRequest +} + +// GetDeployment returns the Deployment 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) GetDeployment() *actions.Deploy { + // return zero value if Events type or Deployment field is nil + if e == nil || e.Deployment == nil { + return new(actions.Deploy) + } + + return e.Deployment +} + +// GetComment returns the Comment 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) GetComment() *actions.Comment { + // return zero value if Events type or Comment field is nil + if e == nil || e.Comment == nil { + return new(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 +// will set nothing and immediately return. +func (e *Events) SetPush(v *actions.Push) { + // return if Events type is nil + if e == nil { + return + } + + e.Push = v +} + +// SetPullRequest sets the Events PullRequest field. +// +// When the provided Events type is nil, it +// will set nothing and immediately return. +func (e *Events) SetPullRequest(v *actions.Pull) { + // return if Events type is nil + if e == nil { + return + } + + e.PullRequest = v +} + +// SetDeployment sets the Events Deployment field. +// +// When the provided Events type is nil, it +// will set nothing and immediately return. +func (e *Events) SetDeployment(v *actions.Deploy) { + // return if Events type is nil + if e == nil { + return + } + + e.Deployment = v +} + +// SetComment sets the Events Comment field. +// +// When the provided Events type is nil, it +// will set nothing and immediately return. +func (e *Events) SetComment(v *actions.Comment) { + // return if Events type is nil + if e == nil { + return + } + + 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/api/types/events_test.go b/api/types/events_test.go new file mode 100644 index 000000000..e01d8d1f8 --- /dev/null +++ b/api/types/events_test.go @@ -0,0 +1,424 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "reflect" + "testing" + + "github.com/go-vela/types/constants" + "github.com/go-vela/types/library/actions" + "github.com/google/go-cmp/cmp" +) + +func TestTypes_Events_Getters(t *testing.T) { + // setup types + eventsOne, eventsTwo := testEvents() + + // setup tests + tests := []struct { + events *Events + want *Events + }{ + { + events: eventsOne, + want: eventsOne, + }, + { + events: eventsTwo, + want: eventsTwo, + }, + { + events: new(Events), + want: new(Events), + }, + } + + // run tests + for _, test := range tests { + if !reflect.DeepEqual(test.events.GetPush(), test.want.GetPush()) { + t.Errorf("GetPush is %v, want %v", test.events.GetPush(), test.want.GetPush()) + } + + if !reflect.DeepEqual(test.events.GetPullRequest(), test.want.GetPullRequest()) { + t.Errorf("GetPullRequest is %v, want %v", test.events.GetPush(), test.want.GetPush()) + } + + if !reflect.DeepEqual(test.events.GetDeployment(), test.want.GetDeployment()) { + t.Errorf("GetDeployment is %v, want %v", test.events.GetPush(), test.want.GetPush()) + } + + 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.GetSchedule(), test.want.GetSchedule()) { + t.Errorf("GetSchedule is %v, want %v", test.events.GetSchedule(), test.want.GetSchedule()) + } + } +} + +func TestTypes_Events_Setters(t *testing.T) { + // setup types + var e *Events + + eventsOne, eventsTwo := testEvents() + + // setup tests + tests := []struct { + events *Events + want *Events + }{ + { + events: eventsOne, + want: eventsOne, + }, + { + events: eventsTwo, + want: eventsTwo, + }, + { + events: e, + want: new(Events), + }, + } + + // run tests + for _, test := range tests { + test.events.SetPush(test.want.GetPush()) + test.events.SetPullRequest(test.want.GetPullRequest()) + test.events.SetDeployment(test.want.GetDeployment()) + test.events.SetComment(test.want.GetComment()) + test.events.SetSchedule(test.want.GetSchedule()) + + if !reflect.DeepEqual(test.events.GetPush(), test.want.GetPush()) { + t.Errorf("SetPush is %v, want %v", test.events.GetPush(), test.want.GetPush()) + } + + if !reflect.DeepEqual(test.events.GetPullRequest(), test.want.GetPullRequest()) { + t.Errorf("SetPullRequest is %v, want %v", test.events.GetPullRequest(), test.want.GetPullRequest()) + } + + if !reflect.DeepEqual(test.events.GetDeployment(), test.want.GetDeployment()) { + t.Errorf("SetDeployment is %v, want %v", test.events.GetDeployment(), test.want.GetDeployment()) + } + + 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.GetSchedule(), test.want.GetSchedule()) { + t.Errorf("SetSchedule is %v, want %v", test.events.GetSchedule(), test.want.GetSchedule()) + } + } +} + +func TestTypes_Events_List(t *testing.T) { + // setup types + eventsOne, eventsTwo := testEvents() + + wantOne := []string{ + "push", + "pull_request:opened", + "pull_request:synchronize", + "pull_request:reopened", + "pull_request:unlabeled", + "tag", + "comment:created", + "schedule", + "delete:branch", + } + + wantTwo := []string{ + "pull_request:edited", + "pull_request:labeled", + "deployment", + "comment:edited", + "delete:tag", + } + + // run test + gotOne := eventsOne.List() + + if diff := cmp.Diff(wantOne, gotOne); diff != "" { + t.Errorf("(List: -want +got):\n%s", diff) + } + + gotTwo := eventsTwo.List() + + if diff := cmp.Diff(wantTwo, gotTwo); diff != "" { + t.Errorf("(List Inverse: -want +got):\n%s", diff) + } +} + +func TestTypes_Events_NewEventsFromMask_ToDatabase(t *testing.T) { + // setup mask + maskOne := int64( + constants.AllowPushBranch | + constants.AllowPushTag | + constants.AllowPushDeleteBranch | + constants.AllowPullOpen | + constants.AllowPullSync | + constants.AllowPullReopen | + constants.AllowPullUnlabel | + constants.AllowCommentCreate | + constants.AllowSchedule, + ) + + maskTwo := int64( + constants.AllowPushDeleteTag | + constants.AllowPullEdit | + constants.AllowCommentEdit | + constants.AllowPullLabel | + constants.AllowDeployCreate, + ) + + wantOne, wantTwo := testEvents() + + // run test + gotOne := NewEventsFromMask(maskOne) + + if diff := cmp.Diff(wantOne, gotOne); diff != "" { + t.Errorf("(NewEventsFromMask: -want +got):\n%s", diff) + } + + gotTwo := NewEventsFromMask(maskTwo) + + 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 Test_NewEventsFromSlice(t *testing.T) { + // setup types + tBool := true + fBool := false + + e1, e2 := testEvents() + + // setup tests + tests := []struct { + name string + events []string + want *Events + failure bool + }{ + { + name: "action specific events to e1", + events: []string{"push:branch", "push:tag", "delete:branch", "pull_request:opened", "pull_request:synchronize", "pull_request:reopened", "comment:created", "schedule:run", "pull_request:unlabeled"}, + want: e1, + failure: false, + }, + { + name: "action specific events to e2", + events: []string{"delete:tag", "pull_request:edited", "deployment:created", "comment:edited", "pull_request:labeled"}, + want: e2, + failure: false, + }, + { + name: "general events", + events: []string{"push", "pull", "deploy", "comment", "schedule", "tag", "delete"}, + want: &Events{ + Push: &actions.Push{ + Branch: &tBool, + Tag: &tBool, + DeleteBranch: &tBool, + DeleteTag: &tBool, + }, + PullRequest: &actions.Pull{ + Opened: &tBool, + Reopened: &tBool, + Edited: &fBool, + Synchronize: &tBool, + Labeled: &fBool, + Unlabeled: &fBool, + }, + Deployment: &actions.Deploy{ + Created: &tBool, + }, + Comment: &actions.Comment{ + Created: &tBool, + Edited: &tBool, + }, + Schedule: &actions.Schedule{ + Run: &tBool, + }, + }, + failure: false, + }, + { + name: "double events", + events: []string{"push", "push:branch", "pull_request", "pull_request:opened"}, + want: &Events{ + Push: &actions.Push{ + Branch: &tBool, + Tag: &fBool, + DeleteBranch: &fBool, + DeleteTag: &fBool, + }, + PullRequest: &actions.Pull{ + Opened: &tBool, + Reopened: &tBool, + Edited: &fBool, + Synchronize: &tBool, + Labeled: &fBool, + Unlabeled: &fBool, + }, + Deployment: &actions.Deploy{ + Created: &fBool, + }, + Comment: &actions.Comment{ + Created: &fBool, + Edited: &fBool, + }, + Schedule: &actions.Schedule{ + Run: &fBool, + }, + }, + failure: false, + }, + { + name: "empty events", + events: []string{}, + want: NewEventsFromMask(0), + }, + { + name: "invalid events", + events: []string{"foo:bar"}, + want: nil, + failure: true, + }, + } + + // run tests + for _, test := range tests { + got, err := NewEventsFromSlice(test.events) + + if test.failure { + if err == nil { + t.Errorf("NewEventsFromSlice should have returned err") + } + + continue + } + + if err != nil { + t.Errorf("NewEventsFromSlice returned err: %v", err) + } + + if diff := cmp.Diff(test.want, got); diff != "" { + t.Errorf("PopulateEvents failed for %s mismatch (-want +got):\n%s", test.name, diff) + } + } +} + +func TestTypes_Events_Allowed(t *testing.T) { + // setup types + eventsOne, eventsTwo := testEvents() + + // setup tests + tests := []struct { + event string + action string + want bool + }{ + {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: "pull_request", action: "labeled", want: false}, + {event: "pull_request", action: "unlabeled", 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 { + 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 gotTwo == test.want { + t.Errorf("Allowed Inverse for %s/%s is %v, want %v", test.event, test.action, gotTwo, !test.want) + } + } +} + +// 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 + + e1 := &Events{ + Push: &actions.Push{ + Branch: &tBool, + Tag: &tBool, + DeleteBranch: &tBool, + DeleteTag: &fBool, + }, + PullRequest: &actions.Pull{ + Opened: &tBool, + Synchronize: &tBool, + Edited: &fBool, + Reopened: &tBool, + Labeled: &fBool, + Unlabeled: &tBool, + }, + Deployment: &actions.Deploy{ + Created: &fBool, + }, + Comment: &actions.Comment{ + Created: &tBool, + Edited: &fBool, + }, + Schedule: &actions.Schedule{ + Run: &tBool, + }, + } + + e2 := &Events{ + Push: &actions.Push{ + Branch: &fBool, + Tag: &fBool, + DeleteBranch: &fBool, + DeleteTag: &tBool, + }, + PullRequest: &actions.Pull{ + Opened: &fBool, + Synchronize: &fBool, + Edited: &tBool, + Reopened: &fBool, + Labeled: &tBool, + Unlabeled: &fBool, + }, + Deployment: &actions.Deploy{ + Created: &tBool, + }, + Comment: &actions.Comment{ + Created: &fBool, + Edited: &tBool, + }, + Schedule: &actions.Schedule{ + Run: &fBool, + }, + } + + return e1, e2 +} diff --git a/api/types/executor.go b/api/types/executor.go new file mode 100644 index 000000000..d1dce126c --- /dev/null +++ b/api/types/executor.go @@ -0,0 +1,227 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "fmt" + "strings" + + "github.com/go-vela/types/library" + "github.com/go-vela/types/pipeline" +) + +// Executor is the library representation of an executor for a worker. +// +// swagger:model Executor +type Executor struct { + ID *int64 `json:"id,omitempty"` + Host *string `json:"host,omitempty"` + Runtime *string `json:"runtime,omitempty"` + Distribution *string `json:"distribution,omitempty"` + Build *library.Build `json:"build,omitempty"` + Repo *Repo `json:"repo,omitempty"` + Pipeline *pipeline.Build `json:"pipeline,omitempty"` +} + +// GetID returns the ID field. +// +// When the provided Executor type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (e *Executor) GetID() int64 { + // return zero value if Executor type or ID field is nil + if e == nil || e.ID == nil { + return 0 + } + + return *e.ID +} + +// GetHost returns the Host field. +// +// When the provided Executor type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (e *Executor) GetHost() string { + // return zero value if Executor type or Host field is nil + if e == nil || e.Host == nil { + return "" + } + + return *e.Host +} + +// GetRuntime returns the Runtime field. +// +// When the provided Executor type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (e *Executor) GetRuntime() string { + // return zero value if Executor type or Runtime field is nil + if e == nil || e.Runtime == nil { + return "" + } + + return *e.Runtime +} + +// GetDistribution returns the Distribution field. +// +// When the provided Executor type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (e *Executor) GetDistribution() string { + // return zero value if Executor type or Distribution field is nil + if e == nil || e.Distribution == nil { + return "" + } + + return *e.Distribution +} + +// GetBuild returns the Build field. +// +// When the provided Executor type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (e *Executor) GetBuild() library.Build { + // return zero value if Executor type or Build field is nil + if e == nil || e.Build == nil { + return library.Build{} + } + + return *e.Build +} + +// GetRepo returns the Repo field. +// +// When the provided Executor type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (e *Executor) GetRepo() Repo { + // return zero value if Executor type or Repo field is nil + if e == nil || e.Repo == nil { + return Repo{} + } + + return *e.Repo +} + +// GetPipeline returns the Pipeline field. +// +// When the provided Executor type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (e *Executor) GetPipeline() pipeline.Build { + // return zero value if Executor type or Pipeline field is nil + if e == nil || e.Pipeline == nil { + return pipeline.Build{} + } + + return *e.Pipeline +} + +// SetID sets the ID field. +// +// When the provided Executor type is nil, it +// will set nothing and immediately return. +func (e *Executor) SetID(v int64) { + // return if Executor type is nil + if e == nil { + return + } + + e.ID = &v +} + +// SetHost sets the Host field. +// +// When the provided Executor type is nil, it +// will set nothing and immediately return. +func (e *Executor) SetHost(v string) { + // return if Executor type is nil + if e == nil { + return + } + + e.Host = &v +} + +// SetRuntime sets the Runtime field. +// +// When the provided Executor type is nil, it +// will set nothing and immediately return. +func (e *Executor) SetRuntime(v string) { + // return if Executor type is nil + if e == nil { + return + } + + e.Runtime = &v +} + +// SetDistribution sets the Distribution field. +// +// When the provided Executor type is nil, it +// will set nothing and immediately return. +func (e *Executor) SetDistribution(v string) { + // return if Executor type is nil + if e == nil { + return + } + + e.Distribution = &v +} + +// SetBuild sets the Build field. +// +// When the provided Executor type is nil, it +// will set nothing and immediately return. +func (e *Executor) SetBuild(v library.Build) { + // return if Executor type is nil + if e == nil { + return + } + + e.Build = &v +} + +// SetRepo sets the Repo field. +// +// When the provided Executor type is nil, it +// will set nothing and immediately return. +func (e *Executor) SetRepo(v Repo) { + // return if Executor type is nil + if e == nil { + return + } + + e.Repo = &v +} + +// SetPipeline sets the pipeline Build field. +// +// When the provided Executor type is nil, it +// will set nothing and immediately return. +func (e *Executor) SetPipeline(v pipeline.Build) { + // return if Executor type is nil + if e == nil { + return + } + + e.Pipeline = &v +} + +// String implements the Stringer interface for the Executor type. +func (e *Executor) String() string { + return fmt.Sprintf(`{ + Build: %s, + Distribution: %s, + Host: %s, + ID: %d, + Repo: %v, + Runtime: %s, + Pipeline: %v, +}`, + strings.ReplaceAll(e.Build.String(), " ", " "), + e.GetDistribution(), + e.GetHost(), + e.GetID(), + strings.ReplaceAll(e.Repo.String(), " ", " "), + e.GetRuntime(), + e.GetPipeline(), + ) +} diff --git a/api/types/executor_test.go b/api/types/executor_test.go new file mode 100644 index 000000000..72dbac4e4 --- /dev/null +++ b/api/types/executor_test.go @@ -0,0 +1,241 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "fmt" + "reflect" + "strings" + "testing" + + "github.com/go-vela/types/library" + "github.com/go-vela/types/pipeline" + "github.com/go-vela/types/raw" +) + +func TestTypes_Executor_Getters(t *testing.T) { + // setup tests + tests := []struct { + executor *Executor + want *Executor + }{ + { + executor: testExecutor(), + want: testExecutor(), + }, + { + executor: new(Executor), + want: new(Executor), + }, + } + + // run tests + for _, test := range tests { + if test.executor.GetID() != test.want.GetID() { + t.Errorf("GetID is %v, want %v", test.executor.GetID(), test.want.GetID()) + } + + if test.executor.GetHost() != test.want.GetHost() { + t.Errorf("GetHost is %v, want %v", test.executor.GetHost(), test.want.GetHost()) + } + + if test.executor.GetRuntime() != test.want.GetRuntime() { + t.Errorf("GetRuntime is %v, want %v", test.executor.GetRuntime(), test.want.GetRuntime()) + } + + if test.executor.GetDistribution() != test.want.GetDistribution() { + t.Errorf("GetDistribution is %v, want %v", test.executor.GetDistribution(), test.want.GetDistribution()) + } + + if !reflect.DeepEqual(test.executor.GetBuild(), test.want.GetBuild()) { + t.Errorf("GetBuild is %v, want %v", test.executor.GetBuild(), test.want.GetBuild()) + } + + if !reflect.DeepEqual(test.executor.GetRepo(), test.want.GetRepo()) { + t.Errorf("GetRepo is %v, want %v", test.executor.GetRepo(), test.want.GetRepo()) + } + + if !reflect.DeepEqual(test.executor.GetPipeline(), test.want.GetPipeline()) { + t.Errorf("GetPipeline is %v, want %v", test.executor.GetPipeline(), test.want.GetPipeline()) + } + } +} + +func TestTypes_Executor_Setters(t *testing.T) { + // setup types + var e *Executor + + // setup tests + tests := []struct { + executor *Executor + want *Executor + }{ + { + executor: testExecutor(), + want: testExecutor(), + }, + { + executor: e, + want: new(Executor), + }, + } + + // run tests + for _, test := range tests { + test.executor.SetID(test.want.GetID()) + test.executor.SetHost(test.want.GetHost()) + test.executor.SetRuntime(test.want.GetRuntime()) + test.executor.SetDistribution(test.want.GetDistribution()) + test.executor.SetBuild(test.want.GetBuild()) + test.executor.SetRepo(test.want.GetRepo()) + test.executor.SetPipeline(test.want.GetPipeline()) + + if test.executor.GetID() != test.want.GetID() { + t.Errorf("SetID is %v, want %v", test.executor.GetID(), test.want.GetID()) + } + + if test.executor.GetHost() != test.want.GetHost() { + t.Errorf("SetHost is %v, want %v", test.executor.GetHost(), test.want.GetHost()) + } + + if test.executor.GetRuntime() != test.want.GetRuntime() { + t.Errorf("SetRuntime is %v, want %v", test.executor.GetRuntime(), test.want.GetRuntime()) + } + + if test.executor.GetDistribution() != test.want.GetDistribution() { + t.Errorf("SetDistribution is %v, want %v", test.executor.GetDistribution(), test.want.GetDistribution()) + } + + if !reflect.DeepEqual(test.executor.GetBuild(), test.want.GetBuild()) { + t.Errorf("SetBuild is %v, want %v", test.executor.GetBuild(), test.want.GetBuild()) + } + + if !reflect.DeepEqual(test.executor.GetRepo(), test.want.GetRepo()) { + t.Errorf("SetRepo is %v, want %v", test.executor.GetRepo(), test.want.GetRepo()) + } + + if !reflect.DeepEqual(test.executor.GetPipeline(), test.want.GetPipeline()) { + t.Errorf("SetPipeline is %v, want %v", test.executor.GetPipeline(), test.want.GetPipeline()) + } + } +} + +func TestTypes_Executor_String(t *testing.T) { + // setup types + e := testExecutor() + + want := fmt.Sprintf(`{ + Build: %s, + Distribution: %s, + Host: %s, + ID: %d, + Repo: %v, + Runtime: %s, + Pipeline: %v, +}`, + strings.ReplaceAll(e.Build.String(), " ", " "), + e.GetDistribution(), + e.GetHost(), + e.GetID(), + strings.ReplaceAll(e.Repo.String(), " ", " "), + e.GetRuntime(), + e.GetPipeline(), + ) + + // run test + got := e.String() + + if !reflect.DeepEqual(got, want) { + t.Errorf("String is %v, want %v", got, want) + } +} + +// testExecutor is a test helper function to create a Executor +// type with all fields set to a fake value. +func testExecutor() *Executor { + e := new(Executor) + + e.SetID(1) + e.SetHost("company.example.com") + e.SetRuntime("docker") + e.SetDistribution("linux") + e.SetBuild(*testBuild()) + e.SetRepo(*testRepo()) + e.SetPipeline(pipeline.Build{ + Version: "1", + ID: "github_octocat_1", + Steps: pipeline.ContainerSlice{ + { + ID: "step_github_octocat_1_init", + Directory: "/home/github/octocat", + Image: "#init", + Name: "init", + Number: 1, + Pull: "always", + }, + { + ID: "step_github_octocat_1_clone", + Directory: "/home/github/octocat", + Image: "target/vela-git:v0.3.0", + Name: "clone", + Number: 2, + Pull: "always", + }, + { + ID: "step_github_octocat_1_echo", + Commands: []string{"echo hello"}, + Directory: "/home/github/octocat", + Image: "alpine:latest", + Name: "echo", + Number: 3, + Pull: "always", + }, + }, + }) + + return e +} + +// testBuild is a test helper function to create a Build +// type with all fields set to a fake value. +// +// TODO: remove this function once the Build type is moved to server. +func testBuild() *library.Build { + b := new(library.Build) + + b.SetID(1) + b.SetRepoID(1) + b.SetPipelineID(1) + b.SetNumber(1) + b.SetParent(1) + b.SetEvent("push") + b.SetStatus("running") + b.SetError("") + b.SetEnqueued(1563474077) + b.SetCreated(1563474076) + 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") + b.SetTitle("push received from https://github.com/github/octocat") + b.SetMessage("First commit...") + b.SetCommit("48afb5bdc41ad69bf22588491333f7cf71135163") + b.SetSender("OctoKitty") + b.SetAuthor("OctoKitty") + b.SetEmail("OctoKitty@github.com") + b.SetLink("https://example.company.com/github/octocat/1") + b.SetBranch("main") + b.SetRef("refs/heads/main") + b.SetBaseRef("") + b.SetHeadRef("changes") + b.SetHost("example.company.com") + b.SetRuntime("docker") + b.SetDistribution("linux") + b.SetApprovedAt(1563474076) + b.SetApprovedBy("OctoCat") + + return b +} diff --git a/api/types/repo.go b/api/types/repo.go new file mode 100644 index 000000000..fe0ad1028 --- /dev/null +++ b/api/types/repo.go @@ -0,0 +1,668 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "fmt" + "strings" + + "github.com/go-vela/types/library" +) + +// Repo is the API representation of a repo. +// +// swagger:model Repo +type Repo struct { + ID *int64 `json:"id,omitempty"` + Owner *library.User `json:"owner,omitempty"` + Hash *string `json:"-"` + Org *string `json:"org,omitempty"` + Name *string `json:"name,omitempty"` + FullName *string `json:"full_name,omitempty"` + Link *string `json:"link,omitempty"` + Clone *string `json:"clone,omitempty"` + Branch *string `json:"branch,omitempty"` + Topics *[]string `json:"topics,omitempty"` + BuildLimit *int64 `json:"build_limit,omitempty"` + Timeout *int64 `json:"timeout,omitempty"` + Counter *int `json:"counter,omitempty"` + Visibility *string `json:"visibility,omitempty"` + Private *bool `json:"private,omitempty"` + Trusted *bool `json:"trusted,omitempty"` + Active *bool `json:"active,omitempty"` + AllowEvents *Events `json:"allow_events,omitempty"` + PipelineType *string `json:"pipeline_type,omitempty"` + PreviousName *string `json:"previous_name,omitempty"` + ApproveBuild *string `json:"approve_build,omitempty"` +} + +// Environment returns a list of environment variables +// provided from the fields of the Repo type. +func (r *Repo) Environment() map[string]string { + return map[string]string{ + "VELA_REPO_ACTIVE": ToString(r.GetActive()), + "VELA_REPO_ALLOW_EVENTS": strings.Join(r.GetAllowEvents().List()[:], ","), + "VELA_REPO_BRANCH": ToString(r.GetBranch()), + "VELA_REPO_TOPICS": strings.Join(r.GetTopics()[:], ","), + "VELA_REPO_BUILD_LIMIT": ToString(r.GetBuildLimit()), + "VELA_REPO_CLONE": ToString(r.GetClone()), + "VELA_REPO_FULL_NAME": ToString(r.GetFullName()), + "VELA_REPO_LINK": ToString(r.GetLink()), + "VELA_REPO_NAME": ToString(r.GetName()), + "VELA_REPO_ORG": ToString(r.GetOrg()), + "VELA_REPO_PRIVATE": ToString(r.GetPrivate()), + "VELA_REPO_TIMEOUT": ToString(r.GetTimeout()), + "VELA_REPO_TRUSTED": ToString(r.GetTrusted()), + "VELA_REPO_VISIBILITY": ToString(r.GetVisibility()), + "VELA_REPO_PIPELINE_TYPE": ToString(r.GetPipelineType()), + "VELA_REPO_APPROVE_BUILD": ToString(r.GetApproveBuild()), + "VELA_REPO_OWNER": ToString(r.GetOwner().GetName()), + + // deprecated environment variables + "REPOSITORY_ACTIVE": ToString(r.GetActive()), + "REPOSITORY_ALLOW_EVENTS": strings.Join(r.GetAllowEvents().List()[:], ","), + "REPOSITORY_BRANCH": ToString(r.GetBranch()), + "REPOSITORY_CLONE": ToString(r.GetClone()), + "REPOSITORY_FULL_NAME": ToString(r.GetFullName()), + "REPOSITORY_LINK": ToString(r.GetLink()), + "REPOSITORY_NAME": ToString(r.GetName()), + "REPOSITORY_ORG": ToString(r.GetOrg()), + "REPOSITORY_PRIVATE": ToString(r.GetPrivate()), + "REPOSITORY_TIMEOUT": ToString(r.GetTimeout()), + "REPOSITORY_TRUSTED": ToString(r.GetTrusted()), + "REPOSITORY_VISIBILITY": ToString(r.GetVisibility()), + } +} + +// GetID returns the ID field. +// +// 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) GetID() int64 { + // return zero value if Repo type or ID field is nil + if r == nil || r.ID == nil { + return 0 + } + + return *r.ID +} + +// GetOwner returns the Owner field. +// +// 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) GetOwner() *library.User { + // return zero value if Repo type or Owner field is nil + if r == nil || r.Owner == nil { + return new(library.User) + } + + return r.Owner +} + +// GetHash returns the Hash field. +// +// 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) GetHash() string { + // return zero value if Repo type or Hash field is nil + if r == nil || r.Hash == nil { + return "" + } + + return *r.Hash +} + +// GetOrg returns the Org field. +// +// 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) GetOrg() string { + // return zero value if Repo type or Org field is nil + if r == nil || r.Org == nil { + return "" + } + + return *r.Org +} + +// GetName returns the Name field. +// +// 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) GetName() string { + // return zero value if Repo type or Name field is nil + if r == nil || r.Name == nil { + return "" + } + + return *r.Name +} + +// GetFullName returns the FullName field. +// +// 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) GetFullName() string { + // return zero value if Repo type or FullName field is nil + if r == nil || r.FullName == nil { + return "" + } + + return *r.FullName +} + +// GetLink returns the Link field. +// +// 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) GetLink() string { + // return zero value if Repo type or Link field is nil + if r == nil || r.Link == nil { + return "" + } + + return *r.Link +} + +// GetClone returns the Clone field. +// +// 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) GetClone() string { + // return zero value if Repo type or Clone field is nil + if r == nil || r.Clone == nil { + return "" + } + + return *r.Clone +} + +// GetBranch returns the Branch field. +// +// 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) GetBranch() string { + // return zero value if Repo type or Branch field is nil + if r == nil || r.Branch == nil { + return "" + } + + return *r.Branch +} + +// GetTopics returns the Topics field. +// +// 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) GetTopics() []string { + // return zero value if Repo type or Topics field is nil + if r == nil || r.Topics == nil { + return []string{} + } + + return *r.Topics +} + +// GetBuildLimit returns the BuildLimit field. +// +// 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) GetBuildLimit() int64 { + // return zero value if Repo type or BuildLimit field is nil + if r == nil || r.BuildLimit == nil { + return 0 + } + + return *r.BuildLimit +} + +// GetTimeout returns the Timeout field. +// +// 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) GetTimeout() int64 { + // return zero value if Repo type or Timeout field is nil + if r == nil || r.Timeout == nil { + return 0 + } + + return *r.Timeout +} + +// GetCounter returns the Counter field. +// +// 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) GetCounter() int { + // return zero value if Repo type or Counter field is nil + if r == nil || r.Counter == nil { + return 0 + } + + return *r.Counter +} + +// GetVisibility returns the Visibility field. +// +// 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) GetVisibility() string { + // return zero value if Repo type or Visibility field is nil + if r == nil || r.Visibility == nil { + return "" + } + + return *r.Visibility +} + +// GetPrivate returns the Private field. +// +// 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) GetPrivate() bool { + // return zero value if Repo type or Private field is nil + if r == nil || r.Private == nil { + return false + } + + return *r.Private +} + +// GetTrusted returns the Trusted field. +// +// 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) GetTrusted() bool { + // return zero value if Repo type or Trusted field is nil + if r == nil || r.Trusted == nil { + return false + } + + return *r.Trusted +} + +// GetActive returns the Active field. +// +// 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) GetActive() bool { + // return zero value if Repo type or Active field is nil + if r == nil || r.Active == nil { + return false + } + + return *r.Active +} + +// GetAllowEvents returns the AllowEvents field. +// +// 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) GetAllowEvents() *Events { + // return zero value if Repo type or AllowPull field is nil + if r == nil || r.AllowEvents == nil { + return new(Events) + } + + return r.AllowEvents +} + +// GetPipelineType returns the PipelineType field. +// +// 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) GetPipelineType() string { + // return zero value if Repo type or PipelineType field is nil + if r == nil || r.PipelineType == nil { + return "" + } + + return *r.PipelineType +} + +// GetPreviousName returns the PreviousName field. +// +// 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) GetPreviousName() string { + // return zero value if Repo type or PreviousName field is nil + if r == nil || r.PreviousName == nil { + return "" + } + + return *r.PreviousName +} + +// GetApproveBuild returns the ApproveBuild field. +// +// 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) GetApproveBuild() string { + // return zero value if Repo type or ApproveBuild field is nil + if r == nil || r.ApproveBuild == nil { + return "" + } + + return *r.ApproveBuild +} + +// SetID sets the ID field. +// +// When the provided Repo type is nil, it +// will set nothing and immediately return. +func (r *Repo) SetID(v int64) { + // return if Repo type is nil + if r == nil { + return + } + + r.ID = &v +} + +// SetOwner sets the Owner field. +// +// When the provided Repo type is nil, it +// will set nothing and immediately return. +func (r *Repo) SetOwner(v *library.User) { + // return if Repo type is nil + if r == nil { + return + } + + r.Owner = v +} + +// SetHash sets the Hash field. +// +// When the provided Repo type is nil, it +// will set nothing and immediately return. +func (r *Repo) SetHash(v string) { + // return if Repo type is nil + if r == nil { + return + } + + r.Hash = &v +} + +// SetOrg sets the Org field. +// +// When the provided Repo type is nil, it +// will set nothing and immediately return. +func (r *Repo) SetOrg(v string) { + // return if Repo type is nil + if r == nil { + return + } + + r.Org = &v +} + +// SetName sets the Name field. +// +// When the provided Repo type is nil, it +// will set nothing and immediately return. +func (r *Repo) SetName(v string) { + // return if Repo type is nil + if r == nil { + return + } + + r.Name = &v +} + +// SetFullName sets the FullName field. +// +// When the provided Repo type is nil, it +// will set nothing and immediately return. +func (r *Repo) SetFullName(v string) { + // return if Repo type is nil + if r == nil { + return + } + + r.FullName = &v +} + +// SetLink sets the Link field. +// +// When the provided Repo type is nil, it +// will set nothing and immediately return. +func (r *Repo) SetLink(v string) { + // return if Repo type is nil + if r == nil { + return + } + + r.Link = &v +} + +// SetClone sets the Clone field. +// +// When the provided Repo type is nil, it +// will set nothing and immediately return. +func (r *Repo) SetClone(v string) { + // return if Repo type is nil + if r == nil { + return + } + + r.Clone = &v +} + +// SetBranch sets the Branch field. +// +// When the provided Repo type is nil, it +// will set nothing and immediately return. +func (r *Repo) SetBranch(v string) { + // return if Repo type is nil + if r == nil { + return + } + + r.Branch = &v +} + +// SetTopics sets the Topics field. +// +// When the provided Repo type is nil, it +// will set nothing and immediately return. +func (r *Repo) SetTopics(v []string) { + // return if Repo type is nil + if r == nil { + return + } + + r.Topics = &v +} + +// SetBuildLimit sets the BuildLimit field. +// +// When the provided Repo type is nil, it +// will set nothing and immediately return. +func (r *Repo) SetBuildLimit(v int64) { + // return if Repo type is nil + if r == nil { + return + } + + r.BuildLimit = &v +} + +// SetTimeout sets the Timeout field. +// +// When the provided Repo type is nil, it +// will set nothing and immediately return. +func (r *Repo) SetTimeout(v int64) { + // return if Repo type is nil + if r == nil { + return + } + + r.Timeout = &v +} + +// SetCounter sets the Counter field. +// +// When the provided Repo type is nil, it +// will set nothing and immediately return. +func (r *Repo) SetCounter(v int) { + // return if Repo type is nil + if r == nil { + return + } + + r.Counter = &v +} + +// SetVisibility sets the Visibility field. +// +// When the provided Repo type is nil, it +// will set nothing and immediately return. +func (r *Repo) SetVisibility(v string) { + // return if Repo type is nil + if r == nil { + return + } + + r.Visibility = &v +} + +// SetPrivate sets the Private field. +// +// When the provided Repo type is nil, it +// will set nothing and immediately return. +func (r *Repo) SetPrivate(v bool) { + // return if Repo type is nil + if r == nil { + return + } + + r.Private = &v +} + +// SetTrusted sets the Trusted field. +// +// When the provided Repo type is nil, it +// will set nothing and immediately return. +func (r *Repo) SetTrusted(v bool) { + // return if Repo type is nil + if r == nil { + return + } + + r.Trusted = &v +} + +// SetActive sets the Active field. +// +// When the provided Repo type is nil, it +// will set nothing and immediately return. +func (r *Repo) SetActive(v bool) { + // return if Repo type is nil + if r == nil { + return + } + + r.Active = &v +} + +// SetAllowEvents sets the AllowEvents field. +// +// When the provided Repo type is nil, it +// will set nothing and immediately return. +func (r *Repo) SetAllowEvents(v *Events) { + // return if Repo type is nil + if r == nil { + return + } + + r.AllowEvents = v +} + +// SetPipelineType sets the PipelineType field. +// +// When the provided Repo type is nil, it +// will set nothing and immediately return. +func (r *Repo) SetPipelineType(v string) { + // return if Repo type is nil + if r == nil { + return + } + + r.PipelineType = &v +} + +// SetPreviousName sets the PreviousName field. +// +// When the provided Repo type is nil, it +// will set nothing and immediately return. +func (r *Repo) SetPreviousName(v string) { + // return if Repo type is nil + if r == nil { + return + } + + r.PreviousName = &v +} + +// SetApproveBuild sets the ApproveBuild field. +// +// When the provided Repo type is nil, it +// will set nothing and immediately return. +func (r *Repo) SetApproveBuild(v string) { + // return if Repo type is nil + if r == nil { + return + } + + r.ApproveBuild = &v +} + +// String implements the Stringer interface for the Repo type. +func (r *Repo) String() string { + return fmt.Sprintf(`{ + Active: %t, + AllowEvents: %s, + ApproveBuild: %s, + Branch: %s, + BuildLimit: %d, + Clone: %s, + Counter: %d, + FullName: %s, + ID: %d, + Link: %s, + Name: %s, + Org: %s, + Owner: %v, + PipelineType: %s, + PreviousName: %s, + Private: %t, + Timeout: %d, + Topics: %s, + Trusted: %t, + Visibility: %s +}`, + r.GetActive(), + r.GetAllowEvents().List(), + r.GetApproveBuild(), + r.GetBranch(), + r.GetBuildLimit(), + r.GetClone(), + r.GetCounter(), + r.GetFullName(), + r.GetID(), + r.GetLink(), + r.GetName(), + r.GetOrg(), + r.GetOwner(), + r.GetPipelineType(), + r.GetPreviousName(), + r.GetPrivate(), + r.GetTimeout(), + r.GetTopics(), + r.GetTrusted(), + r.GetVisibility(), + ) +} diff --git a/api/types/repo_test.go b/api/types/repo_test.go new file mode 100644 index 000000000..b0554d742 --- /dev/null +++ b/api/types/repo_test.go @@ -0,0 +1,371 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "fmt" + "reflect" + "testing" + + "github.com/go-vela/types/constants" + "github.com/go-vela/types/library" + "github.com/google/go-cmp/cmp" +) + +func TestTypes_Repo_Environment(t *testing.T) { + // setup types + want := map[string]string{ + "VELA_REPO_ACTIVE": "true", + "VELA_REPO_ALLOW_EVENTS": "push,pull_request:opened,pull_request:synchronize,pull_request:reopened,pull_request:unlabeled,tag,comment:created,schedule,delete:branch", + "VELA_REPO_BRANCH": "main", + "VELA_REPO_TOPICS": "cloud,security", + "VELA_REPO_BUILD_LIMIT": "10", + "VELA_REPO_CLONE": "https://github.com/github/octocat.git", + "VELA_REPO_FULL_NAME": "github/octocat", + "VELA_REPO_LINK": "https://github.com/github/octocat", + "VELA_REPO_NAME": "octocat", + "VELA_REPO_ORG": "github", + "VELA_REPO_PRIVATE": "false", + "VELA_REPO_TIMEOUT": "30", + "VELA_REPO_TRUSTED": "false", + "VELA_REPO_VISIBILITY": "public", + "VELA_REPO_PIPELINE_TYPE": "", + "VELA_REPO_APPROVE_BUILD": "never", + "VELA_REPO_OWNER": "octocat", + "REPOSITORY_ACTIVE": "true", + "REPOSITORY_ALLOW_EVENTS": "push,pull_request:opened,pull_request:synchronize,pull_request:reopened,pull_request:unlabeled,tag,comment:created,schedule,delete:branch", + "REPOSITORY_BRANCH": "main", + "REPOSITORY_CLONE": "https://github.com/github/octocat.git", + "REPOSITORY_FULL_NAME": "github/octocat", + "REPOSITORY_LINK": "https://github.com/github/octocat", + "REPOSITORY_NAME": "octocat", + "REPOSITORY_ORG": "github", + "REPOSITORY_PRIVATE": "false", + "REPOSITORY_TIMEOUT": "30", + "REPOSITORY_TRUSTED": "false", + "REPOSITORY_VISIBILITY": "public", + } + + // run test + got := testRepo().Environment() + + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("(Environment: -want +got):\n%s", diff) + } +} + +func TestTypes_Repo_Getters(t *testing.T) { + // setup tests + tests := []struct { + repo *Repo + want *Repo + }{ + { + repo: testRepo(), + want: testRepo(), + }, + { + repo: new(Repo), + want: new(Repo), + }, + } + + // run tests + for _, test := range tests { + if test.repo.GetID() != test.want.GetID() { + t.Errorf("GetID is %v, want %v", test.repo.GetID(), test.want.GetID()) + } + + if !reflect.DeepEqual(test.repo.GetOwner(), test.want.GetOwner()) { + t.Errorf("GetOwner is %v, want %v", test.repo.GetOwner(), test.want.GetOwner()) + } + + if test.repo.GetHash() != test.want.GetHash() { + t.Errorf("GetHash is %v, want %v", test.repo.GetHash(), test.want.GetHash()) + } + + if test.repo.GetOrg() != test.want.GetOrg() { + t.Errorf("GetOrg is %v, want %v", test.repo.GetOrg(), test.want.GetOrg()) + } + + if test.repo.GetName() != test.want.GetName() { + t.Errorf("GetName is %v, want %v", test.repo.GetName(), test.want.GetName()) + } + + if test.repo.GetFullName() != test.want.GetFullName() { + t.Errorf("GetFullName is %v, want %v", test.repo.GetFullName(), test.want.GetFullName()) + } + + if test.repo.GetLink() != test.want.GetLink() { + t.Errorf("GetLink is %v, want %v", test.repo.GetLink(), test.want.GetLink()) + } + + if test.repo.GetClone() != test.want.GetClone() { + t.Errorf("GetClone is %v, want %v", test.repo.GetClone(), test.want.GetClone()) + } + + if test.repo.GetBranch() != test.want.GetBranch() { + t.Errorf("GetBranch is %v, want %v", test.repo.GetBranch(), test.want.GetBranch()) + } + + if !reflect.DeepEqual(test.repo.GetTopics(), test.want.GetTopics()) { + t.Errorf("GetTopics is %v, want %v", test.repo.GetTopics(), test.want.GetTopics()) + } + + if test.repo.GetBuildLimit() != test.want.GetBuildLimit() { + t.Errorf("GetBuildLimit is %v, want %v", test.repo.GetBuildLimit(), test.want.GetBuildLimit()) + } + + if test.repo.GetTimeout() != test.want.GetTimeout() { + t.Errorf("GetTimeout is %v, want %v", test.repo.GetTimeout(), test.want.GetTimeout()) + } + + if test.repo.GetVisibility() != test.want.GetVisibility() { + t.Errorf("GetVisibility is %v, want %v", test.repo.GetVisibility(), test.want.GetVisibility()) + } + + if test.repo.GetPrivate() != test.want.GetPrivate() { + t.Errorf("GetPrivate is %v, want %v", test.repo.GetPrivate(), test.want.GetPrivate()) + } + + if test.repo.GetTrusted() != test.want.GetTrusted() { + t.Errorf("GetTrusted is %v, want %v", test.repo.GetTrusted(), test.want.GetTrusted()) + } + + if test.repo.GetActive() != test.want.GetActive() { + t.Errorf("GetActive is %v, want %v", test.repo.GetActive(), test.want.GetActive()) + } + + if !reflect.DeepEqual(test.repo.GetAllowEvents(), test.want.GetAllowEvents()) { + t.Errorf("GetRepo is %v, want %v", test.repo.GetAllowEvents(), test.want.GetAllowEvents()) + } + + if test.repo.GetPipelineType() != test.want.GetPipelineType() { + t.Errorf("GetPipelineType is %v, want %v", test.repo.GetPipelineType(), test.want.GetPipelineType()) + } + + if !reflect.DeepEqual(test.repo.GetPreviousName(), test.want.GetPreviousName()) { + t.Errorf("GetPreviousName is %v, want %v", test.repo.GetPreviousName(), test.want.GetPreviousName()) + } + + if test.repo.GetApproveBuild() != test.want.GetApproveBuild() { + t.Errorf("GetApproveForkBuild is %v, want %v", test.repo.GetApproveBuild(), test.want.GetApproveBuild()) + } + } +} + +func TestTypes_Repo_Setters(t *testing.T) { + // setup types + var r *Repo + + // setup tests + tests := []struct { + repo *Repo + want *Repo + }{ + { + repo: testRepo(), + want: testRepo(), + }, + { + repo: r, + want: new(Repo), + }, + } + + // run tests + for _, test := range tests { + test.repo.SetID(test.want.GetID()) + test.repo.SetOwner(test.want.GetOwner()) + test.repo.SetHash(test.want.GetHash()) + test.repo.SetOrg(test.want.GetOrg()) + test.repo.SetName(test.want.GetName()) + test.repo.SetFullName(test.want.GetFullName()) + test.repo.SetLink(test.want.GetLink()) + test.repo.SetClone(test.want.GetClone()) + test.repo.SetBranch(test.want.GetBranch()) + test.repo.SetTopics(test.want.GetTopics()) + test.repo.SetBuildLimit(test.want.GetBuildLimit()) + test.repo.SetTimeout(test.want.GetTimeout()) + test.repo.SetCounter(test.want.GetCounter()) + test.repo.SetVisibility(test.want.GetVisibility()) + test.repo.SetPrivate(test.want.GetPrivate()) + test.repo.SetTrusted(test.want.GetTrusted()) + test.repo.SetActive(test.want.GetActive()) + test.repo.SetAllowEvents(test.want.GetAllowEvents()) + test.repo.SetPipelineType(test.want.GetPipelineType()) + test.repo.SetPreviousName(test.want.GetPreviousName()) + test.repo.SetApproveBuild(test.want.GetApproveBuild()) + + if test.repo.GetID() != test.want.GetID() { + t.Errorf("SetID is %v, want %v", test.repo.GetID(), test.want.GetID()) + } + + if !reflect.DeepEqual(test.repo.GetOwner(), test.want.GetOwner()) { + t.Errorf("SetOwner is %v, want %v", test.repo.GetOwner(), test.want.GetOwner()) + } + + if test.repo.GetHash() != test.want.GetHash() { + t.Errorf("SetHash is %v, want %v", test.repo.GetHash(), test.want.GetHash()) + } + + if test.repo.GetOrg() != test.want.GetOrg() { + t.Errorf("SetOrg is %v, want %v", test.repo.GetOrg(), test.want.GetOrg()) + } + + if test.repo.GetName() != test.want.GetName() { + t.Errorf("SetName is %v, want %v", test.repo.GetName(), test.want.GetName()) + } + + if test.repo.GetFullName() != test.want.GetFullName() { + t.Errorf("SetFullName is %v, want %v", test.repo.GetFullName(), test.want.GetFullName()) + } + + if test.repo.GetLink() != test.want.GetLink() { + t.Errorf("SetLink is %v, want %v", test.repo.GetLink(), test.want.GetLink()) + } + + if test.repo.GetClone() != test.want.GetClone() { + t.Errorf("SetClone is %v, want %v", test.repo.GetClone(), test.want.GetClone()) + } + + if test.repo.GetBranch() != test.want.GetBranch() { + t.Errorf("SetBranch is %v, want %v", test.repo.GetBranch(), test.want.GetBranch()) + } + + if !reflect.DeepEqual(test.repo.GetTopics(), test.want.GetTopics()) { + t.Errorf("SetTopics is %v, want %v", test.repo.GetTopics(), test.want.GetTopics()) + } + + if test.repo.GetBuildLimit() != test.want.GetBuildLimit() { + t.Errorf("SetBuildLimit is %v, want %v", test.repo.GetBuildLimit(), test.want.GetBuildLimit()) + } + + if test.repo.GetTimeout() != test.want.GetTimeout() { + t.Errorf("SetTimeout is %v, want %v", test.repo.GetTimeout(), test.want.GetTimeout()) + } + + if test.repo.GetVisibility() != test.want.GetVisibility() { + t.Errorf("SetVisibility is %v, want %v", test.repo.GetVisibility(), test.want.GetVisibility()) + } + + if test.repo.GetPrivate() != test.want.GetPrivate() { + t.Errorf("SetPrivate is %v, want %v", test.repo.GetPrivate(), test.want.GetPrivate()) + } + + if test.repo.GetTrusted() != test.want.GetTrusted() { + t.Errorf("SetTrusted is %v, want %v", test.repo.GetTrusted(), test.want.GetTrusted()) + } + + if test.repo.GetActive() != test.want.GetActive() { + t.Errorf("SetActive is %v, want %v", test.repo.GetActive(), test.want.GetActive()) + } + + if !reflect.DeepEqual(test.repo.GetAllowEvents(), test.want.GetAllowEvents()) { + t.Errorf("GetRepo is %v, want %v", test.repo.GetAllowEvents(), test.want.GetAllowEvents()) + } + + if test.repo.GetPipelineType() != test.want.GetPipelineType() { + t.Errorf("SetPipelineType is %v, want %v", test.repo.GetPipelineType(), test.want.GetPipelineType()) + } + + if !reflect.DeepEqual(test.repo.GetPreviousName(), test.want.GetPreviousName()) { + t.Errorf("SetPreviousName is %v, want %v", test.repo.GetPreviousName(), test.want.GetPreviousName()) + } + + if test.repo.GetApproveBuild() != test.want.GetApproveBuild() { + t.Errorf("SetApproveForkBuild is %v, want %v", test.repo.GetApproveBuild(), test.want.GetApproveBuild()) + } + } +} + +func TestTypes_Repo_String(t *testing.T) { + // setup types + r := testRepo() + + want := fmt.Sprintf(`{ + Active: %t, + AllowEvents: %s, + ApproveBuild: %s, + Branch: %s, + BuildLimit: %d, + Clone: %s, + Counter: %d, + FullName: %s, + ID: %d, + Link: %s, + Name: %s, + Org: %s, + Owner: %v, + PipelineType: %s, + PreviousName: %s, + Private: %t, + Timeout: %d, + Topics: %s, + Trusted: %t, + Visibility: %s +}`, + r.GetActive(), + r.GetAllowEvents().List(), + r.GetApproveBuild(), + r.GetBranch(), + r.GetBuildLimit(), + r.GetClone(), + r.GetCounter(), + r.GetFullName(), + r.GetID(), + r.GetLink(), + r.GetName(), + r.GetOrg(), + r.GetOwner(), + r.GetPipelineType(), + r.GetPreviousName(), + r.GetPrivate(), + r.GetTimeout(), + r.GetTopics(), + r.GetTrusted(), + r.GetVisibility(), + ) + + // run test + got := r.String() + + if !reflect.DeepEqual(got, want) { + t.Errorf("String is %v, want %v", got, want) + } +} + +// testRepo is a test helper function to create a Repo +// type with all fields set to a fake value. +func testRepo() *Repo { + r := new(Repo) + + e, _ := testEvents() + + owner := new(library.User) + owner.SetID(1) + owner.SetName("octocat") + + r.SetID(1) + r.SetOwner(owner) + r.SetOrg("github") + r.SetName("octocat") + r.SetFullName("github/octocat") + r.SetLink("https://github.com/github/octocat") + r.SetClone("https://github.com/github/octocat.git") + r.SetBranch("main") + r.SetTopics([]string{"cloud", "security"}) + r.SetBuildLimit(10) + r.SetTimeout(30) + r.SetCounter(0) + r.SetVisibility("public") + r.SetPrivate(false) + r.SetTrusted(false) + r.SetActive(true) + r.SetAllowEvents(e) + r.SetPipelineType("") + r.SetPreviousName("") + r.SetApproveBuild(constants.ApproveNever) + + return r +} diff --git a/api/types/string.go b/api/types/string.go new file mode 100644 index 000000000..33ddacb59 --- /dev/null +++ b/api/types/string.go @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "encoding/base64" + "strconv" + "strings" + + "github.com/buildkite/yaml" + json "github.com/ghodss/yaml" +) + +// ToString is a helper function to convert +// the provided interface value to a string. +func ToString(v interface{}) string { + switch v := v.(type) { + case string: + return v + case bool: + return strconv.FormatBool(v) + case []byte: + return base64.StdEncoding.EncodeToString(v) + case float32: + return strconv.FormatFloat(float64(v), 'g', -1, 32) + case float64: + return strconv.FormatFloat(v, 'g', -1, 64) + case int: + return strconv.Itoa(v) + case int8: + return strconv.FormatInt(int64(v), 10) + case int16: + return strconv.FormatInt(int64(v), 10) + case int32: + return strconv.FormatInt(int64(v), 10) + case int64: + return strconv.FormatInt(v, 10) + case uint: + return strconv.FormatUint(uint64(v), 10) + case uint8: + return strconv.FormatUint(uint64(v), 10) + case uint16: + return strconv.FormatUint(uint64(v), 10) + case uint32: + return strconv.FormatUint(uint64(v), 10) + case uint64: + return strconv.FormatUint(v, 10) + case []interface{}: + return unmarshalSlice(v) + default: + return unmarshalMap(v) + } +} + +// helper function to unmarshal a parameter in map format. +func unmarshalMap(v interface{}) string { + yml, err := yaml.Marshal(v) + if err != nil { + return err.Error() + } + + out, err := json.YAMLToJSON(yml) + if err != nil { + return err.Error() + } + + return string(out) +} + +// helper function to unmarshal a parameter in slice format. +func unmarshalSlice(v interface{}) string { + out, err := yaml.Marshal(v) + if err != nil { + return err.Error() + } + + in := []string{} + + err = yaml.Unmarshal(out, &in) + if err == nil { + return strings.Join(in, ",") + } + + out, err = json.YAMLToJSON(out) + if err != nil { + return err.Error() + } + + return string(out) +} diff --git a/api/types/string_test.go b/api/types/string_test.go new file mode 100644 index 000000000..e362f0766 --- /dev/null +++ b/api/types/string_test.go @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "reflect" + "testing" +) + +func TestTypes_ToString(t *testing.T) { + // setup tests + tests := []struct { + parameter interface{} + want interface{} + }{ + {parameter: "string", want: "string"}, // string + {parameter: true, want: "true"}, // bool + {parameter: []byte{1}, want: "AQ=="}, // []byte + {parameter: float32(1.1), want: "1.1"}, // float32 + {parameter: float64(1.1), want: "1.1"}, // float64 + {parameter: 1, want: "1"}, // int + {parameter: int8(1), want: "1"}, // int8 + {parameter: int16(1), want: "1"}, // int16 + {parameter: int32(1), want: "1"}, // int32 + {parameter: int64(1), want: "1"}, // int64 + {parameter: uint(1), want: "1"}, // uint + {parameter: uint8(1), want: "1"}, // uint8 + {parameter: uint16(1), want: "1"}, // uint16 + {parameter: uint32(1), want: "1"}, // uint32 + {parameter: uint64(1), want: "1"}, // uint64 + { // map + parameter: map[string]string{"hello": "world"}, + want: "{\"hello\":\"world\"}", + }, + { // slice + parameter: []interface{}{1, 2, 3}, + want: "1,2,3", + }, + { // slice complex + parameter: []interface{}{struct{ Foo string }{Foo: "bar"}}, + want: "[{\"foo\":\"bar\"}]", + }, + { // complex + parameter: []struct{ Foo string }{{"bar"}, {"baz"}}, + want: "[{\"foo\":\"bar\"},{\"foo\":\"baz\"}]", + }, + } + + // run tests + for _, test := range tests { + got := ToString(test.parameter) + + if !reflect.DeepEqual(got, test.want) { + t.Errorf("ToString is %v, want %v", got, test.want) + } + } +} diff --git a/api/types/worker_test.go b/api/types/worker_test.go index 19d2defb5..b1cc06fdb 100644 --- a/api/types/worker_test.go +++ b/api/types/worker_test.go @@ -58,7 +58,7 @@ func TestTypes_Worker_Getters(t *testing.T) { } if !reflect.DeepEqual(test.worker.GetRunningBuilds(), test.want.GetRunningBuilds()) { - t.Errorf("GetRunningBuildIDs is %v, want %v", test.worker.GetRunningBuilds(), test.want.GetRunningBuilds()) + t.Errorf("GetRunningBuilds is %v, want %v", test.worker.GetRunningBuilds(), test.want.GetRunningBuilds()) } if test.worker.GetLastBuildStartedAt() != test.want.GetLastBuildStartedAt() { diff --git a/api/user/get_source.go b/api/user/get_source.go index 6390c00e7..b52e3950f 100644 --- a/api/user/get_source.go +++ b/api/user/get_source.go @@ -7,11 +7,11 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" "github.com/go-vela/server/util" - "github.com/go-vela/types/library" "github.com/sirupsen/logrus" ) @@ -49,8 +49,8 @@ func GetSourceRepos(c *gin.Context) { }).Infof("reading available SCM repos for user %s", u.GetName()) // variables to capture requested data - dbRepos := []*library.Repo{} - output := make(map[string][]library.Repo) + dbRepos := []*types.Repo{} + output := make(map[string][]types.Repo) // send API call to capture the list of repos for the user srcRepos, err := scm.FromContext(c).ListUserRepos(ctx, u) @@ -72,7 +72,7 @@ func GetSourceRepos(c *gin.Context) { active := false // library struct to omit optional fields - repo := library.Repo{ + repo := types.Repo{ Org: org, Name: name, Active: &active, diff --git a/api/webhook/post.go b/api/webhook/post.go index d33a201e9..3f1b3bba7 100644 --- a/api/webhook/post.go +++ b/api/webhook/post.go @@ -15,12 +15,13 @@ import ( "github.com/gin-gonic/gin" "github.com/go-vela/server/api/build" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/compiler" "github.com/go-vela/server/database" + "github.com/go-vela/server/internal" "github.com/go-vela/server/queue" "github.com/go-vela/server/scm" "github.com/go-vela/server/util" - "github.com/go-vela/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" "github.com/sirupsen/logrus" @@ -74,7 +75,7 @@ func PostWebhook(c *gin.Context) { logrus.Info("webhook received") // capture middleware values - m := c.MustGet("metadata").(*types.Metadata) + m := c.MustGet("metadata").(*internal.Metadata) ctx := c.Request.Context() // duplicate request so we can perform operations on the request body @@ -307,8 +308,8 @@ func PostWebhook(c *gin.Context) { queue.FromContext(c), ) - // capture the build, repo, and user from the items - b, repo, u := item.Build, item.Repo, item.User + // capture the build and repo from the items + b, repo = item.Build, item.Repo // set hook build_id to the generated build id h.SetBuildID(b.GetID()) @@ -407,7 +408,7 @@ func PostWebhook(c *gin.Context) { switch repo.GetApproveBuild() { case constants.ApproveForkAlways: - err = gatekeepBuild(c, b, repo, u) + err = gatekeepBuild(c, b, repo) if err != nil { util.HandleError(c, http.StatusInternalServerError, err) } @@ -415,9 +416,9 @@ func PostWebhook(c *gin.Context) { return case constants.ApproveForkNoWrite: // determine if build sender has write access to parent repo. If not, this call will result in an error - _, err = scm.FromContext(c).RepoAccess(ctx, b.GetSender(), u.GetToken(), r.GetOrg(), r.GetName()) + _, err = scm.FromContext(c).RepoAccess(ctx, b.GetSender(), r.GetOwner().GetToken(), r.GetOrg(), r.GetName()) if err != nil { - err = gatekeepBuild(c, b, repo, u) + err = gatekeepBuild(c, b, repo) if err != nil { util.HandleError(c, http.StatusInternalServerError, err) } @@ -431,13 +432,13 @@ func PostWebhook(c *gin.Context) { // // NOTE: this call is cumbersome for repos with lots of contributors. Potential TODO: improve this if // GitHub adds a single-contributor API endpoint. - contributor, err := scm.FromContext(c).RepoContributor(ctx, u, b.GetSender(), r.GetOrg(), r.GetName()) + contributor, err := scm.FromContext(c).RepoContributor(ctx, r.GetOwner(), b.GetSender(), r.GetOrg(), r.GetName()) if err != nil { util.HandleError(c, http.StatusInternalServerError, err) } if !contributor { - err = gatekeepBuild(c, b, repo, u) + err = gatekeepBuild(c, b, repo) if err != nil { util.HandleError(c, http.StatusInternalServerError, err) } @@ -454,7 +455,7 @@ func PostWebhook(c *gin.Context) { } // send API call to set the status on the commit - err = scm.FromContext(c).Status(ctx, u, b, repo.GetOrg(), repo.GetName()) + err = scm.FromContext(c).Status(ctx, repo.GetOwner(), b, repo.GetOrg(), repo.GetName()) if err != nil { logrus.Errorf("unable to set commit status for %s/%d: %v", repo.GetFullName(), b.GetNumber(), err) } @@ -471,7 +472,7 @@ func PostWebhook(c *gin.Context) { // handleRepositoryEvent is a helper function that processes repository events from the SCM and updates // the database resources with any relevant changes resulting from the event, such as name changes, transfers, etc. -func handleRepositoryEvent(ctx context.Context, c *gin.Context, m *types.Metadata, h *library.Hook, r *library.Repo) (*library.Repo, error) { +func handleRepositoryEvent(ctx context.Context, c *gin.Context, m *internal.Metadata, h *library.Hook, r *types.Repo) (*types.Repo, error) { logrus.Debugf("webhook is repository event, making necessary updates to repo %s", r.GetFullName()) defer func() { @@ -563,7 +564,7 @@ func handleRepositoryEvent(ctx context.Context, c *gin.Context, m *types.Metadat // queries the database for the repo that matches that name and org, and updates // that repo to its new name in order to preserve it. It also updates the secrets // associated with that repo as well as build links for the UI. -func RenameRepository(ctx context.Context, h *library.Hook, r *library.Repo, c *gin.Context, m *types.Metadata) (*library.Repo, error) { +func RenameRepository(ctx context.Context, h *library.Hook, r *types.Repo, c *gin.Context, m *internal.Metadata) (*types.Repo, error) { logrus.Infof("renaming repository from %s to %s", r.GetPreviousName(), r.GetName()) // get any matching hook with the repo's unique webhook ID in the SCM @@ -688,7 +689,7 @@ func RenameRepository(ctx context.Context, h *library.Hook, r *library.Repo, c * // gatekeepBuild is a helper function that will set the status of a build to 'pending approval' and // send a status update to the SCM. -func gatekeepBuild(c *gin.Context, b *library.Build, r *library.Repo, u *library.User) error { +func gatekeepBuild(c *gin.Context, b *library.Build, r *types.Repo) error { logrus.Debugf("fork PR build %s/%d waiting for approval", r.GetFullName(), b.GetNumber()) b.SetStatus(constants.StatusPendingApproval) @@ -704,7 +705,7 @@ func gatekeepBuild(c *gin.Context, b *library.Build, r *library.Repo, u *library } // send API call to set the status on the commit - err = scm.FromContext(c).Status(c, u, b, r.GetOrg(), r.GetName()) + err = scm.FromContext(c).Status(c, r.GetOwner(), b, r.GetOrg(), r.GetName()) if err != nil { logrus.Errorf("unable to set commit status for %s/%d: %v", r.GetFullName(), b.GetNumber(), err) } diff --git a/cmd/vela-server/metadata.go b/cmd/vela-server/metadata.go index 88a29b23a..4e24723cb 100644 --- a/cmd/vela-server/metadata.go +++ b/cmd/vela-server/metadata.go @@ -5,7 +5,7 @@ package main import ( "net/url" - "github.com/go-vela/types" + "github.com/go-vela/server/internal" "github.com/sirupsen/logrus" @@ -13,10 +13,10 @@ import ( ) // helper function to setup the metadata from the CLI arguments. -func setupMetadata(c *cli.Context) (*types.Metadata, error) { +func setupMetadata(c *cli.Context) (*internal.Metadata, error) { logrus.Debug("Creating metadata from CLI configuration") - m := new(types.Metadata) + m := new(internal.Metadata) database, err := metadataDatabase(c) if err != nil { @@ -50,7 +50,7 @@ func setupMetadata(c *cli.Context) (*types.Metadata, error) { } // helper function to capture the database metadata from the CLI arguments. -func metadataDatabase(c *cli.Context) (*types.Database, error) { +func metadataDatabase(c *cli.Context) (*internal.Database, error) { logrus.Trace("Creating database metadata from CLI configuration") u, err := url.Parse(c.String("database.addr")) @@ -58,14 +58,14 @@ func metadataDatabase(c *cli.Context) (*types.Database, error) { return nil, err } - return &types.Database{ + return &internal.Database{ Driver: c.String("database.driver"), Host: u.Host, }, nil } // helper function to capture the queue metadata from the CLI arguments. -func metadataQueue(c *cli.Context) (*types.Queue, error) { +func metadataQueue(c *cli.Context) (*internal.Queue, error) { logrus.Trace("Creating queue metadata from CLI configuration") u, err := url.Parse(c.String("queue.addr")) @@ -73,14 +73,14 @@ func metadataQueue(c *cli.Context) (*types.Queue, error) { return nil, err } - return &types.Queue{ + return &internal.Queue{ Driver: c.String("queue.driver"), Host: u.Host, }, nil } // helper function to capture the source metadata from the CLI arguments. -func metadataSource(c *cli.Context) (*types.Source, error) { +func metadataSource(c *cli.Context) (*internal.Source, error) { logrus.Trace("Creating source metadata from CLI configuration") u, err := url.Parse(c.String("scm.addr")) @@ -88,7 +88,7 @@ func metadataSource(c *cli.Context) (*types.Source, error) { return nil, err } - return &types.Source{ + return &internal.Source{ Driver: c.String("scm.driver"), Host: u.Host, }, nil @@ -97,10 +97,10 @@ func metadataSource(c *cli.Context) (*types.Source, error) { // helper function to capture the Vela metadata from the CLI arguments. // //nolint:unparam // ignore unparam for now -func metadataVela(c *cli.Context) (*types.Vela, error) { +func metadataVela(c *cli.Context) (*internal.Vela, error) { logrus.Trace("Creating Vela metadata from CLI configuration") - vela := new(types.Vela) + vela := new(internal.Vela) if len(c.String("server-addr")) > 0 { vela.Address = c.String("server-addr") diff --git a/cmd/vela-server/schedule.go b/cmd/vela-server/schedule.go index 3e4ef799f..89a0abece 100644 --- a/cmd/vela-server/schedule.go +++ b/cmd/vela-server/schedule.go @@ -12,10 +12,10 @@ import ( "github.com/go-vela/server/api/build" "github.com/go-vela/server/compiler" "github.com/go-vela/server/database" + "github.com/go-vela/server/internal" "github.com/go-vela/server/queue" "github.com/go-vela/server/scm" "github.com/go-vela/server/util" - "github.com/go-vela/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" "github.com/sirupsen/logrus" @@ -29,7 +29,7 @@ const ( scheduleWait = "waiting to trigger build for schedule" ) -func processSchedules(ctx context.Context, start time.Time, compiler compiler.Engine, database database.Interface, metadata *types.Metadata, queue queue.Service, scm scm.Service, allowList []string) error { +func processSchedules(ctx context.Context, start time.Time, compiler compiler.Engine, database database.Interface, metadata *internal.Metadata, queue queue.Service, scm scm.Service, allowList []string) error { logrus.Infof("processing active schedules to create builds") // send API call to capture the list of active schedules @@ -134,7 +134,7 @@ func processSchedules(ctx context.Context, start time.Time, compiler compiler.En } // processSchedule will, given a schedule, process it and trigger a new build. -func processSchedule(ctx context.Context, s *library.Schedule, compiler compiler.Engine, database database.Interface, metadata *types.Metadata, queue queue.Service, scm scm.Service, allowList []string) error { +func processSchedule(ctx context.Context, s *library.Schedule, compiler compiler.Engine, database database.Interface, metadata *internal.Metadata, queue queue.Service, scm scm.Service, allowList []string) error { // send API call to capture the repo for the schedule r, err := database.GetRepo(ctx, s.GetRepoID()) if err != nil { diff --git a/compiler/engine.go b/compiler/engine.go index 566696b91..6ed310451 100644 --- a/compiler/engine.go +++ b/compiler/engine.go @@ -3,7 +3,8 @@ package compiler import ( - "github.com/go-vela/types" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/internal" "github.com/go-vela/types/library" "github.com/go-vela/types/pipeline" "github.com/go-vela/types/raw" @@ -133,10 +134,10 @@ type Engine interface { WithLocalTemplates([]string) Engine // WithMetadata defines a function that sets // the compiler Metadata type in the Engine. - WithMetadata(*types.Metadata) Engine + WithMetadata(*internal.Metadata) Engine // WithRepo defines a function that sets // the library repo type in the Engine. - WithRepo(*library.Repo) Engine + WithRepo(*api.Repo) Engine // WithUser defines a function that sets // the library user type in the Engine. WithUser(*library.User) Engine diff --git a/compiler/native/compile.go b/compiler/native/compile.go index 1c02e4d7a..cbea8185e 100644 --- a/compiler/native/compile.go +++ b/compiler/native/compile.go @@ -15,6 +15,7 @@ import ( "github.com/go-vela/types/constants" yml "github.com/buildkite/yaml" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/library" "github.com/go-vela/types/pipeline" @@ -502,7 +503,7 @@ func errorHandler(resp *http.Response, err error, attempts int) (*http.Response, } // modifyConfig sends the configuration to external http endpoint for modification. -func (c *client) modifyConfig(build *yaml.Build, libraryBuild *library.Build, repo *library.Repo) (*yaml.Build, error) { +func (c *client) modifyConfig(build *yaml.Build, libraryBuild *library.Build, repo *api.Repo) (*yaml.Build, error) { // create request to send to endpoint data, err := yml.Marshal(build) if err != nil { diff --git a/compiler/native/compile_test.go b/compiler/native/compile_test.go index 4fb45b2dd..4d77cd148 100644 --- a/compiler/native/compile_test.go +++ b/compiler/native/compile_test.go @@ -10,6 +10,8 @@ import ( "os" "path/filepath" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/internal" "github.com/go-vela/types/constants" "github.com/go-vela/types/raw" @@ -23,7 +25,6 @@ import ( "github.com/go-vela/types/library" "github.com/go-vela/types/yaml" - "github.com/go-vela/types" "github.com/go-vela/types/pipeline" "github.com/gin-gonic/gin" @@ -39,21 +40,21 @@ func TestNative_Compile_StagesPipeline(t *testing.T) { set.Int("max-template-depth", 5, "doc") c := cli.NewContext(nil, set, nil) - m := &types.Metadata{ - Database: &types.Database{ + m := &internal.Metadata{ + Database: &internal.Database{ Driver: "foo", Host: "foo", }, - Queue: &types.Queue{ + Queue: &internal.Queue{ Channel: "foo", Driver: "foo", Host: "foo", }, - Source: &types.Source{ + Source: &internal.Source{ Driver: "foo", Host: "foo", }, - Vela: &types.Vela{ + Vela: &internal.Vela{ Address: "foo", WebAddress: "foo", }, @@ -308,7 +309,7 @@ func TestNative_Compile_StagesPipeline_Modification(t *testing.T) { type args struct { endpoint string libraryBuild *library.Build - repo *library.Repo + repo *api.Repo } tests := []struct { @@ -318,12 +319,12 @@ func TestNative_Compile_StagesPipeline_Modification(t *testing.T) { }{ {"bad url", args{ libraryBuild: &library.Build{Number: &number, Author: &author}, - repo: &library.Repo{Name: &name}, + repo: &api.Repo{Name: &name}, endpoint: "bad", }, true}, {"invalid return", args{ libraryBuild: &library.Build{Number: &number, Author: &author}, - repo: &library.Repo{Name: &name}, + repo: &api.Repo{Name: &name}, endpoint: fmt.Sprintf("%s/%s", s.URL, "config/bad"), }, true}, } @@ -335,7 +336,7 @@ func TestNative_Compile_StagesPipeline_Modification(t *testing.T) { Timeout: 1 * time.Second, Endpoint: tt.args.endpoint, }, - repo: &library.Repo{Name: &author}, + repo: &api.Repo{Name: &author}, build: &library.Build{Author: &name, Number: &number}, } _, _, err := compiler.Compile(yaml) @@ -376,7 +377,7 @@ func TestNative_Compile_StepsPipeline_Modification(t *testing.T) { type args struct { endpoint string libraryBuild *library.Build - repo *library.Repo + repo *api.Repo } tests := []struct { @@ -386,12 +387,12 @@ func TestNative_Compile_StepsPipeline_Modification(t *testing.T) { }{ {"bad url", args{ libraryBuild: &library.Build{Number: &number, Author: &author}, - repo: &library.Repo{Name: &name}, + repo: &api.Repo{Name: &name}, endpoint: "bad", }, true}, {"invalid return", args{ libraryBuild: &library.Build{Number: &number, Author: &author}, - repo: &library.Repo{Name: &name}, + repo: &api.Repo{Name: &name}, endpoint: fmt.Sprintf("%s/%s", s.URL, "config/bad"), }, true}, } @@ -422,21 +423,21 @@ func TestNative_Compile_StepsPipeline(t *testing.T) { set.Int("max-template-depth", 5, "doc") c := cli.NewContext(nil, set, nil) - m := &types.Metadata{ - Database: &types.Database{ + m := &internal.Metadata{ + Database: &internal.Database{ Driver: "foo", Host: "foo", }, - Queue: &types.Queue{ + Queue: &internal.Queue{ Channel: "foo", Driver: "foo", Host: "foo", }, - Source: &types.Source{ + Source: &internal.Source{ Driver: "foo", Host: "foo", }, - Vela: &types.Vela{ + Vela: &internal.Vela{ Address: "foo", WebAddress: "foo", }, @@ -633,21 +634,21 @@ func TestNative_Compile_StagesPipelineTemplate(t *testing.T) { set.Int("max-template-depth", 5, "doc") c := cli.NewContext(nil, set, nil) - m := &types.Metadata{ - Database: &types.Database{ + m := &internal.Metadata{ + Database: &internal.Database{ Driver: "foo", Host: "foo", }, - Queue: &types.Queue{ + Queue: &internal.Queue{ Channel: "foo", Driver: "foo", Host: "foo", }, - Source: &types.Source{ + Source: &internal.Source{ Driver: "foo", Host: "foo", }, - Vela: &types.Vela{ + Vela: &internal.Vela{ Address: "foo", WebAddress: "foo", }, @@ -904,21 +905,21 @@ func TestNative_Compile_StepsPipelineTemplate(t *testing.T) { set.Int("max-template-depth", 5, "doc") c := cli.NewContext(nil, set, nil) - m := &types.Metadata{ - Database: &types.Database{ + m := &internal.Metadata{ + Database: &internal.Database{ Driver: "foo", Host: "foo", }, - Queue: &types.Queue{ + Queue: &internal.Queue{ Channel: "foo", Driver: "foo", Host: "foo", }, - Source: &types.Source{ + Source: &internal.Source{ Driver: "foo", Host: "foo", }, - Vela: &types.Vela{ + Vela: &internal.Vela{ Address: "foo", WebAddress: "foo", }, @@ -1138,21 +1139,21 @@ func TestNative_Compile_StepsPipelineTemplate_VelaFunction_TemplateName(t *testi set.Int("max-template-depth", 5, "doc") c := cli.NewContext(nil, set, nil) - m := &types.Metadata{ - Database: &types.Database{ + m := &internal.Metadata{ + Database: &internal.Database{ Driver: "foo", Host: "foo", }, - Queue: &types.Queue{ + Queue: &internal.Queue{ Channel: "foo", Driver: "foo", Host: "foo", }, - Source: &types.Source{ + Source: &internal.Source{ Driver: "foo", Host: "foo", }, - Vela: &types.Vela{ + Vela: &internal.Vela{ Address: "foo", WebAddress: "foo", }, @@ -1259,21 +1260,21 @@ func TestNative_Compile_StepsPipelineTemplate_VelaFunction_TemplateName_Inline(t set.Int("max-template-depth", 5, "doc") c := cli.NewContext(nil, set, nil) - m := &types.Metadata{ - Database: &types.Database{ + m := &internal.Metadata{ + Database: &internal.Database{ Driver: "foo", Host: "foo", }, - Queue: &types.Queue{ + Queue: &internal.Queue{ Channel: "foo", Driver: "foo", Host: "foo", }, - Source: &types.Source{ + Source: &internal.Source{ Driver: "foo", Host: "foo", }, - Vela: &types.Vela{ + Vela: &internal.Vela{ Address: "foo", WebAddress: "foo", }, @@ -1378,21 +1379,21 @@ func TestNative_Compile_InvalidType(t *testing.T) { set.Int("max-template-depth", 5, "doc") c := cli.NewContext(nil, set, nil) - m := &types.Metadata{ - Database: &types.Database{ + m := &internal.Metadata{ + Database: &internal.Database{ Driver: "foo", Host: "foo", }, - Queue: &types.Queue{ + Queue: &internal.Queue{ Channel: "foo", Driver: "foo", Host: "foo", }, - Source: &types.Source{ + Source: &internal.Source{ Driver: "foo", Host: "foo", }, - Vela: &types.Vela{ + Vela: &internal.Vela{ Address: "foo", WebAddress: "foo", }, @@ -1435,21 +1436,21 @@ func TestNative_Compile_Clone(t *testing.T) { set.Int("max-template-depth", 5, "doc") c := cli.NewContext(nil, set, nil) - m := &types.Metadata{ - Database: &types.Database{ + m := &internal.Metadata{ + Database: &internal.Database{ Driver: "foo", Host: "foo", }, - Queue: &types.Queue{ + Queue: &internal.Queue{ Channel: "foo", Driver: "foo", Host: "foo", }, - Source: &types.Source{ + Source: &internal.Source{ Driver: "foo", Host: "foo", }, - Vela: &types.Vela{ + Vela: &internal.Vela{ Address: "foo", WebAddress: "foo", }, @@ -1629,21 +1630,21 @@ func TestNative_Compile_Pipeline_Type(t *testing.T) { set.Int("max-template-depth", 5, "doc") c := cli.NewContext(nil, set, nil) - m := &types.Metadata{ - Database: &types.Database{ + m := &internal.Metadata{ + Database: &internal.Database{ Driver: "foo", Host: "foo", }, - Queue: &types.Queue{ + Queue: &internal.Queue{ Channel: "foo", Driver: "foo", Host: "foo", }, - Source: &types.Source{ + Source: &internal.Source{ Driver: "foo", Host: "foo", }, - Vela: &types.Vela{ + Vela: &internal.Vela{ Address: "foo", WebAddress: "foo", }, @@ -1695,10 +1696,10 @@ func TestNative_Compile_Pipeline_Type(t *testing.T) { goPipelineType := "go" - goFooEnv := environment(nil, m, &library.Repo{PipelineType: &goPipelineType}, nil) + goFooEnv := environment(nil, m, &api.Repo{PipelineType: &goPipelineType}, nil) goFooEnv["PARAMETER_REGISTRY"] = "foo" - defaultGoEnv := environment(nil, m, &library.Repo{PipelineType: &goPipelineType}, nil) + defaultGoEnv := environment(nil, m, &api.Repo{PipelineType: &goPipelineType}, nil) wantGo := &pipeline.Build{ Version: "1", ID: "__0", @@ -1741,10 +1742,10 @@ func TestNative_Compile_Pipeline_Type(t *testing.T) { starPipelineType := "starlark" - starlarkFooEnv := environment(nil, m, &library.Repo{PipelineType: &starPipelineType}, nil) + starlarkFooEnv := environment(nil, m, &api.Repo{PipelineType: &starPipelineType}, nil) starlarkFooEnv["PARAMETER_REGISTRY"] = "foo" - defaultStarlarkEnv := environment(nil, m, &library.Repo{PipelineType: &starPipelineType}, nil) + defaultStarlarkEnv := environment(nil, m, &api.Repo{PipelineType: &starPipelineType}, nil) wantStarlark := &pipeline.Build{ Version: "1", ID: "__0", @@ -1815,7 +1816,9 @@ func TestNative_Compile_Pipeline_Type(t *testing.T) { } compiler.WithMetadata(m) - compiler.WithRepo(&library.Repo{PipelineType: &tt.args.pipelineType}) + + pipelineType := tt.args.pipelineType + compiler.WithRepo(&api.Repo{PipelineType: &pipelineType}) got, _, err := compiler.Compile(yaml) if err != nil { @@ -1848,7 +1851,7 @@ func TestNative_Compile_NoStepsorStages(t *testing.T) { t.Errorf("Creating compiler returned err: %v", err) } - compiler.repo = &library.Repo{Name: &author} + compiler.repo = &api.Repo{Name: &author} compiler.build = &library.Build{Author: &name, Number: &number} got, _, err := compiler.Compile(yaml) @@ -1880,7 +1883,7 @@ func TestNative_Compile_StepsandStages(t *testing.T) { t.Errorf("Creating compiler returned err: %v", err) } - compiler.repo = &library.Repo{Name: &author} + compiler.repo = &api.Repo{Name: &author} compiler.build = &library.Build{Author: &name, Number: &number} got, _, err := compiler.Compile(yaml) @@ -1923,21 +1926,21 @@ func Test_client_modifyConfig(t *testing.T) { c.JSON(http.StatusOK, body) }) - m := &types.Metadata{ - Database: &types.Database{ + m := &internal.Metadata{ + Database: &internal.Database{ Driver: "foo", Host: "foo", }, - Queue: &types.Queue{ + Queue: &internal.Queue{ Channel: "foo", Driver: "foo", Host: "foo", }, - Source: &types.Source{ + Source: &internal.Source{ Driver: "foo", Host: "foo", }, - Vela: &types.Vela{ + Vela: &internal.Vela{ Address: "foo", WebAddress: "foo", }, @@ -2083,7 +2086,7 @@ func Test_client_modifyConfig(t *testing.T) { endpoint string build *yaml.Build libraryBuild *library.Build - repo *library.Repo + repo *api.Repo } tests := []struct { @@ -2095,37 +2098,37 @@ func Test_client_modifyConfig(t *testing.T) { {"unmodified", args{ build: want, libraryBuild: &library.Build{Number: &number, Author: &author}, - repo: &library.Repo{Name: &name}, + repo: &api.Repo{Name: &name}, endpoint: fmt.Sprintf("%s/%s", s.URL, "config/unmodified"), }, want, false}, {"modified", args{ build: want, libraryBuild: &library.Build{Number: &number, Author: &author}, - repo: &library.Repo{Name: &name}, + repo: &api.Repo{Name: &name}, endpoint: fmt.Sprintf("%s/%s", s.URL, "config/modified"), }, want2, false}, {"invalid endpoint", args{ build: want, libraryBuild: &library.Build{Number: &number, Author: &author}, - repo: &library.Repo{Name: &name}, + repo: &api.Repo{Name: &name}, endpoint: "bad", }, nil, true}, {"unauthorized endpoint", args{ build: want, libraryBuild: &library.Build{Number: &number, Author: &author}, - repo: &library.Repo{Name: &name}, + repo: &api.Repo{Name: &name}, endpoint: fmt.Sprintf("%s/%s", s.URL, "config/unauthorized"), }, nil, true}, {"timeout endpoint", args{ build: want, libraryBuild: &library.Build{Number: &number, Author: &author}, - repo: &library.Repo{Name: &name}, + repo: &api.Repo{Name: &name}, endpoint: fmt.Sprintf("%s/%s", s.URL, "config/timeout"), }, nil, true}, {"empty payload", args{ build: want, libraryBuild: &library.Build{Number: &number, Author: &author}, - repo: &library.Repo{Name: &name}, + repo: &api.Repo{Name: &name}, endpoint: fmt.Sprintf("%s/%s", s.URL, "config/empty"), }, nil, true}, } @@ -2166,7 +2169,7 @@ func convertFileToGithubResponse(file string) (github.RepositoryContent, error) return content, nil } -func generateTestEnv(command string, m *types.Metadata, pipelineType string) map[string]string { +func generateTestEnv(command string, m *internal.Metadata, pipelineType string) map[string]string { output := environment(nil, m, nil, nil) output["VELA_BUILD_SCRIPT"] = generateScriptPosix([]string{command}) output["HOME"] = "/root" @@ -2204,21 +2207,21 @@ func Test_Compile_Inline(t *testing.T) { set.Int("max-template-depth", 5, "doc") c := cli.NewContext(nil, set, nil) - m := &types.Metadata{ - Database: &types.Database{ + m := &internal.Metadata{ + Database: &internal.Database{ Driver: "foo", Host: "foo", }, - Queue: &types.Queue{ + Queue: &internal.Queue{ Channel: "foo", Driver: "foo", Host: "foo", }, - Source: &types.Source{ + Source: &internal.Source{ Driver: "foo", Host: "foo", }, - Vela: &types.Vela{ + Vela: &internal.Vela{ Address: "foo", WebAddress: "foo", }, @@ -2964,7 +2967,8 @@ func Test_Compile_Inline(t *testing.T) { compiler.WithMetadata(m) if tt.args.pipelineType != "" { - compiler.WithRepo(&library.Repo{PipelineType: &tt.args.pipelineType}) + pipelineType := tt.args.pipelineType + compiler.WithRepo(&api.Repo{PipelineType: &pipelineType}) } got, _, err := compiler.Compile(yaml) @@ -3021,21 +3025,21 @@ func Test_CompileLite(t *testing.T) { set.Int("max-template-depth", 5, "doc") c := cli.NewContext(nil, set, nil) - m := &types.Metadata{ - Database: &types.Database{ + m := &internal.Metadata{ + Database: &internal.Database{ Driver: "foo", Host: "foo", }, - Queue: &types.Queue{ + Queue: &internal.Queue{ Channel: "foo", Driver: "foo", Host: "foo", }, - Source: &types.Source{ + Source: &internal.Source{ Driver: "foo", Host: "foo", }, - Vela: &types.Vela{ + Vela: &internal.Vela{ Address: "foo", WebAddress: "foo", }, @@ -3833,7 +3837,8 @@ func Test_CompileLite(t *testing.T) { compiler.WithMetadata(m) if tt.args.pipelineType != "" { - compiler.WithRepo(&library.Repo{PipelineType: &tt.args.pipelineType}) + pipelineType := tt.args.pipelineType + compiler.WithRepo(&api.Repo{PipelineType: &pipelineType}) } yaml, err := os.ReadFile(tt.args.file) diff --git a/compiler/native/environment.go b/compiler/native/environment.go index 5841825b3..b6d9571b0 100644 --- a/compiler/native/environment.go +++ b/compiler/native/environment.go @@ -7,7 +7,8 @@ import ( "os" "strings" - "github.com/go-vela/types" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/internal" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" "github.com/go-vela/types/raw" @@ -281,7 +282,7 @@ func appendMap(originalMap, otherMap map[string]string) map[string]string { } // helper function that creates the standard set of environment variables for a pipeline. -func environment(b *library.Build, m *types.Metadata, r *library.Repo, u *library.User) map[string]string { +func environment(b *library.Build, m *internal.Metadata, r *api.Repo, u *library.User) map[string]string { // set default workspace workspace := constants.WorkspaceDefault notImplemented := "TODO" diff --git a/compiler/native/environment_test.go b/compiler/native/environment_test.go index 01755972e..cfacbd880 100644 --- a/compiler/native/environment_test.go +++ b/compiler/native/environment_test.go @@ -8,10 +8,11 @@ import ( "strings" "testing" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/internal" "github.com/go-vela/types/raw" "github.com/google/go-cmp/cmp" - "github.com/go-vela/types" "github.com/go-vela/types/library" "github.com/go-vela/types/yaml" @@ -186,6 +187,7 @@ func TestNative_EnvironmentSteps(t *testing.T) { "VELA_REPO_LINK": "", "VELA_REPO_NAME": "", "VELA_REPO_ORG": "", + "VELA_REPO_OWNER": "", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "0", @@ -360,6 +362,7 @@ func TestNative_EnvironmentServices(t *testing.T) { "VELA_REPO_LINK": "", "VELA_REPO_NAME": "", "VELA_REPO_ORG": "", + "VELA_REPO_OWNER": "", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "0", @@ -516,6 +519,7 @@ func TestNative_EnvironmentSecrets(t *testing.T) { "VELA_REPO_LINK": "", "VELA_REPO_NAME": "", "VELA_REPO_ORG": "", + "VELA_REPO_OWNER": "", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "0", @@ -575,8 +579,8 @@ func TestNative_environment(t *testing.T) { tests := []struct { w string b *library.Build - m *types.Metadata - r *library.Repo + m *internal.Metadata + r *api.Repo u *library.User want map[string]string }{ @@ -584,37 +588,37 @@ func TestNative_environment(t *testing.T) { { w: workspace, b: &library.Build{ID: &num64, RepoID: &num64, Number: &num, Parent: &num, Event: &push, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &str, BaseRef: &str}, - m: &types.Metadata{Database: &types.Database{Driver: str, Host: str}, Queue: &types.Queue{Channel: str, Driver: str, Host: str}, Source: &types.Source{Driver: str, Host: str}, Vela: &types.Vela{Address: str, WebAddress: str}}, - r: &library.Repo{ID: &num64, UserID: &num64, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, + m: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, + r: &api.Repo{ID: &num64, Owner: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, u: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, - want: map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "push", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "foo", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "push", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "foo", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, + want: map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "push", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "foo", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "push", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "foo", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_OWNER": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, }, // tag { w: workspace, b: &library.Build{ID: &num64, RepoID: &num64, Number: &num, Parent: &num, Event: &tag, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &tagref, BaseRef: &str}, - m: &types.Metadata{Database: &types.Database{Driver: str, Host: str}, Queue: &types.Queue{Channel: str, Driver: str, Host: str}, Source: &types.Source{Driver: str, Host: str}, Vela: &types.Vela{Address: str, WebAddress: str}}, - r: &library.Repo{ID: &num64, UserID: &num64, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, + m: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, + r: &api.Repo{ID: &num64, Owner: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, u: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, - want: map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "tag", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "refs/tags/1", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TAG": "1", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "tag", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "refs/tags/1", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TAG": "1", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, + want: map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "tag", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "refs/tags/1", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TAG": "1", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "tag", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "refs/tags/1", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TAG": "1", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_OWNER": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, }, // pull_request { w: workspace, b: &library.Build{ID: &num64, RepoID: &num64, Number: &num, Parent: &num, Event: &pull, EventAction: &pullact, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &pullref, BaseRef: &str}, - m: &types.Metadata{Database: &types.Database{Driver: str, Host: str}, Queue: &types.Queue{Channel: str, Driver: str, Host: str}, Source: &types.Source{Driver: str, Host: str}, Vela: &types.Vela{Address: str, WebAddress: str}}, - r: &library.Repo{ID: &num64, UserID: &num64, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, + m: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, + r: &api.Repo{ID: &num64, Owner: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, u: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, - want: map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "pull_request", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_PULL_REQUEST_NUMBER": "1", "BUILD_REF": "refs/pull/1/head", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "pull_request", "VELA_BUILD_EVENT_ACTION": "opened", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_PULL_REQUEST": "1", "VELA_BUILD_REF": "refs/pull/1/head", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_PULL_REQUEST": "1", "VELA_PULL_REQUEST_SOURCE": "", "VELA_PULL_REQUEST_TARGET": "foo", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, + want: map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "pull_request", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_PULL_REQUEST_NUMBER": "1", "BUILD_REF": "refs/pull/1/head", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "pull_request", "VELA_BUILD_EVENT_ACTION": "opened", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_PULL_REQUEST": "1", "VELA_BUILD_REF": "refs/pull/1/head", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_PULL_REQUEST": "1", "VELA_PULL_REQUEST_SOURCE": "", "VELA_PULL_REQUEST_TARGET": "foo", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_OWNER": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, }, // deployment { w: workspace, b: &library.Build{ID: &num64, RepoID: &num64, Number: &num, Parent: &num, Event: &deploy, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &target, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &pullref, BaseRef: &str}, - m: &types.Metadata{Database: &types.Database{Driver: str, Host: str}, Queue: &types.Queue{Channel: str, Driver: str, Host: str}, Source: &types.Source{Driver: str, Host: str}, Vela: &types.Vela{Address: str, WebAddress: str}}, - r: &library.Repo{ID: &num64, UserID: &num64, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, + m: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, + r: &api.Repo{ID: &num64, Owner: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, u: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, - want: map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "deployment", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "refs/pull/1/head", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TARGET": "production", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "deployment", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "refs/pull/1/head", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TARGET": "production", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DEPLOYMENT": "production", "VELA_DEPLOYMENT_NUMBER": "0", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, + want: map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "deployment", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "refs/pull/1/head", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TARGET": "production", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "deployment", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "refs/pull/1/head", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TARGET": "production", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DEPLOYMENT": "production", "VELA_DEPLOYMENT_NUMBER": "0", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_OWNER": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, }, } @@ -688,8 +692,8 @@ func Test_client_EnvironmentBuild(t *testing.T) { type fields struct { build *library.Build - metadata *types.Metadata - repo *library.Repo + metadata *internal.Metadata + repo *api.Repo user *library.User } @@ -700,30 +704,30 @@ func Test_client_EnvironmentBuild(t *testing.T) { }{ {"push", fields{ build: &library.Build{ID: &num64, RepoID: &num64, Number: &num, Parent: &num, Event: &push, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &str, BaseRef: &str}, - metadata: &types.Metadata{Database: &types.Database{Driver: str, Host: str}, Queue: &types.Queue{Channel: str, Driver: str, Host: str}, Source: &types.Source{Driver: str, Host: str}, Vela: &types.Vela{Address: str, WebAddress: str}}, - repo: &library.Repo{ID: &num64, UserID: &num64, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, + metadata: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, + repo: &api.Repo{ID: &num64, Owner: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, user: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, - }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "push", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "foo", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "push", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "foo", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}}, + }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "push", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "foo", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "push", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "foo", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_OWNER": "foo", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}}, {"tag", fields{ build: &library.Build{ID: &num64, RepoID: &num64, Number: &num, Parent: &num, Event: &tag, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &tagref, BaseRef: &str}, - metadata: &types.Metadata{Database: &types.Database{Driver: str, Host: str}, Queue: &types.Queue{Channel: str, Driver: str, Host: str}, Source: &types.Source{Driver: str, Host: str}, Vela: &types.Vela{Address: str, WebAddress: str}}, - repo: &library.Repo{ID: &num64, UserID: &num64, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, + metadata: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, + repo: &api.Repo{ID: &num64, Owner: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, user: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, - }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "tag", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "refs/tags/1", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TAG": "1", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "tag", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "refs/tags/1", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TAG": "1", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, + }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "tag", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "refs/tags/1", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TAG": "1", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "tag", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "refs/tags/1", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TAG": "1", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_OWNER": "foo", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, }, {"pull_request", fields{ build: &library.Build{ID: &num64, RepoID: &num64, Number: &num, Parent: &num, Event: &pull, EventAction: &pullact, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &pullref, BaseRef: &str}, - metadata: &types.Metadata{Database: &types.Database{Driver: str, Host: str}, Queue: &types.Queue{Channel: str, Driver: str, Host: str}, Source: &types.Source{Driver: str, Host: str}, Vela: &types.Vela{Address: str, WebAddress: str}}, - repo: &library.Repo{ID: &num64, UserID: &num64, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, + metadata: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, + repo: &api.Repo{ID: &num64, Owner: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, user: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, - }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "pull_request", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_PULL_REQUEST_NUMBER": "1", "BUILD_REF": "refs/pull/1/head", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "pull_request", "VELA_BUILD_EVENT_ACTION": "opened", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_PULL_REQUEST": "1", "VELA_BUILD_REF": "refs/pull/1/head", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_PULL_REQUEST": "1", "VELA_PULL_REQUEST_SOURCE": "", "VELA_PULL_REQUEST_TARGET": "foo", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, + }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "pull_request", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_PULL_REQUEST_NUMBER": "1", "BUILD_REF": "refs/pull/1/head", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "pull_request", "VELA_BUILD_EVENT_ACTION": "opened", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_PULL_REQUEST": "1", "VELA_BUILD_REF": "refs/pull/1/head", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_PULL_REQUEST": "1", "VELA_PULL_REQUEST_SOURCE": "", "VELA_PULL_REQUEST_TARGET": "foo", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_OWNER": "foo", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, }, {"deployment", fields{ build: &library.Build{ID: &num64, RepoID: &num64, Number: &num, Parent: &num, Event: &deploy, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &target, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &pullref, BaseRef: &str}, - metadata: &types.Metadata{Database: &types.Database{Driver: str, Host: str}, Queue: &types.Queue{Channel: str, Driver: str, Host: str}, Source: &types.Source{Driver: str, Host: str}, Vela: &types.Vela{Address: str, WebAddress: str}}, - repo: &library.Repo{ID: &num64, UserID: &num64, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, + metadata: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, + repo: &api.Repo{ID: &num64, Owner: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, user: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, - }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "deployment", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "refs/pull/1/head", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TARGET": "production", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "deployment", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "refs/pull/1/head", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TARGET": "production", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DEPLOYMENT": "production", "VELA_DEPLOYMENT_NUMBER": "0", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, + }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "deployment", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "refs/pull/1/head", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TARGET": "production", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "deployment", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "refs/pull/1/head", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TARGET": "production", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DEPLOYMENT": "production", "VELA_DEPLOYMENT_NUMBER": "0", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_OWNER": "foo", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, }, } for _, tt := range tests { diff --git a/compiler/native/expand_test.go b/compiler/native/expand_test.go index 6d9479a53..8400bd6a4 100644 --- a/compiler/native/expand_test.go +++ b/compiler/native/expand_test.go @@ -9,6 +9,7 @@ import ( "reflect" "testing" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/library" "github.com/go-vela/types/pipeline" "github.com/go-vela/types/raw" @@ -228,7 +229,7 @@ func TestNative_ExpandSteps(t *testing.T) { set.Int("max-template-depth", 5, "doc") c := cli.NewContext(nil, set, nil) - testRepo := new(library.Repo) + testRepo := new(api.Repo) testRepo.SetID(1) testRepo.SetOrg("foo") @@ -767,7 +768,7 @@ func TestNative_ExpandSteps_TemplateCallTemplate(t *testing.T) { testBuild.SetID(1) testBuild.SetCommit("123abc456def") - testRepo := new(library.Repo) + testRepo := new(api.Repo) testRepo.SetID(1) testRepo.SetOrg("foo") @@ -935,7 +936,7 @@ func TestNative_ExpandSteps_TemplateCallTemplate_CircularFail(t *testing.T) { testBuild.SetID(1) testBuild.SetCommit("123abc456def") - testRepo := new(library.Repo) + testRepo := new(api.Repo) testRepo.SetID(1) testRepo.SetOrg("foo") @@ -1021,7 +1022,7 @@ func TestNative_ExpandSteps_CallTemplateWithRenderInline(t *testing.T) { testBuild.SetID(1) testBuild.SetCommit("123abc456def") - testRepo := new(library.Repo) + testRepo := new(api.Repo) testRepo.SetID(1) testRepo.SetOrg("foo") diff --git a/compiler/native/native.go b/compiler/native/native.go index 048f22307..04db6b72c 100644 --- a/compiler/native/native.go +++ b/compiler/native/native.go @@ -5,12 +5,13 @@ package native import ( "time" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/compiler" + "github.com/go-vela/server/internal" "github.com/go-vela/server/compiler/registry" "github.com/go-vela/server/compiler/registry/github" - "github.com/go-vela/types" "github.com/go-vela/types/library" "github.com/sirupsen/logrus" @@ -39,8 +40,8 @@ type client struct { files []string local bool localTemplates []string - metadata *types.Metadata - repo *library.Repo + metadata *internal.Metadata + repo *api.Repo user *library.User labels []string } @@ -175,7 +176,7 @@ func (c *client) WithLocalTemplates(templates []string) compiler.Engine { } // WithMetadata sets the compiler metadata type in the Engine. -func (c *client) WithMetadata(m *types.Metadata) compiler.Engine { +func (c *client) WithMetadata(m *internal.Metadata) compiler.Engine { if m != nil { c.metadata = m } @@ -195,7 +196,7 @@ func (c *client) WithPrivateGitHub(url, token string) compiler.Engine { } // WithRepo sets the library repo type in the Engine. -func (c *client) WithRepo(r *library.Repo) compiler.Engine { +func (c *client) WithRepo(r *api.Repo) compiler.Engine { if r != nil { c.repo = r } diff --git a/compiler/native/native_test.go b/compiler/native/native_test.go index 489288ee7..db0859c02 100644 --- a/compiler/native/native_test.go +++ b/compiler/native/native_test.go @@ -7,9 +7,10 @@ import ( "reflect" "testing" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/compiler/registry/github" + "github.com/go-vela/server/internal" - "github.com/go-vela/types" "github.com/go-vela/types/library" "github.com/urfave/cli/v2" @@ -225,21 +226,21 @@ func TestNative_WithMetadata(t *testing.T) { set := flag.NewFlagSet("test", 0) c := cli.NewContext(nil, set, nil) - m := &types.Metadata{ - Database: &types.Database{ + m := &internal.Metadata{ + Database: &internal.Database{ Driver: "foo", Host: "foo", }, - Queue: &types.Queue{ + Queue: &internal.Queue{ Channel: "foo", Driver: "foo", Host: "foo", }, - Source: &types.Source{ + Source: &internal.Source{ Driver: "foo", Host: "foo", }, - Vela: &types.Vela{ + Vela: &internal.Vela{ Address: "foo", WebAddress: "foo", }, @@ -291,7 +292,7 @@ func TestNative_WithRepo(t *testing.T) { c := cli.NewContext(nil, set, nil) id := int64(1) - r := &library.Repo{ID: &id} + r := &api.Repo{ID: &id} want, _ := New(c) want.repo = r diff --git a/compiler/native/parse_test.go b/compiler/native/parse_test.go index 7176438e1..a24d3bf34 100644 --- a/compiler/native/parse_test.go +++ b/compiler/native/parse_test.go @@ -10,8 +10,8 @@ import ( "reflect" "testing" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" "github.com/go-vela/types/raw" "github.com/go-vela/types/yaml" @@ -858,7 +858,7 @@ func TestNative_ParseString_Metadata(t *testing.T) { type FailReader struct{} -func (FailReader) Read(p []byte) (n int, err error) { +func (FailReader) Read(_ []byte) (n int, err error) { return 0, errors.New("this is a reader that fails when you try to read") } @@ -910,11 +910,13 @@ func Test_client_Parse(t *testing.T) { } var c *client - if tt.args.pipelineType == "nil" { + + pipelineType := tt.args.pipelineType + if pipelineType == "nil" { c = &client{} } else { c = &client{ - repo: &library.Repo{PipelineType: &tt.args.pipelineType}, + repo: &api.Repo{PipelineType: &pipelineType}, } } diff --git a/compiler/native/transform_test.go b/compiler/native/transform_test.go index 743f9a46c..82ec72d3d 100644 --- a/compiler/native/transform_test.go +++ b/compiler/native/transform_test.go @@ -7,7 +7,7 @@ import ( "reflect" "testing" - "github.com/go-vela/types" + "github.com/go-vela/server/internal" "github.com/go-vela/types/pipeline" "github.com/go-vela/types/yaml" @@ -19,21 +19,21 @@ func TestNative_TransformStages(t *testing.T) { set := flag.NewFlagSet("test", 0) c := cli.NewContext(nil, set, nil) - m := &types.Metadata{ - Database: &types.Database{ + m := &internal.Metadata{ + Database: &internal.Database{ Driver: "foo", Host: "foo", }, - Queue: &types.Queue{ + Queue: &internal.Queue{ Channel: "foo", Driver: "foo", Host: "foo", }, - Source: &types.Source{ + Source: &internal.Source{ Driver: "foo", Host: "foo", }, - Vela: &types.Vela{ + Vela: &internal.Vela{ Address: "foo", WebAddress: "foo", }, @@ -259,21 +259,21 @@ func TestNative_TransformSteps(t *testing.T) { set := flag.NewFlagSet("test", 0) c := cli.NewContext(nil, set, nil) - m := &types.Metadata{ - Database: &types.Database{ + m := &internal.Metadata{ + Database: &internal.Database{ Driver: "foo", Host: "foo", }, - Queue: &types.Queue{ + Queue: &internal.Queue{ Channel: "foo", Driver: "foo", Host: "foo", }, - Source: &types.Source{ + Source: &internal.Source{ Driver: "foo", Host: "foo", }, - Vela: &types.Vela{ + Vela: &internal.Vela{ Address: "foo", WebAddress: "foo", }, diff --git a/database/build/build_test.go b/database/build/build_test.go index 16910e5ac..419e9443c 100644 --- a/database/build/build_test.go +++ b/database/build/build_test.go @@ -10,6 +10,7 @@ import ( "time" "github.com/DATA-DOG/go-sqlmock" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/library" "github.com/go-vela/types/raw" "github.com/sirupsen/logrus" @@ -241,10 +242,9 @@ func testDeployment() *library.Deployment { // testRepo is a test helper function to create a library // Repo type with all fields set to their zero values. -func testRepo() *library.Repo { - return &library.Repo{ +func testRepo() *api.Repo { + return &api.Repo{ ID: new(int64), - UserID: new(int64), BuildLimit: new(int64), Timeout: new(int64), Counter: new(int), diff --git a/database/build/count_org_test.go b/database/build/count_org_test.go index 6b6283dbb..968b1d7c2 100644 --- a/database/build/count_org_test.go +++ b/database/build/count_org_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/repo" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" ) @@ -30,7 +31,7 @@ func TestBuild_Engine_CountBuildsForOrg(t *testing.T) { _repoOne := testRepo() _repoOne.SetID(1) - _repoOne.SetUserID(1) + _repoOne.GetOwner().SetID(1) _repoOne.SetHash("baz") _repoOne.SetOrg("foo") _repoOne.SetName("bar") @@ -41,7 +42,7 @@ func TestBuild_Engine_CountBuildsForOrg(t *testing.T) { _repoTwo := testRepo() _repoTwo.SetID(2) - _repoTwo.SetUserID(1) + _repoTwo.GetOwner().SetID(1) _repoTwo.SetHash("bar") _repoTwo.SetOrg("foo") _repoTwo.SetName("baz") @@ -81,12 +82,12 @@ func TestBuild_Engine_CountBuildsForOrg(t *testing.T) { t.Errorf("unable to create repo table for sqlite: %v", err) } - err = _sqlite.client.Table(constants.TableRepo).Create(database.RepoFromLibrary(_repoOne)).Error + err = _sqlite.client.Table(constants.TableRepo).Create(repo.FromAPI(_repoOne)).Error if err != nil { t.Errorf("unable to create test repo for sqlite: %v", err) } - err = _sqlite.client.Table(constants.TableRepo).Create(database.RepoFromLibrary(_repoTwo)).Error + err = _sqlite.client.Table(constants.TableRepo).Create(repo.FromAPI(_repoTwo)).Error if err != nil { t.Errorf("unable to create test repo for sqlite: %v", err) } diff --git a/database/build/count_repo.go b/database/build/count_repo.go index 152d867a2..342e49491 100644 --- a/database/build/count_repo.go +++ b/database/build/count_repo.go @@ -5,13 +5,13 @@ package build import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" "github.com/sirupsen/logrus" ) // CountBuildsForRepo gets the count of builds by repo ID from the database. -func (e *engine) CountBuildsForRepo(ctx context.Context, r *library.Repo, filters map[string]interface{}) (int64, error) { +func (e *engine) CountBuildsForRepo(ctx context.Context, r *api.Repo, filters map[string]interface{}) (int64, error) { e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), diff --git a/database/build/count_repo_test.go b/database/build/count_repo_test.go index ebf0dbe47..edbb77816 100644 --- a/database/build/count_repo_test.go +++ b/database/build/count_repo_test.go @@ -26,7 +26,7 @@ func TestBuild_Engine_CountBuildsForRepo(t *testing.T) { _repo := testRepo() _repo.SetID(1) - _repo.SetUserID(1) + _repo.GetOwner().SetID(1) _repo.SetHash("baz") _repo.SetOrg("foo") _repo.SetName("bar") diff --git a/database/build/get_repo.go b/database/build/get_repo.go index 3728b6232..17dfdcb41 100644 --- a/database/build/get_repo.go +++ b/database/build/get_repo.go @@ -5,6 +5,7 @@ package build import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" @@ -12,7 +13,7 @@ import ( ) // GetBuildForRepo gets a build by repo ID and number from the database. -func (e *engine) GetBuildForRepo(ctx context.Context, r *library.Repo, number int) (*library.Build, error) { +func (e *engine) GetBuildForRepo(ctx context.Context, r *api.Repo, number int) (*library.Build, error) { e.logger.WithFields(logrus.Fields{ "build": number, "org": r.GetOrg(), diff --git a/database/build/get_repo_test.go b/database/build/get_repo_test.go index c34fa8a2e..ca714d017 100644 --- a/database/build/get_repo_test.go +++ b/database/build/get_repo_test.go @@ -22,7 +22,7 @@ func TestBuild_Engine_GetBuildForRepo(t *testing.T) { _repo := testRepo() _repo.SetID(1) - _repo.SetUserID(1) + _repo.GetOwner().SetID(1) _repo.SetHash("baz") _repo.SetOrg("foo") _repo.SetName("bar") diff --git a/database/build/interface.go b/database/build/interface.go index e28d230b4..18c85d194 100644 --- a/database/build/interface.go +++ b/database/build/interface.go @@ -5,6 +5,7 @@ package build import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/library" ) @@ -35,7 +36,7 @@ type BuildInterface interface { // CountBuildsForOrg defines a function that gets the count of builds by org name. CountBuildsForOrg(context.Context, string, map[string]interface{}) (int64, error) // CountBuildsForRepo defines a function that gets the count of builds by repo ID. - CountBuildsForRepo(context.Context, *library.Repo, map[string]interface{}) (int64, error) + CountBuildsForRepo(context.Context, *api.Repo, map[string]interface{}) (int64, error) // CountBuildsForStatus defines a function that gets the count of builds by status. CountBuildsForStatus(context.Context, string, map[string]interface{}) (int64, error) // CreateBuild defines a function that creates a new build. @@ -45,19 +46,19 @@ type BuildInterface interface { // GetBuild defines a function that gets a build by ID. GetBuild(context.Context, int64) (*library.Build, error) // GetBuildForRepo defines a function that gets a build by repo ID and number. - GetBuildForRepo(context.Context, *library.Repo, int) (*library.Build, error) + GetBuildForRepo(context.Context, *api.Repo, int) (*library.Build, error) // LastBuildForRepo defines a function that gets the last build ran by repo ID and branch. - LastBuildForRepo(context.Context, *library.Repo, string) (*library.Build, error) + LastBuildForRepo(context.Context, *api.Repo, string) (*library.Build, error) // ListBuilds defines a function that gets a list of all builds. ListBuilds(context.Context) ([]*library.Build, error) // ListBuildsForOrg defines a function that gets a list of builds by org name. ListBuildsForOrg(context.Context, string, map[string]interface{}, int, int) ([]*library.Build, int64, error) // ListBuildsForRepo defines a function that gets a list of builds by repo ID. - ListBuildsForRepo(context.Context, *library.Repo, map[string]interface{}, int64, int64, int, int) ([]*library.Build, int64, error) + ListBuildsForRepo(context.Context, *api.Repo, map[string]interface{}, int64, int64, int, int) ([]*library.Build, int64, error) // ListPendingAndRunningBuilds defines a function that gets a list of pending and running builds. ListPendingAndRunningBuilds(context.Context, string) ([]*library.BuildQueue, error) // ListPendingAndRunningBuildsForRepo defines a function that gets a list of pending and running builds for a repo. - ListPendingAndRunningBuildsForRepo(context.Context, *library.Repo) ([]*library.Build, error) + ListPendingAndRunningBuildsForRepo(context.Context, *api.Repo) ([]*library.Build, error) // UpdateBuild defines a function that updates an existing build. UpdateBuild(context.Context, *library.Build) (*library.Build, error) } diff --git a/database/build/last_repo.go b/database/build/last_repo.go index 36b923379..d92e3eea5 100644 --- a/database/build/last_repo.go +++ b/database/build/last_repo.go @@ -6,6 +6,7 @@ import ( "context" "errors" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" @@ -15,7 +16,7 @@ import ( ) // LastBuildForRepo gets the last build by repo ID and branch from the database. -func (e *engine) LastBuildForRepo(ctx context.Context, r *library.Repo, branch string) (*library.Build, error) { +func (e *engine) LastBuildForRepo(ctx context.Context, r *api.Repo, branch string) (*library.Build, error) { e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), diff --git a/database/build/last_repo_test.go b/database/build/last_repo_test.go index 7baebe01d..5e3d9d216 100644 --- a/database/build/last_repo_test.go +++ b/database/build/last_repo_test.go @@ -22,7 +22,7 @@ func TestBuild_Engine_LastBuildForRepo(t *testing.T) { _repo := testRepo() _repo.SetID(1) - _repo.SetUserID(1) + _repo.GetOwner().SetID(1) _repo.SetHash("baz") _repo.SetOrg("foo") _repo.SetName("bar") diff --git a/database/build/list_org_test.go b/database/build/list_org_test.go index 718517d3d..6b8df4c19 100644 --- a/database/build/list_org_test.go +++ b/database/build/list_org_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/repo" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" @@ -31,7 +32,7 @@ func TestBuild_Engine_ListBuildsForOrg(t *testing.T) { _repoOne := testRepo() _repoOne.SetID(1) - _repoOne.SetUserID(1) + _repoOne.GetOwner().SetID(1) _repoOne.SetHash("baz") _repoOne.SetOrg("foo") _repoOne.SetName("bar") @@ -42,7 +43,7 @@ func TestBuild_Engine_ListBuildsForOrg(t *testing.T) { _repoTwo := testRepo() _repoTwo.SetID(2) - _repoTwo.SetUserID(1) + _repoTwo.GetOwner().SetID(1) _repoTwo.SetHash("bar") _repoTwo.SetOrg("foo") _repoTwo.SetName("baz") @@ -108,12 +109,12 @@ func TestBuild_Engine_ListBuildsForOrg(t *testing.T) { t.Errorf("unable to create repo table for sqlite: %v", err) } - err = _sqlite.client.Table(constants.TableRepo).Create(database.RepoFromLibrary(_repoOne)).Error + err = _sqlite.client.Table(constants.TableRepo).Create(repo.FromAPI(_repoOne)).Error if err != nil { t.Errorf("unable to create test repo for sqlite: %v", err) } - err = _sqlite.client.Table(constants.TableRepo).Create(database.RepoFromLibrary(_repoTwo)).Error + err = _sqlite.client.Table(constants.TableRepo).Create(repo.FromAPI(_repoTwo)).Error if err != nil { t.Errorf("unable to create test repo for sqlite: %v", err) } diff --git a/database/build/list_pending_running_repo.go b/database/build/list_pending_running_repo.go index ad0963aee..119b78625 100644 --- a/database/build/list_pending_running_repo.go +++ b/database/build/list_pending_running_repo.go @@ -5,13 +5,14 @@ package build import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" ) // ListPendingAndRunningBuilds gets a list of all pending and running builds in the provided timeframe from the database. -func (e *engine) ListPendingAndRunningBuildsForRepo(ctx context.Context, repo *library.Repo) ([]*library.Build, error) { +func (e *engine) ListPendingAndRunningBuildsForRepo(ctx context.Context, repo *api.Repo) ([]*library.Build, error) { e.logger.Trace("listing all pending and running builds from the database") // variables to store query results and return value diff --git a/database/build/list_pending_running_repo_test.go b/database/build/list_pending_running_repo_test.go index 34993713b..d6b2d5a4f 100644 --- a/database/build/list_pending_running_repo_test.go +++ b/database/build/list_pending_running_repo_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/repo" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" @@ -41,7 +42,7 @@ func TestBuild_Engine_ListPendingAndRunningBuildsForRepo(t *testing.T) { _repo := testRepo() _repo.SetID(1) - _repo.SetUserID(1) + _repo.GetOwner().SetID(1) _repo.SetHash("baz") _repo.SetOrg("foo") _repo.SetName("bar") @@ -50,7 +51,7 @@ func TestBuild_Engine_ListPendingAndRunningBuildsForRepo(t *testing.T) { _repoTwo := testRepo() _repoTwo.SetID(2) - _repoTwo.SetUserID(1) + _repoTwo.GetOwner().SetID(1) _repoTwo.SetHash("bazzy") _repoTwo.SetOrg("foo") _repoTwo.SetName("baz") @@ -92,12 +93,12 @@ func TestBuild_Engine_ListPendingAndRunningBuildsForRepo(t *testing.T) { t.Errorf("unable to create repo table for sqlite: %v", err) } - err = _sqlite.client.Table(constants.TableRepo).Create(database.RepoFromLibrary(_repo)).Error + err = _sqlite.client.Table(constants.TableRepo).Create(repo.FromAPI(_repo)).Error if err != nil { t.Errorf("unable to create test repo for sqlite: %v", err) } - err = _sqlite.client.Table(constants.TableRepo).Create(database.RepoFromLibrary(_repoTwo)).Error + err = _sqlite.client.Table(constants.TableRepo).Create(repo.FromAPI(_repoTwo)).Error if err != nil { t.Errorf("unable to create test repo for sqlite: %v", err) } diff --git a/database/build/list_pending_running_test.go b/database/build/list_pending_running_test.go index 9115745f3..b7144a815 100644 --- a/database/build/list_pending_running_test.go +++ b/database/build/list_pending_running_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/repo" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" @@ -45,7 +46,7 @@ func TestBuild_Engine_ListPendingAndRunningBuilds(t *testing.T) { _repo := testRepo() _repo.SetID(1) - _repo.SetUserID(1) + _repo.GetOwner().SetID(1) _repo.SetHash("baz") _repo.SetOrg("foo") _repo.SetName("bar") @@ -79,7 +80,7 @@ func TestBuild_Engine_ListPendingAndRunningBuilds(t *testing.T) { t.Errorf("unable to create repo table for sqlite: %v", err) } - err = _sqlite.client.Table(constants.TableRepo).Create(database.RepoFromLibrary(_repo)).Error + err = _sqlite.client.Table(constants.TableRepo).Create(repo.FromAPI(_repo)).Error if err != nil { t.Errorf("unable to create test repo for sqlite: %v", err) } diff --git a/database/build/list_repo.go b/database/build/list_repo.go index 8b4386457..f8d7a0c00 100644 --- a/database/build/list_repo.go +++ b/database/build/list_repo.go @@ -5,6 +5,7 @@ package build import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" @@ -14,7 +15,7 @@ import ( // ListBuildsForRepo gets a list of builds by repo ID from the database. // //nolint:lll // ignore long line length due to variable names -func (e *engine) ListBuildsForRepo(ctx context.Context, r *library.Repo, filters map[string]interface{}, before, after int64, page, perPage int) ([]*library.Build, int64, error) { +func (e *engine) ListBuildsForRepo(ctx context.Context, r *api.Repo, filters map[string]interface{}, before, after int64, page, perPage int) ([]*library.Build, int64, error) { e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), diff --git a/database/build/list_repo_test.go b/database/build/list_repo_test.go index 4cb4622a5..90b54988a 100644 --- a/database/build/list_repo_test.go +++ b/database/build/list_repo_test.go @@ -30,7 +30,7 @@ func TestBuild_Engine_ListBuildsForRepo(t *testing.T) { _repo := testRepo() _repo.SetID(1) - _repo.SetUserID(1) + _repo.GetOwner().SetID(1) _repo.SetHash("baz") _repo.SetOrg("foo") _repo.SetName("bar") diff --git a/database/deployment/count_repo.go b/database/deployment/count_repo.go index 93a7c1ac8..c9eef1aad 100644 --- a/database/deployment/count_repo.go +++ b/database/deployment/count_repo.go @@ -5,13 +5,13 @@ package deployment import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" "github.com/sirupsen/logrus" ) // CountDeploymentsForRepo gets the count of deployments by repo ID from the database. -func (e *engine) CountDeploymentsForRepo(ctx context.Context, r *library.Repo) (int64, error) { +func (e *engine) CountDeploymentsForRepo(ctx context.Context, r *api.Repo) (int64, error) { e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), diff --git a/database/deployment/count_repo_test.go b/database/deployment/count_repo_test.go index 6d3afece4..586ca6ffb 100644 --- a/database/deployment/count_repo_test.go +++ b/database/deployment/count_repo_test.go @@ -47,7 +47,7 @@ func TestDeployment_Engine_CountDeploymentsForRepo(t *testing.T) { _repo := testRepo() _repo.SetID(1) - _repo.SetUserID(1) + _repo.GetOwner().SetID(1) _repo.SetOrg("foo") _repo.SetName("bar") _repo.SetFullName("foo/bar") diff --git a/database/deployment/deployment_test.go b/database/deployment/deployment_test.go index 0184fbcce..60265211d 100644 --- a/database/deployment/deployment_test.go +++ b/database/deployment/deployment_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/library" "github.com/go-vela/types/raw" "github.com/sirupsen/logrus" @@ -188,10 +189,9 @@ func testDeployment() *library.Deployment { // testRepo is a test helper function to create a library // Repo type with all fields set to their zero values. -func testRepo() *library.Repo { - return &library.Repo{ +func testRepo() *api.Repo { + return &api.Repo{ ID: new(int64), - UserID: new(int64), BuildLimit: new(int64), Timeout: new(int64), Counter: new(int), diff --git a/database/deployment/get_repo.go b/database/deployment/get_repo.go index b240adc20..a359bbcb7 100644 --- a/database/deployment/get_repo.go +++ b/database/deployment/get_repo.go @@ -6,6 +6,7 @@ import ( "context" "strconv" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" @@ -13,7 +14,7 @@ import ( ) // GetDeploymentForRepo gets a deployment by repo ID and number from the database. -func (e *engine) GetDeploymentForRepo(ctx context.Context, r *library.Repo, number int64) (*library.Deployment, error) { +func (e *engine) GetDeploymentForRepo(ctx context.Context, r *api.Repo, number int64) (*library.Deployment, error) { e.logger.WithFields(logrus.Fields{ "deployment": number, "org": r.GetOrg(), diff --git a/database/deployment/get_repo_test.go b/database/deployment/get_repo_test.go index 5ddbb61d5..289b3ad87 100644 --- a/database/deployment/get_repo_test.go +++ b/database/deployment/get_repo_test.go @@ -32,7 +32,7 @@ func TestDeployment_Engine_GetDeploymentForRepo(t *testing.T) { _repo := testRepo() _repo.SetID(1) - _repo.SetUserID(1) + _repo.GetOwner().SetID(1) _repo.SetOrg("foo") _repo.SetName("bar") _repo.SetFullName("foo/bar") diff --git a/database/deployment/interface.go b/database/deployment/interface.go index 837aa2121..cd1f6cebc 100644 --- a/database/deployment/interface.go +++ b/database/deployment/interface.go @@ -5,6 +5,7 @@ package deployment import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/library" ) @@ -29,7 +30,7 @@ type DeploymentInterface interface { // CountDeployments defines a function that gets the count of all deployments. CountDeployments(context.Context) (int64, error) // CountDeploymentsForRepo defines a function that gets the count of deployments by repo ID. - CountDeploymentsForRepo(context.Context, *library.Repo) (int64, error) + CountDeploymentsForRepo(context.Context, *api.Repo) (int64, error) // CreateDeployment defines a function that creates a new deployment. CreateDeployment(context.Context, *library.Deployment) (*library.Deployment, error) // DeleteDeployment defines a function that deletes an existing deployment. @@ -37,11 +38,11 @@ type DeploymentInterface interface { // GetDeployment defines a function that gets a deployment by ID. GetDeployment(context.Context, int64) (*library.Deployment, error) // GetDeploymentForRepo defines a function that gets a deployment by repo ID and number. - GetDeploymentForRepo(context.Context, *library.Repo, int64) (*library.Deployment, error) + GetDeploymentForRepo(context.Context, *api.Repo, int64) (*library.Deployment, error) // ListDeployments defines a function that gets a list of all deployments. ListDeployments(context.Context) ([]*library.Deployment, error) // ListDeploymentsForRepo defines a function that gets a list of deployments by repo ID. - ListDeploymentsForRepo(context.Context, *library.Repo, int, int) ([]*library.Deployment, error) + ListDeploymentsForRepo(context.Context, *api.Repo, int, int) ([]*library.Deployment, error) // UpdateDeployment defines a function that updates an existing deployment. UpdateDeployment(context.Context, *library.Deployment) (*library.Deployment, error) } diff --git a/database/deployment/list_repo.go b/database/deployment/list_repo.go index 471da6cf0..76c973e6d 100644 --- a/database/deployment/list_repo.go +++ b/database/deployment/list_repo.go @@ -6,6 +6,7 @@ import ( "context" "strconv" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" @@ -13,7 +14,7 @@ import ( ) // ListDeploymentsForRepo gets a list of deployments by repo ID from the database. -func (e *engine) ListDeploymentsForRepo(ctx context.Context, r *library.Repo, page, perPage int) ([]*library.Deployment, error) { +func (e *engine) ListDeploymentsForRepo(ctx context.Context, r *api.Repo, page, perPage int) ([]*library.Deployment, error) { e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), diff --git a/database/hook/count_repo.go b/database/hook/count_repo.go index 7b536804f..28549dec9 100644 --- a/database/hook/count_repo.go +++ b/database/hook/count_repo.go @@ -5,13 +5,13 @@ package hook import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" "github.com/sirupsen/logrus" ) // CountHooksForRepo gets the count of hooks by repo ID from the database. -func (e *engine) CountHooksForRepo(ctx context.Context, r *library.Repo) (int64, error) { +func (e *engine) CountHooksForRepo(ctx context.Context, r *api.Repo) (int64, error) { e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), diff --git a/database/hook/count_repo_test.go b/database/hook/count_repo_test.go index 87f6c97bb..cd1592f4e 100644 --- a/database/hook/count_repo_test.go +++ b/database/hook/count_repo_test.go @@ -30,7 +30,7 @@ func TestHook_Engine_CountHooksForRepo(t *testing.T) { _repo := testRepo() _repo.SetID(1) - _repo.SetUserID(1) + _repo.GetOwner().SetID(1) _repo.SetOrg("foo") _repo.SetName("bar") _repo.SetFullName("foo/bar") diff --git a/database/hook/get_repo.go b/database/hook/get_repo.go index 6182d86c9..af5d2b9bc 100644 --- a/database/hook/get_repo.go +++ b/database/hook/get_repo.go @@ -5,6 +5,7 @@ package hook import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" @@ -12,7 +13,7 @@ import ( ) // GetHookForRepo gets a hook by repo ID and number from the database. -func (e *engine) GetHookForRepo(ctx context.Context, r *library.Repo, number int) (*library.Hook, error) { +func (e *engine) GetHookForRepo(ctx context.Context, r *api.Repo, number int) (*library.Hook, error) { e.logger.WithFields(logrus.Fields{ "hook": number, "org": r.GetOrg(), diff --git a/database/hook/get_repo_test.go b/database/hook/get_repo_test.go index e7c33c2d8..f52eb1bd4 100644 --- a/database/hook/get_repo_test.go +++ b/database/hook/get_repo_test.go @@ -23,7 +23,7 @@ func TestHook_Engine_GetHookForRepo(t *testing.T) { _repo := testRepo() _repo.SetID(1) - _repo.SetUserID(1) + _repo.GetOwner().SetID(1) _repo.SetOrg("foo") _repo.SetName("bar") _repo.SetFullName("foo/bar") diff --git a/database/hook/hook_test.go b/database/hook/hook_test.go index fd358715f..50b689c00 100644 --- a/database/hook/hook_test.go +++ b/database/hook/hook_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/library" "github.com/sirupsen/logrus" @@ -187,10 +188,9 @@ func testHook() *library.Hook { // testRepo is a test helper function to create a library // Repo type with all fields set to their zero values. -func testRepo() *library.Repo { - return &library.Repo{ +func testRepo() *api.Repo { + return &api.Repo{ ID: new(int64), - UserID: new(int64), BuildLimit: new(int64), Timeout: new(int64), Counter: new(int), diff --git a/database/hook/interface.go b/database/hook/interface.go index 6a9cec8f6..674dca20c 100644 --- a/database/hook/interface.go +++ b/database/hook/interface.go @@ -5,6 +5,7 @@ package hook import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/library" ) @@ -29,7 +30,7 @@ type HookInterface interface { // CountHooks defines a function that gets the count of all hooks. CountHooks(context.Context) (int64, error) // CountHooksForRepo defines a function that gets the count of hooks by repo ID. - CountHooksForRepo(context.Context, *library.Repo) (int64, error) + CountHooksForRepo(context.Context, *api.Repo) (int64, error) // CreateHook defines a function that creates a new hook. CreateHook(context.Context, *library.Hook) (*library.Hook, error) // DeleteHook defines a function that deletes an existing hook. @@ -39,13 +40,13 @@ type HookInterface interface { // GetHookByWebhookID defines a function that gets any hook with a matching webhook_id. GetHookByWebhookID(context.Context, int64) (*library.Hook, error) // GetHookForRepo defines a function that gets a hook by repo ID and number. - GetHookForRepo(context.Context, *library.Repo, int) (*library.Hook, error) + GetHookForRepo(context.Context, *api.Repo, int) (*library.Hook, error) // LastHookForRepo defines a function that gets the last hook by repo ID. - LastHookForRepo(context.Context, *library.Repo) (*library.Hook, error) + LastHookForRepo(context.Context, *api.Repo) (*library.Hook, error) // ListHooks defines a function that gets a list of all hooks. ListHooks(context.Context) ([]*library.Hook, error) // ListHooksForRepo defines a function that gets a list of hooks by repo ID. - ListHooksForRepo(context.Context, *library.Repo, int, int) ([]*library.Hook, int64, error) + ListHooksForRepo(context.Context, *api.Repo, int, int) ([]*library.Hook, int64, error) // UpdateHook defines a function that updates an existing hook. UpdateHook(context.Context, *library.Hook) (*library.Hook, error) } diff --git a/database/hook/last_repo.go b/database/hook/last_repo.go index bf85be4dc..76fb7cbf0 100644 --- a/database/hook/last_repo.go +++ b/database/hook/last_repo.go @@ -6,6 +6,7 @@ import ( "context" "errors" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" @@ -15,7 +16,7 @@ import ( ) // LastHookForRepo gets the last hook by repo ID from the database. -func (e *engine) LastHookForRepo(ctx context.Context, r *library.Repo) (*library.Hook, error) { +func (e *engine) LastHookForRepo(ctx context.Context, r *api.Repo) (*library.Hook, error) { e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), diff --git a/database/hook/last_repo_test.go b/database/hook/last_repo_test.go index b7911f91d..d7409cc8e 100644 --- a/database/hook/last_repo_test.go +++ b/database/hook/last_repo_test.go @@ -23,7 +23,7 @@ func TestHook_Engine_LastHookForRepo(t *testing.T) { _repo := testRepo() _repo.SetID(1) - _repo.SetUserID(1) + _repo.GetOwner().SetID(1) _repo.SetOrg("foo") _repo.SetName("bar") _repo.SetFullName("foo/bar") diff --git a/database/hook/list_repo.go b/database/hook/list_repo.go index 28220b1dd..3a2ec497f 100644 --- a/database/hook/list_repo.go +++ b/database/hook/list_repo.go @@ -5,6 +5,7 @@ package hook import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" @@ -12,7 +13,7 @@ import ( ) // ListHooksForRepo gets a list of hooks by repo ID from the database. -func (e *engine) ListHooksForRepo(ctx context.Context, r *library.Repo, page, perPage int) ([]*library.Hook, int64, error) { +func (e *engine) ListHooksForRepo(ctx context.Context, r *api.Repo, page, perPage int) ([]*library.Hook, int64, error) { e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), diff --git a/database/hook/list_repo_test.go b/database/hook/list_repo_test.go index 38e72a93f..b2967a1f0 100644 --- a/database/hook/list_repo_test.go +++ b/database/hook/list_repo_test.go @@ -31,7 +31,7 @@ func TestHook_Engine_ListHooksForRepo(t *testing.T) { _repo := testRepo() _repo.SetID(1) - _repo.SetUserID(1) + _repo.GetOwner().SetID(1) _repo.SetOrg("foo") _repo.SetName("bar") _repo.SetFullName("foo/bar") diff --git a/database/integration_test.go b/database/integration_test.go index 0bde55005..e1a0c1432 100644 --- a/database/integration_test.go +++ b/database/integration_test.go @@ -38,7 +38,7 @@ type Resources struct { Hooks []*library.Hook Logs []*library.Log Pipelines []*library.Pipeline - Repos []*library.Repo + Repos []*api.Repo Schedules []*library.Schedule Secrets []*library.Secret Services []*library.Service @@ -994,6 +994,14 @@ func testRepos(t *testing.T, db Interface, resources *Resources) { methods[element.Method(i).Name] = false } + // create owners + for _, user := range resources.Users { + _, err := db.CreateUser(context.TODO(), user) + if err != nil { + t.Errorf("unable to create user %d: %v", user.GetID(), err) + } + } + // create the repos for _, repo := range resources.Repos { _, err := db.CreateRepo(context.TODO(), repo) @@ -1110,6 +1118,14 @@ func testRepos(t *testing.T, db Interface, resources *Resources) { } methods["DeleteRepo"] = true + // delete the owners + for _, user := range resources.Users { + err := db.DeleteUser(context.TODO(), user) + if err != nil { + t.Errorf("unable to delete user %d: %v", user.GetID(), err) + } + } + // ensure we called all the methods we expected to for method, called := range methods { if !called { @@ -2221,9 +2237,29 @@ func newResources() *Resources { pipelineTwo.SetTemplates(false) pipelineTwo.SetData([]byte("version: 1")) - repoOne := new(library.Repo) + userOne := new(library.User) + userOne.SetID(1) + userOne.SetName("octocat") + userOne.SetToken("superSecretToken") + userOne.SetRefreshToken("superSecretRefreshToken") + userOne.SetHash("MzM4N2MzMDAtNmY4Mi00OTA5LWFhZDAtNWIzMTlkNTJkODMy") + userOne.SetFavorites([]string{"github/octocat"}) + userOne.SetActive(true) + userOne.SetAdmin(false) + + userTwo := new(library.User) + userTwo.SetID(2) + userTwo.SetName("octokitty") + userTwo.SetToken("superSecretToken") + userTwo.SetRefreshToken("superSecretRefreshToken") + userTwo.SetHash("MzM4N2MzMDAtNmY4Mi00OTA5LWFhZDAtNWIzMTlkNTJkODMy") + userTwo.SetFavorites([]string{"github/octocat"}) + userTwo.SetActive(true) + userTwo.SetAdmin(false) + + repoOne := new(api.Repo) repoOne.SetID(1) - repoOne.SetUserID(1) + repoOne.SetOwner(userOne) repoOne.SetHash("MzM4N2MzMDAtNmY4Mi00OTA5LWFhZDAtNWIzMTlkNTJkODMy") repoOne.SetOrg("github") repoOne.SetName("octocat") @@ -2242,11 +2278,11 @@ func newResources() *Resources { repoOne.SetPipelineType("") repoOne.SetPreviousName("") repoOne.SetApproveBuild(constants.ApproveNever) - repoOne.SetAllowEvents(library.NewEventsFromMask(1)) + repoOne.SetAllowEvents(api.NewEventsFromMask(1)) - repoTwo := new(library.Repo) + repoTwo := new(api.Repo) repoTwo.SetID(2) - repoTwo.SetUserID(1) + repoTwo.SetOwner(userOne) repoTwo.SetHash("MzM4N2MzMDAtNmY4Mi00OTA5LWFhZDAtNWIzMTlkNTJkODMy") repoTwo.SetOrg("github") repoTwo.SetName("octokitty") @@ -2265,7 +2301,7 @@ func newResources() *Resources { repoTwo.SetPipelineType("") repoTwo.SetPreviousName("") repoTwo.SetApproveBuild(constants.ApproveForkAlways) - repoTwo.SetAllowEvents(library.NewEventsFromMask(1)) + repoTwo.SetAllowEvents(api.NewEventsFromMask(1)) scheduleOne := new(library.Schedule) scheduleOne.SetID(1) @@ -2416,26 +2452,6 @@ func newResources() *Resources { stepTwo.SetDistribution("linux") stepTwo.SetReportAs("test") - userOne := new(library.User) - userOne.SetID(1) - userOne.SetName("octocat") - userOne.SetToken("superSecretToken") - userOne.SetRefreshToken("superSecretRefreshToken") - userOne.SetHash("MzM4N2MzMDAtNmY4Mi00OTA5LWFhZDAtNWIzMTlkNTJkODMy") - userOne.SetFavorites([]string{"github/octocat"}) - userOne.SetActive(true) - userOne.SetAdmin(false) - - userTwo := new(library.User) - userTwo.SetID(2) - userTwo.SetName("octokitty") - userTwo.SetToken("superSecretToken") - userTwo.SetRefreshToken("superSecretRefreshToken") - userTwo.SetHash("MzM4N2MzMDAtNmY4Mi00OTA5LWFhZDAtNWIzMTlkNTJkODMy") - userTwo.SetFavorites([]string{"github/octocat"}) - userTwo.SetActive(true) - userTwo.SetAdmin(false) - _bPartialOne := new(library.Build) _bPartialOne.SetID(1) @@ -2477,7 +2493,7 @@ func newResources() *Resources { Hooks: []*library.Hook{hookOne, hookTwo, hookThree}, Logs: []*library.Log{logServiceOne, logServiceTwo, logStepOne, logStepTwo}, Pipelines: []*library.Pipeline{pipelineOne, pipelineTwo}, - Repos: []*library.Repo{repoOne, repoTwo}, + Repos: []*api.Repo{repoOne, repoTwo}, Schedules: []*library.Schedule{scheduleOne, scheduleTwo}, Secrets: []*library.Secret{secretOrg, secretRepo, secretShared}, Services: []*library.Service{serviceOne, serviceTwo}, diff --git a/database/pipeline/count_repo.go b/database/pipeline/count_repo.go index 549a9ecc9..00cecda46 100644 --- a/database/pipeline/count_repo.go +++ b/database/pipeline/count_repo.go @@ -5,13 +5,13 @@ package pipeline import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" "github.com/sirupsen/logrus" ) // CountPipelinesForRepo gets the count of pipelines by repo ID from the database. -func (e *engine) CountPipelinesForRepo(ctx context.Context, r *library.Repo) (int64, error) { +func (e *engine) CountPipelinesForRepo(ctx context.Context, r *api.Repo) (int64, error) { e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), diff --git a/database/pipeline/count_repo_test.go b/database/pipeline/count_repo_test.go index e40888f3c..d4776cd77 100644 --- a/database/pipeline/count_repo_test.go +++ b/database/pipeline/count_repo_test.go @@ -8,7 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" ) func TestPipeline_Engine_CountPipelinesForRepo(t *testing.T) { @@ -75,7 +75,7 @@ func TestPipeline_Engine_CountPipelinesForRepo(t *testing.T) { // run tests for _, test := range tests { t.Run(test.name, func(t *testing.T) { - got, err := test.database.CountPipelinesForRepo(context.TODO(), &library.Repo{ID: _pipelineOne.RepoID}) + got, err := test.database.CountPipelinesForRepo(context.TODO(), &api.Repo{ID: _pipelineOne.RepoID}) if test.failure { if err == nil { diff --git a/database/pipeline/get_repo.go b/database/pipeline/get_repo.go index 934c0dcd2..b5581df56 100644 --- a/database/pipeline/get_repo.go +++ b/database/pipeline/get_repo.go @@ -5,6 +5,7 @@ package pipeline import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" @@ -12,7 +13,7 @@ import ( ) // GetPipelineForRepo gets a pipeline by number and repo ID from the database. -func (e *engine) GetPipelineForRepo(ctx context.Context, commit string, r *library.Repo) (*library.Pipeline, error) { +func (e *engine) GetPipelineForRepo(ctx context.Context, commit string, r *api.Repo) (*library.Pipeline, error) { e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "pipeline": commit, diff --git a/database/pipeline/get_repo_test.go b/database/pipeline/get_repo_test.go index 82b9669da..fd4a5dea8 100644 --- a/database/pipeline/get_repo_test.go +++ b/database/pipeline/get_repo_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/library" ) @@ -65,7 +66,7 @@ func TestPipeline_Engine_GetPipelineForRepo(t *testing.T) { // run tests for _, test := range tests { t.Run(test.name, func(t *testing.T) { - got, err := test.database.GetPipelineForRepo(context.TODO(), "48afb5bdc41ad69bf22588491333f7cf71135163", &library.Repo{ID: _pipeline.RepoID}) + got, err := test.database.GetPipelineForRepo(context.TODO(), "48afb5bdc41ad69bf22588491333f7cf71135163", &api.Repo{ID: _pipeline.RepoID}) if test.failure { if err == nil { diff --git a/database/pipeline/interface.go b/database/pipeline/interface.go index 602cfbb1d..64666952e 100644 --- a/database/pipeline/interface.go +++ b/database/pipeline/interface.go @@ -5,6 +5,7 @@ package pipeline import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/library" ) @@ -29,7 +30,7 @@ type PipelineInterface interface { // CountPipelines defines a function that gets the count of all pipelines. CountPipelines(context.Context) (int64, error) // CountPipelinesForRepo defines a function that gets the count of pipelines by repo ID. - CountPipelinesForRepo(context.Context, *library.Repo) (int64, error) + CountPipelinesForRepo(context.Context, *api.Repo) (int64, error) // CreatePipeline defines a function that creates a new pipeline. CreatePipeline(context.Context, *library.Pipeline) (*library.Pipeline, error) // DeletePipeline defines a function that deletes an existing pipeline. @@ -37,11 +38,11 @@ type PipelineInterface interface { // GetPipeline defines a function that gets a pipeline by ID. GetPipeline(context.Context, int64) (*library.Pipeline, error) // GetPipelineForRepo defines a function that gets a pipeline by commit SHA and repo ID. - GetPipelineForRepo(context.Context, string, *library.Repo) (*library.Pipeline, error) + GetPipelineForRepo(context.Context, string, *api.Repo) (*library.Pipeline, error) // ListPipelines defines a function that gets a list of all pipelines. ListPipelines(context.Context) ([]*library.Pipeline, error) // ListPipelinesForRepo defines a function that gets a list of pipelines by repo ID. - ListPipelinesForRepo(context.Context, *library.Repo, int, int) ([]*library.Pipeline, int64, error) + ListPipelinesForRepo(context.Context, *api.Repo, int, int) ([]*library.Pipeline, int64, error) // UpdatePipeline defines a function that updates an existing pipeline. UpdatePipeline(context.Context, *library.Pipeline) (*library.Pipeline, error) } diff --git a/database/pipeline/list_repo.go b/database/pipeline/list_repo.go index f4ed90fde..f4ccc6a3e 100644 --- a/database/pipeline/list_repo.go +++ b/database/pipeline/list_repo.go @@ -5,6 +5,7 @@ package pipeline import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" @@ -14,7 +15,7 @@ import ( // ListPipelinesForRepo gets a list of pipelines by repo ID from the database. // //nolint:lll // ignore long line length due to variable names -func (e *engine) ListPipelinesForRepo(ctx context.Context, r *library.Repo, page, perPage int) ([]*library.Pipeline, int64, error) { +func (e *engine) ListPipelinesForRepo(ctx context.Context, r *api.Repo, page, perPage int) ([]*library.Pipeline, int64, error) { e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), diff --git a/database/pipeline/list_repo_test.go b/database/pipeline/list_repo_test.go index aec274702..909605f19 100644 --- a/database/pipeline/list_repo_test.go +++ b/database/pipeline/list_repo_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/library" ) @@ -86,7 +87,7 @@ func TestPipeline_Engine_ListPipelinesForRepo(t *testing.T) { // run tests for _, test := range tests { t.Run(test.name, func(t *testing.T) { - got, _, err := test.database.ListPipelinesForRepo(context.TODO(), &library.Repo{ID: _pipelineOne.RepoID}, 1, 10) + got, _, err := test.database.ListPipelinesForRepo(context.TODO(), &api.Repo{ID: _pipelineOne.RepoID}, 1, 10) if test.failure { if err == nil { diff --git a/database/repo/count_org_test.go b/database/repo/count_org_test.go index c89299773..e77b39e28 100644 --- a/database/repo/count_org_test.go +++ b/database/repo/count_org_test.go @@ -14,7 +14,7 @@ func TestRepo_Engine_CountReposForOrg(t *testing.T) { // setup types _repoOne := testRepo() _repoOne.SetID(1) - _repoOne.SetUserID(1) + _repoOne.GetOwner().SetID(1) _repoOne.SetHash("baz") _repoOne.SetOrg("foo") _repoOne.SetName("bar") @@ -23,7 +23,7 @@ func TestRepo_Engine_CountReposForOrg(t *testing.T) { _repoTwo := testRepo() _repoTwo.SetID(2) - _repoTwo.SetUserID(1) + _repoTwo.GetOwner().SetID(1) _repoTwo.SetHash("baz") _repoTwo.SetOrg("bar") _repoTwo.SetName("foo") diff --git a/database/repo/count_test.go b/database/repo/count_test.go index c399411d6..522779f92 100644 --- a/database/repo/count_test.go +++ b/database/repo/count_test.go @@ -14,7 +14,7 @@ func TestRepo_Engine_CountRepos(t *testing.T) { // setup types _repoOne := testRepo() _repoOne.SetID(1) - _repoOne.SetUserID(1) + _repoOne.GetOwner().SetID(1) _repoOne.SetHash("baz") _repoOne.SetOrg("foo") _repoOne.SetName("bar") @@ -23,7 +23,7 @@ func TestRepo_Engine_CountRepos(t *testing.T) { _repoTwo := testRepo() _repoTwo.SetID(2) - _repoTwo.SetUserID(1) + _repoTwo.GetOwner().SetID(1) _repoTwo.SetHash("baz") _repoTwo.SetOrg("bar") _repoTwo.SetName("foo") diff --git a/database/repo/count_user_test.go b/database/repo/count_user_test.go index a2b580a52..f62b43ff6 100644 --- a/database/repo/count_user_test.go +++ b/database/repo/count_user_test.go @@ -15,7 +15,7 @@ func TestRepo_Engine_CountReposForUser(t *testing.T) { // setup types _repoOne := testRepo() _repoOne.SetID(1) - _repoOne.SetUserID(1) + _repoOne.GetOwner().SetID(1) _repoOne.SetHash("baz") _repoOne.SetOrg("foo") _repoOne.SetName("bar") @@ -24,7 +24,7 @@ func TestRepo_Engine_CountReposForUser(t *testing.T) { _repoTwo := testRepo() _repoTwo.SetID(2) - _repoTwo.SetUserID(1) + _repoTwo.GetOwner().SetID(1) _repoTwo.SetHash("baz") _repoTwo.SetOrg("bar") _repoTwo.SetName("foo") diff --git a/database/repo/create.go b/database/repo/create.go index 578b54fb6..f716bf518 100644 --- a/database/repo/create.go +++ b/database/repo/create.go @@ -7,35 +7,28 @@ import ( "context" "fmt" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" "github.com/sirupsen/logrus" ) // CreateRepo creates a new repo in the database. -func (e *engine) CreateRepo(ctx context.Context, r *library.Repo) (*library.Repo, error) { +func (e *engine) CreateRepo(ctx context.Context, r *api.Repo) (*api.Repo, error) { e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), }).Tracef("creating repo %s in the database", r.GetFullName()) // cast the library type to database type - // - // https://pkg.go.dev/github.com/go-vela/types/database#RepoFromLibrary - repo := database.RepoFromLibrary(r) + repo := FromAPI(r) // validate the necessary fields are populated - // - // https://pkg.go.dev/github.com/go-vela/types/database#Repo.Validate err := repo.Validate() if err != nil { return nil, err } // encrypt the fields for the repo - // - // https://pkg.go.dev/github.com/go-vela/types/database#Repo.Encrypt err = repo.Encrypt(e.config.EncryptionKey) if err != nil { return nil, fmt.Errorf("unable to encrypt repo %s: %w", r.GetFullName(), err) @@ -53,8 +46,12 @@ func (e *engine) CreateRepo(ctx context.Context, r *library.Repo) (*library.Repo // only log to preserve backwards compatibility e.logger.Errorf("unable to decrypt repo %d: %v", r.GetID(), err) - return repo.ToLibrary(), nil + return repo.ToAPI(), nil } - return repo.ToLibrary(), nil + // set owner to provided owner if creation successful + result := repo.ToAPI() + result.SetOwner(r.GetOwner()) + + return result, nil } diff --git a/database/repo/create_test.go b/database/repo/create_test.go index 1a523b563..ddd3d209d 100644 --- a/database/repo/create_test.go +++ b/database/repo/create_test.go @@ -14,7 +14,7 @@ func TestRepo_Engine_CreateRepo(t *testing.T) { // setup types _repo := testRepo() _repo.SetID(1) - _repo.SetUserID(1) + _repo.GetOwner().SetID(1) _repo.SetHash("baz") _repo.SetOrg("foo") _repo.SetName("bar") @@ -75,7 +75,7 @@ VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$ t.Errorf("CreateRepo for %s returned err: %v", test.name, err) } - if diff := cmp.Diff(got, _repo); diff != "" { + if diff := cmp.Diff(_repo, got); diff != "" { t.Errorf("CreateRepo mismatch (-want +got):\n%s", diff) } }) diff --git a/database/repo/delete.go b/database/repo/delete.go index 6432e4ce1..c31dd43e3 100644 --- a/database/repo/delete.go +++ b/database/repo/delete.go @@ -5,23 +5,20 @@ package repo import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" "github.com/sirupsen/logrus" ) // DeleteRepo deletes an existing repo from the database. -func (e *engine) DeleteRepo(ctx context.Context, r *library.Repo) error { +func (e *engine) DeleteRepo(ctx context.Context, r *api.Repo) error { e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), }).Tracef("deleting repo %s from the database", r.GetFullName()) // cast the library type to database type - // - // https://pkg.go.dev/github.com/go-vela/types/database#RepoFromLibrary - repo := database.RepoFromLibrary(r) + repo := FromAPI(r) // send query to the database return e.client. diff --git a/database/repo/delete_test.go b/database/repo/delete_test.go index 30ff1d84c..34038d5fc 100644 --- a/database/repo/delete_test.go +++ b/database/repo/delete_test.go @@ -13,7 +13,7 @@ func TestRepo_Engine_DeleteRepo(t *testing.T) { // setup types _repo := testRepo() _repo.SetID(1) - _repo.SetUserID(1) + _repo.GetOwner().SetID(1) _repo.SetHash("baz") _repo.SetOrg("foo") _repo.SetName("bar") diff --git a/database/repo/get.go b/database/repo/get.go index af9db8e1c..ee603b09d 100644 --- a/database/repo/get.go +++ b/database/repo/get.go @@ -5,21 +5,21 @@ package repo import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" ) // GetRepo gets a repo by ID from the database. -func (e *engine) GetRepo(ctx context.Context, id int64) (*library.Repo, error) { +func (e *engine) GetRepo(ctx context.Context, id int64) (*api.Repo, error) { e.logger.Tracef("getting repo %d from the database", id) // variable to store query results - r := new(database.Repo) + r := new(Repo) // send query to the database and store result in variable err := e.client. Table(constants.TableRepo). + Preload("Owner"). Where("id = ?", id). Take(r). Error @@ -42,11 +42,20 @@ func (e *engine) GetRepo(ctx context.Context, id int64) (*library.Repo, error) { // return the unencrypted repo // // https://pkg.go.dev/github.com/go-vela/types/database#Repo.ToLibrary - return r.ToLibrary(), nil + return r.ToAPI(), nil + } + + // decrypt owner fields + err = r.Owner.Decrypt(e.config.EncryptionKey) + if err != nil { + e.logger.Errorf("unable to decrypt repo owner %d: %v", id, err) + + // return the unencrypted repo + return r.ToAPI(), nil } // return the decrypted repo // // https://pkg.go.dev/github.com/go-vela/types/database#Repo.ToLibrary - return r.ToLibrary(), nil + return r.ToAPI(), nil } diff --git a/database/repo/get_org.go b/database/repo/get_org.go index 2a1d053ea..186624276 100644 --- a/database/repo/get_org.go +++ b/database/repo/get_org.go @@ -5,25 +5,25 @@ package repo import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" "github.com/sirupsen/logrus" ) // GetRepoForOrg gets a repo by org and repo name from the database. -func (e *engine) GetRepoForOrg(ctx context.Context, org, name string) (*library.Repo, error) { +func (e *engine) GetRepoForOrg(ctx context.Context, org, name string) (*api.Repo, error) { e.logger.WithFields(logrus.Fields{ "org": org, "repo": name, }).Tracef("getting repo %s/%s from the database", org, name) // variable to store query results - r := new(database.Repo) + r := new(Repo) // send query to the database and store result in variable err := e.client. Table(constants.TableRepo). + Preload("Owner"). Where("org = ?", org). Where("name = ?", name). Take(r). @@ -33,8 +33,6 @@ func (e *engine) GetRepoForOrg(ctx context.Context, org, name string) (*library. } // decrypt the fields for the repo - // - // https://pkg.go.dev/github.com/go-vela/types/database#Repo.Decrypt err = r.Decrypt(e.config.EncryptionKey) if err != nil { // TODO: remove backwards compatibility before 1.x.x release @@ -45,13 +43,18 @@ func (e *engine) GetRepoForOrg(ctx context.Context, org, name string) (*library. e.logger.Errorf("unable to decrypt repo %s/%s: %v", org, name, err) // return the unencrypted repo - // - // https://pkg.go.dev/github.com/go-vela/types/database#Repo.ToLibrary - return r.ToLibrary(), nil + return r.ToAPI(), nil + } + + // decrypt owner fields + err = r.Owner.Decrypt(e.config.EncryptionKey) + if err != nil { + e.logger.Errorf("unable to decrypt repo owner %s/%s: %v", org, name, err) + + // return the unencrypted repo + return r.ToAPI(), nil } // return the decrypted repo - // - // https://pkg.go.dev/github.com/go-vela/types/database#Repo.ToLibrary - return r.ToLibrary(), nil + return r.ToAPI(), nil } diff --git a/database/repo/get_org_test.go b/database/repo/get_org_test.go index db5b36314..9df07c42d 100644 --- a/database/repo/get_org_test.go +++ b/database/repo/get_org_test.go @@ -4,18 +4,19 @@ package repo import ( "context" - "reflect" "testing" "github.com/DATA-DOG/go-sqlmock" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/types/constants" + "github.com/go-vela/types/database" + "github.com/google/go-cmp/cmp" ) func TestRepo_Engine_GetRepoForOrg(t *testing.T) { // setup types _repo := testRepo() _repo.SetID(1) - _repo.SetUserID(1) _repo.SetHash("baz") _repo.SetOrg("foo") _repo.SetName("bar") @@ -23,7 +24,15 @@ func TestRepo_Engine_GetRepoForOrg(t *testing.T) { _repo.SetVisibility("public") _repo.SetPipelineType("yaml") _repo.SetTopics([]string{}) - _repo.SetAllowEvents(library.NewEventsFromMask(1)) + _repo.SetAllowEvents(api.NewEventsFromMask(1)) + + _owner := testOwner() + _owner.SetID(1) + _owner.SetName("foo") + _owner.SetToken("bar") + _owner.SetHash("baz") + + _repo.SetOwner(_owner) _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() @@ -33,8 +42,13 @@ func TestRepo_Engine_GetRepoForOrg(t *testing.T) { []string{"id", "user_id", "hash", "org", "name", "full_name", "link", "clone", "branch", "topics", "build_limit", "timeout", "counter", "visibility", "private", "trusted", "active", "allow_events", "pipeline_type", "previous_name", "approve_build"}). AddRow(1, 1, "baz", "foo", "bar", "foo/bar", "", "", "", "{}", 0, 0, 0, "public", false, false, false, 1, "yaml", "", "") + _userRows := sqlmock.NewRows( + []string{"id", "name", "token", "hash", "active", "admin"}). + AddRow(1, "foo", "bar", "baz", false, false) + // ensure the mock expects the query _mock.ExpectQuery(`SELECT * FROM "repos" WHERE org = $1 AND name = $2 LIMIT $3`).WithArgs("foo", "bar", 1).WillReturnRows(_rows) + _mock.ExpectQuery(`SELECT * FROM "users" WHERE "users"."id" = $1`).WithArgs(1).WillReturnRows(_userRows) _sqlite := testSqlite(t) defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() @@ -44,12 +58,22 @@ func TestRepo_Engine_GetRepoForOrg(t *testing.T) { t.Errorf("unable to create test repo for sqlite: %v", err) } + err = _sqlite.client.AutoMigrate(&database.User{}) + if err != nil { + t.Errorf("unable to create build table for sqlite: %v", err) + } + + err = _sqlite.client.Table(constants.TableUser).Create(database.UserFromLibrary(_owner)).Error + if err != nil { + t.Errorf("unable to create test user for sqlite: %v", err) + } + // setup tests tests := []struct { failure bool name string database *engine - want *library.Repo + want *api.Repo }{ { failure: false, @@ -82,8 +106,8 @@ func TestRepo_Engine_GetRepoForOrg(t *testing.T) { t.Errorf("GetRepoForOrg for %s returned err: %v", test.name, err) } - if !reflect.DeepEqual(got, test.want) { - t.Errorf("GetRepoForOrg for %s is %v, want %v", test.name, got, test.want) + if diff := cmp.Diff(_repo, got); diff != "" { + t.Errorf("GetRepoForOrg mismatch (-want +got):\n%s", diff) } }) } diff --git a/database/repo/get_test.go b/database/repo/get_test.go index 3957975d2..281d079b5 100644 --- a/database/repo/get_test.go +++ b/database/repo/get_test.go @@ -8,14 +8,15 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/types/constants" + "github.com/go-vela/types/database" ) func TestRepo_Engine_GetRepo(t *testing.T) { // setup types _repo := testRepo() _repo.SetID(1) - _repo.SetUserID(1) _repo.SetHash("baz") _repo.SetOrg("foo") _repo.SetName("bar") @@ -23,7 +24,15 @@ func TestRepo_Engine_GetRepo(t *testing.T) { _repo.SetVisibility("public") _repo.SetPipelineType("yaml") _repo.SetTopics([]string{}) - _repo.SetAllowEvents(library.NewEventsFromMask(1)) + _repo.SetAllowEvents(api.NewEventsFromMask(1)) + + _owner := testOwner() + _owner.SetID(1) + _owner.SetName("foo") + _owner.SetToken("bar") + _owner.SetHash("baz") + + _repo.SetOwner(_owner) _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() @@ -33,8 +42,13 @@ func TestRepo_Engine_GetRepo(t *testing.T) { []string{"id", "user_id", "hash", "org", "name", "full_name", "link", "clone", "branch", "topics", "build_limit", "timeout", "counter", "visibility", "private", "trusted", "active", "allow_events", "pipeline_type", "previous_name", "approve_build"}). AddRow(1, 1, "baz", "foo", "bar", "foo/bar", "", "", "", "{}", 0, 0, 0, "public", false, false, false, 1, "yaml", "", "") + _userRows := sqlmock.NewRows( + []string{"id", "name", "token", "hash", "active", "admin"}). + AddRow(1, "foo", "bar", "baz", false, false) + // ensure the mock expects the query _mock.ExpectQuery(`SELECT * FROM "repos" WHERE id = $1 LIMIT $2`).WithArgs(1, 1).WillReturnRows(_rows) + _mock.ExpectQuery(`SELECT * FROM "users" WHERE "users"."id" = $1`).WithArgs(1).WillReturnRows(_userRows) _sqlite := testSqlite(t) defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() @@ -44,12 +58,22 @@ func TestRepo_Engine_GetRepo(t *testing.T) { t.Errorf("unable to create test repo for sqlite: %v", err) } + err = _sqlite.client.AutoMigrate(&database.User{}) + if err != nil { + t.Errorf("unable to create build table for sqlite: %v", err) + } + + err = _sqlite.client.Table(constants.TableUser).Create(database.UserFromLibrary(_owner)).Error + if err != nil { + t.Errorf("unable to create test user for sqlite: %v", err) + } + // setup tests tests := []struct { failure bool name string database *engine - want *library.Repo + want *api.Repo }{ { failure: false, diff --git a/database/repo/interface.go b/database/repo/interface.go index a69b5fa31..f73a085b4 100644 --- a/database/repo/interface.go +++ b/database/repo/interface.go @@ -5,6 +5,7 @@ package repo import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/library" ) @@ -33,19 +34,19 @@ type RepoInterface interface { // CountReposForUser defines a function that gets the count of repos by user ID. CountReposForUser(context.Context, *library.User, map[string]interface{}) (int64, error) // CreateRepo defines a function that creates a new repo. - CreateRepo(context.Context, *library.Repo) (*library.Repo, error) + CreateRepo(context.Context, *api.Repo) (*api.Repo, error) // DeleteRepo defines a function that deletes an existing repo. - DeleteRepo(context.Context, *library.Repo) error + DeleteRepo(context.Context, *api.Repo) error // GetRepo defines a function that gets a repo by ID. - GetRepo(context.Context, int64) (*library.Repo, error) + GetRepo(context.Context, int64) (*api.Repo, error) // GetRepoForOrg defines a function that gets a repo by org and repo name. - GetRepoForOrg(context.Context, string, string) (*library.Repo, error) + GetRepoForOrg(context.Context, string, string) (*api.Repo, error) // ListRepos defines a function that gets a list of all repos. - ListRepos(context.Context) ([]*library.Repo, error) + ListRepos(context.Context) ([]*api.Repo, error) // ListReposForOrg defines a function that gets a list of repos by org name. - ListReposForOrg(context.Context, string, string, map[string]interface{}, int, int) ([]*library.Repo, int64, error) + ListReposForOrg(context.Context, string, string, map[string]interface{}, int, int) ([]*api.Repo, int64, error) // ListReposForUser defines a function that gets a list of repos by user ID. - ListReposForUser(context.Context, *library.User, string, map[string]interface{}, int, int) ([]*library.Repo, int64, error) + ListReposForUser(context.Context, *library.User, string, map[string]interface{}, int, int) ([]*api.Repo, int64, error) // UpdateRepo defines a function that updates an existing repo. - UpdateRepo(context.Context, *library.Repo) (*library.Repo, error) + UpdateRepo(context.Context, *api.Repo) (*api.Repo, error) } diff --git a/database/repo/list.go b/database/repo/list.go index 790227d63..2197acbb1 100644 --- a/database/repo/list.go +++ b/database/repo/list.go @@ -5,19 +5,18 @@ package repo import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" ) // ListRepos gets a list of all repos from the database. -func (e *engine) ListRepos(ctx context.Context) ([]*library.Repo, error) { +func (e *engine) ListRepos(ctx context.Context) ([]*api.Repo, error) { e.logger.Trace("listing all repos from the database") // variables to store query results and return value count := int64(0) - r := new([]database.Repo) - repos := []*library.Repo{} + r := new([]Repo) + repos := []*api.Repo{} // count the results count, err := e.CountRepos(ctx) @@ -33,6 +32,7 @@ func (e *engine) ListRepos(ctx context.Context) ([]*library.Repo, error) { // send query to the database and store result in variable err = e.client. Table(constants.TableRepo). + Preload("Owner"). Find(&r). Error if err != nil { @@ -45,8 +45,6 @@ func (e *engine) ListRepos(ctx context.Context) ([]*library.Repo, error) { tmp := repo // decrypt the fields for the repo - // - // https://pkg.go.dev/github.com/go-vela/types/database#Repo.Decrypt err = tmp.Decrypt(e.config.EncryptionKey) if err != nil { // TODO: remove backwards compatibility before 1.x.x release @@ -57,10 +55,14 @@ func (e *engine) ListRepos(ctx context.Context) ([]*library.Repo, error) { e.logger.Errorf("unable to decrypt repo %d: %v", tmp.ID.Int64, err) } + // decrypt owner fields + err = tmp.Owner.Decrypt(e.config.EncryptionKey) + if err != nil { + e.logger.Errorf("unable to decrypt repo owner %d: %v", tmp.ID.Int64, err) + } + // convert query result to library type - // - // https://pkg.go.dev/github.com/go-vela/types/database#Repo.ToLibrary - repos = append(repos, tmp.ToLibrary()) + repos = append(repos, tmp.ToAPI()) } return repos, nil diff --git a/database/repo/list_org.go b/database/repo/list_org.go index 95783bd95..646f9b184 100644 --- a/database/repo/list_org.go +++ b/database/repo/list_org.go @@ -5,24 +5,23 @@ package repo import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" "github.com/sirupsen/logrus" ) // ListReposForOrg gets a list of repos by org name from the database. // //nolint:lll // ignore long line length due to variable names -func (e *engine) ListReposForOrg(ctx context.Context, org, sortBy string, filters map[string]interface{}, page, perPage int) ([]*library.Repo, int64, error) { +func (e *engine) ListReposForOrg(ctx context.Context, org, sortBy string, filters map[string]interface{}, page, perPage int) ([]*api.Repo, int64, error) { e.logger.WithFields(logrus.Fields{ "org": org, }).Tracef("listing repos for org %s from the database", org) // variables to store query results and return values count := int64(0) - r := new([]database.Repo) - repos := []*library.Repo{} + r := new([]Repo) + repos := []*api.Repo{} // count the results count, err := e.CountReposForOrg(ctx, org, filters) @@ -49,6 +48,7 @@ func (e *engine) ListReposForOrg(ctx context.Context, org, sortBy string, filter err = e.client. Table(constants.TableRepo). + Preload("Owner"). Select("repos.*"). Joins("LEFT JOIN (?) t on repos.id = t.id", query). Order("latest_build DESC NULLS LAST"). @@ -64,6 +64,7 @@ func (e *engine) ListReposForOrg(ctx context.Context, org, sortBy string, filter default: err = e.client. Table(constants.TableRepo). + Preload("Owner"). Where("org = ?", org). Where(filters). Order("name"). @@ -82,8 +83,6 @@ func (e *engine) ListReposForOrg(ctx context.Context, org, sortBy string, filter tmp := repo // decrypt the fields for the repo - // - // https://pkg.go.dev/github.com/go-vela/types/database#Repo.Decrypt err = tmp.Decrypt(e.config.EncryptionKey) if err != nil { // TODO: remove backwards compatibility before 1.x.x release @@ -94,10 +93,14 @@ func (e *engine) ListReposForOrg(ctx context.Context, org, sortBy string, filter e.logger.Errorf("unable to decrypt repo %d: %v", tmp.ID.Int64, err) } - // convert query result to library type - // - // https://pkg.go.dev/github.com/go-vela/types/database#Repo.ToLibrary - repos = append(repos, tmp.ToLibrary()) + // decrypt owner fields + err = tmp.Owner.Decrypt(e.config.EncryptionKey) + if err != nil { + e.logger.Errorf("unable to decrypt repo owner %d: %v", tmp.ID.Int64, err) + } + + // convert query result to API type + repos = append(repos, tmp.ToAPI()) } return repos, count, nil diff --git a/database/repo/list_org_test.go b/database/repo/list_org_test.go index e59e29d49..8f790d72b 100644 --- a/database/repo/list_org_test.go +++ b/database/repo/list_org_test.go @@ -4,14 +4,15 @@ package repo import ( "context" - "reflect" "testing" "time" "github.com/DATA-DOG/go-sqlmock" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" + "github.com/google/go-cmp/cmp" ) func TestRepo_Engine_ListReposForOrg(t *testing.T) { @@ -30,7 +31,6 @@ func TestRepo_Engine_ListReposForOrg(t *testing.T) { _repoOne := testRepo() _repoOne.SetID(1) - _repoOne.SetUserID(1) _repoOne.SetHash("baz") _repoOne.SetOrg("foo") _repoOne.SetName("bar") @@ -38,11 +38,10 @@ func TestRepo_Engine_ListReposForOrg(t *testing.T) { _repoOne.SetVisibility("public") _repoOne.SetPipelineType("yaml") _repoOne.SetTopics([]string{}) - _repoOne.SetAllowEvents(library.NewEventsFromMask(1)) + _repoOne.SetAllowEvents(api.NewEventsFromMask(1)) _repoTwo := testRepo() _repoTwo.SetID(2) - _repoTwo.SetUserID(1) _repoTwo.SetHash("bar") _repoTwo.SetOrg("foo") _repoTwo.SetName("baz") @@ -50,7 +49,16 @@ func TestRepo_Engine_ListReposForOrg(t *testing.T) { _repoTwo.SetVisibility("public") _repoTwo.SetPipelineType("yaml") _repoTwo.SetTopics([]string{}) - _repoTwo.SetAllowEvents(library.NewEventsFromMask(1)) + _repoTwo.SetAllowEvents(api.NewEventsFromMask(1)) + + _owner := testOwner() + _owner.SetID(1) + _owner.SetName("foo") + _owner.SetToken("bar") + _owner.SetHash("baz") + + _repoOne.SetOwner(_owner) + _repoTwo.SetOwner(_owner) _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() @@ -67,8 +75,13 @@ func TestRepo_Engine_ListReposForOrg(t *testing.T) { AddRow(1, 1, "baz", "foo", "bar", "foo/bar", "", "", "", "{}", 0, 0, "public", false, false, false, 1, "yaml", nil, nil). AddRow(2, 1, "bar", "foo", "baz", "foo/baz", "", "", "", "{}", 0, 0, "public", false, false, false, 1, "yaml", nil, nil) + _userRows := sqlmock.NewRows( + []string{"id", "name", "token", "hash", "active", "admin"}). + AddRow(1, "foo", "bar", "baz", false, false) + // ensure the mock expects the name query _mock.ExpectQuery(`SELECT * FROM "repos" WHERE org = $1 ORDER BY name LIMIT $2`).WithArgs("foo", 10).WillReturnRows(_rows) + _mock.ExpectQuery(`SELECT * FROM "users" WHERE "users"."id" = $1`).WithArgs(1).WillReturnRows(_userRows) // create expected latest count query result in mock _rows = sqlmock.NewRows([]string{"count"}).AddRow(2) @@ -82,8 +95,13 @@ func TestRepo_Engine_ListReposForOrg(t *testing.T) { AddRow(1, 1, "baz", "foo", "bar", "foo/bar", "", "", "", "{}", 0, 0, "public", false, false, false, 1, "yaml", nil, nil). AddRow(2, 1, "bar", "foo", "baz", "foo/baz", "", "", "", "{}", 0, 0, "public", false, false, false, 1, "yaml", nil, nil) + _userRows = sqlmock.NewRows( + []string{"id", "name", "token", "hash", "active", "admin"}). + AddRow(1, "foo", "bar", "baz", false, false) + // ensure the mock expects the latest query _mock.ExpectQuery(`SELECT repos.* FROM "repos" LEFT JOIN (SELECT repos.id, MAX(builds.created) AS latest_build FROM "builds" INNER JOIN repos repos ON builds.repo_id = repos.id WHERE repos.org = $1 GROUP BY "repos"."id") t on repos.id = t.id ORDER BY latest_build DESC NULLS LAST LIMIT $2`).WithArgs("foo", 10).WillReturnRows(_rows) + _mock.ExpectQuery(`SELECT * FROM "users" WHERE "users"."id" = $1`).WithArgs(1).WillReturnRows(_userRows) _sqlite := testSqlite(t) defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() @@ -113,41 +131,51 @@ func TestRepo_Engine_ListReposForOrg(t *testing.T) { t.Errorf("unable to create test build for sqlite: %v", err) } + err = _sqlite.client.AutoMigrate(&database.User{}) + if err != nil { + t.Errorf("unable to create build table for sqlite: %v", err) + } + + err = _sqlite.client.Table(constants.TableUser).Create(database.UserFromLibrary(_owner)).Error + if err != nil { + t.Errorf("unable to create test user for sqlite: %v", err) + } + // setup tests tests := []struct { failure bool name string sort string database *engine - want []*library.Repo + want []*api.Repo }{ { failure: false, name: "postgres with name", database: _postgres, sort: "name", - want: []*library.Repo{_repoOne, _repoTwo}, + want: []*api.Repo{_repoOne, _repoTwo}, }, { failure: false, name: "postgres with latest", database: _postgres, sort: "latest", - want: []*library.Repo{_repoOne, _repoTwo}, + want: []*api.Repo{_repoOne, _repoTwo}, }, { failure: false, name: "sqlite with name", database: _sqlite, sort: "name", - want: []*library.Repo{_repoOne, _repoTwo}, + want: []*api.Repo{_repoOne, _repoTwo}, }, { failure: false, name: "sqlite with latest", database: _sqlite, sort: "latest", - want: []*library.Repo{_repoOne, _repoTwo}, + want: []*api.Repo{_repoOne, _repoTwo}, }, } @@ -170,8 +198,8 @@ func TestRepo_Engine_ListReposForOrg(t *testing.T) { t.Errorf("ListReposForOrg for %s returned err: %v", test.name, err) } - if !reflect.DeepEqual(got, test.want) { - t.Errorf("ListReposForOrg for %s is %v, want %v", test.name, got, test.want) + if diff := cmp.Diff(test.want, got); diff != "" { + t.Errorf("ListReposForOrg for %s mismatch (-want +got):\n%s", test.name, diff) } }) } diff --git a/database/repo/list_test.go b/database/repo/list_test.go index 7b3a5ff5e..8d3dd2c76 100644 --- a/database/repo/list_test.go +++ b/database/repo/list_test.go @@ -8,14 +8,15 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/types/constants" + "github.com/go-vela/types/database" ) func TestRepo_Engine_ListRepos(t *testing.T) { // setup types _repoOne := testRepo() _repoOne.SetID(1) - _repoOne.SetUserID(1) _repoOne.SetHash("baz") _repoOne.SetOrg("foo") _repoOne.SetName("bar") @@ -23,11 +24,10 @@ func TestRepo_Engine_ListRepos(t *testing.T) { _repoOne.SetVisibility("public") _repoOne.SetPipelineType("yaml") _repoOne.SetTopics([]string{}) - _repoOne.SetAllowEvents(library.NewEventsFromMask(1)) + _repoOne.SetAllowEvents(api.NewEventsFromMask(1)) _repoTwo := testRepo() _repoTwo.SetID(2) - _repoTwo.SetUserID(1) _repoTwo.SetHash("baz") _repoTwo.SetOrg("bar") _repoTwo.SetName("foo") @@ -35,7 +35,16 @@ func TestRepo_Engine_ListRepos(t *testing.T) { _repoTwo.SetVisibility("public") _repoTwo.SetPipelineType("yaml") _repoTwo.SetTopics([]string{}) - _repoTwo.SetAllowEvents(library.NewEventsFromMask(1)) + _repoTwo.SetAllowEvents(api.NewEventsFromMask(1)) + + _owner := testOwner() + _owner.SetID(1) + _owner.SetName("foo") + _owner.SetToken("bar") + _owner.SetHash("baz") + + _repoOne.SetOwner(_owner) + _repoTwo.SetOwner(_owner) _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() @@ -52,8 +61,13 @@ func TestRepo_Engine_ListRepos(t *testing.T) { AddRow(1, 1, "baz", "foo", "bar", "foo/bar", "", "", "", "{}", 0, 0, "public", false, false, false, 1, "yaml", nil, nil). AddRow(2, 1, "baz", "bar", "foo", "bar/foo", "", "", "", "{}", 0, 0, "public", false, false, false, 1, "yaml", nil, nil) + _userRows := sqlmock.NewRows( + []string{"id", "name", "token", "hash", "active", "admin"}). + AddRow(1, "foo", "bar", "baz", false, false) + // ensure the mock expects the query _mock.ExpectQuery(`SELECT * FROM "repos"`).WillReturnRows(_rows) + _mock.ExpectQuery(`SELECT * FROM "users" WHERE "users"."id" = $1`).WithArgs(1).WillReturnRows(_userRows) _sqlite := testSqlite(t) defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() @@ -68,24 +82,34 @@ func TestRepo_Engine_ListRepos(t *testing.T) { t.Errorf("unable to create test repo for sqlite: %v", err) } + err = _sqlite.client.AutoMigrate(&database.User{}) + if err != nil { + t.Errorf("unable to create build table for sqlite: %v", err) + } + + err = _sqlite.client.Table(constants.TableUser).Create(database.UserFromLibrary(_owner)).Error + if err != nil { + t.Errorf("unable to create test user for sqlite: %v", err) + } + // setup tests tests := []struct { failure bool name string database *engine - want []*library.Repo + want []*api.Repo }{ { failure: false, name: "postgres", database: _postgres, - want: []*library.Repo{_repoOne, _repoTwo}, + want: []*api.Repo{_repoOne, _repoTwo}, }, { failure: false, name: "sqlite3", database: _sqlite, - want: []*library.Repo{_repoOne, _repoTwo}, + want: []*api.Repo{_repoOne, _repoTwo}, }, } diff --git a/database/repo/list_user.go b/database/repo/list_user.go index bc11fb1b2..76c5d8d7d 100644 --- a/database/repo/list_user.go +++ b/database/repo/list_user.go @@ -5,8 +5,8 @@ package repo import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" "github.com/go-vela/types/library" "github.com/sirupsen/logrus" ) @@ -14,15 +14,15 @@ import ( // ListReposForUser gets a list of repos by user ID from the database. // //nolint:lll // ignore long line length due to variable names -func (e *engine) ListReposForUser(ctx context.Context, u *library.User, sortBy string, filters map[string]interface{}, page, perPage int) ([]*library.Repo, int64, error) { +func (e *engine) ListReposForUser(ctx context.Context, u *library.User, sortBy string, filters map[string]interface{}, page, perPage int) ([]*api.Repo, int64, error) { e.logger.WithFields(logrus.Fields{ "user": u.GetName(), }).Tracef("listing repos for user %s from the database", u.GetName()) // variables to store query results and return values count := int64(0) - r := new([]database.Repo) - repos := []*library.Repo{} + r := new([]Repo) + repos := []*api.Repo{} // count the results count, err := e.CountReposForUser(ctx, u, filters) @@ -49,6 +49,7 @@ func (e *engine) ListReposForUser(ctx context.Context, u *library.User, sortBy s err = e.client. Table(constants.TableRepo). + Preload("Owner"). Select("repos.*"). Joins("LEFT JOIN (?) t on repos.id = t.id", query). Order("latest_build DESC NULLS LAST"). @@ -64,6 +65,7 @@ func (e *engine) ListReposForUser(ctx context.Context, u *library.User, sortBy s default: err = e.client. Table(constants.TableRepo). + Preload("Owner"). Where("user_id = ?", u.GetID()). Where(filters). Order("name"). @@ -82,8 +84,6 @@ func (e *engine) ListReposForUser(ctx context.Context, u *library.User, sortBy s tmp := repo // decrypt the fields for the repo - // - // https://pkg.go.dev/github.com/go-vela/types/database#Repo.Decrypt err = tmp.Decrypt(e.config.EncryptionKey) if err != nil { // TODO: remove backwards compatibility before 1.x.x release @@ -94,10 +94,14 @@ func (e *engine) ListReposForUser(ctx context.Context, u *library.User, sortBy s e.logger.Errorf("unable to decrypt repo %d: %v", tmp.ID.Int64, err) } + // decrypt owner fields + err = tmp.Owner.Decrypt(e.config.EncryptionKey) + if err != nil { + e.logger.Errorf("unable to decrypt repo owner %d: %v", tmp.ID.Int64, err) + } + // convert query result to library type - // - // https://pkg.go.dev/github.com/go-vela/types/database#Repo.ToLibrary - repos = append(repos, tmp.ToLibrary()) + repos = append(repos, tmp.ToAPI()) } return repos, count, nil diff --git a/database/repo/list_user_test.go b/database/repo/list_user_test.go index 30f6bc3b1..4ac0112c0 100644 --- a/database/repo/list_user_test.go +++ b/database/repo/list_user_test.go @@ -9,6 +9,7 @@ import ( "time" "github.com/DATA-DOG/go-sqlmock" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" @@ -30,7 +31,7 @@ func TestRepo_Engine_ListReposForUser(t *testing.T) { _repoOne := testRepo() _repoOne.SetID(1) - _repoOne.SetUserID(1) + _repoOne.GetOwner().SetID(1) _repoOne.SetHash("baz") _repoOne.SetOrg("foo") _repoOne.SetName("bar") @@ -38,11 +39,11 @@ func TestRepo_Engine_ListReposForUser(t *testing.T) { _repoOne.SetVisibility("public") _repoOne.SetPipelineType("yaml") _repoOne.SetTopics([]string{}) - _repoOne.SetAllowEvents(library.NewEventsFromMask(1)) + _repoOne.SetAllowEvents(api.NewEventsFromMask(1)) _repoTwo := testRepo() _repoTwo.SetID(2) - _repoTwo.SetUserID(1) + _repoTwo.GetOwner().SetID(1) _repoTwo.SetHash("baz") _repoTwo.SetOrg("bar") _repoTwo.SetName("foo") @@ -50,12 +51,16 @@ func TestRepo_Engine_ListReposForUser(t *testing.T) { _repoTwo.SetVisibility("public") _repoTwo.SetPipelineType("yaml") _repoTwo.SetTopics([]string{}) - _repoTwo.SetAllowEvents(library.NewEventsFromMask(1)) + _repoTwo.SetAllowEvents(api.NewEventsFromMask(1)) - _user := new(library.User) - _user.SetID(1) - _user.SetName("foo") - _user.SetToken("bar") + _owner := testOwner() + _owner.SetID(1) + _owner.SetName("foo") + _owner.SetToken("bar") + _owner.SetHash("baz") + + _repoOne.SetOwner(_owner) + _repoTwo.SetOwner(_owner) _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() @@ -72,8 +77,13 @@ func TestRepo_Engine_ListReposForUser(t *testing.T) { AddRow(1, 1, "baz", "foo", "bar", "foo/bar", "", "", "", "{}", 0, 0, "public", false, false, false, 1, "yaml", nil, nil). AddRow(2, 1, "baz", "bar", "foo", "bar/foo", "", "", "", "{}", 0, 0, "public", false, false, false, 1, "yaml", nil, nil) + _userRows := sqlmock.NewRows( + []string{"id", "name", "token", "hash", "active", "admin"}). + AddRow(1, "foo", "bar", "baz", false, false) + // ensure the mock expects the name query _mock.ExpectQuery(`SELECT * FROM "repos" WHERE user_id = $1 ORDER BY name LIMIT $2`).WithArgs(1, 10).WillReturnRows(_rows) + _mock.ExpectQuery(`SELECT * FROM "users" WHERE "users"."id" = $1`).WithArgs(1).WillReturnRows(_userRows) // create expected latest count query result in mock _rows = sqlmock.NewRows([]string{"count"}).AddRow(2) @@ -87,8 +97,13 @@ func TestRepo_Engine_ListReposForUser(t *testing.T) { AddRow(1, 1, "baz", "foo", "bar", "foo/bar", "", "", "", "{}", 0, 0, "public", false, false, false, 1, "yaml", nil, nil). AddRow(2, 1, "baz", "bar", "foo", "bar/foo", "", "", "", "{}", 0, 0, "public", false, false, false, 1, "yaml", nil, nil) + _userRows = sqlmock.NewRows( + []string{"id", "name", "token", "hash", "active", "admin"}). + AddRow(1, "foo", "bar", "baz", false, false) + // ensure the mock expects the latest query _mock.ExpectQuery(`SELECT repos.* FROM "repos" LEFT JOIN (SELECT repos.id, MAX(builds.created) AS latest_build FROM "builds" INNER JOIN repos repos ON builds.repo_id = repos.id WHERE repos.user_id = $1 GROUP BY "repos"."id") t on repos.id = t.id ORDER BY latest_build DESC NULLS LAST LIMIT $2`).WithArgs(1, 10).WillReturnRows(_rows) + _mock.ExpectQuery(`SELECT * FROM "users" WHERE "users"."id" = $1`).WithArgs(1).WillReturnRows(_userRows) _sqlite := testSqlite(t) defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() @@ -118,41 +133,51 @@ func TestRepo_Engine_ListReposForUser(t *testing.T) { t.Errorf("unable to create test build for sqlite: %v", err) } + err = _sqlite.client.AutoMigrate(&database.User{}) + if err != nil { + t.Errorf("unable to create build table for sqlite: %v", err) + } + + err = _sqlite.client.Table(constants.TableUser).Create(database.UserFromLibrary(_owner)).Error + if err != nil { + t.Errorf("unable to create test user for sqlite: %v", err) + } + // setup tests tests := []struct { failure bool name string sort string database *engine - want []*library.Repo + want []*api.Repo }{ { failure: false, name: "postgres with name", database: _postgres, sort: "name", - want: []*library.Repo{_repoOne, _repoTwo}, + want: []*api.Repo{_repoOne, _repoTwo}, }, { failure: false, name: "postgres with latest", database: _postgres, sort: "latest", - want: []*library.Repo{_repoOne, _repoTwo}, + want: []*api.Repo{_repoOne, _repoTwo}, }, { failure: false, name: "sqlite with name", database: _sqlite, sort: "name", - want: []*library.Repo{_repoOne, _repoTwo}, + want: []*api.Repo{_repoOne, _repoTwo}, }, { failure: false, name: "sqlite with latest", database: _sqlite, sort: "latest", - want: []*library.Repo{_repoOne, _repoTwo}, + want: []*api.Repo{_repoOne, _repoTwo}, }, } @@ -161,7 +186,7 @@ func TestRepo_Engine_ListReposForUser(t *testing.T) { // run tests for _, test := range tests { t.Run(test.name, func(t *testing.T) { - got, _, err := test.database.ListReposForUser(context.TODO(), _user, test.sort, filters, 1, 10) + got, _, err := test.database.ListReposForUser(context.TODO(), _owner, test.sort, filters, 1, 10) if test.failure { if err == nil { diff --git a/database/repo/repo.go b/database/repo/repo.go index 5e4300e19..40a755723 100644 --- a/database/repo/repo.go +++ b/database/repo/repo.go @@ -4,14 +4,51 @@ package repo import ( "context" + "database/sql" + "encoding/base64" + "errors" "fmt" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/util" "github.com/go-vela/types/constants" + "github.com/go-vela/types/database" + "github.com/lib/pq" "github.com/sirupsen/logrus" "gorm.io/gorm" ) +var ( + // ErrEmptyRepoFullName defines the error type when a + // Repo type has an empty FullName field provided. + ErrEmptyRepoFullName = errors.New("empty repo full_name provided") + + // ErrEmptyRepoHash defines the error type when a + // Repo type has an empty Hash field provided. + ErrEmptyRepoHash = errors.New("empty repo hash provided") + + // ErrEmptyRepoName defines the error type when a + // Repo type has an empty Name field provided. + ErrEmptyRepoName = errors.New("empty repo name provided") + + // ErrEmptyRepoOrg defines the error type when a + // Repo type has an empty Org field provided. + ErrEmptyRepoOrg = errors.New("empty repo org provided") + + // ErrEmptyRepoUserID defines the error type when a + // Repo type has an empty UserID field provided. + ErrEmptyRepoUserID = errors.New("empty repo user_id provided") + + // ErrEmptyRepoVisibility defines the error type when a + // Repo type has an empty Visibility field provided. + ErrEmptyRepoVisibility = errors.New("empty repo visibility provided") + + // ErrExceededTopicsLimit defines the error type when a + // Repo type has Topics field provided that exceeds the database limit. + ErrExceededTopicsLimit = errors.New("exceeded topics limit") +) + type ( // config represents the settings required to create the engine that implements the RepoInterface interface. config struct { @@ -38,6 +75,33 @@ type ( // https://pkg.go.dev/github.com/sirupsen/logrus#Entry logger *logrus.Entry } + + // Repo is the database representation of a repo. + Repo struct { + ID sql.NullInt64 `sql:"id"` + UserID sql.NullInt64 `sql:"user_id"` + Hash sql.NullString `sql:"hash"` + Org sql.NullString `sql:"org"` + Name sql.NullString `sql:"name"` + FullName sql.NullString `sql:"full_name"` + Link sql.NullString `sql:"link"` + Clone sql.NullString `sql:"clone"` + Branch sql.NullString `sql:"branch"` + Topics pq.StringArray `sql:"topics" gorm:"type:varchar(1020)"` + BuildLimit sql.NullInt64 `sql:"build_limit"` + Timeout sql.NullInt64 `sql:"timeout"` + Counter sql.NullInt32 `sql:"counter"` + Visibility sql.NullString `sql:"visibility"` + Private sql.NullBool `sql:"private"` + Trusted sql.NullBool `sql:"trusted"` + Active sql.NullBool `sql:"active"` + AllowEvents sql.NullInt64 `sql:"allow_events"` + PipelineType sql.NullString `sql:"pipeline_type"` + PreviousName sql.NullString `sql:"previous_name"` + ApproveBuild sql.NullString `sql:"approve_build"` + + Owner database.User `gorm:"foreignKey:UserID"` + } ) // New creates and returns a Vela service for integrating with repos in the database. @@ -81,3 +145,267 @@ func New(opts ...EngineOpt) (*engine, error) { return e, nil } + +// Decrypt will manipulate the existing repo hash by +// base64 decoding that value. Then, a AES-256 cipher +// block is created from the encryption key in order to +// decrypt the base64 decoded secret value. +func (r *Repo) Decrypt(key string) error { + // base64 decode the encrypted repo hash + decoded, err := base64.StdEncoding.DecodeString(r.Hash.String) + if err != nil { + return err + } + + // decrypt the base64 decoded repo hash + decrypted, err := util.Decrypt(key, decoded) + if err != nil { + return err + } + + // set the decrypted repo hash + r.Hash = sql.NullString{ + String: string(decrypted), + Valid: true, + } + + return nil +} + +// Encrypt will manipulate the existing repo hash by +// creating a AES-256 cipher block from the encryption +// key in order to encrypt the repo hash. Then, the +// repo hash is base64 encoded for transport across +// network boundaries. +func (r *Repo) Encrypt(key string) error { + // encrypt the repo hash + encrypted, err := util.Encrypt(key, []byte(r.Hash.String)) + if err != nil { + return err + } + + // base64 encode the encrypted repo hash to make it network safe + r.Hash = sql.NullString{ + String: base64.StdEncoding.EncodeToString(encrypted), + Valid: true, + } + + return nil +} + +// Nullify ensures the valid flag for +// the sql.Null types are properly set. +// +// When a field within the Repo type is the zero +// value for the field, the valid flag is set to +// false causing it to be NULL in the database. +func (r *Repo) Nullify() *Repo { + if r == nil { + return nil + } + + // check if the ID field should be false + if r.ID.Int64 == 0 { + r.ID.Valid = false + } + + // check if the UserID field should be false + if r.UserID.Int64 == 0 { + r.UserID.Valid = false + } + + // check if the Hash field should be false + if len(r.Hash.String) == 0 { + r.Hash.Valid = false + } + + // check if the Org field should be false + if len(r.Org.String) == 0 { + r.Org.Valid = false + } + + // check if the Name field should be false + if len(r.Name.String) == 0 { + r.Name.Valid = false + } + + // check if the FullName field should be false + if len(r.FullName.String) == 0 { + r.FullName.Valid = false + } + + // check if the Link field should be false + if len(r.Link.String) == 0 { + r.Link.Valid = false + } + + // check if the Clone field should be false + if len(r.Clone.String) == 0 { + r.Clone.Valid = false + } + + // check if the Branch field should be false + if len(r.Branch.String) == 0 { + r.Branch.Valid = false + } + + // check if the BuildLimit field should be false + if r.BuildLimit.Int64 == 0 { + r.BuildLimit.Valid = false + } + + // check if the Timeout field should be false + if r.Timeout.Int64 == 0 { + r.Timeout.Valid = false + } + + // check if the AllowEvents field should be false + if r.AllowEvents.Int64 == 0 { + r.AllowEvents.Valid = false + } + + // check if the Visibility field should be false + if len(r.Visibility.String) == 0 { + r.Visibility.Valid = false + } + + // check if the PipelineType field should be false + if len(r.PipelineType.String) == 0 { + r.PipelineType.Valid = false + } + + // check if the PreviousName field should be false + if len(r.PreviousName.String) == 0 { + r.PreviousName.Valid = false + } + + // check if the ApproveForkBuild field should be false + if len(r.ApproveBuild.String) == 0 { + r.ApproveBuild.Valid = false + } + + return r +} + +// ToAPI converts the Repo type +// to an API Repo type. +func (r *Repo) ToAPI() *api.Repo { + repo := new(api.Repo) + + repo.SetID(r.ID.Int64) + repo.SetOwner(r.Owner.ToLibrary()) + repo.SetHash(r.Hash.String) + repo.SetOrg(r.Org.String) + repo.SetName(r.Name.String) + repo.SetFullName(r.FullName.String) + repo.SetLink(r.Link.String) + repo.SetClone(r.Clone.String) + repo.SetBranch(r.Branch.String) + repo.SetTopics(r.Topics) + repo.SetBuildLimit(r.BuildLimit.Int64) + repo.SetTimeout(r.Timeout.Int64) + repo.SetCounter(int(r.Counter.Int32)) + repo.SetVisibility(r.Visibility.String) + repo.SetPrivate(r.Private.Bool) + repo.SetTrusted(r.Trusted.Bool) + repo.SetActive(r.Active.Bool) + repo.SetAllowEvents(api.NewEventsFromMask(r.AllowEvents.Int64)) + repo.SetPipelineType(r.PipelineType.String) + repo.SetPreviousName(r.PreviousName.String) + repo.SetApproveBuild(r.ApproveBuild.String) + + return repo +} + +// Validate verifies the necessary fields for +// the Repo type are populated correctly. +func (r *Repo) Validate() error { + // verify the UserID field is populated + if r.UserID.Int64 <= 0 { + return ErrEmptyRepoUserID + } + + // verify the Hash field is populated + if len(r.Hash.String) == 0 { + return ErrEmptyRepoHash + } + + // verify the Org field is populated + if len(r.Org.String) == 0 { + return ErrEmptyRepoOrg + } + + // verify the Name field is populated + if len(r.Name.String) == 0 { + return ErrEmptyRepoName + } + + // verify the FullName field is populated + if len(r.FullName.String) == 0 { + return ErrEmptyRepoFullName + } + + // verify the Visibility field is populated + if len(r.Visibility.String) == 0 { + return ErrEmptyRepoVisibility + } + + // calculate total size of favorites while sanitizing entries + total := 0 + + for i, t := range r.Topics { + r.Topics[i] = util.Sanitize(t) + total += len(t) + } + + // verify the Favorites field is within the database constraints + // len is to factor in number of comma separators included in the database field, + // removing 1 due to the last item not having an appended comma + if (total + len(r.Topics) - 1) > constants.TopicsMaxSize { + return ErrExceededTopicsLimit + } + + // ensure that all Repo string fields + // that can be returned as JSON are sanitized + // to avoid unsafe HTML content + r.Org = sql.NullString{String: util.Sanitize(r.Org.String), Valid: r.Org.Valid} + r.Name = sql.NullString{String: util.Sanitize(r.Name.String), Valid: r.Name.Valid} + r.FullName = sql.NullString{String: util.Sanitize(r.FullName.String), Valid: r.FullName.Valid} + r.Link = sql.NullString{String: util.Sanitize(r.Link.String), Valid: r.Link.Valid} + r.Clone = sql.NullString{String: util.Sanitize(r.Clone.String), Valid: r.Clone.Valid} + r.Branch = sql.NullString{String: util.Sanitize(r.Branch.String), Valid: r.Branch.Valid} + r.Visibility = sql.NullString{String: util.Sanitize(r.Visibility.String), Valid: r.Visibility.Valid} + r.PipelineType = sql.NullString{String: util.Sanitize(r.PipelineType.String), Valid: r.PipelineType.Valid} + + return nil +} + +// FromAPI converts the API Repo type +// to a database repo type. +func FromAPI(r *api.Repo) *Repo { + repo := &Repo{ + ID: sql.NullInt64{Int64: r.GetID(), Valid: true}, + UserID: sql.NullInt64{Int64: r.GetOwner().GetID(), Valid: true}, + Hash: sql.NullString{String: r.GetHash(), Valid: true}, + Org: sql.NullString{String: r.GetOrg(), Valid: true}, + Name: sql.NullString{String: r.GetName(), Valid: true}, + FullName: sql.NullString{String: r.GetFullName(), Valid: true}, + Link: sql.NullString{String: r.GetLink(), Valid: true}, + Clone: sql.NullString{String: r.GetClone(), Valid: true}, + Branch: sql.NullString{String: r.GetBranch(), Valid: true}, + Topics: pq.StringArray(r.GetTopics()), + BuildLimit: sql.NullInt64{Int64: r.GetBuildLimit(), Valid: true}, + Timeout: sql.NullInt64{Int64: r.GetTimeout(), Valid: true}, + Counter: sql.NullInt32{Int32: int32(r.GetCounter()), Valid: true}, + Visibility: sql.NullString{String: r.GetVisibility(), Valid: true}, + Private: sql.NullBool{Bool: r.GetPrivate(), Valid: true}, + Trusted: sql.NullBool{Bool: r.GetTrusted(), Valid: true}, + Active: sql.NullBool{Bool: r.GetActive(), Valid: true}, + AllowEvents: sql.NullInt64{Int64: r.GetAllowEvents().ToDatabase(), Valid: true}, + PipelineType: sql.NullString{String: r.GetPipelineType(), Valid: true}, + PreviousName: sql.NullString{String: r.GetPreviousName(), Valid: true}, + ApproveBuild: sql.NullString{String: r.GetApproveBuild(), Valid: true}, + } + + return repo.Nullify() +} diff --git a/database/repo/repo_test.go b/database/repo/repo_test.go index 7abb255d6..e617e4feb 100644 --- a/database/repo/repo_test.go +++ b/database/repo/repo_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/library" "github.com/go-vela/types/library/actions" "github.com/sirupsen/logrus" @@ -171,12 +172,12 @@ func testSqlite(t *testing.T) *engine { return _engine } -// testRepo is a test helper function to create a library +// testRepo is a test helper function to create an API // Repo type with all fields set to their zero values. -func testRepo() *library.Repo { - return &library.Repo{ +func testRepo() *api.Repo { + return &api.Repo{ ID: new(int64), - UserID: new(int64), + Owner: testOwner(), BuildLimit: new(int64), Timeout: new(int64), Counter: new(int), @@ -198,8 +199,8 @@ func testRepo() *library.Repo { } } -func testEvents() *library.Events { - return &library.Events{ +func testEvents() *api.Events { + return &api.Events{ Push: &actions.Push{ Branch: new(bool), Tag: new(bool), @@ -227,6 +228,19 @@ func testEvents() *library.Events { } } +func testOwner() *library.User { + return &library.User{ + ID: new(int64), + Name: new(string), + RefreshToken: new(string), + Token: new(string), + Hash: new(string), + Favorites: new([]string), + Active: new(bool), + Admin: new(bool), + } +} + // This will be used with the github.com/DATA-DOG/go-sqlmock library to compare values // that are otherwise not easily compared. These typically would be values generated // before adding or updating them in the database. diff --git a/database/repo/update.go b/database/repo/update.go index 0c3273ce2..14ff985f7 100644 --- a/database/repo/update.go +++ b/database/repo/update.go @@ -7,35 +7,28 @@ import ( "context" "fmt" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" "github.com/sirupsen/logrus" ) // UpdateRepo updates an existing repo in the database. -func (e *engine) UpdateRepo(ctx context.Context, r *library.Repo) (*library.Repo, error) { +func (e *engine) UpdateRepo(ctx context.Context, r *api.Repo) (*api.Repo, error) { e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), }).Tracef("creating repo %s in the database", r.GetFullName()) // cast the library type to database type - // - // https://pkg.go.dev/github.com/go-vela/types/database#RepoFromLibrary - repo := database.RepoFromLibrary(r) + repo := FromAPI(r) // validate the necessary fields are populated - // - // https://pkg.go.dev/github.com/go-vela/types/database#Repo.Validate err := repo.Validate() if err != nil { return nil, err } // encrypt the fields for the repo - // - // https://pkg.go.dev/github.com/go-vela/types/database#Repo.Encrypt err = repo.Encrypt(e.config.EncryptionKey) if err != nil { return nil, fmt.Errorf("unable to encrypt repo %s: %w", r.GetFullName(), err) @@ -53,8 +46,12 @@ func (e *engine) UpdateRepo(ctx context.Context, r *library.Repo) (*library.Repo // only log to preserve backwards compatibility e.logger.Errorf("unable to decrypt repo %d: %v", r.GetID(), err) - return repo.ToLibrary(), nil + return repo.ToAPI(), nil } - return repo.ToLibrary(), nil + // set owner to provided owner if creation successful + result := repo.ToAPI() + result.SetOwner(r.GetOwner()) + + return result, nil } diff --git a/database/repo/update_test.go b/database/repo/update_test.go index c7bca1d15..e36a44ad2 100644 --- a/database/repo/update_test.go +++ b/database/repo/update_test.go @@ -8,15 +8,15 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" ) func TestRepo_Engine_UpdateRepo(t *testing.T) { // setup types _repo := testRepo() _repo.SetID(1) - _repo.SetUserID(1) + _repo.GetOwner().SetID(1) _repo.SetHash("baz") _repo.SetOrg("foo") _repo.SetName("bar") @@ -26,7 +26,7 @@ func TestRepo_Engine_UpdateRepo(t *testing.T) { _repo.SetPreviousName("oldName") _repo.SetApproveBuild(constants.ApproveForkAlways) _repo.SetTopics([]string{}) - _repo.SetAllowEvents(library.NewEventsFromMask(1)) + _repo.SetAllowEvents(api.NewEventsFromMask(1)) _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() diff --git a/database/schedule/count_repo.go b/database/schedule/count_repo.go index 471537d8f..e876dda57 100644 --- a/database/schedule/count_repo.go +++ b/database/schedule/count_repo.go @@ -4,13 +4,14 @@ package schedule import ( "context" + + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" "github.com/sirupsen/logrus" ) // CountSchedulesForRepo gets the count of schedules by repo ID from the database. -func (e *engine) CountSchedulesForRepo(ctx context.Context, r *library.Repo) (int64, error) { +func (e *engine) CountSchedulesForRepo(ctx context.Context, r *api.Repo) (int64, error) { e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), diff --git a/database/schedule/get_repo.go b/database/schedule/get_repo.go index 6ee2e6bb7..3d8efbf0d 100644 --- a/database/schedule/get_repo.go +++ b/database/schedule/get_repo.go @@ -4,6 +4,8 @@ package schedule import ( "context" + + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" @@ -11,7 +13,7 @@ import ( ) // GetScheduleForRepo gets a schedule by repo ID and name from the database. -func (e *engine) GetScheduleForRepo(ctx context.Context, r *library.Repo, name string) (*library.Schedule, error) { +func (e *engine) GetScheduleForRepo(ctx context.Context, r *api.Repo, name string) (*library.Schedule, error) { e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), diff --git a/database/schedule/interface.go b/database/schedule/interface.go index 8d80a7c36..b25b3c363 100644 --- a/database/schedule/interface.go +++ b/database/schedule/interface.go @@ -5,6 +5,7 @@ package schedule import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/library" ) @@ -29,7 +30,7 @@ type ScheduleInterface interface { // CountSchedules defines a function that gets the count of all schedules. CountSchedules(context.Context) (int64, error) // CountSchedulesForRepo defines a function that gets the count of schedules by repo ID. - CountSchedulesForRepo(context.Context, *library.Repo) (int64, error) + CountSchedulesForRepo(context.Context, *api.Repo) (int64, error) // CreateSchedule defines a function that creates a new schedule. CreateSchedule(context.Context, *library.Schedule) (*library.Schedule, error) // DeleteSchedule defines a function that deletes an existing schedule. @@ -37,13 +38,13 @@ type ScheduleInterface interface { // GetSchedule defines a function that gets a schedule by ID. GetSchedule(context.Context, int64) (*library.Schedule, error) // GetScheduleForRepo defines a function that gets a schedule by repo ID and name. - GetScheduleForRepo(context.Context, *library.Repo, string) (*library.Schedule, error) + GetScheduleForRepo(context.Context, *api.Repo, string) (*library.Schedule, error) // ListActiveSchedules defines a function that gets a list of all active schedules. ListActiveSchedules(context.Context) ([]*library.Schedule, error) // ListSchedules defines a function that gets a list of all schedules. ListSchedules(context.Context) ([]*library.Schedule, error) // ListSchedulesForRepo defines a function that gets a list of schedules by repo ID. - ListSchedulesForRepo(context.Context, *library.Repo, int, int) ([]*library.Schedule, int64, error) + ListSchedulesForRepo(context.Context, *api.Repo, int, int) ([]*library.Schedule, int64, error) // UpdateSchedule defines a function that updates an existing schedule. UpdateSchedule(context.Context, *library.Schedule, bool) (*library.Schedule, error) } diff --git a/database/schedule/list_repo.go b/database/schedule/list_repo.go index c5d7866ca..6c4435a03 100644 --- a/database/schedule/list_repo.go +++ b/database/schedule/list_repo.go @@ -4,6 +4,8 @@ package schedule import ( "context" + + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" @@ -11,7 +13,7 @@ import ( ) // ListSchedulesForRepo gets a list of schedules by repo ID from the database. -func (e *engine) ListSchedulesForRepo(ctx context.Context, r *library.Repo, page, perPage int) ([]*library.Schedule, int64, error) { +func (e *engine) ListSchedulesForRepo(ctx context.Context, r *api.Repo, page, perPage int) ([]*library.Schedule, int64, error) { e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), diff --git a/database/schedule/schedule_test.go b/database/schedule/schedule_test.go index 723c40aaa..45663008b 100644 --- a/database/schedule/schedule_test.go +++ b/database/schedule/schedule_test.go @@ -10,6 +10,7 @@ import ( "time" "github.com/DATA-DOG/go-sqlmock" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/library" "github.com/sirupsen/logrus" @@ -190,10 +191,9 @@ func testSchedule() *library.Schedule { } // testRepo is a test helper function to create a library Repo type with all fields set to their zero values. -func testRepo() *library.Repo { - return &library.Repo{ +func testRepo() *api.Repo { + return &api.Repo{ ID: new(int64), - UserID: new(int64), BuildLimit: new(int64), Timeout: new(int64), Counter: new(int), diff --git a/database/secret/count_repo.go b/database/secret/count_repo.go index 8fd9b0090..c248e5ee5 100644 --- a/database/secret/count_repo.go +++ b/database/secret/count_repo.go @@ -5,13 +5,13 @@ package secret import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" "github.com/sirupsen/logrus" ) // CountSecretsForRepo gets the count of secrets by org and repo name from the database. -func (e *engine) CountSecretsForRepo(ctx context.Context, r *library.Repo, filters map[string]interface{}) (int64, error) { +func (e *engine) CountSecretsForRepo(ctx context.Context, r *api.Repo, filters map[string]interface{}) (int64, error) { e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), diff --git a/database/secret/count_repo_test.go b/database/secret/count_repo_test.go index 3e688b0c2..fd5afacb4 100644 --- a/database/secret/count_repo_test.go +++ b/database/secret/count_repo_test.go @@ -16,7 +16,7 @@ func TestSecret_Engine_CountSecretsForRepo(t *testing.T) { // setup types _repo := testRepo() _repo.SetID(1) - _repo.SetUserID(1) + _repo.GetOwner().SetID(1) _repo.SetHash("baz") _repo.SetOrg("foo") _repo.SetName("bar") diff --git a/database/secret/count_team_test.go b/database/secret/count_team_test.go index 9800b34fd..07db848e9 100644 --- a/database/secret/count_team_test.go +++ b/database/secret/count_team_test.go @@ -112,7 +112,7 @@ func TestSecret_Engine_CountSecretsForTeams(t *testing.T) { // setup types _repo := testRepo() _repo.SetID(1) - _repo.SetUserID(1) + _repo.GetOwner().SetID(1) _repo.SetHash("baz") _repo.SetOrg("foo") _repo.SetName("bar") diff --git a/database/secret/get_repo.go b/database/secret/get_repo.go index b33b0d58d..d1ae48e7f 100644 --- a/database/secret/get_repo.go +++ b/database/secret/get_repo.go @@ -5,6 +5,7 @@ package secret import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" @@ -12,7 +13,7 @@ import ( ) // GetSecretForRepo gets a secret by org and repo name from the database. -func (e *engine) GetSecretForRepo(ctx context.Context, name string, r *library.Repo) (*library.Secret, error) { +func (e *engine) GetSecretForRepo(ctx context.Context, name string, r *api.Repo) (*library.Secret, error) { e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), diff --git a/database/secret/get_repo_test.go b/database/secret/get_repo_test.go index d32f81cc0..fb1c1ca9b 100644 --- a/database/secret/get_repo_test.go +++ b/database/secret/get_repo_test.go @@ -16,7 +16,7 @@ func TestSecret_Engine_GetSecretForRepo(t *testing.T) { // setup types _repo := testRepo() _repo.SetID(1) - _repo.SetUserID(1) + _repo.GetOwner().SetID(1) _repo.SetHash("baz") _repo.SetOrg("foo") _repo.SetName("bar") diff --git a/database/secret/interface.go b/database/secret/interface.go index e431fd458..b5aa4f73e 100644 --- a/database/secret/interface.go +++ b/database/secret/interface.go @@ -5,6 +5,7 @@ package secret import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/library" ) @@ -31,7 +32,7 @@ type SecretInterface interface { // CountSecretsForOrg defines a function that gets the count of secrets by org name. CountSecretsForOrg(context.Context, string, map[string]interface{}) (int64, error) // CountSecretsForRepo defines a function that gets the count of secrets by org and repo name. - CountSecretsForRepo(context.Context, *library.Repo, map[string]interface{}) (int64, error) + CountSecretsForRepo(context.Context, *api.Repo, map[string]interface{}) (int64, error) // CountSecretsForTeam defines a function that gets the count of secrets by org and team name. CountSecretsForTeam(context.Context, string, string, map[string]interface{}) (int64, error) // CountSecretsForTeams defines a function that gets the count of secrets by teams within an org. @@ -45,7 +46,7 @@ type SecretInterface interface { // GetSecretForOrg defines a function that gets a secret by org name. GetSecretForOrg(context.Context, string, string) (*library.Secret, error) // GetSecretForRepo defines a function that gets a secret by org and repo name. - GetSecretForRepo(context.Context, string, *library.Repo) (*library.Secret, error) + GetSecretForRepo(context.Context, string, *api.Repo) (*library.Secret, error) // GetSecretForTeam defines a function that gets a secret by org and team name. GetSecretForTeam(context.Context, string, string, string) (*library.Secret, error) // ListSecrets defines a function that gets a list of all secrets. @@ -53,7 +54,7 @@ type SecretInterface interface { // ListSecretsForOrg defines a function that gets a list of secrets by org name. ListSecretsForOrg(context.Context, string, map[string]interface{}, int, int) ([]*library.Secret, int64, error) // ListSecretsForRepo defines a function that gets a list of secrets by org and repo name. - ListSecretsForRepo(context.Context, *library.Repo, map[string]interface{}, int, int) ([]*library.Secret, int64, error) + ListSecretsForRepo(context.Context, *api.Repo, map[string]interface{}, int, int) ([]*library.Secret, int64, error) // ListSecretsForTeam defines a function that gets a list of secrets by org and team name. ListSecretsForTeam(context.Context, string, string, map[string]interface{}, int, int) ([]*library.Secret, int64, error) // ListSecretsForTeams defines a function that gets a list of secrets by teams within an org. diff --git a/database/secret/list_repo.go b/database/secret/list_repo.go index 213ee9353..a2731e321 100644 --- a/database/secret/list_repo.go +++ b/database/secret/list_repo.go @@ -5,6 +5,7 @@ package secret import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" @@ -14,7 +15,7 @@ import ( // ListSecretsForRepo gets a list of secrets by org name from the database. // //nolint:lll // ignore long line length due to variable names -func (e *engine) ListSecretsForRepo(ctx context.Context, r *library.Repo, filters map[string]interface{}, page, perPage int) ([]*library.Secret, int64, error) { +func (e *engine) ListSecretsForRepo(ctx context.Context, r *api.Repo, filters map[string]interface{}, page, perPage int) ([]*library.Secret, int64, error) { e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), diff --git a/database/secret/list_repo_test.go b/database/secret/list_repo_test.go index 9fc76e7bf..304520c3e 100644 --- a/database/secret/list_repo_test.go +++ b/database/secret/list_repo_test.go @@ -17,7 +17,7 @@ func TestSecret_Engine_ListSecretsForRepo(t *testing.T) { // setup types _repo := testRepo() _repo.SetID(1) - _repo.SetUserID(1) + _repo.GetOwner().SetID(1) _repo.SetHash("baz") _repo.SetOrg("foo") _repo.SetName("bar") diff --git a/database/secret/secret_test.go b/database/secret/secret_test.go index 5382c054b..cbbefd9e2 100644 --- a/database/secret/secret_test.go +++ b/database/secret/secret_test.go @@ -9,6 +9,7 @@ import ( "time" "github.com/DATA-DOG/go-sqlmock" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/library" "github.com/go-vela/types/library/actions" "github.com/sirupsen/logrus" @@ -178,10 +179,9 @@ func testSqlite(t *testing.T) *engine { // testRepo is a test helper function to create a library // Repo type with all fields set to their zero values. -func testRepo() *library.Repo { - return &library.Repo{ +func testRepo() *api.Repo { + return &api.Repo{ ID: new(int64), - UserID: new(int64), BuildLimit: new(int64), Timeout: new(int64), Counter: new(int), diff --git a/go.mod b/go.mod index 2b2c83713..c0b21447e 100644 --- a/go.mod +++ b/go.mod @@ -12,9 +12,10 @@ require ( github.com/aws/aws-sdk-go v1.51.0 github.com/buildkite/yaml v0.0.0-20181016232759-0caa5f0796e3 github.com/drone/envsubst v1.0.3 + github.com/ghodss/yaml v1.0.0 github.com/gin-gonic/gin v1.9.1 github.com/go-playground/assert/v2 v2.2.0 - github.com/go-vela/types v0.23.4-0.20240402153726-f16c3e4cb5fb + github.com/go-vela/types v0.23.4-0.20240405205548-f24f795ac0b7 github.com/golang-jwt/jwt/v5 v5.2.1 github.com/google/go-cmp v0.6.0 github.com/google/go-github/v61 v61.0.0 @@ -58,7 +59,6 @@ require ( github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect - github.com/ghodss/yaml v1.0.0 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-jose/go-jose/v3 v3.0.3 // indirect github.com/go-logr/logr v1.3.0 // indirect diff --git a/go.sum b/go.sum index f3bc883ef..1f35c936b 100644 --- a/go.sum +++ b/go.sum @@ -85,8 +85,8 @@ github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw= github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= -github.com/go-vela/types v0.23.4-0.20240402153726-f16c3e4cb5fb h1:jHao/NNRswInMLEb0m1OJ84d1m/LGWMCmaeRqSDnWQY= -github.com/go-vela/types v0.23.4-0.20240402153726-f16c3e4cb5fb/go.mod h1:mEF9dLkk00rUXf/t39n2WvXZgJbxnPEEWy+DHqIlRUo= +github.com/go-vela/types v0.23.4-0.20240405205548-f24f795ac0b7 h1:3mN7ej69dMH3Vis3G/tPLzLL0Rfp8nR5qd0gpj5ejRM= +github.com/go-vela/types v0.23.4-0.20240405205548-f24f795ac0b7/go.mod h1:mEF9dLkk00rUXf/t39n2WvXZgJbxnPEEWy+DHqIlRUo= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= diff --git a/internal/metadata.go b/internal/metadata.go new file mode 100644 index 000000000..00a94bde0 --- /dev/null +++ b/internal/metadata.go @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: Apache-2.0 + +package internal + +import "time" + +type ( + // Database is the extra set of database data passed to the compiler. + Database struct { + Driver string `json:"driver"` + Host string `json:"host"` + } + + // Queue is the extra set of queue data passed to the compiler. + Queue struct { + Channel string `json:"channel"` + Driver string `json:"driver"` + Host string `json:"host"` + } + + // Source is the extra set of source data passed to the compiler. + Source struct { + Driver string `json:"driver"` + Host string `json:"host"` + } + + // Vela is the extra set of Vela data passed to the compiler. + Vela struct { + Address string `json:"address"` + WebAddress string `json:"web_address"` + WebOauthCallbackPath string `json:"web_oauth_callback_path"` + AccessTokenDuration time.Duration `json:"access_token_duration"` + RefreshTokenDuration time.Duration `json:"refresh_token_duration"` + } + + // Metadata is the extra set of data passed to the compiler for + // converting a yaml configuration to an executable pipeline. + Metadata struct { + Database *Database `json:"database"` + Queue *Queue `json:"queue"` + Source *Source `json:"source"` + Vela *Vela `json:"vela"` + } +) diff --git a/internal/token/compose.go b/internal/token/compose.go index 6e48647e2..df3d9c652 100644 --- a/internal/token/compose.go +++ b/internal/token/compose.go @@ -7,7 +7,7 @@ import ( "net/url" "github.com/gin-gonic/gin" - "github.com/go-vela/types" + "github.com/go-vela/server/internal" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" ) @@ -21,7 +21,7 @@ import ( func (tm *Manager) Compose(c *gin.Context, u *library.User) (string, string, error) { // grab the metadata from the context to pull in provided // cookie duration information - m := c.MustGet("metadata").(*types.Metadata) + m := c.MustGet("metadata").(*internal.Metadata) // mint token options for refresh token rmto := MintTokenOpts{ diff --git a/internal/token/compose_test.go b/internal/token/compose_test.go index a73bf912b..44e06f3b5 100644 --- a/internal/token/compose_test.go +++ b/internal/token/compose_test.go @@ -9,7 +9,7 @@ import ( "time" "github.com/gin-gonic/gin" - "github.com/go-vela/types" + "github.com/go-vela/server/internal" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" @@ -53,8 +53,8 @@ func TestToken_Compose(t *testing.T) { t.Errorf("Unable to create test token: %v", err) } - m := &types.Metadata{ - Vela: &types.Vela{ + m := &internal.Metadata{ + Vela: &internal.Vela{ AccessTokenDuration: d, }, } diff --git a/internal/webhook.go b/internal/webhook.go new file mode 100644 index 000000000..ace36987e --- /dev/null +++ b/internal/webhook.go @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: Apache-2.0 + +package internal + +import ( + "strings" + + api "github.com/go-vela/server/api/types" + "github.com/go-vela/types/constants" + "github.com/go-vela/types/library" +) + +var ( + skipDirectiveMsg = "skip ci directive found in commit title/message" +) + +// PullRequest defines the data pulled from PRs while +// processing a webhook. +type PullRequest struct { + Comment string + Number int + IsFromFork bool + Labels []string +} + +// Webhook defines a struct that is used to return +// the required data when processing webhook event +// a for a source provider event. +type Webhook struct { + Hook *library.Hook + Repo *api.Repo + Build *library.Build + PullRequest PullRequest + Deployment *library.Deployment +} + +// ShouldSkip uses the build information +// associated with the given hook to determine +// whether the hook should be skipped. +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()) { + // check for skip ci directive in message or title + if hasSkipDirective(w.Build.GetMessage()) || + hasSkipDirective(w.Build.GetTitle()) { + return true, skipDirectiveMsg + } + } + + return false, "" +} + +// hasSkipDirective is a small helper function +// to check a string for a number of patterns +// that signal to vela that the hook should +// be skipped from processing. +func hasSkipDirective(s string) bool { + sl := strings.ToLower(s) + + switch { + case strings.Contains(sl, "[skip ci]"), + strings.Contains(sl, "[ci skip]"), + strings.Contains(sl, "[skip vela]"), + strings.Contains(sl, "[vela skip]"), + strings.Contains(sl, "***no_ci***"): + return true + default: + return false + } +} diff --git a/internal/webhook_test.go b/internal/webhook_test.go new file mode 100644 index 000000000..6b072090b --- /dev/null +++ b/internal/webhook_test.go @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: Apache-2.0 + +package internal + +import ( + "testing" + + "github.com/go-vela/types/constants" + "github.com/go-vela/types/library" +) + +func TestWebhook_ShouldSkip(t *testing.T) { + // set up tests + tests := []struct { + hook *Webhook + wantBool bool + wantString string + }{ + { + &Webhook{Build: testPushBuild("testing [SKIP CI]", "", constants.EventPush)}, + true, + skipDirectiveMsg, + }, + { + &Webhook{Build: testPushBuild("testing", "wip [ci skip]", constants.EventPush)}, + true, + skipDirectiveMsg, + }, + { + &Webhook{Build: testPushBuild("testing [skip VELA]", "", constants.EventPush)}, + true, + skipDirectiveMsg, + }, + { + &Webhook{Build: testPushBuild("testing", "wip [vela skip]", constants.EventPush)}, + true, + skipDirectiveMsg, + }, + { + &Webhook{Build: testPushBuild("testing ***NO_CI*** ok", "nothing", constants.EventPush)}, + true, + skipDirectiveMsg, + }, + { + &Webhook{Build: testPushBuild("testing ok", "nothing", constants.EventPush)}, + false, + "", + }, + { + &Webhook{Build: testPushBuild("testing [SKIP CI]", "", constants.EventTag)}, + true, + skipDirectiveMsg, + }, + { + &Webhook{Build: testPushBuild("testing", "wip [ci skip]", constants.EventTag)}, + true, + skipDirectiveMsg, + }, + { + &Webhook{Build: testPushBuild("testing [skip VELA]", "", constants.EventTag)}, + true, + skipDirectiveMsg, + }, + { + &Webhook{Build: testPushBuild("testing", "wip [vela skip]", constants.EventTag)}, + true, + skipDirectiveMsg, + }, + { + &Webhook{Build: testPushBuild("testing ***NO_CI*** ok", "nothing", constants.EventTag)}, + true, + skipDirectiveMsg, + }, + { + &Webhook{Build: testPushBuild("testing ok", "nothing", constants.EventTag)}, + false, + "", + }, + } + + // run tests + for _, test := range tests { + gotBool, gotString := test.hook.ShouldSkip() + + if gotString != test.wantString { + t.Errorf("returned an error, wanted %s, but got %s", test.wantString, gotString) + } + + if gotBool != test.wantBool { + t.Errorf("returned an error, wanted %v, but got %v", test.wantBool, gotBool) + } + } +} + +func testPushBuild(message, title, event string) *library.Build { + b := new(library.Build) + + b.SetEvent(event) + + if len(message) > 0 { + b.SetMessage(message) + } + + if len(title) > 0 { + b.SetTitle(title) + } + + b.SetCommit("deadbeef") + + return b +} diff --git a/mock/server/repo.go b/mock/server/repo.go index 88b4d4715..79b82b7df 100644 --- a/mock/server/repo.go +++ b/mock/server/repo.go @@ -9,15 +9,21 @@ import ( "strings" "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types" - "github.com/go-vela/types/library" ) const ( // RepoResp represents a JSON return for a single repo. RepoResp = `{ "id": 1, - "user_id": 1, + "owner": { + "id": 1, + "name": "octocat", + "favorites": [], + "active": true, + "admin": false + }, "org": "github", "counter": 10, "name": "octocat", @@ -97,7 +103,7 @@ const ( func getRepos(c *gin.Context) { data := []byte(ReposResp) - var body []library.Repo + var body []api.Repo _ = json.Unmarshal(data, &body) c.JSON(http.StatusOK, body) @@ -119,7 +125,7 @@ func getRepo(c *gin.Context) { data := []byte(RepoResp) - var body library.Repo + var body api.Repo _ = json.Unmarshal(data, &body) c.JSON(http.StatusOK, body) @@ -129,7 +135,7 @@ func getRepo(c *gin.Context) { func addRepo(c *gin.Context) { data := []byte(RepoResp) - var body library.Repo + var body api.Repo _ = json.Unmarshal(data, &body) c.JSON(http.StatusCreated, body) @@ -153,7 +159,7 @@ func updateRepo(c *gin.Context) { data := []byte(RepoResp) - var body library.Repo + var body api.Repo _ = json.Unmarshal(data, &body) c.JSON(http.StatusOK, body) diff --git a/mock/server/repo_test.go b/mock/server/repo_test.go index 1e59ba022..b6b408a8f 100644 --- a/mock/server/repo_test.go +++ b/mock/server/repo_test.go @@ -7,11 +7,11 @@ import ( "reflect" "testing" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" ) func TestRepo_ActiveRepoResp(t *testing.T) { - testRepo := library.Repo{} + testRepo := api.Repo{} err := json.Unmarshal([]byte(RepoResp), &testRepo) if err != nil { diff --git a/queue/models/item.go b/queue/models/item.go new file mode 100644 index 000000000..f0a5f4fa3 --- /dev/null +++ b/queue/models/item.go @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: Apache-2.0 + +package models + +import ( + api "github.com/go-vela/server/api/types" + "github.com/go-vela/types/library" +) + +// ItemVersion allows the worker to detect items that were queued before an Vela server +// upgrade or downgrade, so it can handle such stale data gracefully. +// For example, the worker could fail a stale build or ask the server to recompile it. +// This is not a public API and is unrelated to the version key in pipeline yaml. +const ItemVersion uint64 = 3 + +// Item is the queue representation of an item to publish to the queue. +type Item struct { + Build *library.Build `json:"build"` + Repo *api.Repo `json:"repo"` + // The 0-value is the implicit ItemVersion for queued Items that pre-date adding the field. + ItemVersion uint64 `json:"item_version"` +} + +// ToItem creates a queue item from a build, repo and user. +func ToItem(b *library.Build, r *api.Repo) *Item { + return &Item{ + Build: b, + Repo: r, + ItemVersion: ItemVersion, + } +} diff --git a/queue/models/item_test.go b/queue/models/item_test.go new file mode 100644 index 000000000..f6d34e19f --- /dev/null +++ b/queue/models/item_test.go @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: Apache-2.0 + +package models + +import ( + "reflect" + "testing" + + api "github.com/go-vela/server/api/types" + "github.com/go-vela/types/library" +) + +func TestTypes_ToItem(t *testing.T) { + // setup types + booL := false + num := 1 + num64 := int64(num) + str := "foo" + e := new(api.Events) + + b := &library.Build{ + ID: &num64, + RepoID: &num64, + Number: &num, + Parent: &num, + Event: &str, + Status: &str, + Error: &str, + Enqueued: &num64, + Created: &num64, + Started: &num64, + Finished: &num64, + Deploy: &str, + Clone: &str, + Source: &str, + Title: &str, + Message: &str, + Commit: &str, + Sender: &str, + Author: &str, + Branch: &str, + Ref: &str, + BaseRef: &str, + } + r := &api.Repo{ + ID: &num64, + Owner: &library.User{ + ID: &num64, + Name: &str, + Token: &str, + Active: &booL, + Admin: &booL, + }, + Org: &str, + Name: &str, + FullName: &str, + Link: &str, + Clone: &str, + Branch: &str, + Timeout: &num64, + Visibility: &str, + Private: &booL, + Trusted: &booL, + Active: &booL, + AllowEvents: e, + } + want := &Item{ + Build: &library.Build{ + ID: &num64, + RepoID: &num64, + Number: &num, + Parent: &num, + Event: &str, + Status: &str, + Error: &str, + Enqueued: &num64, + Created: &num64, + Started: &num64, + Finished: &num64, + Deploy: &str, + Clone: &str, + Source: &str, + Title: &str, + Message: &str, + Commit: &str, + Sender: &str, + Author: &str, + Branch: &str, + Ref: &str, + BaseRef: &str, + }, + Repo: &api.Repo{ + ID: &num64, + Owner: &library.User{ + ID: &num64, + Name: &str, + Token: &str, + Active: &booL, + Admin: &booL, + }, + Org: &str, + Name: &str, + FullName: &str, + Link: &str, + Clone: &str, + Branch: &str, + Timeout: &num64, + Visibility: &str, + Private: &booL, + Trusted: &booL, + Active: &booL, + AllowEvents: e, + }, + ItemVersion: ItemVersion, + } + + // run test + got := ToItem(b, r) + + if !reflect.DeepEqual(got, want) { + t.Errorf("ToItem is %v, want %v", got, want) + } +} diff --git a/queue/redis/length_test.go b/queue/redis/length_test.go index 0049b3809..3f27ce60f 100644 --- a/queue/redis/length_test.go +++ b/queue/redis/length_test.go @@ -7,17 +7,16 @@ import ( "reflect" "testing" - "github.com/go-vela/types" + "github.com/go-vela/server/queue/models" "gopkg.in/square/go-jose.v2/json" ) func TestRedis_Length(t *testing.T) { // setup types // use global variables in redis_test.go - _item := &types.Item{ + _item := &models.Item{ Build: _build, Repo: _repo, - User: _user, } // setup queue item diff --git a/queue/redis/pop.go b/queue/redis/pop.go index 250d0c915..bd5872c9a 100644 --- a/queue/redis/pop.go +++ b/queue/redis/pop.go @@ -7,13 +7,13 @@ import ( "encoding/json" "errors" - "github.com/go-vela/types" + "github.com/go-vela/server/queue/models" "github.com/redis/go-redis/v9" "golang.org/x/crypto/nacl/sign" ) // Pop grabs an item from the specified channel off the queue. -func (c *client) Pop(ctx context.Context, routes []string) (*types.Item, error) { +func (c *client) Pop(ctx context.Context, routes []string) (*models.Item, error) { c.Logger.Tracef("popping item from queue %s", c.config.Channels) // define channels to pop from @@ -58,7 +58,7 @@ func (c *client) Pop(ctx context.Context, routes []string) (*types.Item, error) } // unmarshal result into queue item - item := new(types.Item) + item := new(models.Item) err = json.Unmarshal(opened, item) if err != nil { diff --git a/queue/redis/pop_test.go b/queue/redis/pop_test.go index eb05030bd..e95f828ab 100644 --- a/queue/redis/pop_test.go +++ b/queue/redis/pop_test.go @@ -4,11 +4,11 @@ package redis import ( "context" - "reflect" "testing" "time" - "github.com/go-vela/types" + "github.com/go-vela/server/queue/models" + "github.com/google/go-cmp/cmp" "golang.org/x/crypto/nacl/sign" "gopkg.in/square/go-jose.v2/json" ) @@ -16,10 +16,9 @@ import ( func TestRedis_Pop(t *testing.T) { // setup types // use global variables in redis_test.go - _item := &types.Item{ + _item := &models.Item{ Build: _build, Repo: _repo, - User: _user, } var signed []byte @@ -79,7 +78,7 @@ func TestRedis_Pop(t *testing.T) { tests := []struct { failure bool redis *client - want *types.Item + want *models.Item channels []string }{ { @@ -121,8 +120,8 @@ func TestRedis_Pop(t *testing.T) { t.Errorf("Pop returned err: %v", err) } - if !reflect.DeepEqual(got, test.want) { - t.Errorf("Pop is %v, want %v", got, test.want) + if diff := cmp.Diff(test.want, got); diff != "" { + t.Errorf("Pop() mismatch (-want +got):\n%s", diff) } } } diff --git a/queue/redis/push_test.go b/queue/redis/push_test.go index 5db7e1510..75acc317e 100644 --- a/queue/redis/push_test.go +++ b/queue/redis/push_test.go @@ -7,16 +7,15 @@ import ( "encoding/json" "testing" - "github.com/go-vela/types" + "github.com/go-vela/server/queue/models" ) func TestRedis_Push(t *testing.T) { // setup types // use global variables in redis_test.go - _item := &types.Item{ + _item := &models.Item{ Build: _build, Repo: _repo, - User: _user, } // setup queue item diff --git a/queue/redis/redis_test.go b/queue/redis/redis_test.go index 3f632b129..ee4a35a9b 100644 --- a/queue/redis/redis_test.go +++ b/queue/redis/redis_test.go @@ -8,8 +8,8 @@ import ( "time" "github.com/alicebob/miniredis/v2" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/library" - "github.com/go-vela/types/pipeline" ) // The following functions were taken from @@ -73,8 +73,16 @@ var ( Distribution: String("linux"), } - _repo = &library.Repo{ - ID: Int64(1), + _repo = &api.Repo{ + ID: Int64(1), + Owner: &library.User{ + ID: Int64(1), + Name: String("octocat"), + Token: nil, + Hash: nil, + Active: Bool(true), + Admin: Bool(false), + }, Org: String("github"), Name: String("octocat"), FullName: String("github/octocat"), @@ -87,62 +95,6 @@ var ( Trusted: Bool(false), Active: Bool(true), } - - _steps = &pipeline.Build{ - Version: "1", - ID: "github_octocat_1", - Services: pipeline.ContainerSlice{ - { - ID: "service_github_octocat_1_postgres", - Directory: "/home/github/octocat", - Environment: map[string]string{"FOO": "bar"}, - Image: "postgres:12-alpine", - Name: "postgres", - Number: 1, - Ports: []string{"5432:5432"}, - Pull: "not_present", - }, - }, - Steps: pipeline.ContainerSlice{ - { - ID: "step_github_octocat_1_init", - Directory: "/home/github/octocat", - Environment: map[string]string{"FOO": "bar"}, - Image: "#init", - Name: "init", - Number: 1, - Pull: "always", - }, - { - ID: "step_github_octocat_1_clone", - Directory: "/home/github/octocat", - Environment: map[string]string{"FOO": "bar"}, - Image: "target/vela-git:v0.5.1", - Name: "clone", - Number: 2, - Pull: "always", - }, - { - ID: "step_github_octocat_1_echo", - Commands: []string{"echo hello"}, - Directory: "/home/github/octocat", - Environment: map[string]string{"FOO": "bar"}, - Image: "alpine:latest", - Name: "echo", - Number: 3, - Pull: "always", - }, - }, - } - - _user = &library.User{ - ID: Int64(1), - Name: String("octocat"), - Token: nil, - Hash: nil, - Active: Bool(true), - Admin: Bool(false), - } ) func TestRedis_New(t *testing.T) { diff --git a/queue/service.go b/queue/service.go index fd36a64bc..3fdf27515 100644 --- a/queue/service.go +++ b/queue/service.go @@ -5,7 +5,7 @@ package queue import ( "context" - "github.com/go-vela/types" + "github.com/go-vela/server/queue/models" "github.com/go-vela/types/pipeline" ) @@ -24,7 +24,7 @@ type Service interface { // Pop defines a function that grabs an // item off the queue. - Pop(context.Context, []string) (*types.Item, error) + Pop(context.Context, []string) (*models.Item, error) // Push defines a function that publishes an // item to the specified route in the queue. diff --git a/router/middleware/build/build_test.go b/router/middleware/build/build_test.go index f86353d3a..b3be6b0c3 100644 --- a/router/middleware/build/build_test.go +++ b/router/middleware/build/build_test.go @@ -10,6 +10,7 @@ import ( "testing" "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" @@ -37,9 +38,12 @@ func TestBuild_Retrieve(t *testing.T) { func TestBuild_Establish(t *testing.T) { // setup types - r := new(library.Repo) + owner := new(library.User) + owner.SetID(1) + + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.SetOwner(owner) r.SetHash("baz") r.SetOrg("foo") r.SetName("bar") @@ -158,9 +162,12 @@ func TestBuild_Establish_NoRepo(t *testing.T) { func TestBuild_Establish_NoBuildParameter(t *testing.T) { // setup types - r := new(library.Repo) + owner := new(library.User) + owner.SetID(1) + + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.SetOwner(owner) r.SetHash("baz") r.SetOrg("foo") r.SetName("bar") @@ -206,9 +213,12 @@ func TestBuild_Establish_NoBuildParameter(t *testing.T) { func TestBuild_Establish_InvalidBuildParameter(t *testing.T) { // setup types - r := new(library.Repo) + owner := new(library.User) + owner.SetID(1) + + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.SetOwner(owner) r.SetHash("baz") r.SetOrg("foo") r.SetName("bar") @@ -254,9 +264,9 @@ func TestBuild_Establish_InvalidBuildParameter(t *testing.T) { func TestBuild_Establish_NoBuild(t *testing.T) { // setup types - r := new(library.Repo) + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.GetOwner().SetID(1) r.SetHash("baz") r.SetOrg("foo") r.SetName("bar") diff --git a/router/middleware/executors/context.go b/router/middleware/executors/context.go index d040fa73a..8fcd5cfa0 100644 --- a/router/middleware/executors/context.go +++ b/router/middleware/executors/context.go @@ -5,7 +5,7 @@ package executors import ( "context" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" ) const key = "executors" @@ -16,13 +16,13 @@ type Setter interface { } // FromContext returns the executors associated with this context. -func FromContext(c context.Context) []library.Executor { +func FromContext(c context.Context) []api.Executor { value := c.Value(key) if value == nil { return nil } - e, ok := value.([]library.Executor) + e, ok := value.([]api.Executor) if !ok { return nil } @@ -32,6 +32,6 @@ func FromContext(c context.Context) []library.Executor { // ToContext adds the executor to this context if it supports // the Setter interface. -func ToContext(c Setter, e []library.Executor) { +func ToContext(c Setter, e []api.Executor) { c.Set(key, e) } diff --git a/router/middleware/executors/context_test.go b/router/middleware/executors/context_test.go index 3cabdb687..f7e080d61 100644 --- a/router/middleware/executors/context_test.go +++ b/router/middleware/executors/context_test.go @@ -6,16 +6,15 @@ import ( "reflect" "testing" - "github.com/go-vela/types/library" - "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" ) func TestExecutors_FromContext(t *testing.T) { // setup types eID := int64(1) - e := library.Executor{ID: &eID} - want := []library.Executor{e} + e := api.Executor{ID: &eID} + want := []api.Executor{e} // setup context gin.SetMode(gin.TestMode) @@ -74,8 +73,8 @@ func TestExecutors_FromContext_Empty(t *testing.T) { func TestExecutors_ToContext(t *testing.T) { // setup types eID := int64(1) - e := library.Executor{ID: &eID} - want := []library.Executor{e} + e := api.Executor{ID: &eID} + want := []api.Executor{e} // setup context gin.SetMode(gin.TestMode) diff --git a/router/middleware/executors/executor_test.go b/router/middleware/executors/executor_test.go index 66006b6e2..423336a10 100644 --- a/router/middleware/executors/executor_test.go +++ b/router/middleware/executors/executor_test.go @@ -6,16 +6,15 @@ import ( "reflect" "testing" - "github.com/go-vela/types/library" - "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" ) func TestExecutors_Retrieve(t *testing.T) { // setup types eID := int64(1) - e := library.Executor{ID: &eID} - want := []library.Executor{e} + e := api.Executor{ID: &eID} + want := []api.Executor{e} // setup context gin.SetMode(gin.TestMode) diff --git a/router/middleware/executors/executors.go b/router/middleware/executors/executors.go index 688434f07..8ea9de2c1 100644 --- a/router/middleware/executors/executors.go +++ b/router/middleware/executors/executors.go @@ -12,23 +12,23 @@ import ( "time" "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/internal/token" "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/util" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" ) // Retrieve gets the executors in the given context. -func Retrieve(c *gin.Context) []library.Executor { +func Retrieve(c *gin.Context) []api.Executor { return FromContext(c) } // Establish sets the executors in the given context. func Establish() gin.HandlerFunc { return func(c *gin.Context) { - e := new([]library.Executor) + e := new([]api.Executor) b := build.Retrieve(c) ctx := c.Request.Context() diff --git a/router/middleware/header.go b/router/middleware/header.go index f04180bfd..980243f16 100644 --- a/router/middleware/header.go +++ b/router/middleware/header.go @@ -7,8 +7,8 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/go-vela/server/internal" "github.com/go-vela/server/version" - "github.com/go-vela/types" ) // NoCache is a middleware function that appends headers @@ -24,7 +24,7 @@ func NoCache(c *gin.Context) { // for OPTIONS preflight requests and aborts then exits // the middleware chain and ends the request. func Options(c *gin.Context) { - m := c.MustGet("metadata").(*types.Metadata) + m := c.MustGet("metadata").(*internal.Metadata) if c.Request.Method != "OPTIONS" { c.Next() @@ -58,7 +58,7 @@ func Secure(c *gin.Context) { // CORS related requests. These are attached to actual requests // unlike the OPTIONS preflight requests. func Cors(c *gin.Context) { - m := c.MustGet("metadata").(*types.Metadata) + m := c.MustGet("metadata").(*internal.Metadata) c.Header("Access-Control-Allow-Origin", "*") diff --git a/router/middleware/header_test.go b/router/middleware/header_test.go index ab13f992a..dfa18e063 100644 --- a/router/middleware/header_test.go +++ b/router/middleware/header_test.go @@ -11,7 +11,7 @@ import ( "time" "github.com/gin-gonic/gin" - "github.com/go-vela/types" + "github.com/go-vela/server/internal" ) func TestMiddleware_NoCache(t *testing.T) { @@ -64,8 +64,8 @@ func TestMiddleware_Options(t *testing.T) { wantHeaders := "authorization, origin, content-type, accept" wantAllow := "HEAD,GET,POST,PUT,PATCH,DELETE,OPTIONS" wantContentType := "application/json" - m := &types.Metadata{ - Vela: &types.Vela{ + m := &internal.Metadata{ + Vela: &internal.Vela{ Address: "http://localhost:8080", }, } @@ -120,8 +120,8 @@ func TestMiddleware_Options(t *testing.T) { func TestMiddleware_Options_InvalidMethod(t *testing.T) { // setup types - m := &types.Metadata{ - Vela: &types.Vela{ + m := &internal.Metadata{ + Vela: &internal.Vela{ Address: "http://localhost:8080", }, } @@ -178,8 +178,8 @@ func TestMiddleware_Cors(t *testing.T) { // setup types wantOrigin := "*" wantExposeHeaders := "link, x-total-count" - m := &types.Metadata{ - Vela: &types.Vela{ + m := &internal.Metadata{ + Vela: &internal.Vela{ Address: "http://localhost:8080", }, } diff --git a/router/middleware/logger_test.go b/router/middleware/logger_test.go index bfc084437..18677ae7c 100644 --- a/router/middleware/logger_test.go +++ b/router/middleware/logger_test.go @@ -33,9 +33,9 @@ func TestMiddleware_Logger(t *testing.T) { b.SetRepoID(1) b.SetNumber(1) - r := new(library.Repo) + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.GetOwner().SetID(1) r.SetOrg("foo") r.SetName("bar") r.SetFullName("foo/bar") @@ -162,9 +162,9 @@ func TestMiddleware_Logger_Error(t *testing.T) { func TestMiddleware_Logger_Sanitize(t *testing.T) { var logBody, logWant map[string]interface{} - r := new(library.Repo) + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.GetOwner().SetID(1) r.SetOrg("foo") r.SetName("bar") r.SetFullName("foo/bar") diff --git a/router/middleware/metadata.go b/router/middleware/metadata.go index 67ed62157..672491d1d 100644 --- a/router/middleware/metadata.go +++ b/router/middleware/metadata.go @@ -4,13 +4,12 @@ package middleware import ( "github.com/gin-gonic/gin" - - "github.com/go-vela/types" + "github.com/go-vela/server/internal" ) // Metadata is a middleware function that attaches the metadata // to the context of every http.Request. -func Metadata(m *types.Metadata) gin.HandlerFunc { +func Metadata(m *internal.Metadata) gin.HandlerFunc { return func(c *gin.Context) { c.Set("metadata", m) c.Next() diff --git a/router/middleware/metadata_test.go b/router/middleware/metadata_test.go index 0baaee36a..8e955805b 100644 --- a/router/middleware/metadata_test.go +++ b/router/middleware/metadata_test.go @@ -8,15 +8,14 @@ import ( "reflect" "testing" - "github.com/go-vela/types" - "github.com/gin-gonic/gin" + "github.com/go-vela/server/internal" ) func TestMiddleware_Metadata(t *testing.T) { // setup types - got := new(types.Metadata) - want := &types.Metadata{} + got := new(internal.Metadata) + want := &internal.Metadata{} // setup context gin.SetMode(gin.TestMode) @@ -28,7 +27,7 @@ func TestMiddleware_Metadata(t *testing.T) { // setup mock server engine.Use(Metadata(want)) engine.GET("/health", func(c *gin.Context) { - got = c.Value("metadata").(*types.Metadata) + got = c.Value("metadata").(*internal.Metadata) c.Status(http.StatusOK) }) diff --git a/router/middleware/org/org_test.go b/router/middleware/org/org_test.go index 8b217f5f8..a54d9ad33 100644 --- a/router/middleware/org/org_test.go +++ b/router/middleware/org/org_test.go @@ -10,8 +10,8 @@ import ( "testing" "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" - "github.com/go-vela/types/library" ) func TestOrg_Retrieve(t *testing.T) { @@ -33,9 +33,9 @@ func TestOrg_Retrieve(t *testing.T) { func TestOrg_Establish(t *testing.T) { // setup types - r := new(library.Repo) + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.GetOwner().SetID(1) r.SetHash("baz") r.SetOrg("foo") r.SetName("bar") diff --git a/router/middleware/perm/perm.go b/router/middleware/perm/perm.go index a8656a261..3cac40571 100644 --- a/router/middleware/perm/perm.go +++ b/router/middleware/perm/perm.go @@ -8,7 +8,6 @@ import ( "strings" "github.com/gin-gonic/gin" - "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/claims" "github.com/go-vela/server/router/middleware/org" @@ -371,16 +370,7 @@ func MustAdmin() gin.HandlerFunc { // try again using the repo owner token // // https://docs.github.com/en/rest/reference/repos#get-repository-permissions-for-a-user - ro, err := database.FromContext(c).GetUser(ctx, r.GetUserID()) - if err != nil { - retErr := fmt.Errorf("unable to get owner for %s: %w", r.GetFullName(), err) - - util.HandleError(c, http.StatusBadRequest, retErr) - - return - } - - perm, err = scm.FromContext(c).RepoAccess(ctx, u.GetName(), ro.GetToken(), r.GetOrg(), r.GetName()) + perm, err = scm.FromContext(c).RepoAccess(ctx, u.GetName(), r.GetOwner().GetToken(), r.GetOrg(), r.GetName()) if err != nil { logger.Errorf("unable to get user %s access level for repo %s", u.GetName(), r.GetFullName()) } @@ -430,16 +420,7 @@ func MustWrite() gin.HandlerFunc { // try again using the repo owner token // // https://docs.github.com/en/rest/reference/repos#get-repository-permissions-for-a-user - ro, err := database.FromContext(c).GetUser(ctx, r.GetUserID()) - if err != nil { - retErr := fmt.Errorf("unable to get owner for %s: %w", r.GetFullName(), err) - - util.HandleError(c, http.StatusBadRequest, retErr) - - return - } - - perm, err = scm.FromContext(c).RepoAccess(ctx, u.GetName(), ro.GetToken(), r.GetOrg(), r.GetName()) + perm, err = scm.FromContext(c).RepoAccess(ctx, u.GetName(), r.GetOwner().GetToken(), r.GetOrg(), r.GetName()) if err != nil { logger.Errorf("unable to get user %s access level for repo %s", u.GetName(), r.GetFullName()) } @@ -513,16 +494,7 @@ func MustRead() gin.HandlerFunc { // try again using the repo owner token // // https://docs.github.com/en/rest/reference/repos#get-repository-permissions-for-a-user - ro, err := database.FromContext(c).GetUser(ctx, r.GetUserID()) - if err != nil { - retErr := fmt.Errorf("unable to get owner for %s: %w", r.GetFullName(), err) - - util.HandleError(c, http.StatusBadRequest, retErr) - - return - } - - perm, err = scm.FromContext(c).RepoAccess(ctx, u.GetName(), ro.GetToken(), r.GetOrg(), r.GetName()) + perm, err = scm.FromContext(c).RepoAccess(ctx, u.GetName(), r.GetOwner().GetToken(), r.GetOrg(), r.GetName()) if err != nil { logger.Errorf("unable to get user %s access level for repo %s", u.GetName(), r.GetFullName()) } diff --git a/router/middleware/perm/perm_test.go b/router/middleware/perm/perm_test.go index c2c9642e4..0628457e1 100644 --- a/router/middleware/perm/perm_test.go +++ b/router/middleware/perm/perm_test.go @@ -11,6 +11,7 @@ import ( "time" "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/internal/token" "github.com/go-vela/server/router/middleware/build" @@ -397,9 +398,12 @@ func TestPerm_MustBuildAccess(t *testing.T) { // setup types secret := "superSecret" - r := new(library.Repo) + owner := new(library.User) + owner.SetID(1) + + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.SetOwner(owner) r.SetHash("baz") r.SetOrg("foo") r.SetName("bar") @@ -483,9 +487,12 @@ func TestPerm_MustBuildAccess_PlatAdmin(t *testing.T) { // setup types secret := "superSecret" - r := new(library.Repo) + owner := new(library.User) + owner.SetID(1) + + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.SetOwner(owner) r.SetHash("baz") r.SetOrg("foo") r.SetName("bar") @@ -576,9 +583,12 @@ func TestPerm_MustBuildToken_WrongBuild(t *testing.T) { // setup types secret := "superSecret" - r := new(library.Repo) + owner := new(library.User) + owner.SetID(1) + + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.SetOwner(owner) r.SetHash("baz") r.SetOrg("foo") r.SetName("bar") @@ -662,9 +672,12 @@ func TestPerm_MustSecretAdmin_BuildToken_Repo(t *testing.T) { // setup types secret := "superSecret" - r := new(library.Repo) + owner := new(library.User) + owner.SetID(1) + + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.SetOwner(owner) r.SetHash("baz") r.SetOrg("foo") r.SetName("bar") @@ -745,9 +758,12 @@ func TestPerm_MustSecretAdmin_BuildToken_Org(t *testing.T) { // setup types secret := "superSecret" - r := new(library.Repo) + owner := new(library.User) + owner.SetID(1) + + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.SetOwner(owner) r.SetHash("baz") r.SetOrg("foo") r.SetName("bar") @@ -828,9 +844,12 @@ func TestPerm_MustSecretAdmin_BuildToken_Shared(t *testing.T) { // setup types secret := "superSecret" - r := new(library.Repo) + owner := new(library.User) + owner.SetID(1) + + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.SetOwner(owner) r.SetHash("baz") r.SetOrg("foo") r.SetName("bar") @@ -918,9 +937,12 @@ func TestPerm_MustAdmin(t *testing.T) { UserRefreshTokenDuration: time.Minute * 30, } - r := new(library.Repo) + owner := new(library.User) + owner.SetID(1) + + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.SetOwner(owner) r.SetHash("baz") r.SetOrg("foo") r.SetName("bar") @@ -1016,9 +1038,12 @@ func TestPerm_MustAdmin_PlatAdmin(t *testing.T) { UserRefreshTokenDuration: time.Minute * 30, } - r := new(library.Repo) + owner := new(library.User) + owner.SetID(1) + + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.SetOwner(owner) r.SetHash("baz") r.SetOrg("foo") r.SetName("bar") @@ -1114,9 +1139,12 @@ func TestPerm_MustAdmin_NotAdmin(t *testing.T) { UserRefreshTokenDuration: time.Minute * 30, } - r := new(library.Repo) + owner := new(library.User) + owner.SetID(1) + + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.SetOwner(owner) r.SetHash("baz") r.SetOrg("foo") r.SetName("bar") @@ -1212,9 +1240,12 @@ func TestPerm_MustWrite(t *testing.T) { UserRefreshTokenDuration: time.Minute * 30, } - r := new(library.Repo) + owner := new(library.User) + owner.SetID(1) + + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.SetOwner(owner) r.SetHash("baz") r.SetOrg("foo") r.SetName("bar") @@ -1310,9 +1341,12 @@ func TestPerm_MustWrite_PlatAdmin(t *testing.T) { UserRefreshTokenDuration: time.Minute * 30, } - r := new(library.Repo) + owner := new(library.User) + owner.SetID(1) + + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.SetOwner(owner) r.SetHash("baz") r.SetOrg("foo") r.SetName("bar") @@ -1408,9 +1442,12 @@ func TestPerm_MustWrite_RepoAdmin(t *testing.T) { UserRefreshTokenDuration: time.Minute * 30, } - r := new(library.Repo) + owner := new(library.User) + owner.SetID(1) + + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.SetOwner(owner) r.SetHash("baz") r.SetOrg("foo") r.SetName("bar") @@ -1506,9 +1543,12 @@ func TestPerm_MustWrite_NotWrite(t *testing.T) { UserRefreshTokenDuration: time.Minute * 30, } - r := new(library.Repo) + owner := new(library.User) + owner.SetID(1) + + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.SetOwner(owner) r.SetHash("baz") r.SetOrg("foo") r.SetName("bar") @@ -1604,9 +1644,12 @@ func TestPerm_MustRead(t *testing.T) { UserRefreshTokenDuration: time.Minute * 30, } - r := new(library.Repo) + owner := new(library.User) + owner.SetID(1) + + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.SetOwner(owner) r.SetHash("baz") r.SetOrg("foo") r.SetName("bar") @@ -1702,9 +1745,12 @@ func TestPerm_MustRead_PlatAdmin(t *testing.T) { UserRefreshTokenDuration: time.Minute * 30, } - r := new(library.Repo) + owner := new(library.User) + owner.SetID(1) + + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.SetOwner(owner) r.SetHash("baz") r.SetOrg("foo") r.SetName("bar") @@ -1800,9 +1846,12 @@ func TestPerm_MustRead_WorkerBuildToken(t *testing.T) { UserRefreshTokenDuration: time.Minute * 30, } - r := new(library.Repo) + owner := new(library.User) + owner.SetID(1) + + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.SetOwner(owner) r.SetHash("baz") r.SetOrg("foo") r.SetName("bar") @@ -1886,9 +1935,12 @@ func TestPerm_MustRead_RepoAdmin(t *testing.T) { UserRefreshTokenDuration: time.Minute * 30, } - r := new(library.Repo) + owner := new(library.User) + owner.SetID(1) + + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.SetOwner(owner) r.SetHash("baz") r.SetOrg("foo") r.SetName("bar") @@ -1984,9 +2036,12 @@ func TestPerm_MustRead_RepoWrite(t *testing.T) { UserRefreshTokenDuration: time.Minute * 30, } - r := new(library.Repo) + owner := new(library.User) + owner.SetID(1) + + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.SetOwner(owner) r.SetHash("baz") r.SetOrg("foo") r.SetName("bar") @@ -2082,9 +2137,12 @@ func TestPerm_MustRead_RepoPublic(t *testing.T) { UserRefreshTokenDuration: time.Minute * 30, } - r := new(library.Repo) + owner := new(library.User) + owner.SetID(1) + + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.SetOwner(owner) r.SetHash("baz") r.SetOrg("foo") r.SetName("bar") @@ -2180,9 +2238,12 @@ func TestPerm_MustRead_NotRead(t *testing.T) { UserRefreshTokenDuration: time.Minute * 30, } - r := new(library.Repo) + owner := new(library.User) + owner.SetID(1) + + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.SetOwner(owner) r.SetHash("baz") r.SetOrg("foo") r.SetName("bar") diff --git a/router/middleware/pipeline/pipeline.go b/router/middleware/pipeline/pipeline.go index 61f308854..b8f3b819a 100644 --- a/router/middleware/pipeline/pipeline.go +++ b/router/middleware/pipeline/pipeline.go @@ -9,12 +9,12 @@ import ( "github.com/gin-gonic/gin" "github.com/go-vela/server/compiler" "github.com/go-vela/server/database" + "github.com/go-vela/server/internal" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" "github.com/go-vela/server/util" - "github.com/go-vela/types" "github.com/go-vela/types/library" "github.com/sirupsen/logrus" ) @@ -77,7 +77,7 @@ func Establish() gin.HandlerFunc { _, pipeline, err = compiler.FromContext(c). Duplicate(). WithCommit(p). - WithMetadata(c.MustGet("metadata").(*types.Metadata)). + WithMetadata(c.MustGet("metadata").(*internal.Metadata)). WithRepo(r). WithUser(u). Compile(config) diff --git a/router/middleware/pipeline/pipeline_test.go b/router/middleware/pipeline/pipeline_test.go index 545edb338..552a40989 100644 --- a/router/middleware/pipeline/pipeline_test.go +++ b/router/middleware/pipeline/pipeline_test.go @@ -13,9 +13,11 @@ import ( "time" "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/compiler" "github.com/go-vela/server/compiler/native" "github.com/go-vela/server/database" + "github.com/go-vela/server/internal" "github.com/go-vela/server/internal/token" "github.com/go-vela/server/router/middleware/claims" "github.com/go-vela/server/router/middleware/org" @@ -23,7 +25,6 @@ import ( "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" "github.com/go-vela/server/scm/github" - "github.com/go-vela/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" "github.com/golang-jwt/jwt/v5" @@ -66,9 +67,12 @@ func TestPipeline_Retrieve(t *testing.T) { func TestPipeline_Establish(t *testing.T) { // setup types - r := new(library.Repo) + owner := new(library.User) + owner.SetID(1) + + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.SetOwner(owner) r.SetHash("baz") r.SetOrg("foo") r.SetName("bar") @@ -168,9 +172,12 @@ func TestPipeline_Establish_NoRepo(t *testing.T) { func TestPipeline_Establish_NoPipelineParameter(t *testing.T) { // setup types - r := new(library.Repo) + owner := new(library.User) + owner.SetID(1) + + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.SetOwner(owner) r.SetHash("baz") r.SetOrg("foo") r.SetName("bar") @@ -225,9 +232,12 @@ func TestPipeline_Establish_NoPipeline(t *testing.T) { UserRefreshTokenDuration: time.Minute * 30, } - r := new(library.Repo) + owner := new(library.User) + owner.SetID(1) + + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.SetOwner(owner) r.SetHash("baz") r.SetOrg("foo") r.SetName("bar") @@ -241,21 +251,21 @@ func TestPipeline_Establish_NoPipeline(t *testing.T) { u.SetHash("baz") u.SetAdmin(true) - m := &types.Metadata{ - Database: &types.Database{ + m := &internal.Metadata{ + Database: &internal.Database{ Driver: "foo", Host: "foo", }, - Queue: &types.Queue{ + Queue: &internal.Queue{ Channel: "foo", Driver: "foo", Host: "foo", }, - Source: &types.Source{ + Source: &internal.Source{ Driver: "foo", Host: "foo", }, - Vela: &types.Vela{ + Vela: &internal.Vela{ Address: "foo", WebAddress: "foo", }, diff --git a/router/middleware/repo/context.go b/router/middleware/repo/context.go index 620aaf0c8..73c0db4f1 100644 --- a/router/middleware/repo/context.go +++ b/router/middleware/repo/context.go @@ -5,7 +5,7 @@ package repo import ( "context" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" ) const key = "repo" @@ -16,13 +16,13 @@ type Setter interface { } // FromContext returns the Repo associated with this context. -func FromContext(c context.Context) *library.Repo { +func FromContext(c context.Context) *api.Repo { value := c.Value(key) if value == nil { return nil } - r, ok := value.(*library.Repo) + r, ok := value.(*api.Repo) if !ok { return nil } @@ -32,6 +32,6 @@ func FromContext(c context.Context) *library.Repo { // ToContext adds the Repo to this context if it supports // the Setter interface. -func ToContext(c Setter, r *library.Repo) { +func ToContext(c Setter, r *api.Repo) { c.Set(key, r) } diff --git a/router/middleware/repo/context_test.go b/router/middleware/repo/context_test.go index ebcadf01e..c02923ab8 100644 --- a/router/middleware/repo/context_test.go +++ b/router/middleware/repo/context_test.go @@ -5,15 +5,14 @@ package repo import ( "testing" - "github.com/go-vela/types/library" - "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" ) func TestRepo_FromContext(t *testing.T) { // setup types num := int64(1) - want := &library.Repo{ID: &num} + want := &api.Repo{ID: &num} // setup context gin.SetMode(gin.TestMode) @@ -72,7 +71,7 @@ func TestRepo_FromContext_Empty(t *testing.T) { func TestRepo_ToContext(t *testing.T) { // setup types num := int64(1) - want := &library.Repo{ID: &num} + want := &api.Repo{ID: &num} // setup context gin.SetMode(gin.TestMode) diff --git a/router/middleware/repo/repo.go b/router/middleware/repo/repo.go index 748a17bb7..f6f51cad7 100644 --- a/router/middleware/repo/repo.go +++ b/router/middleware/repo/repo.go @@ -7,16 +7,16 @@ import ( "net/http" "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/go-vela/types/library" "github.com/sirupsen/logrus" ) // Retrieve gets the repo in the given context. -func Retrieve(c *gin.Context) *library.Repo { +func Retrieve(c *gin.Context) *api.Repo { return FromContext(c) } diff --git a/router/middleware/repo/repo_test.go b/router/middleware/repo/repo_test.go index 488bcac8d..64321b409 100644 --- a/router/middleware/repo/repo_test.go +++ b/router/middleware/repo/repo_test.go @@ -9,16 +9,17 @@ import ( "reflect" "testing" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/router/middleware/org" + "github.com/go-vela/types/library" "github.com/gin-gonic/gin" "github.com/go-vela/server/database" - "github.com/go-vela/types/library" ) func TestRepo_Retrieve(t *testing.T) { // setup types - want := new(library.Repo) + want := new(api.Repo) want.SetID(1) // setup context @@ -36,9 +37,19 @@ func TestRepo_Retrieve(t *testing.T) { func TestRepo_Establish(t *testing.T) { // setup types - want := new(library.Repo) + owner := new(library.User) + owner.SetID(1) + owner.SetName("foo") + owner.SetActive(false) + owner.SetAdmin(false) + owner.SetFavorites([]string{}) + owner.SetHash("bar") + owner.SetToken("baz") + owner.SetRefreshToken("fresh") + + want := new(api.Repo) want.SetID(1) - want.SetUserID(1) + want.SetOwner(owner) want.SetHash("baz") want.SetOrg("foo") want.SetName("bar") @@ -54,12 +65,12 @@ func TestRepo_Establish(t *testing.T) { want.SetPrivate(false) want.SetTrusted(false) want.SetActive(false) - want.SetAllowEvents(library.NewEventsFromMask(1)) + want.SetAllowEvents(api.NewEventsFromMask(1)) want.SetPipelineType("yaml") want.SetPreviousName("") want.SetApproveBuild("") - got := new(library.Repo) + got := new(api.Repo) // setup database db, err := database.NewTest() @@ -69,9 +80,11 @@ func TestRepo_Establish(t *testing.T) { defer func() { _ = db.DeleteRepo(context.TODO(), want) + _ = db.DeleteUser(context.TODO(), owner) db.Close() }() + _, _ = db.CreateUser(context.TODO(), owner) _, _ = db.CreateRepo(context.TODO(), want) // setup context diff --git a/router/middleware/service/service_test.go b/router/middleware/service/service_test.go index fba880671..612f1e55f 100644 --- a/router/middleware/service/service_test.go +++ b/router/middleware/service/service_test.go @@ -10,6 +10,7 @@ import ( "testing" "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/org" @@ -37,9 +38,12 @@ func TestService_Retrieve(t *testing.T) { func TestService_Establish(t *testing.T) { // setup types - r := new(library.Repo) + owner := new(library.User) + owner.SetID(1) + + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.SetOwner(owner) r.SetHash("baz") r.SetOrg("foo") r.SetName("bar") @@ -150,9 +154,9 @@ func TestService_Establish_NoRepo(t *testing.T) { func TestService_Establish_NoBuild(t *testing.T) { // setup types - r := new(library.Repo) + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.GetOwner().SetID(1) r.SetHash("baz") r.SetOrg("foo") r.SetName("bar") @@ -198,9 +202,12 @@ func TestService_Establish_NoBuild(t *testing.T) { func TestService_Establish_NoServiceParameter(t *testing.T) { // setup types - r := new(library.Repo) + owner := new(library.User) + owner.SetID(1) + + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.SetOwner(owner) r.SetHash("baz") r.SetOrg("foo") r.SetName("bar") @@ -254,9 +261,12 @@ func TestService_Establish_NoServiceParameter(t *testing.T) { func TestService_Establish_InvalidServiceParameter(t *testing.T) { // setup types - r := new(library.Repo) + owner := new(library.User) + owner.SetID(1) + + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.SetOwner(owner) r.SetHash("baz") r.SetOrg("foo") r.SetName("bar") @@ -310,9 +320,9 @@ func TestService_Establish_InvalidServiceParameter(t *testing.T) { func TestService_Establish_NoService(t *testing.T) { // setup types - r := new(library.Repo) + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.GetOwner().SetID(1) r.SetHash("baz") r.SetOrg("foo") r.SetName("bar") diff --git a/router/middleware/step/step_test.go b/router/middleware/step/step_test.go index e4432a14a..ee02d4a8a 100644 --- a/router/middleware/step/step_test.go +++ b/router/middleware/step/step_test.go @@ -10,6 +10,7 @@ import ( "testing" "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/org" @@ -38,9 +39,12 @@ func TestStep_Retrieve(t *testing.T) { func TestStep_Establish(t *testing.T) { // setup types - r := new(library.Repo) + owner := new(library.User) + owner.SetID(1) + + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.SetOwner(owner) r.SetHash("baz") r.SetOrg("foo") r.SetName("bar") @@ -153,9 +157,12 @@ func TestStep_Establish_NoRepo(t *testing.T) { func TestStep_Establish_NoBuild(t *testing.T) { // setup types - r := new(library.Repo) + owner := new(library.User) + owner.SetID(1) + + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.SetOwner(owner) r.SetHash("baz") r.SetOrg("foo") r.SetName("bar") @@ -201,9 +208,12 @@ func TestStep_Establish_NoBuild(t *testing.T) { func TestStep_Establish_NoStepParameter(t *testing.T) { // setup types - r := new(library.Repo) + owner := new(library.User) + owner.SetID(1) + + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.SetOwner(owner) r.SetHash("baz") r.SetOrg("foo") r.SetName("bar") @@ -257,9 +267,12 @@ func TestStep_Establish_NoStepParameter(t *testing.T) { func TestStep_Establish_InvalidStepParameter(t *testing.T) { // setup types - r := new(library.Repo) + owner := new(library.User) + owner.SetID(1) + + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.SetOwner(owner) r.SetHash("baz") r.SetOrg("foo") r.SetName("bar") @@ -313,9 +326,12 @@ func TestStep_Establish_InvalidStepParameter(t *testing.T) { func TestStep_Establish_NoStep(t *testing.T) { // setup types - r := new(library.Repo) + owner := new(library.User) + owner.SetID(1) + + r := new(api.Repo) r.SetID(1) - r.SetUserID(1) + r.SetOwner(owner) r.SetHash("baz") r.SetOrg("foo") r.SetName("bar") diff --git a/scm/github/changeset.go b/scm/github/changeset.go index de97c22d4..b99a00371 100644 --- a/scm/github/changeset.go +++ b/scm/github/changeset.go @@ -8,20 +8,20 @@ import ( "github.com/sirupsen/logrus" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" "github.com/google/go-github/v61/github" ) // Changeset captures the list of files changed for a commit. -func (c *client) Changeset(ctx context.Context, u *library.User, r *library.Repo, sha string) ([]string, error) { +func (c *client) Changeset(ctx context.Context, r *api.Repo, sha string) ([]string, error) { c.Logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), - "user": u.GetName(), + "user": r.GetOwner().GetName(), }).Tracef("capturing commit changeset for %s/commit/%s", r.GetFullName(), sha) // create GitHub OAuth client with user's token - client := c.newClientToken(u.GetToken()) + client := c.newClientToken(r.GetOwner().GetToken()) s := []string{} // set the max per page for the options to capture the commit @@ -42,15 +42,15 @@ func (c *client) Changeset(ctx context.Context, u *library.User, r *library.Repo } // ChangesetPR captures the list of files changed for a pull request. -func (c *client) ChangesetPR(ctx context.Context, u *library.User, r *library.Repo, number int) ([]string, error) { +func (c *client) ChangesetPR(ctx context.Context, r *api.Repo, number int) ([]string, error) { c.Logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), - "user": u.GetName(), + "user": r.GetOwner().GetName(), }).Tracef("capturing pull request changeset for %s/pull/%d", r.GetFullName(), number) // create GitHub OAuth client with user's token - client := c.newClientToken(u.GetToken()) + client := c.newClientToken(r.GetOwner().GetToken()) s := []string{} f := []*github.CommitFile{} diff --git a/scm/github/changeset_test.go b/scm/github/changeset_test.go index 2fefbad93..713f08f9a 100644 --- a/scm/github/changeset_test.go +++ b/scm/github/changeset_test.go @@ -11,6 +11,7 @@ import ( "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/library" ) @@ -38,14 +39,15 @@ func TestGithub_Changeset(t *testing.T) { u.SetName("foo") u.SetToken("bar") - r := new(library.Repo) + r := new(api.Repo) r.SetOrg("repos") r.SetName("octocat") + r.SetOwner(u) client, _ := NewTest(s.URL) // run test - got, err := client.Changeset(context.TODO(), u, r, "6dcb09b5b57875f334f61aebed695e2e4193db5e") + got, err := client.Changeset(context.TODO(), r, "6dcb09b5b57875f334f61aebed695e2e4193db5e") if resp.Code != http.StatusOK { t.Errorf("Changeset returned %v, want %v", resp.Code, http.StatusOK) @@ -84,14 +86,15 @@ func TestGithub_ChangesetPR(t *testing.T) { u.SetName("foo") u.SetToken("bar") - r := new(library.Repo) + r := new(api.Repo) r.SetOrg("repos") r.SetName("octocat") + r.SetOwner(u) client, _ := NewTest(s.URL) // run test - got, err := client.ChangesetPR(context.TODO(), u, r, 1) + got, err := client.ChangesetPR(context.TODO(), r, 1) if resp.Code != http.StatusOK { t.Errorf("ChangesetPR returned %v, want %v", resp.Code, http.StatusOK) diff --git a/scm/github/deployment.go b/scm/github/deployment.go index 835ad851a..ce0db052d 100644 --- a/scm/github/deployment.go +++ b/scm/github/deployment.go @@ -8,13 +8,14 @@ import ( "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/library" "github.com/go-vela/types/raw" "github.com/google/go-github/v61/github" ) // GetDeployment gets a deployment from the GitHub repo. -func (c *client) GetDeployment(ctx context.Context, u *library.User, r *library.Repo, id int64) (*library.Deployment, error) { +func (c *client) GetDeployment(ctx context.Context, u *library.User, r *api.Repo, id int64) (*library.Deployment, error) { c.Logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), @@ -55,7 +56,7 @@ func (c *client) GetDeployment(ctx context.Context, u *library.User, r *library. } // GetDeploymentCount counts a list of deployments from the GitHub repo. -func (c *client) GetDeploymentCount(ctx context.Context, u *library.User, r *library.Repo) (int64, error) { +func (c *client) GetDeploymentCount(ctx context.Context, u *library.User, r *api.Repo) (int64, error) { c.Logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), @@ -97,7 +98,7 @@ func (c *client) GetDeploymentCount(ctx context.Context, u *library.User, r *lib } // GetDeploymentList gets a list of deployments from the GitHub repo. -func (c *client) GetDeploymentList(ctx context.Context, u *library.User, r *library.Repo, page, perPage int) ([]*library.Deployment, error) { +func (c *client) GetDeploymentList(ctx context.Context, u *library.User, r *api.Repo, page, perPage int) ([]*library.Deployment, error) { c.Logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), @@ -155,7 +156,7 @@ func (c *client) GetDeploymentList(ctx context.Context, u *library.User, r *libr } // CreateDeployment creates a new deployment for the GitHub repo. -func (c *client) CreateDeployment(ctx context.Context, u *library.User, r *library.Repo, d *library.Deployment) error { +func (c *client) CreateDeployment(ctx context.Context, u *library.User, r *api.Repo, d *library.Deployment) error { c.Logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), diff --git a/scm/github/deployment_test.go b/scm/github/deployment_test.go index 378a2417a..622dacfb4 100644 --- a/scm/github/deployment_test.go +++ b/scm/github/deployment_test.go @@ -10,6 +10,7 @@ import ( "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/library" ) @@ -35,7 +36,7 @@ func TestGithub_CreateDeployment(t *testing.T) { u.SetName("foo") u.SetToken("bar") - r := new(library.Repo) + r := new(api.Repo) r.SetID(1) r.SetOrg("foo") r.SetName("bar") diff --git a/scm/github/repo.go b/scm/github/repo.go index df90e5cb1..7a2d973f8 100644 --- a/scm/github/repo.go +++ b/scm/github/repo.go @@ -12,6 +12,7 @@ import ( "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" "github.com/google/go-github/v61/github" @@ -19,7 +20,7 @@ import ( // ConfigBackoff is a wrapper for Config that will retry five times if the function // fails to retrieve the yaml/yml file. -func (c *client) ConfigBackoff(ctx context.Context, u *library.User, r *library.Repo, ref string) (data []byte, err error) { +func (c *client) ConfigBackoff(ctx context.Context, u *library.User, r *api.Repo, ref string) (data []byte, err error) { // number of times to retry retryLimit := 5 @@ -47,7 +48,7 @@ func (c *client) ConfigBackoff(ctx context.Context, u *library.User, r *library. } // Config gets the pipeline configuration from the GitHub repo. -func (c *client) Config(ctx context.Context, u *library.User, r *library.Repo, ref string) ([]byte, error) { +func (c *client) Config(ctx context.Context, u *library.User, r *api.Repo, ref string) ([]byte, error) { c.Logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), @@ -149,7 +150,7 @@ func (c *client) Disable(ctx context.Context, u *library.User, org, name string) } // Enable activates a repo by creating the webhook. -func (c *client) Enable(ctx context.Context, u *library.User, r *library.Repo, h *library.Hook) (*library.Hook, string, error) { +func (c *client) Enable(ctx context.Context, u *library.User, r *api.Repo, h *library.Hook) (*library.Hook, string, error) { c.Logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), @@ -223,7 +224,7 @@ func (c *client) Enable(ctx context.Context, u *library.User, r *library.Repo, h } // Update edits a repo webhook. -func (c *client) Update(ctx context.Context, u *library.User, r *library.Repo, hookID int64) (bool, error) { +func (c *client) Update(ctx context.Context, u *library.User, r *api.Repo, hookID int64) (bool, error) { c.Logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), @@ -462,7 +463,7 @@ func (c *client) StepStatus(ctx context.Context, u *library.User, b *library.Bui } // GetRepo gets repo information from Github. -func (c *client) GetRepo(ctx context.Context, u *library.User, r *library.Repo) (*library.Repo, int, error) { +func (c *client) GetRepo(ctx context.Context, u *library.User, r *api.Repo) (*api.Repo, int, error) { c.Logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), @@ -502,7 +503,7 @@ func (c *client) GetOrgAndRepoName(ctx context.Context, u *library.User, o strin } // ListUserRepos returns a list of all repos the user has access to. -func (c *client) ListUserRepos(ctx context.Context, u *library.User) ([]*library.Repo, error) { +func (c *client) ListUserRepos(ctx context.Context, u *library.User) ([]*api.Repo, error) { c.Logger.WithFields(logrus.Fields{ "user": u.GetName(), }).Tracef("listing source repositories for %s", u.GetName()) @@ -511,7 +512,7 @@ func (c *client) ListUserRepos(ctx context.Context, u *library.User) ([]*library client := c.newClientToken(u.GetToken()) r := []*github.Repository{} - f := []*library.Repo{} + f := []*api.Repo{} // set the max per page for the options to capture the list of repos opts := &github.RepositoryListOptions{ @@ -556,7 +557,7 @@ func (c *client) ListUserRepos(ctx context.Context, u *library.User) ([]*library } // toLibraryRepo does a partial conversion of a github repo to a library repo. -func toLibraryRepo(gr github.Repository) *library.Repo { +func toLibraryRepo(gr github.Repository) *api.Repo { // setting the visbility to match the SCM visbility var visibility string if *gr.Private { @@ -565,7 +566,7 @@ func toLibraryRepo(gr github.Repository) *library.Repo { visibility = constants.VisibilityPublic } - return &library.Repo{ + return &api.Repo{ Org: gr.GetOwner().Login, Name: gr.Name, FullName: gr.FullName, @@ -580,15 +581,15 @@ func toLibraryRepo(gr github.Repository) *library.Repo { // GetPullRequest defines a function that retrieves // a pull request for a repo. -func (c *client) GetPullRequest(ctx context.Context, u *library.User, r *library.Repo, number int) (string, string, string, string, error) { +func (c *client) GetPullRequest(ctx context.Context, r *api.Repo, number int) (string, string, string, string, error) { c.Logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), - "user": u.GetName(), + "user": r.GetOwner().GetName(), }).Tracef("retrieving pull request %d for repo %s", number, r.GetFullName()) // create GitHub OAuth client with user's token - client := c.newClientToken(u.GetToken()) + client := c.newClientToken(r.GetOwner().GetToken()) pull, _, err := client.PullRequests.Get(ctx, r.GetOrg(), r.GetName(), number) if err != nil { @@ -640,15 +641,15 @@ func (c *client) GetHTMLURL(ctx context.Context, u *library.User, org, repo, nam } // GetBranch defines a function that retrieves a branch for a repo. -func (c *client) GetBranch(ctx context.Context, u *library.User, r *library.Repo, branch string) (string, string, error) { +func (c *client) GetBranch(ctx context.Context, r *api.Repo, branch string) (string, string, error) { c.Logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), - "user": u.GetName(), + "user": r.GetOwner().GetName(), }).Tracef("retrieving branch %s for repo %s", branch, r.GetFullName()) // create GitHub OAuth client with user's token - client := c.newClientToken(u.GetToken()) + client := c.newClientToken(r.GetOwner().GetToken()) maxRedirects := 3 diff --git a/scm/github/repo_test.go b/scm/github/repo_test.go index b34e704ac..64d86cb21 100644 --- a/scm/github/repo_test.go +++ b/scm/github/repo_test.go @@ -14,6 +14,7 @@ import ( "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" ) @@ -50,7 +51,7 @@ func TestGithub_Config_YML(t *testing.T) { u.SetName("foo") u.SetToken("bar") - r := new(library.Repo) + r := new(api.Repo) r.SetOrg("foo") r.SetName("bar") @@ -111,7 +112,7 @@ func TestGithub_ConfigBackoff_YML(t *testing.T) { u.SetName("foo") u.SetToken("bar") - r := new(library.Repo) + r := new(api.Repo) r.SetOrg("foo") r.SetName("bar") @@ -165,7 +166,7 @@ func TestGithub_Config_YAML(t *testing.T) { u.SetName("foo") u.SetToken("bar") - r := new(library.Repo) + r := new(api.Repo) r.SetOrg("foo") r.SetName("bar") @@ -219,7 +220,7 @@ func TestGithub_Config_Star(t *testing.T) { u.SetName("foo") u.SetToken("bar") - r := new(library.Repo) + r := new(api.Repo) r.SetOrg("foo") r.SetName("bar") r.SetPipelineType(constants.PipelineTypeStarlark) @@ -279,7 +280,7 @@ func TestGithub_Config_Star_Prefer(t *testing.T) { u.SetName("foo") u.SetToken("bar") - r := new(library.Repo) + r := new(api.Repo) r.SetOrg("foo") r.SetName("bar") r.SetPipelineType(constants.PipelineTypeStarlark) @@ -334,7 +335,7 @@ func TestGithub_Config_Py(t *testing.T) { u.SetName("foo") u.SetToken("bar") - r := new(library.Repo) + r := new(api.Repo) r.SetOrg("foo") r.SetName("bar") r.SetPipelineType(constants.PipelineTypeStarlark) @@ -384,7 +385,7 @@ func TestGithub_Config_YAML_BadRequest(t *testing.T) { u.SetName("foo") u.SetToken("bar") - r := new(library.Repo) + r := new(api.Repo) r.SetOrg("foo") r.SetName("bar") @@ -426,7 +427,7 @@ func TestGithub_Config_NotFound(t *testing.T) { u.SetName("foo") u.SetToken("bar") - r := new(library.Repo) + r := new(api.Repo) r.SetOrg("foo") r.SetName("bar") @@ -475,7 +476,7 @@ func TestGithub_Config_BadEncoding(t *testing.T) { u.SetName("foo") u.SetToken("bar") - r := new(library.Repo) + r := new(api.Repo) r.SetOrg("foo") r.SetName("bar") @@ -685,7 +686,7 @@ func TestGithub_Enable(t *testing.T) { wantHook.SetEvent("initialize") wantHook.SetStatus("success") - r := new(library.Repo) + r := new(api.Repo) r.SetID(1) r.SetName("bar") r.SetOrg("foo") @@ -731,7 +732,7 @@ func TestGithub_Update(t *testing.T) { u.SetName("foo") u.SetToken("bar") - r := new(library.Repo) + r := new(api.Repo) r.SetID(1) r.SetName("bar") r.SetOrg("foo") @@ -774,7 +775,7 @@ func TestGithub_Update_webhookExists_True(t *testing.T) { u.SetName("foo") u.SetToken("bar") - r := new(library.Repo) + r := new(api.Repo) client, _ := NewTest(s.URL) @@ -811,7 +812,7 @@ func TestGithub_Update_webhookExists_False(t *testing.T) { u.SetName("foo") u.SetToken("bar") - r := new(library.Repo) + r := new(api.Repo) client, _ := NewTest(s.URL) @@ -1260,11 +1261,11 @@ func TestGithub_GetRepo(t *testing.T) { u.SetName("foo") u.SetToken("bar") - r := new(library.Repo) + r := new(api.Repo) r.SetOrg("octocat") r.SetName("Hello-World") - want := new(library.Repo) + want := new(api.Repo) want.SetOrg("octocat") want.SetName("Hello-World") want.SetFullName("octocat/Hello-World") @@ -1314,7 +1315,7 @@ func TestGithub_GetRepo_Fail(t *testing.T) { u.SetName("foo") u.SetToken("bar") - r := new(library.Repo) + r := new(api.Repo) r.SetOrg("octocat") r.SetName("Hello-World") @@ -1432,7 +1433,7 @@ func TestGithub_ListUserRepos(t *testing.T) { u.SetName("foo") u.SetToken("bar") - r := new(library.Repo) + r := new(api.Repo) r.SetOrg("octocat") r.SetName("Hello-World") r.SetFullName("octocat/Hello-World") @@ -1443,7 +1444,7 @@ func TestGithub_ListUserRepos(t *testing.T) { r.SetTopics([]string{"octocat", "atom", "electron", "api"}) r.SetVisibility("public") - want := []*library.Repo{r} + want := []*api.Repo{r} client, _ := NewTest(s.URL) @@ -1480,7 +1481,7 @@ func TestGithub_ListUserRepos_Ineligible(t *testing.T) { u.SetName("foo") u.SetToken("bar") - want := []*library.Repo{} + want := []*api.Repo{} client, _ := NewTest(s.URL) @@ -1517,9 +1518,10 @@ func TestGithub_GetPullRequest(t *testing.T) { u.SetName("foo") u.SetToken("bar") - r := new(library.Repo) + r := new(api.Repo) r.SetOrg("octocat") r.SetName("Hello-World") + r.SetOwner(u) wantCommit := "6dcb09b5b57875f334f61aebed695e2e4193db5e" wantBranch := "main" @@ -1529,7 +1531,7 @@ func TestGithub_GetPullRequest(t *testing.T) { client, _ := NewTest(s.URL) // run test - gotCommit, gotBranch, gotBaseRef, gotHeadRef, err := client.GetPullRequest(context.TODO(), u, r, 1) + gotCommit, gotBranch, gotBaseRef, gotHeadRef, err := client.GetPullRequest(context.TODO(), r, 1) if err != nil { t.Errorf("Status returned err: %v", err) } @@ -1573,11 +1575,12 @@ func TestGithub_GetBranch(t *testing.T) { u.SetName("foo") u.SetToken("bar") - r := new(library.Repo) + r := new(api.Repo) r.SetOrg("octocat") r.SetName("Hello-World") r.SetFullName("octocat/Hello-World") r.SetBranch("main") + r.SetOwner(u) wantBranch := "main" wantCommit := "7fd1a60b01f91b314f59955a4e4d4e80d8edf11d" @@ -1585,7 +1588,7 @@ func TestGithub_GetBranch(t *testing.T) { client, _ := NewTest(s.URL) // run test - gotBranch, gotCommit, err := client.GetBranch(context.TODO(), u, r, "main") + gotBranch, gotCommit, err := client.GetBranch(context.TODO(), r, "main") if err != nil { t.Errorf("Status returned err: %v", err) } diff --git a/scm/github/webhook.go b/scm/github/webhook.go index 3e2e5badd..9e9dccac5 100644 --- a/scm/github/webhook.go +++ b/scm/github/webhook.go @@ -15,7 +15,8 @@ import ( "github.com/sirupsen/logrus" - "github.com/go-vela/types" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/internal" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" "github.com/google/go-github/v61/github" @@ -24,7 +25,7 @@ import ( // ProcessWebhook parses the webhook from a repo. // //nolint:nilerr // ignore webhook returning nil -func (c *client) ProcessWebhook(ctx context.Context, request *http.Request) (*types.Webhook, error) { +func (c *client) ProcessWebhook(ctx context.Context, request *http.Request) (*internal.Webhook, error) { c.Logger.Tracef("processing GitHub webhook") // create our own record of the hook and populate its fields @@ -55,14 +56,14 @@ func (c *client) ProcessWebhook(ctx context.Context, request *http.Request) (*ty payload, err := github.ValidatePayloadFromBody(contentType, request.Body, "", nil) if err != nil { - return &types.Webhook{Hook: h}, nil + return &internal.Webhook{Hook: h}, nil } // parse the payload from the webhook event, err := github.ParseWebHook(github.WebHookType(request), payload) if err != nil { - return &types.Webhook{Hook: h}, nil + return &internal.Webhook{Hook: h}, nil } // process the event from the webhook @@ -79,11 +80,11 @@ func (c *client) ProcessWebhook(ctx context.Context, request *http.Request) (*ty return c.processRepositoryEvent(h, event) } - return &types.Webhook{Hook: h}, nil + return &internal.Webhook{Hook: h}, nil } // VerifyWebhook verifies the webhook from a repo. -func (c *client) VerifyWebhook(ctx context.Context, request *http.Request, r *library.Repo) error { +func (c *client) VerifyWebhook(ctx context.Context, request *http.Request, r *api.Repo) error { c.Logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), @@ -98,7 +99,7 @@ func (c *client) VerifyWebhook(ctx context.Context, request *http.Request, r *li } // RedeliverWebhook redelivers webhooks from GitHub. -func (c *client) RedeliverWebhook(ctx context.Context, u *library.User, r *library.Repo, h *library.Hook) error { +func (c *client) RedeliverWebhook(ctx context.Context, u *library.User, r *api.Repo, h *library.Hook) error { // create GitHub OAuth client with user's token //nolint:contextcheck // do not need to pass context in this instance client := c.newClientToken(*u.Token) @@ -127,7 +128,7 @@ func (c *client) RedeliverWebhook(ctx context.Context, u *library.User, r *libra } // processPushEvent is a helper function to process the push event. -func (c *client) processPushEvent(h *library.Hook, payload *github.PushEvent) (*types.Webhook, error) { +func (c *client) processPushEvent(h *library.Hook, payload *github.PushEvent) (*internal.Webhook, error) { c.Logger.WithFields(logrus.Fields{ "org": payload.GetRepo().GetOwner().GetLogin(), "repo": payload.GetRepo().GetName(), @@ -136,7 +137,7 @@ func (c *client) processPushEvent(h *library.Hook, payload *github.PushEvent) (* repo := payload.GetRepo() // convert payload to library repo - r := new(library.Repo) + r := new(api.Repo) r.SetOrg(repo.GetOwner().GetLogin()) r.SetName(repo.GetName()) r.SetFullName(repo.GetFullName()) @@ -224,7 +225,7 @@ func (c *client) processPushEvent(h *library.Hook, payload *github.PushEvent) (* } } - return &types.Webhook{ + return &internal.Webhook{ Hook: h, Repo: r, Build: b, @@ -232,7 +233,7 @@ func (c *client) processPushEvent(h *library.Hook, payload *github.PushEvent) (* } // processPREvent is a helper function to process the pull_request event. -func (c *client) processPREvent(h *library.Hook, payload *github.PullRequestEvent) (*types.Webhook, error) { +func (c *client) processPREvent(h *library.Hook, payload *github.PullRequestEvent) (*internal.Webhook, error) { c.Logger.WithFields(logrus.Fields{ "org": payload.GetRepo().GetOwner().GetLogin(), "repo": payload.GetRepo().GetName(), @@ -247,7 +248,7 @@ func (c *client) processPREvent(h *library.Hook, payload *github.PullRequestEven // if the pull request state isn't open we ignore it if payload.GetPullRequest().GetState() != "open" { - return &types.Webhook{Hook: h}, nil + return &internal.Webhook{Hook: h}, nil } // skip if the pull request action is not opened, synchronize, reopened, edited, labeled, or unlabeled @@ -257,14 +258,14 @@ func (c *client) processPREvent(h *library.Hook, payload *github.PullRequestEven !strings.EqualFold(payload.GetAction(), "edited") && !strings.EqualFold(payload.GetAction(), "labeled") && !strings.EqualFold(payload.GetAction(), "unlabeled") { - return &types.Webhook{Hook: h}, nil + return &internal.Webhook{Hook: h}, nil } // capture the repo from the payload repo := payload.GetRepo() // convert payload to library repo - r := new(library.Repo) + r := new(api.Repo) r.SetOrg(repo.GetOwner().GetLogin()) r.SetName(repo.GetName()) r.SetFullName(repo.GetFullName()) @@ -326,8 +327,8 @@ func (c *client) processPREvent(h *library.Hook, payload *github.PullRequestEven fromFork := payload.GetPullRequest().GetHead().GetRepo().GetFork() && !strings.EqualFold(payload.GetPullRequest().GetBase().GetRepo().GetFullName(), payload.GetPullRequest().GetHead().GetRepo().GetFullName()) - return &types.Webhook{ - PullRequest: types.PullRequest{ + return &internal.Webhook{ + PullRequest: internal.PullRequest{ Number: payload.GetNumber(), IsFromFork: fromFork, Labels: prLabels, @@ -339,7 +340,7 @@ func (c *client) processPREvent(h *library.Hook, payload *github.PullRequestEven } // processDeploymentEvent is a helper function to process the deployment event. -func (c *client) processDeploymentEvent(h *library.Hook, payload *github.DeploymentEvent) (*types.Webhook, error) { +func (c *client) processDeploymentEvent(h *library.Hook, payload *github.DeploymentEvent) (*internal.Webhook, error) { c.Logger.WithFields(logrus.Fields{ "org": payload.GetRepo().GetOwner().GetLogin(), "repo": payload.GetRepo().GetName(), @@ -349,7 +350,7 @@ func (c *client) processDeploymentEvent(h *library.Hook, payload *github.Deploym repo := payload.GetRepo() // convert payload to library repo - r := new(library.Repo) + r := new(api.Repo) r.SetOrg(repo.GetOwner().GetLogin()) r.SetName(repo.GetName()) r.SetFullName(repo.GetFullName()) @@ -399,7 +400,7 @@ func (c *client) processDeploymentEvent(h *library.Hook, payload *github.Deploym // unmarshal the payload into the expected map[string]string format err := json.Unmarshal(payload.GetDeployment().Payload, &deployPayload) if err != nil { - return &types.Webhook{}, err + return &internal.Webhook{}, err } // check if the map is empty @@ -430,7 +431,7 @@ func (c *client) processDeploymentEvent(h *library.Hook, payload *github.Deploym fmt.Sprintf("https://%s/%s/settings/hooks", h.GetHost(), r.GetFullName()), ) - return &types.Webhook{ + return &internal.Webhook{ Hook: h, Repo: r, Build: b, @@ -439,7 +440,7 @@ func (c *client) processDeploymentEvent(h *library.Hook, payload *github.Deploym } // processIssueCommentEvent is a helper function to process the issue comment event. -func (c *client) processIssueCommentEvent(h *library.Hook, payload *github.IssueCommentEvent) (*types.Webhook, error) { +func (c *client) processIssueCommentEvent(h *library.Hook, payload *github.IssueCommentEvent) (*internal.Webhook, error) { c.Logger.WithFields(logrus.Fields{ "org": payload.GetRepo().GetOwner().GetLogin(), "repo": payload.GetRepo().GetName(), @@ -453,8 +454,8 @@ func (c *client) processIssueCommentEvent(h *library.Hook, payload *github.Issue // skip if the comment action is deleted or not part of a pull request if strings.EqualFold(payload.GetAction(), "deleted") || !payload.GetIssue().IsPullRequest() { - // return &types.Webhook{Hook: h}, nil - return &types.Webhook{ + // return &internal.Webhook{Hook: h}, nil + return &internal.Webhook{ Hook: h, }, nil } @@ -463,7 +464,7 @@ func (c *client) processIssueCommentEvent(h *library.Hook, payload *github.Issue repo := payload.GetRepo() // convert payload to library repo - r := new(library.Repo) + r := new(api.Repo) r.SetOrg(repo.GetOwner().GetLogin()) r.SetName(repo.GetName()) r.SetFullName(repo.GetFullName()) @@ -486,8 +487,8 @@ func (c *client) processIssueCommentEvent(h *library.Hook, payload *github.Issue b.SetEmail(payload.GetIssue().GetUser().GetEmail()) b.SetRef(fmt.Sprintf("refs/pull/%d/head", payload.GetIssue().GetNumber())) - return &types.Webhook{ - PullRequest: types.PullRequest{ + return &internal.Webhook{ + PullRequest: internal.PullRequest{ Comment: payload.GetComment().GetBody(), Number: payload.GetIssue().GetNumber(), }, @@ -499,13 +500,13 @@ func (c *client) processIssueCommentEvent(h *library.Hook, payload *github.Issue // processRepositoryEvent is a helper function to process the repository event. -func (c *client) processRepositoryEvent(h *library.Hook, payload *github.RepositoryEvent) (*types.Webhook, error) { +func (c *client) processRepositoryEvent(h *library.Hook, payload *github.RepositoryEvent) (*internal.Webhook, error) { logrus.Tracef("processing repository event GitHub webhook for %s", payload.GetRepo().GetFullName()) repo := payload.GetRepo() // convert payload to library repo - r := new(library.Repo) + r := new(api.Repo) r.SetOrg(repo.GetOwner().GetLogin()) r.SetName(repo.GetName()) r.SetFullName(repo.GetFullName()) @@ -523,7 +524,7 @@ func (c *client) processRepositoryEvent(h *library.Hook, payload *github.Reposit fmt.Sprintf("https://%s/%s/settings/hooks", h.GetHost(), r.GetFullName()), ) - return &types.Webhook{ + return &internal.Webhook{ Hook: h, Repo: r, }, nil @@ -531,7 +532,7 @@ func (c *client) processRepositoryEvent(h *library.Hook, payload *github.Reposit // getDeliveryID gets the last 100 webhook deliveries for a repo and // finds the matching delivery id with the source id in the hook. -func (c *client) getDeliveryID(ctx context.Context, ghClient *github.Client, r *library.Repo, h *library.Hook) (int64, error) { +func (c *client) getDeliveryID(ctx context.Context, ghClient *github.Client, r *api.Repo, h *library.Hook) (int64, error) { c.Logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), diff --git a/scm/github/webhook_test.go b/scm/github/webhook_test.go index 3bf0415f9..00454fdf7 100644 --- a/scm/github/webhook_test.go +++ b/scm/github/webhook_test.go @@ -13,10 +13,11 @@ import ( "time" "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/internal" "github.com/go-vela/types/raw" "github.com/google/go-cmp/cmp" - "github.com/go-vela/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" ) @@ -56,7 +57,7 @@ func TestGithub_ProcessWebhook_Push(t *testing.T) { wantHook.SetStatus(constants.StatusSuccess) wantHook.SetLink("https://github.com/Codertocat/Hello-World/settings/hooks") - wantRepo := new(library.Repo) + wantRepo := new(api.Repo) wantRepo.SetOrg("Codertocat") wantRepo.SetName("Hello-World") wantRepo.SetFullName("Codertocat/Hello-World") @@ -80,7 +81,7 @@ func TestGithub_ProcessWebhook_Push(t *testing.T) { wantBuild.SetRef("refs/heads/main") wantBuild.SetBaseRef("") - want := &types.Webhook{ + want := &internal.Webhook{ Hook: wantHook, Repo: wantRepo, Build: wantBuild, @@ -134,7 +135,7 @@ func TestGithub_ProcessWebhook_Push_NoSender(t *testing.T) { wantHook.SetStatus(constants.StatusSuccess) wantHook.SetLink("https://github.com/Codertocat/Hello-World/settings/hooks") - wantRepo := new(library.Repo) + wantRepo := new(api.Repo) wantRepo.SetOrg("Codertocat") wantRepo.SetName("Hello-World") wantRepo.SetFullName("Codertocat/Hello-World") @@ -158,7 +159,7 @@ func TestGithub_ProcessWebhook_Push_NoSender(t *testing.T) { wantBuild.SetRef("refs/heads/main") wantBuild.SetBaseRef("") - want := &types.Webhook{ + want := &internal.Webhook{ Hook: wantHook, Repo: wantRepo, Build: wantBuild, @@ -210,7 +211,7 @@ func TestGithub_ProcessWebhook_Push_Branch_Delete(t *testing.T) { wantHook.SetStatus(constants.StatusSuccess) wantHook.SetLink("https://github.com/Codertocat/Hello-World/settings/hooks") - wantRepo := new(library.Repo) + wantRepo := new(api.Repo) wantRepo.SetOrg("Codertocat") wantRepo.SetName("Hello-World") wantRepo.SetFullName("Codertocat/Hello-World") @@ -235,7 +236,7 @@ func TestGithub_ProcessWebhook_Push_Branch_Delete(t *testing.T) { wantBuild.SetRef("d3d9188fc87a6977343e922c128f162a86018d76") wantBuild.SetBaseRef("") - want := &types.Webhook{ + want := &internal.Webhook{ Hook: wantHook, Repo: wantRepo, Build: wantBuild, @@ -287,7 +288,7 @@ func TestGithub_ProcessWebhook_Push_Tag_Delete(t *testing.T) { wantHook.SetStatus(constants.StatusSuccess) wantHook.SetLink("https://github.com/Codertocat/Hello-World/settings/hooks") - wantRepo := new(library.Repo) + wantRepo := new(api.Repo) wantRepo.SetOrg("Codertocat") wantRepo.SetName("Hello-World") wantRepo.SetFullName("Codertocat/Hello-World") @@ -312,7 +313,7 @@ func TestGithub_ProcessWebhook_Push_Tag_Delete(t *testing.T) { wantBuild.SetRef("d3d9188fc87a6977343e922c128f162a86018d76") wantBuild.SetBaseRef("") - want := &types.Webhook{ + want := &internal.Webhook{ Hook: wantHook, Repo: wantRepo, Build: wantBuild, @@ -346,7 +347,7 @@ func TestGithub_ProcessWebhook_PullRequest(t *testing.T) { wantHook.SetStatus(constants.StatusSuccess) wantHook.SetLink("https://github.com/Codertocat/Hello-World/settings/hooks") - wantRepo := new(library.Repo) + wantRepo := new(api.Repo) wantRepo.SetOrg("Codertocat") wantRepo.SetName("Hello-World") wantRepo.SetFullName("Codertocat/Hello-World") @@ -423,14 +424,14 @@ func TestGithub_ProcessWebhook_PullRequest(t *testing.T) { tests := []struct { name string testData string - want *types.Webhook + want *internal.Webhook wantErr bool }{ { name: "success", testData: "testdata/hooks/pull_request.json", - want: &types.Webhook{ - PullRequest: types.PullRequest{ + want: &internal.Webhook{ + PullRequest: internal.PullRequest{ Number: wantHook.GetNumber(), IsFromFork: false, }, @@ -442,8 +443,8 @@ func TestGithub_ProcessWebhook_PullRequest(t *testing.T) { { name: "fork", testData: "testdata/hooks/pull_request_fork.json", - want: &types.Webhook{ - PullRequest: types.PullRequest{ + want: &internal.Webhook{ + PullRequest: internal.PullRequest{ Number: wantHook.GetNumber(), IsFromFork: true, }, @@ -455,8 +456,8 @@ func TestGithub_ProcessWebhook_PullRequest(t *testing.T) { { name: "fork same repo", testData: "testdata/hooks/pull_request_fork_same-repo.json", - want: &types.Webhook{ - PullRequest: types.PullRequest{ + want: &internal.Webhook{ + PullRequest: internal.PullRequest{ Number: wantHook.GetNumber(), IsFromFork: false, }, @@ -468,7 +469,7 @@ func TestGithub_ProcessWebhook_PullRequest(t *testing.T) { { name: "closed action", testData: "testdata/hooks/pull_request_closed_action.json", - want: &types.Webhook{ + want: &internal.Webhook{ Hook: wantHook, Repo: nil, Build: nil, @@ -477,7 +478,7 @@ func TestGithub_ProcessWebhook_PullRequest(t *testing.T) { { name: "closed state", testData: "testdata/hooks/pull_request_closed_state.json", - want: &types.Webhook{ + want: &internal.Webhook{ Hook: wantHook, Repo: nil, Build: nil, @@ -486,8 +487,8 @@ func TestGithub_ProcessWebhook_PullRequest(t *testing.T) { { name: "labeled documentation", testData: "testdata/hooks/pull_request_labeled.json", - want: &types.Webhook{ - PullRequest: types.PullRequest{ + want: &internal.Webhook{ + PullRequest: internal.PullRequest{ Number: wantHook.GetNumber(), IsFromFork: false, Labels: []string{"documentation"}, @@ -500,8 +501,8 @@ func TestGithub_ProcessWebhook_PullRequest(t *testing.T) { { name: "unlabeled documentation", testData: "testdata/hooks/pull_request_unlabeled.json", - want: &types.Webhook{ - PullRequest: types.PullRequest{ + want: &internal.Webhook{ + PullRequest: internal.PullRequest{ Number: wantHook.GetNumber(), IsFromFork: false, Labels: []string{"documentation"}, @@ -514,8 +515,8 @@ func TestGithub_ProcessWebhook_PullRequest(t *testing.T) { { name: "edited while labeled documentation", testData: "testdata/hooks/pull_request_edited_while_labeled.json", - want: &types.Webhook{ - PullRequest: types.PullRequest{ + want: &internal.Webhook{ + PullRequest: internal.PullRequest{ Number: wantHook.GetNumber(), IsFromFork: false, Labels: []string{"documentation", "enhancement"}, @@ -576,7 +577,7 @@ func TestGithub_ProcessWebhook_Deployment(t *testing.T) { wantHook.SetEvent("deployment") wantHook.SetStatus(constants.StatusSuccess) - wantRepo := new(library.Repo) + wantRepo := new(api.Repo) wantRepo.SetOrg("Codertocat") wantRepo.SetName("Hello-World") wantRepo.SetFullName("Codertocat/Hello-World") @@ -615,7 +616,7 @@ func TestGithub_ProcessWebhook_Deployment(t *testing.T) { type args struct { file string hook *library.Hook - repo *library.Repo + repo *api.Repo build *library.Build deploymentPayload raw.StringSliceMap deployment *library.Deployment @@ -652,7 +653,7 @@ func TestGithub_ProcessWebhook_Deployment(t *testing.T) { client, _ := NewTest(s.URL) wantBuild.SetDeployPayload(tt.args.deploymentPayload) - want := &types.Webhook{ + want := &internal.Webhook{ Hook: tt.args.hook, Repo: tt.args.repo, Build: tt.args.build, @@ -709,7 +710,7 @@ func TestGithub_ProcessWebhook_Deployment_Commit(t *testing.T) { wantHook.SetEvent("deployment") wantHook.SetStatus(constants.StatusSuccess) - wantRepo := new(library.Repo) + wantRepo := new(api.Repo) wantRepo.SetOrg("Codertocat") wantRepo.SetName("Hello-World") wantRepo.SetFullName("Codertocat/Hello-World") @@ -746,7 +747,7 @@ func TestGithub_ProcessWebhook_Deployment_Commit(t *testing.T) { wantDeployment.SetCreatedAt(time.Now().UTC().Unix()) wantDeployment.SetCreatedBy("Codertocat") - want := &types.Webhook{ + want := &internal.Webhook{ Hook: wantHook, Repo: wantRepo, Build: wantBuild, @@ -799,7 +800,7 @@ func TestGithub_ProcessWebhook_BadGithubEvent(t *testing.T) { wantHook.SetEvent("foobar") wantHook.SetStatus(constants.StatusSuccess) - want := &types.Webhook{ + want := &internal.Webhook{ Hook: wantHook, Repo: nil, Build: nil, @@ -852,7 +853,7 @@ func TestGithub_ProcessWebhook_BadContentType(t *testing.T) { wantHook.SetEvent("pull_request") wantHook.SetStatus(constants.StatusSuccess) - want := &types.Webhook{ + want := &internal.Webhook{ Hook: wantHook, Repo: nil, Build: nil, @@ -896,7 +897,7 @@ func TestGithub_VerifyWebhook_EmptyRepo(t *testing.T) { client, _ := NewTest(s.URL) // run test - err = client.VerifyWebhook(context.TODO(), request, new(library.Repo)) + err = client.VerifyWebhook(context.TODO(), request, new(api.Repo)) if err != nil { t.Errorf("VerifyWebhook should have returned err") } @@ -907,7 +908,7 @@ func TestGithub_VerifyWebhook_NoSecret(t *testing.T) { s := httptest.NewServer(http.NotFoundHandler()) defer s.Close() - r := new(library.Repo) + r := new(api.Repo) r.SetOrg("Codertocat") r.SetName("Hello-World") r.SetFullName("Codertocat/Hello-World") @@ -979,7 +980,7 @@ func TestGithub_ProcessWebhook_IssueComment_PR(t *testing.T) { wantHook.SetStatus(constants.StatusSuccess) wantHook.SetLink("https://github.com/Codertocat/Hello-World/settings/hooks") - wantRepo := new(library.Repo) + wantRepo := new(api.Repo) wantRepo.SetOrg("Codertocat") wantRepo.SetName("Hello-World") wantRepo.SetFullName("Codertocat/Hello-World") @@ -1001,8 +1002,8 @@ func TestGithub_ProcessWebhook_IssueComment_PR(t *testing.T) { wantBuild.SetEmail("") wantBuild.SetRef("refs/pull/1/head") - want := &types.Webhook{ - PullRequest: types.PullRequest{ + want := &internal.Webhook{ + PullRequest: internal.PullRequest{ Comment: "ok to test", Number: wantHook.GetNumber(), }, @@ -1058,7 +1059,7 @@ func TestGithub_ProcessWebhook_IssueComment_Created(t *testing.T) { wantHook.SetStatus(constants.StatusSuccess) wantHook.SetLink("https://github.com/Codertocat/Hello-World/settings/hooks") - want := &types.Webhook{ + want := &internal.Webhook{ Hook: wantHook, } @@ -1109,7 +1110,7 @@ func TestGithub_ProcessWebhook_IssueComment_Deleted(t *testing.T) { wantHook.SetStatus(constants.StatusSuccess) wantHook.SetLink("https://github.com/Codertocat/Hello-World/settings/hooks") - want := &types.Webhook{ + want := &internal.Webhook{ Hook: wantHook, } @@ -1160,7 +1161,7 @@ func TestGitHub_ProcessWebhook_RepositoryRename(t *testing.T) { wantHook.SetStatus(constants.StatusSuccess) wantHook.SetLink("https://github.com/Codertocat/Hello-World/settings/hooks") - wantRepo := new(library.Repo) + wantRepo := new(api.Repo) wantRepo.SetActive(true) wantRepo.SetOrg("Codertocat") wantRepo.SetName("Hello-World") @@ -1171,7 +1172,7 @@ func TestGitHub_ProcessWebhook_RepositoryRename(t *testing.T) { wantRepo.SetPrivate(false) wantRepo.SetTopics(nil) - want := &types.Webhook{ + want := &internal.Webhook{ Hook: wantHook, Repo: wantRepo, } @@ -1223,7 +1224,7 @@ func TestGitHub_ProcessWebhook_RepositoryTransfer(t *testing.T) { wantHook.SetStatus(constants.StatusSuccess) wantHook.SetLink("https://github.com/Codertocat/Hello-World/settings/hooks") - wantRepo := new(library.Repo) + wantRepo := new(api.Repo) wantRepo.SetActive(true) wantRepo.SetOrg("Codertocat") wantRepo.SetName("Hello-World") @@ -1234,7 +1235,7 @@ func TestGitHub_ProcessWebhook_RepositoryTransfer(t *testing.T) { wantRepo.SetPrivate(false) wantRepo.SetTopics(nil) - want := &types.Webhook{ + want := &internal.Webhook{ Hook: wantHook, Repo: wantRepo, } @@ -1286,7 +1287,7 @@ func TestGitHub_ProcessWebhook_RepositoryArchived(t *testing.T) { wantHook.SetStatus(constants.StatusSuccess) wantHook.SetLink("https://github.com/Codertocat/Hello-World/settings/hooks") - wantRepo := new(library.Repo) + wantRepo := new(api.Repo) wantRepo.SetActive(false) wantRepo.SetOrg("Codertocat") wantRepo.SetName("Hello-World") @@ -1297,7 +1298,7 @@ func TestGitHub_ProcessWebhook_RepositoryArchived(t *testing.T) { wantRepo.SetPrivate(false) wantRepo.SetTopics(nil) - want := &types.Webhook{ + want := &internal.Webhook{ Hook: wantHook, Repo: wantRepo, } @@ -1349,7 +1350,7 @@ func TestGitHub_ProcessWebhook_RepositoryEdited(t *testing.T) { wantHook.SetStatus(constants.StatusSuccess) wantHook.SetLink("https://github.com/Codertocat/Hello-World/settings/hooks") - wantRepo := new(library.Repo) + wantRepo := new(api.Repo) wantRepo.SetActive(true) wantRepo.SetOrg("Codertocat") wantRepo.SetName("Hello-World") @@ -1360,7 +1361,7 @@ func TestGitHub_ProcessWebhook_RepositoryEdited(t *testing.T) { wantRepo.SetTopics([]string{"cloud", "security"}) wantRepo.SetPrivate(false) - want := &types.Webhook{ + want := &internal.Webhook{ Hook: wantHook, Repo: wantRepo, } @@ -1412,7 +1413,7 @@ func TestGitHub_ProcessWebhook_Repository(t *testing.T) { wantHook.SetStatus(constants.StatusSuccess) wantHook.SetLink("https://github.com/Codertocat/Hello-World/settings/hooks") - wantRepo := new(library.Repo) + wantRepo := new(api.Repo) wantRepo.SetActive(true) wantRepo.SetOrg("Codertocat") wantRepo.SetName("Hello-World") @@ -1423,7 +1424,7 @@ func TestGitHub_ProcessWebhook_Repository(t *testing.T) { wantRepo.SetPrivate(false) wantRepo.SetTopics(nil) - want := &types.Webhook{ + want := &internal.Webhook{ Hook: wantHook, Repo: wantRepo, } @@ -1474,7 +1475,7 @@ func TestGithub_Redeliver_Webhook(t *testing.T) { _hook.SetNumber(1) _hook.SetWebhookID(1234) - _repo := new(library.Repo) + _repo := new(api.Repo) _repo.SetID(1) _repo.SetName("bar") _repo.SetOrg("foo") @@ -1518,7 +1519,7 @@ func TestGithub_GetDeliveryID(t *testing.T) { _hook.SetNumber(1) _hook.SetWebhookID(1234) - _repo := new(library.Repo) + _repo := new(api.Repo) _repo.SetID(1) _repo.SetName("bar") _repo.SetOrg("foo") diff --git a/scm/service.go b/scm/service.go index bc594af03..b04a8cd5e 100644 --- a/scm/service.go +++ b/scm/service.go @@ -6,7 +6,8 @@ import ( "context" "net/http" - "github.com/go-vela/types" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/internal" "github.com/go-vela/types/library" ) @@ -67,46 +68,46 @@ type Service interface { // of files changed for a commit. // // https://en.wikipedia.org/wiki/Changeset. - Changeset(context.Context, *library.User, *library.Repo, string) ([]string, error) + Changeset(context.Context, *api.Repo, string) ([]string, error) // ChangesetPR defines a function that captures the list // of files changed for a pull request. // // https://en.wikipedia.org/wiki/Changeset. - ChangesetPR(context.Context, *library.User, *library.Repo, int) ([]string, error) + ChangesetPR(context.Context, *api.Repo, int) ([]string, error) // Deployment SCM Interface Functions // GetDeployment defines a function that // gets a deployment by number and repo. - GetDeployment(context.Context, *library.User, *library.Repo, int64) (*library.Deployment, error) + GetDeployment(context.Context, *library.User, *api.Repo, int64) (*library.Deployment, error) // GetDeploymentCount defines a function that // counts a list of all deployment for a repo. - GetDeploymentCount(context.Context, *library.User, *library.Repo) (int64, error) + GetDeploymentCount(context.Context, *library.User, *api.Repo) (int64, error) // GetDeploymentList defines a function that gets // a list of all deployments for a repo. - GetDeploymentList(context.Context, *library.User, *library.Repo, int, int) ([]*library.Deployment, error) + GetDeploymentList(context.Context, *library.User, *api.Repo, int, int) ([]*library.Deployment, error) // CreateDeployment defines a function that // creates a new deployment. - CreateDeployment(context.Context, *library.User, *library.Repo, *library.Deployment) error + CreateDeployment(context.Context, *library.User, *api.Repo, *library.Deployment) error // Repo SCM Interface Functions // Config defines a function that captures // the pipeline configuration from a repo. - Config(context.Context, *library.User, *library.Repo, string) ([]byte, error) + Config(context.Context, *library.User, *api.Repo, string) ([]byte, error) // ConfigBackoff is a truncated constant backoff wrapper for Config. // Retry again in five seconds if Config fails to retrieve yaml/yml file. // Will return an error after five failed attempts. - ConfigBackoff(context.Context, *library.User, *library.Repo, string) ([]byte, error) + ConfigBackoff(context.Context, *library.User, *api.Repo, string) ([]byte, error) // Disable defines a function that deactivates // a repo by destroying the webhook. Disable(context.Context, *library.User, string, string) error // Enable defines a function that activates // a repo by creating the webhook. - Enable(context.Context, *library.User, *library.Repo, *library.Hook) (*library.Hook, string, error) + Enable(context.Context, *library.User, *api.Repo, *library.Hook) (*library.Hook, string, error) // Update defines a function that updates // a webhook for a specified repo. - Update(context.Context, *library.User, *library.Repo, int64) (bool, error) + Update(context.Context, *library.User, *api.Repo, int64) (bool, error) // Status defines a function that sends the // commit status for the given SHA from a repo. Status(context.Context, *library.User, *library.Build, string, string) error @@ -115,16 +116,16 @@ type Service interface { StepStatus(context.Context, *library.User, *library.Build, *library.Step, string, string) error // ListUserRepos defines a function that retrieves // all repos with admin rights for the user. - ListUserRepos(context.Context, *library.User) ([]*library.Repo, error) + ListUserRepos(context.Context, *library.User) ([]*api.Repo, error) // GetBranch defines a function that retrieves // a branch for a repo. - GetBranch(context.Context, *library.User, *library.Repo, string) (string, string, error) + GetBranch(context.Context, *api.Repo, string) (string, string, error) // GetPullRequest defines a function that retrieves // a pull request for a repo. - GetPullRequest(context.Context, *library.User, *library.Repo, int) (string, string, string, string, error) + GetPullRequest(context.Context, *api.Repo, int) (string, string, string, string, error) // GetRepo defines a function that retrieves // details for a repo. - GetRepo(context.Context, *library.User, *library.Repo) (*library.Repo, int, error) + GetRepo(context.Context, *library.User, *api.Repo) (*api.Repo, int, error) // GetOrgAndRepoName defines a function that retrieves // the name of the org and repo in the SCM. GetOrgAndRepoName(context.Context, *library.User, string, string) (string, string, error) @@ -139,13 +140,13 @@ type Service interface { // ProcessWebhook defines a function that // parses the webhook from a repo. - ProcessWebhook(context.Context, *http.Request) (*types.Webhook, error) + ProcessWebhook(context.Context, *http.Request) (*internal.Webhook, error) // VerifyWebhook defines a function that // verifies the webhook from a repo. - VerifyWebhook(context.Context, *http.Request, *library.Repo) error + VerifyWebhook(context.Context, *http.Request, *api.Repo) error // RedeliverWebhook defines a function that // redelivers the webhook from the SCM. - RedeliverWebhook(context.Context, *library.User, *library.Repo, *library.Hook) error + RedeliverWebhook(context.Context, *library.User, *api.Repo, *library.Hook) error // TODO: Add convert functions to interface? } diff --git a/secret/native/count.go b/secret/native/count.go index d76da83cc..379391d1b 100644 --- a/secret/native/count.go +++ b/secret/native/count.go @@ -6,8 +6,8 @@ import ( "context" "fmt" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" "github.com/sirupsen/logrus" ) @@ -31,7 +31,7 @@ func (c *client) Count(ctx context.Context, sType, org, name string, teams []str }).Tracef("counting native %s secrets for %s/%s", sType, org, name) // create the repo with the information available - r := new(library.Repo) + r := new(api.Repo) r.SetOrg(org) r.SetName(name) r.SetFullName(fmt.Sprintf("%s/%s", org, name)) diff --git a/secret/native/get.go b/secret/native/get.go index ae80f1d09..059ee917e 100644 --- a/secret/native/get.go +++ b/secret/native/get.go @@ -6,6 +6,7 @@ import ( "context" "fmt" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" "github.com/sirupsen/logrus" @@ -33,7 +34,7 @@ func (c *client) Get(ctx context.Context, sType, org, name, path string) (*libra }).Tracef("getting native %s secret %s for %s/%s", sType, path, org, name) // create the repo with the information available - r := new(library.Repo) + r := new(api.Repo) r.SetOrg(org) r.SetName(name) r.SetFullName(fmt.Sprintf("%s/%s", org, name)) diff --git a/secret/native/list.go b/secret/native/list.go index 6e153c422..ab6f7d57b 100644 --- a/secret/native/list.go +++ b/secret/native/list.go @@ -6,6 +6,7 @@ import ( "context" "fmt" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" "github.com/sirupsen/logrus" @@ -36,7 +37,7 @@ func (c *client) List(ctx context.Context, sType, org, name string, page, perPag }).Tracef("listing native %s secrets for %s/%s", sType, org, name) // create the repo with the information available - r := new(library.Repo) + r := new(api.Repo) r.SetOrg(org) r.SetName(name) r.SetFullName(fmt.Sprintf("%s/%s", org, name)) diff --git a/util/encryption.go b/util/encryption.go new file mode 100644 index 000000000..06124d357 --- /dev/null +++ b/util/encryption.go @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: Apache-2.0 + +package util + +import ( + "crypto/aes" + "crypto/cipher" + "crypto/rand" + "fmt" + "io" +) + +// Decrypt is a helper function to Decrypt values. First +// a AES-256 Galois Counter Mode cipher block is created +// from the encryption key to Decrypt the value. Then, we +// verify the value isn't smaller than the nonce which +// would indicate the value isn't encrypted. Finally the +// cipher block and nonce is used to Decrypt the value. +func Decrypt(key string, value []byte) ([]byte, error) { + // create a new cipher block from the encryption key + // + // the key should have a length of 64 bits to ensure + // we are using the AES-256 standard + // + // https://en.wikipedia.org/wiki/Advanced_Encryption_Standard + block, err := aes.NewCipher([]byte(key)) + if err != nil { + return value, err + } + + // creates a new Galois Counter Mode cipher block + gcm, err := cipher.NewGCM(block) + if err != nil { + return value, err + } + + // nonce is an arbitrary number used to to ensure that + // old communications cannot be reused in replay attacks. + // + // https://en.wikipedia.org/wiki/Cryptographic_nonce + nonceSize := gcm.NonceSize() + + // verify the value has a length greater than the nonce + // + // if the value is less than the nonce size, then we + // can assume the value hasn't been encrypted yet. + if len(value) < nonceSize { + return value, fmt.Errorf("invalid value length for decrypt provided: %d", len(value)) + } + + // capture nonce and ciphertext from the value + nonce, ciphertext := value[:nonceSize], value[nonceSize:] + + // decrypt the value from the ciphertext + return gcm.Open(nil, nonce, ciphertext, nil) +} + +// Encrypt is a helper function to Encrypt values. First +// a AES-256 Galois Counter Mode cipher block is created +// from the encryption key to Encrypt the value. Then, +// we create the nonce from a cryptographically secure +// random number generator. Finally, the cipher block +// and nonce is used to Encrypt the value. +func Encrypt(key string, value []byte) ([]byte, error) { + // create a new cipher block from the encryption key + // + // the key should have a length of 64 bits to ensure + // we are using the AES-256 standard + // + // https://en.wikipedia.org/wiki/Advanced_Encryption_Standard + block, err := aes.NewCipher([]byte(key)) + if err != nil { + return value, err + } + + // creates a new Galois Counter Mode cipher block + gcm, err := cipher.NewGCM(block) + if err != nil { + return value, err + } + + // nonce is an arbitrary number used to to ensure that + // old communications cannot be reused in replay attacks. + // + // https://en.wikipedia.org/wiki/Cryptographic_nonce + nonce := make([]byte, gcm.NonceSize()) + + // set nonce from a cryptographically secure random number generator + _, err = io.ReadFull(rand.Reader, nonce) + if err != nil { + return value, err + } + + // encrypt the value with the randomly generated nonce + return gcm.Seal(nonce, nonce, value, nil), nil +} diff --git a/util/encryption_test.go b/util/encryption_test.go new file mode 100644 index 000000000..efe2c8791 --- /dev/null +++ b/util/encryption_test.go @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: Apache-2.0 + +package util + +import ( + "testing" +) + +func TestDatabase_decrypt(t *testing.T) { + // setup types + key := "C639A572E14D5075C526FDDD43E4ECF6" + value := []byte("abc") + + encrypted, err := Encrypt(key, value) + if err != nil { + t.Errorf("unable to encrypt value: %v", err) + } + + // setup tests + tests := []struct { + failure bool + key string + value []byte + }{ + { + failure: false, + key: key, + value: encrypted, + }, + { + failure: true, + key: "", + value: encrypted, + }, + { + failure: true, + key: key, + value: value, + }, + } + + // run tests + for _, test := range tests { + _, err := Decrypt(test.key, test.value) + + if test.failure { + if err == nil { + t.Errorf("decrypt should have returned err") + } + + continue + } + + if err != nil { + t.Errorf("decrypt returned err: %v", err) + } + } +} + +func TestDatabase_encrypt(t *testing.T) { + // setup types + key := "C639A572E14D5075C526FDDD43E4ECF6" + value := []byte("abc") + + // setup tests + tests := []struct { + failure bool + key string + value []byte + }{ + { + failure: false, + key: key, + value: value, + }, + { + failure: true, + key: "", + value: value, + }, + } + + // run tests + for _, test := range tests { + _, err := Encrypt(test.key, test.value) + + if test.failure { + if err == nil { + t.Errorf("encrypt should have returned err") + } + + continue + } + + if err != nil { + t.Errorf("encrypt returned err: %v", err) + } + } +} diff --git a/util/util.go b/util/util.go index 401c6a814..60d709765 100644 --- a/util/util.go +++ b/util/util.go @@ -8,7 +8,7 @@ import ( "net/url" "strings" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" "github.com/microcosm-cc/bluemonday" "github.com/gin-gonic/gin" @@ -117,7 +117,7 @@ func Unique(stringSlice []string) []string { // allowlist are specified. // // a single entry of '*' allows any repo to be enabled. -func CheckAllowlist(r *library.Repo, allowlist []string) bool { +func CheckAllowlist(r *api.Repo, allowlist []string) bool { // check if all repos are allowed to be enabled if len(allowlist) == 1 && allowlist[0] == "*" { return true From 4fea679514ac1ac549922e404d0822b9c79d55a8 Mon Sep 17 00:00:00 2001 From: David May <49894298+wass3rw3rk@users.noreply.github.com> Date: Thu, 11 Apr 2024 09:02:14 -0500 Subject: [PATCH 26/71] chore(go): specific go version (#1101) --- .github/workflows/validate.yml | 7 +++++-- go.mod | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index ec175ea5b..466a71d51 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -36,9 +36,12 @@ jobs: # Check that go fmt ./... produces a zero diff; clean up any changes afterwards. go fmt ./... && git diff --exit-code; code=$?; git checkout -- .; (exit $code) # Check that go fix ./... produces a zero diff; clean up any changes afterwards. - go fix ./... && git diff --exit-code; code=$?; git checkout -- .; (exit $code) + # + # Renable this after https://github.com/golang/go/commit/7fd62ba821b1044e8e4077df052b0a1232672d57 + # has been released. + # go fix ./... && git diff --exit-code; code=$?; git checkout -- .; (exit $code) - name: validate spec run: | sudo make spec-install - make spec \ No newline at end of file + make spec diff --git a/go.mod b/go.mod index c0b21447e..bc25fc72b 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/go-vela/server -go 1.21 +go 1.21.9 require ( github.com/Bose/minisentinel v0.0.0-20200130220412-917c5a9223bb From ed4ab246226e515d696aca725f764bcf021b7b16 Mon Sep 17 00:00:00 2001 From: dave vader <48764154+plyr4@users.noreply.github.com> Date: Thu, 11 Apr 2024 09:15:30 -0500 Subject: [PATCH 27/71] fix(deployments): set deployment created event action (#1087) --- scm/github/webhook.go | 2 ++ scm/github/webhook_test.go | 12 ++++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/scm/github/webhook.go b/scm/github/webhook.go index 9e9dccac5..47aefee38 100644 --- a/scm/github/webhook.go +++ b/scm/github/webhook.go @@ -363,6 +363,7 @@ func (c *client) processDeploymentEvent(h *library.Hook, payload *github.Deploym // convert payload to library build b := new(library.Build) b.SetEvent(constants.EventDeploy) + b.SetEventAction(constants.ActionCreated) b.SetClone(repo.GetCloneURL()) b.SetDeploy(payload.GetDeployment().GetEnvironment()) b.SetDeployNumber(payload.GetDeployment().GetID()) @@ -427,6 +428,7 @@ func (c *client) processDeploymentEvent(h *library.Hook, payload *github.Deploym // update the hook object h.SetBranch(b.GetBranch()) h.SetEvent(constants.EventDeploy) + h.SetEventAction(constants.ActionCreated) h.SetLink( fmt.Sprintf("https://%s/%s/settings/hooks", h.GetHost(), r.GetFullName()), ) diff --git a/scm/github/webhook_test.go b/scm/github/webhook_test.go index 00454fdf7..50aea20b4 100644 --- a/scm/github/webhook_test.go +++ b/scm/github/webhook_test.go @@ -574,7 +574,8 @@ func TestGithub_ProcessWebhook_Deployment(t *testing.T) { wantHook.SetBranch("main") wantHook.SetLink("https://github.com/Codertocat/Hello-World/settings/hooks") wantHook.SetHost("github.com") - wantHook.SetEvent("deployment") + wantHook.SetEvent(constants.EventDeploy) + wantHook.SetEventAction(constants.ActionCreated) wantHook.SetStatus(constants.StatusSuccess) wantRepo := new(api.Repo) @@ -588,7 +589,8 @@ func TestGithub_ProcessWebhook_Deployment(t *testing.T) { wantRepo.SetTopics(nil) wantBuild := new(library.Build) - wantBuild.SetEvent("deployment") + wantBuild.SetEvent(constants.EventDeploy) + wantBuild.SetEventAction(constants.ActionCreated) wantBuild.SetClone("https://github.com/Codertocat/Hello-World.git") wantBuild.SetDeploy("production") wantBuild.SetDeployNumber(145988746) @@ -707,7 +709,8 @@ func TestGithub_ProcessWebhook_Deployment_Commit(t *testing.T) { wantHook.SetBranch("main") wantHook.SetLink("https://github.com/Codertocat/Hello-World/settings/hooks") wantHook.SetHost("github.com") - wantHook.SetEvent("deployment") + wantHook.SetEvent(constants.EventDeploy) + wantHook.SetEventAction(constants.ActionCreated) wantHook.SetStatus(constants.StatusSuccess) wantRepo := new(api.Repo) @@ -721,7 +724,8 @@ func TestGithub_ProcessWebhook_Deployment_Commit(t *testing.T) { wantRepo.SetTopics(nil) wantBuild := new(library.Build) - wantBuild.SetEvent("deployment") + wantBuild.SetEvent(constants.EventDeploy) + wantBuild.SetEventAction(constants.ActionCreated) wantBuild.SetClone("https://github.com/Codertocat/Hello-World.git") wantBuild.SetDeploy("production") wantBuild.SetDeployNumber(145988746) From 132447406cf759e4035948f55c3e83f91a4f3eb4 Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Thu, 11 Apr 2024 10:55:41 -0400 Subject: [PATCH 28/71] fix(types): correct actions pkg for repo events (#1103) --- api/repo/create.go | 2 +- api/types/events.go | 2 +- api/types/events_test.go | 2 +- database/repo/repo_test.go | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/repo/create.go b/api/repo/create.go index bc0c1103d..636b955b3 100644 --- a/api/repo/create.go +++ b/api/repo/create.go @@ -10,13 +10,13 @@ import ( "github.com/gin-gonic/gin" "github.com/go-vela/server/api/types" + "github.com/go-vela/server/api/types/actions" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" "github.com/go-vela/server/util" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/go-vela/types/library/actions" "github.com/google/uuid" "github.com/sirupsen/logrus" ) diff --git a/api/types/events.go b/api/types/events.go index 9c4885667..589f4de46 100644 --- a/api/types/events.go +++ b/api/types/events.go @@ -5,8 +5,8 @@ package types import ( "fmt" + "github.com/go-vela/server/api/types/actions" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library/actions" ) // Events is the library representation of the various events that generate a diff --git a/api/types/events_test.go b/api/types/events_test.go index e01d8d1f8..45b003398 100644 --- a/api/types/events_test.go +++ b/api/types/events_test.go @@ -6,8 +6,8 @@ import ( "reflect" "testing" + "github.com/go-vela/server/api/types/actions" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library/actions" "github.com/google/go-cmp/cmp" ) diff --git a/database/repo/repo_test.go b/database/repo/repo_test.go index e617e4feb..92d1228a4 100644 --- a/database/repo/repo_test.go +++ b/database/repo/repo_test.go @@ -9,8 +9,8 @@ import ( "github.com/DATA-DOG/go-sqlmock" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/api/types/actions" "github.com/go-vela/types/library" - "github.com/go-vela/types/library/actions" "github.com/sirupsen/logrus" "gorm.io/driver/postgres" From a0e290bef829f9fedbac8098ffa48307ce3e83e4 Mon Sep 17 00:00:00 2001 From: david may <1301201+wass3r@users.noreply.github.com> Date: Thu, 11 Apr 2024 13:39:49 -0500 Subject: [PATCH 29/71] refactor: consistent import order (#1077) --- .golangci.yml | 108 ++++++++++-------- Makefile | 11 ++ api/admin/build.go | 7 +- api/admin/clean.go | 6 +- api/admin/hook.go | 3 +- api/admin/repo.go | 6 +- api/admin/secret.go | 7 +- api/admin/service.go | 7 +- api/admin/step.go | 7 +- api/admin/user.go | 7 +- api/admin/worker.go | 6 +- api/auth/get_token.go | 1 + api/auth/login.go | 3 +- api/auth/logout.go | 7 +- api/auth/post_token.go | 1 + api/auth/redirect.go | 3 +- api/auth/refresh.go | 1 + api/auth/validate.go | 1 + api/auth/validate_oauth.go | 1 + api/badge.go | 3 +- api/build/approve.go | 3 +- api/build/auto_cancel.go | 1 + api/build/cancel.go | 3 +- api/build/clean.go | 3 +- api/build/compile_publish.go | 3 +- api/build/create.go | 3 +- api/build/delete.go | 3 +- api/build/enqueue.go | 3 +- api/build/executable.go | 3 +- api/build/get.go | 3 +- api/build/get_id.go | 3 +- api/build/graph.go | 3 +- api/build/list_org.go | 3 +- api/build/list_repo.go | 3 +- api/build/restart.go | 3 +- api/build/token.go | 3 +- api/build/update.go | 3 +- api/deployment/create.go | 3 +- api/deployment/get.go | 3 +- api/deployment/list.go | 3 +- api/hook/create.go | 3 +- api/hook/delete.go | 3 +- api/hook/get.go | 3 +- api/hook/list.go | 3 +- api/hook/redeliver.go | 3 +- api/hook/update.go | 3 +- api/log/create_service.go | 3 +- api/log/create_step.go | 3 +- api/log/delete_service.go | 3 +- api/log/delete_step.go | 3 +- api/log/get_service.go | 3 +- api/log/get_step.go | 3 +- api/log/list_build.go | 3 +- api/log/update_service.go | 3 +- api/log/update_step.go | 3 +- api/metrics.go | 7 +- api/pipeline/compile.go | 3 +- api/pipeline/compile_test.go | 3 +- api/pipeline/create.go | 3 +- api/pipeline/delete.go | 3 +- api/pipeline/expand.go | 3 +- api/pipeline/get.go | 3 +- api/pipeline/list.go | 3 +- api/pipeline/output.go | 1 + api/pipeline/template.go | 3 +- api/pipeline/update.go | 3 +- api/pipeline/validate.go | 3 +- api/queue/queue.go | 3 +- api/repo/chown.go | 3 +- api/repo/create.go | 5 +- api/repo/delete.go | 3 +- api/repo/get.go | 3 +- api/repo/list.go | 3 +- api/repo/list_org.go | 3 +- api/repo/repair.go | 3 +- api/repo/update.go | 5 +- api/schedule/create.go | 3 +- api/schedule/delete.go | 3 +- api/schedule/get.go | 3 +- api/schedule/list.go | 3 +- api/schedule/update.go | 3 +- api/scm/sync.go | 3 +- api/scm/sync_org.go | 3 +- api/secret/create.go | 3 +- api/secret/delete.go | 3 +- api/secret/get.go | 3 +- api/secret/list.go | 3 +- api/secret/update.go | 3 +- api/service/create.go | 3 +- api/service/delete.go | 3 +- api/service/get.go | 3 +- api/service/list.go | 3 +- api/service/update.go | 3 +- api/step/create.go | 3 +- api/step/delete.go | 3 +- api/step/get.go | 3 +- api/step/list.go | 3 +- api/step/plan.go | 3 +- api/step/update.go | 3 +- api/types/events_test.go | 3 +- api/types/repo_test.go | 3 +- api/user/create.go | 3 +- api/user/create_token.go | 3 +- api/user/delete.go | 3 +- api/user/delete_token.go | 3 +- api/user/get.go | 3 +- api/user/get_current.go | 3 +- api/user/get_source.go | 3 +- api/user/list.go | 3 +- api/user/update.go | 3 +- api/user/update_current.go | 3 +- api/webhook/post.go | 5 +- api/worker/create.go | 3 +- api/worker/delete.go | 3 +- api/worker/get.go | 3 +- api/worker/list.go | 3 +- api/worker/refresh.go | 3 +- api/worker/update.go | 3 +- cmd/vela-server/compiler.go | 8 +- cmd/vela-server/main.go | 10 +- cmd/vela-server/metadata.go | 5 +- cmd/vela-server/queue.go | 5 +- cmd/vela-server/schedule.go | 6 +- cmd/vela-server/scm.go | 4 +- cmd/vela-server/secret.go | 7 +- cmd/vela-server/server.go | 8 +- cmd/vela-server/token.go | 2 - cmd/vela-server/validate.go | 4 +- compiler/native/clone_test.go | 3 +- compiler/native/compile.go | 13 +-- compiler/native/compile_test.go | 24 ++-- compiler/native/environment_test.go | 9 +- compiler/native/expand.go | 9 +- compiler/native/expand_test.go | 8 +- compiler/native/initialize_test.go | 3 +- compiler/native/native.go | 10 +- compiler/native/native_test.go | 5 +- compiler/native/parse.go | 4 +- compiler/native/parse_test.go | 7 +- compiler/native/script_test.go | 4 +- compiler/native/substitute.go | 1 - compiler/native/substitute_test.go | 2 +- compiler/native/transform_test.go | 4 +- compiler/native/validate_test.go | 4 +- compiler/registry/github/parse.go | 4 +- compiler/registry/github/template.go | 5 +- compiler/registry/github/template_test.go | 5 +- compiler/template/native/render.go | 8 +- compiler/template/starlark/convert.go | 3 +- compiler/template/starlark/convert_test.go | 3 +- compiler/template/starlark/render.go | 6 +- compiler/template/starlark/render_test.go | 3 +- database/build/build.go | 4 +- database/build/build_test.go | 8 +- database/build/clean.go | 3 +- database/build/count_deployment.go | 3 +- database/build/count_org.go | 3 +- database/build/count_org_test.go | 1 + database/build/count_repo.go | 3 +- database/build/create.go | 3 +- database/build/delete.go | 3 +- database/build/get_repo.go | 3 +- database/build/get_repo_test.go | 1 + database/build/get_test.go | 1 + database/build/last_repo.go | 6 +- database/build/last_repo_test.go | 1 + database/build/list_org.go | 3 +- database/build/list_org_test.go | 1 + .../build/list_pending_running_repo_test.go | 1 + database/build/list_pending_running_test.go | 1 + database/build/list_repo.go | 3 +- database/build/list_repo_test.go | 1 + database/build/list_test.go | 1 + database/build/opts.go | 1 - database/build/opts_test.go | 1 - database/build/update.go | 3 +- database/close_test.go | 1 - database/database.go | 10 +- database/database_test.go | 1 - database/deployment/count_repo.go | 3 +- database/deployment/count_repo_test.go | 1 + database/deployment/count_test.go | 1 + database/deployment/create.go | 3 +- database/deployment/create_test.go | 1 + database/deployment/delete.go | 4 +- database/deployment/delete_test.go | 1 + database/deployment/deployment.go | 4 +- database/deployment/deployment_test.go | 8 +- database/deployment/get_repo.go | 3 +- database/deployment/get_repo_test.go | 1 + database/deployment/get_test.go | 1 + database/deployment/list_repo.go | 3 +- database/deployment/list_repo_test.go | 1 + database/deployment/list_test.go | 1 + database/deployment/opts.go | 1 - database/deployment/opts_test.go | 1 - database/deployment/update.go | 4 +- database/deployment/update_test.go | 1 + database/executable/clean.go | 3 +- database/executable/clean_test.go | 1 + database/executable/create.go | 3 +- database/executable/executable.go | 4 +- database/executable/executable_test.go | 6 +- database/executable/opts.go | 1 - database/executable/opts_test.go | 1 - database/executable/pop.go | 3 +- database/executable/pop_test.go | 1 + database/flags.go | 3 +- database/hook/count_repo.go | 3 +- database/hook/create.go | 3 +- database/hook/delete.go | 3 +- database/hook/get_repo.go | 3 +- database/hook/get_repo_test.go | 1 + database/hook/get_test.go | 1 + database/hook/get_webhook_test.go | 1 + database/hook/hook.go | 4 +- database/hook/hook_test.go | 6 +- database/hook/last_repo.go | 6 +- database/hook/last_repo_test.go | 1 + database/hook/list_repo.go | 3 +- database/hook/list_repo_test.go | 1 + database/hook/list_test.go | 1 + database/hook/opts.go | 1 - database/hook/opts_test.go | 1 - database/hook/update.go | 3 +- database/integration_test.go | 3 +- database/log/create_test.go | 1 + database/log/get_service_test.go | 1 + database/log/get_step_test.go | 1 + database/log/get_test.go | 1 + database/log/list_build_test.go | 1 + database/log/list_test.go | 1 + database/log/log.go | 4 +- database/log/log_test.go | 4 +- database/log/opts.go | 1 - database/log/opts_test.go | 1 - database/log/update_test.go | 1 + database/pipeline/count_repo.go | 3 +- database/pipeline/count_repo_test.go | 1 + database/pipeline/create.go | 3 +- database/pipeline/delete.go | 3 +- database/pipeline/get_repo.go | 3 +- database/pipeline/get_repo_test.go | 1 + database/pipeline/get_test.go | 1 + database/pipeline/list_repo.go | 3 +- database/pipeline/list_repo_test.go | 1 + database/pipeline/list_test.go | 1 + database/pipeline/opts.go | 1 - database/pipeline/opts_test.go | 1 - database/pipeline/pipeline.go | 4 +- database/pipeline/pipeline_test.go | 4 +- database/pipeline/update.go | 3 +- database/repo/count_org.go | 3 +- database/repo/count_user.go | 3 +- database/repo/count_user_test.go | 1 + database/repo/create.go | 3 +- database/repo/delete.go | 3 +- database/repo/get_org.go | 3 +- database/repo/get_org_test.go | 3 +- database/repo/get_test.go | 1 + database/repo/list_org.go | 3 +- database/repo/list_org_test.go | 3 +- database/repo/list_test.go | 1 + database/repo/list_user.go | 3 +- database/repo/list_user_test.go | 1 + database/repo/opts.go | 1 - database/repo/opts_test.go | 1 - database/repo/repo.go | 8 +- database/repo/repo_test.go | 8 +- database/repo/update.go | 3 +- database/repo/update_test.go | 1 + database/resource_test.go | 1 + database/schedule/count.go | 1 + database/schedule/count_active.go | 1 + database/schedule/count_repo.go | 3 +- database/schedule/create.go | 3 +- database/schedule/delete.go | 4 +- database/schedule/get.go | 1 + database/schedule/get_repo.go | 3 +- database/schedule/get_repo_test.go | 1 + database/schedule/get_test.go | 1 + database/schedule/list.go | 1 + database/schedule/list_active.go | 1 + database/schedule/list_active_test.go | 1 + database/schedule/list_repo.go | 3 +- database/schedule/list_repo_test.go | 1 + database/schedule/list_test.go | 1 + database/schedule/opts.go | 2 +- database/schedule/opts_test.go | 1 - database/schedule/schedule.go | 4 +- database/schedule/schedule_test.go | 6 +- database/schedule/update.go | 3 +- database/secret/count_org.go | 3 +- database/secret/count_org_test.go | 1 + database/secret/count_repo.go | 3 +- database/secret/count_repo_test.go | 4 +- database/secret/count_team.go | 3 +- database/secret/count_team_test.go | 4 +- database/secret/create.go | 3 +- database/secret/create_test.go | 1 + database/secret/delete.go | 3 +- database/secret/delete_test.go | 1 + database/secret/get_org.go | 3 +- database/secret/get_org_test.go | 1 + database/secret/get_repo.go | 3 +- database/secret/get_repo_test.go | 1 + database/secret/get_team.go | 3 +- database/secret/get_team_test.go | 1 + database/secret/get_test.go | 1 + database/secret/list_org.go | 3 +- database/secret/list_org_test.go | 1 + database/secret/list_repo.go | 3 +- database/secret/list_repo_test.go | 4 +- database/secret/list_team.go | 3 +- database/secret/list_team_test.go | 4 +- database/secret/list_test.go | 1 + database/secret/opts.go | 1 - database/secret/opts_test.go | 1 - database/secret/secret.go | 4 +- database/secret/secret_test.go | 8 +- database/secret/update.go | 3 +- database/secret/update_test.go | 1 + database/service/clean.go | 3 +- database/service/count_build.go | 3 +- database/service/create.go | 3 +- database/service/delete.go | 3 +- database/service/get_build.go | 3 +- database/service/get_build_test.go | 1 + database/service/get_test.go | 1 + database/service/list_build.go | 3 +- database/service/list_build_test.go | 1 + database/service/list_test.go | 1 + database/service/opts.go | 1 - database/service/opts_test.go | 1 - database/service/service.go | 4 +- database/service/service_test.go | 4 +- database/service/update.go | 3 +- database/step/clean.go | 3 +- database/step/count.go | 1 + database/step/count_build.go | 4 +- database/step/create.go | 4 +- database/step/delete.go | 4 +- database/step/get.go | 1 + database/step/get_build.go | 4 +- database/step/get_build_test.go | 3 +- database/step/get_test.go | 1 + database/step/interface.go | 1 + database/step/list.go | 1 + database/step/list_build.go | 4 +- database/step/list_build_test.go | 1 + database/step/list_test.go | 1 + database/step/opts.go | 2 +- database/step/opts_test.go | 1 - database/step/step.go | 4 +- database/step/step_test.go | 4 +- database/step/update.go | 4 +- database/user/create.go | 3 +- database/user/delete.go | 3 +- database/user/get_name.go | 3 +- database/user/get_name_test.go | 1 + database/user/get_test.go | 1 + database/user/list_lite_test.go | 1 + database/user/list_test.go | 1 + database/user/opts.go | 1 - database/user/opts_test.go | 1 - database/user/update.go | 3 +- database/user/user.go | 4 +- database/user/user_test.go | 4 +- database/validate.go | 3 +- database/worker/create.go | 3 +- database/worker/delete.go | 3 +- database/worker/get_hostname.go | 3 +- database/worker/get_hostname_test.go | 1 + database/worker/get_test.go | 1 + database/worker/list_test.go | 3 +- database/worker/opts.go | 1 - database/worker/opts_test.go | 1 - database/worker/update.go | 3 +- database/worker/worker.go | 8 +- database/worker/worker_test.go | 6 +- internal/token/compose.go | 1 + internal/token/compose_test.go | 4 +- internal/token/mint.go | 3 +- internal/token/parse_test.go | 4 +- internal/token/refresh.go | 1 + internal/token/refresh_test.go | 3 +- mock/server/authentication.go | 1 + mock/server/build.go | 1 + mock/server/deployment.go | 1 + mock/server/hook.go | 1 + mock/server/log.go | 1 + mock/server/pipeline.go | 7 +- mock/server/repo.go | 1 + mock/server/schedule.go | 1 + mock/server/scm.go | 1 + mock/server/secret.go | 1 + mock/server/service.go | 1 + mock/server/step.go | 1 + mock/server/user.go | 1 + mock/server/worker.go | 1 + queue/flags.go | 3 +- queue/queue.go | 3 +- queue/redis/driver_test.go | 1 + queue/redis/length_test.go | 3 +- queue/redis/ping_test.go | 3 +- queue/redis/pop.go | 3 +- queue/redis/pop_test.go | 3 +- queue/redis/redis.go | 1 - queue/redis/redis_test.go | 1 + queue/setup.go | 3 +- router/admin.go | 1 + router/build.go | 1 + router/deployment.go | 2 +- router/hook.go | 1 + router/log.go | 1 + router/middleware/auth/auth.go | 4 +- router/middleware/build/build.go | 3 +- router/middleware/build/build_test.go | 1 + router/middleware/build/context_test.go | 4 +- router/middleware/claims/claims.go | 4 +- router/middleware/claims/claims_test.go | 3 +- router/middleware/claims/context_test.go | 6 +- router/middleware/compiler.go | 1 + router/middleware/compiler_test.go | 7 +- router/middleware/database.go | 1 + router/middleware/database_test.go | 1 + .../middleware/default_repo_settings_test.go | 4 +- router/middleware/executors/context_test.go | 1 + router/middleware/executors/executor_test.go | 1 + router/middleware/executors/executors.go | 1 + router/middleware/header.go | 1 + router/middleware/header_test.go | 1 + router/middleware/logger.go | 3 +- router/middleware/logger_test.go | 5 +- router/middleware/metadata.go | 1 + router/middleware/metadata_test.go | 1 + router/middleware/org/org.go | 1 + router/middleware/org/org_test.go | 1 + router/middleware/perm/perm.go | 3 +- router/middleware/perm/perm_test.go | 3 +- router/middleware/pipeline/context_test.go | 1 + router/middleware/pipeline/pipeline.go | 3 +- router/middleware/pipeline/pipeline_test.go | 5 +- router/middleware/queue.go | 1 + router/middleware/queue_test.go | 4 +- router/middleware/repo/context_test.go | 1 + router/middleware/repo/repo.go | 3 +- router/middleware/repo/repo_test.go | 6 +- router/middleware/schedule/context_test.go | 1 + router/middleware/schedule/schedule.go | 3 +- router/middleware/scm.go | 1 + router/middleware/scm_test.go | 4 +- router/middleware/secret_test.go | 4 +- router/middleware/secure_cookie_test.go | 3 +- router/middleware/service/context_test.go | 4 +- router/middleware/service/service.go | 3 +- router/middleware/service/service_test.go | 1 + router/middleware/step/context_test.go | 4 +- router/middleware/step/step.go | 3 +- router/middleware/step/step_test.go | 1 + router/middleware/token_manager_test.go | 4 +- router/middleware/user/context_test.go | 4 +- router/middleware/user/user.go | 7 +- router/middleware/user/user_test.go | 3 +- router/middleware/webhook_validation_test.go | 3 +- router/middleware/worker/context_test.go | 4 +- router/middleware/worker/worker.go | 3 +- router/middleware/worker/worker_test.go | 1 + router/pipeline.go | 1 + router/queue.go | 1 + router/repo.go | 1 + router/router.go | 1 + router/schedule.go | 1 + router/scm.go | 1 + router/search.go | 1 + router/secret.go | 4 +- router/service.go | 1 + router/step.go | 1 + router/user.go | 1 + router/worker.go | 1 + scm/context_test.go | 4 +- scm/flags.go | 3 +- scm/github/access.go | 2 +- scm/github/authentication.go | 3 +- scm/github/authentication_test.go | 4 +- scm/github/changeset.go | 2 +- scm/github/deployment.go | 2 +- scm/github/github.go | 1 - scm/github/repo.go | 2 +- scm/github/webhook.go | 2 +- scm/github/webhook_test.go | 6 +- scm/scm.go | 4 +- scm/setup.go | 4 +- secret/context_test.go | 1 + secret/native/count.go | 3 +- secret/native/create.go | 3 +- secret/native/delete.go | 3 +- secret/native/get.go | 3 +- secret/native/list.go | 3 +- secret/native/native.go | 3 +- secret/native/update.go | 3 +- secret/secret.go | 4 +- secret/setup.go | 3 +- secret/vault/count.go | 3 +- secret/vault/create_test.go | 4 +- secret/vault/get.go | 2 +- secret/vault/get_test.go | 4 +- secret/vault/list.go | 4 +- secret/vault/list_test.go | 4 +- secret/vault/update_test.go | 4 +- secret/vault/vault.go | 5 +- secret/vault/vault_test.go | 3 +- util/util.go | 4 +- version/version.go | 3 +- 514 files changed, 961 insertions(+), 629 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 48151b3e9..5e05f9822 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -32,6 +32,18 @@ linters-settings: lines: 160 statements: 70 + # https://github.com/daixiang0/gci + # ensure import order is consistent + # gci write --custom-order -s standard -s default -s blank -s dot -s "prefix(github.com/go-vela)" . + gci: + custom-order: true + sections: + - standard + - default + - blank + - dot + - prefix(github.com/go-vela) + # https://github.com/denis-tingaikin/go-header goheader: template: |- @@ -43,10 +55,9 @@ linters-settings: # https://github.com/golangci/golangci-lint/blob/master/pkg/golinters/nolintlint nolintlint: - allow-leading-space: true # allow non-"machine-readable" format (ie. with leading space) - allow-unused: false # allow nolint directives that don't address a linting issue - require-explanation: true # require an explanation for nolint directives - require-specific: true # require nolint directives to be specific about which linter is being skipped + allow-unused: false # allow nolint directives that don't address a linting issue + require-explanation: true # require an explanation for nolint directives + require-specific: true # require nolint directives to be specific about which linter is being skipped # This section provides the configuration for which linters # golangci will execute. Several of them were disabled by @@ -57,46 +68,47 @@ linters: # enable a specific set of linters to run enable: - - bidichk # checks for dangerous unicode character sequences - - bodyclose # checks whether HTTP response body is closed successfully - - contextcheck # check the function whether use a non-inherited context - - deadcode # finds unused code - - dupl # code clone detection - - errcheck # checks for unchecked errors - - errorlint # find misuses of errors - - exportloopref # check for exported loop vars - - funlen # detects long functions - - goconst # finds repeated strings that could be replaced by a constant - - gocyclo # computes and checks the cyclomatic complexity of functions - - godot # checks if comments end in a period - - gofmt # checks whether code was gofmt-ed - - goheader # checks is file header matches to pattern - - goimports # fixes imports and formats code in same style as gofmt - - gomoddirectives # manage the use of 'replace', 'retract', and 'excludes' directives in go.mod - - goprintffuncname # checks that printf-like functions are named with f at the end - - gosec # inspects code for security problems - - gosimple # linter that specializes in simplifying a code - - govet # reports suspicious constructs, ex. Printf calls whose arguments don't align with the format string - - ineffassign # detects when assignments to existing variables aren't used - - makezero # finds slice declarations with non-zero initial length - - misspell # finds commonly misspelled English words in comments - - nakedret # finds naked returns in functions greater than a specified function length - - nilerr # finds the code that returns nil even if it checks that the error is not nil - - noctx # noctx finds sending http request without context.Context - - nolintlint # reports ill-formed or insufficient nolint directives - - revive # linter for go - - staticcheck # applies static analysis checks, go vet on steroids - - structcheck # finds unused struct fields - - stylecheck # replacement for golint - - tenv # analyzer that detects using os.Setenv instead of t.Setenv since Go1.17 - - typecheck # parses and type-checks go code, like the front-end of a go compiler - - unconvert # remove unnecessary type conversions - - unparam # reports unused function parameters - - unused # checks for unused constants, variables, functions and types - - varcheck # finds unused global variables and constants - - whitespace # detects leading and trailing whitespace - - wsl # forces code to use empty lines - + - bidichk # checks for dangerous unicode character sequences + - bodyclose # checks whether HTTP response body is closed successfully + - contextcheck # check the function whether use a non-inherited context + - deadcode # finds unused code + - dupl # code clone detection + - errcheck # checks for unchecked errors + - errorlint # find misuses of errors + - exportloopref # check for exported loop vars + - funlen # detects long functions + - gci # consistent import ordering + - goconst # finds repeated strings that could be replaced by a constant + - gocyclo # computes and checks the cyclomatic complexity of functions + - godot # checks if comments end in a period + - gofmt # checks whether code was gofmt-ed + - goheader # checks is file header matches to pattern + - goimports # fixes imports and formats code in same style as gofmt + - gomoddirectives # manage the use of 'replace', 'retract', and 'excludes' directives in go.mod + - goprintffuncname # checks that printf-like functions are named with f at the end + - gosec # inspects code for security problems + - gosimple # linter that specializes in simplifying a code + - govet # reports suspicious constructs, ex. Printf calls whose arguments don't align with the format string + - ineffassign # detects when assignments to existing variables aren't used + - makezero # finds slice declarations with non-zero initial length + - misspell # finds commonly misspelled English words in comments + - nakedret # finds naked returns in functions greater than a specified function length + - nilerr # finds the code that returns nil even if it checks that the error is not nil + - noctx # noctx finds sending http request without context.Context + - nolintlint # reports ill-formed or insufficient nolint directives + - revive # linter for go + - staticcheck # applies static analysis checks, go vet on steroids + - structcheck # finds unused struct fields + - stylecheck # replacement for golint + - tenv # analyzer that detects using os.Setenv instead of t.Setenv since Go1.17 + - typecheck # parses and type-checks go code, like the front-end of a go compiler + - unconvert # remove unnecessary type conversions + - unparam # reports unused function parameters + - unused # checks for unused constants, variables, functions and types + - varcheck # finds unused global variables and constants + - whitespace # detects leading and trailing whitespace + - wsl # forces code to use empty lines + # static list of linters we know golangci can run but we've # chosen to leave disabled for now # - asciicheck - non-critical @@ -109,13 +121,13 @@ linters: # - exhaustivestruct - style preference # - forbidigo - unused # - forcetypeassert - unused - # - gci - use goimports # - gochecknoinits - unused # - gochecknoglobals - global variables allowed - # - gocognit - unused complexity metric + # - gocognit - unused complexity metric # - gocritic - style preference # - godox - to be used in the future # - goerr113 - to be used in the future + # - goimports - use gci # - golint - archived, replaced with revive # - gofumpt - use gofmt # - gomnd - get too many false-positives @@ -123,7 +135,7 @@ linters: # - ifshort - use both styles # - ireturn - allow interfaces to be returned # - importas - want flexibility with naming - # - lll - not too concerned about line length + # - lll - not too concerned about line length # - interfacer - archived # - nestif - non-critical # - nilnil - style preference @@ -132,7 +144,7 @@ linters: # - paralleltest - false-positives # - prealloc - don't use # - predeclared - unused - # - promlinter - style preference + # - promlinter - style preference # - rowserrcheck - unused # - scopelint - deprecated - replaced with exportloopref # - sqlclosecheck - unused diff --git a/Makefile b/Makefile index 0df0c3fe9..83527e308 100644 --- a/Makefile +++ b/Makefile @@ -336,3 +336,14 @@ lint: @echo @echo "### Linting Go Code" @golangci-lint run ./... + +# The `lintfix` target is intended to lint the +# Go source code with golangci-lint and apply +# any fixes that can be automatically applied. +# +# Usage: `make lintfix` +.PHONY: lintfix +lintfix: + @echo + @echo "### Fixing Go code with linter" + @golangci-lint run ./... --fix diff --git a/api/admin/build.go b/api/admin/build.go index a56cdbd16..d77d3f4b2 100644 --- a/api/admin/build.go +++ b/api/admin/build.go @@ -9,13 +9,12 @@ import ( "strconv" "time" + "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/util" - "github.com/go-vela/types/library" - - "github.com/gin-gonic/gin" - "github.com/sirupsen/logrus" ) // swagger:operation GET /api/v1/admin/builds/queue admin AllBuildsQueue diff --git a/api/admin/clean.go b/api/admin/clean.go index 5078a217b..9813a7fc7 100644 --- a/api/admin/clean.go +++ b/api/admin/clean.go @@ -8,14 +8,14 @@ import ( "strconv" "time" + "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types" "github.com/go-vela/types/constants" - - "github.com/gin-gonic/gin" - "github.com/sirupsen/logrus" ) // swagger:operation PUT /api/v1/admin/clean admin AdminCleanResources diff --git a/api/admin/hook.go b/api/admin/hook.go index 4336a0744..156110880 100644 --- a/api/admin/hook.go +++ b/api/admin/hook.go @@ -8,10 +8,11 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/util" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // swagger:operation PUT /api/v1/admin/hook admin AdminUpdateHook diff --git a/api/admin/repo.go b/api/admin/repo.go index 46eb3ccc2..52da52301 100644 --- a/api/admin/repo.go +++ b/api/admin/repo.go @@ -7,12 +7,12 @@ import ( "fmt" "net/http" + "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/util" - - "github.com/gin-gonic/gin" - "github.com/sirupsen/logrus" ) // swagger:operation PUT /api/v1/admin/repo admin AdminUpdateRepo diff --git a/api/admin/secret.go b/api/admin/secret.go index 9c00c830c..f9573d9dd 100644 --- a/api/admin/secret.go +++ b/api/admin/secret.go @@ -7,13 +7,12 @@ import ( "fmt" "net/http" + "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/util" - "github.com/go-vela/types/library" - - "github.com/gin-gonic/gin" - "github.com/sirupsen/logrus" ) // swagger:operation PUT /api/v1/admin/secret admin AdminUpdateSecret diff --git a/api/admin/service.go b/api/admin/service.go index 190d4f902..4d74fb388 100644 --- a/api/admin/service.go +++ b/api/admin/service.go @@ -7,13 +7,12 @@ import ( "fmt" "net/http" + "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/util" - "github.com/go-vela/types/library" - - "github.com/gin-gonic/gin" - "github.com/sirupsen/logrus" ) // swagger:operation PUT /api/v1/admin/service admin AdminUpdateService diff --git a/api/admin/step.go b/api/admin/step.go index 9fd909414..aeb2e1f4b 100644 --- a/api/admin/step.go +++ b/api/admin/step.go @@ -6,13 +6,12 @@ import ( "fmt" "net/http" + "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/util" - "github.com/go-vela/types/library" - - "github.com/gin-gonic/gin" - "github.com/sirupsen/logrus" ) // swagger:operation PUT /api/v1/admin/step admin AdminUpdateStep diff --git a/api/admin/user.go b/api/admin/user.go index 416cd2e09..cc276220d 100644 --- a/api/admin/user.go +++ b/api/admin/user.go @@ -7,13 +7,12 @@ import ( "fmt" "net/http" + "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/util" - "github.com/go-vela/types/library" - - "github.com/gin-gonic/gin" - "github.com/sirupsen/logrus" ) // swagger:operation PUT /api/v1/admin/user admin AdminUpdateUser diff --git a/api/admin/worker.go b/api/admin/worker.go index 1966d7d25..e09d0b046 100644 --- a/api/admin/worker.go +++ b/api/admin/worker.go @@ -6,14 +6,14 @@ import ( "fmt" "net/http" + "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/internal/token" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - - "github.com/gin-gonic/gin" - "github.com/sirupsen/logrus" ) // swagger:operation POST /api/v1/admin/workers/{worker}/register-token admin RegisterToken diff --git a/api/auth/get_token.go b/api/auth/get_token.go index 16b4334ae..d1d076631 100644 --- a/api/auth/get_token.go +++ b/api/auth/get_token.go @@ -7,6 +7,7 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/go-vela/server/database" "github.com/go-vela/server/internal/token" "github.com/go-vela/server/scm" diff --git a/api/auth/login.go b/api/auth/login.go index a6e026fc2..3c6edcaa4 100644 --- a/api/auth/login.go +++ b/api/auth/login.go @@ -8,9 +8,10 @@ import ( "net/url" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/internal" "github.com/go-vela/server/util" - "github.com/sirupsen/logrus" ) // swagger:operation GET /login authenticate GetLogin diff --git a/api/auth/logout.go b/api/auth/logout.go index 2c1cf9a33..ad21740ed 100644 --- a/api/auth/logout.go +++ b/api/auth/logout.go @@ -7,15 +7,14 @@ import ( "net/http" "net/url" + "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/internal" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/go-vela/types/constants" - - "github.com/gin-gonic/gin" - "github.com/sirupsen/logrus" ) // swagger:operation GET /logout authenticate GetLogout diff --git a/api/auth/post_token.go b/api/auth/post_token.go index 2f68af691..40ffbf99a 100644 --- a/api/auth/post_token.go +++ b/api/auth/post_token.go @@ -7,6 +7,7 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/go-vela/server/database" "github.com/go-vela/server/internal/token" "github.com/go-vela/server/scm" diff --git a/api/auth/redirect.go b/api/auth/redirect.go index 2e96b3482..dcaba1844 100644 --- a/api/auth/redirect.go +++ b/api/auth/redirect.go @@ -7,9 +7,10 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/internal" "github.com/go-vela/server/util" - "github.com/sirupsen/logrus" ) // swagger:operation GET /authenticate/web authenticate GetAuthenticateTypeWeb diff --git a/api/auth/refresh.go b/api/auth/refresh.go index 65a7626b7..0dc10b7e7 100644 --- a/api/auth/refresh.go +++ b/api/auth/refresh.go @@ -7,6 +7,7 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/go-vela/server/internal/token" "github.com/go-vela/server/router/middleware/auth" "github.com/go-vela/server/util" diff --git a/api/auth/validate.go b/api/auth/validate.go index 6485fe9f9..3282baafb 100644 --- a/api/auth/validate.go +++ b/api/auth/validate.go @@ -8,6 +8,7 @@ import ( "strings" "github.com/gin-gonic/gin" + "github.com/go-vela/server/router/middleware/claims" "github.com/go-vela/server/util" ) diff --git a/api/auth/validate_oauth.go b/api/auth/validate_oauth.go index 5a31c0069..399d3e2e2 100644 --- a/api/auth/validate_oauth.go +++ b/api/auth/validate_oauth.go @@ -7,6 +7,7 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/go-vela/server/scm" "github.com/go-vela/server/util" ) diff --git a/api/badge.go b/api/badge.go index df4fcd97a..4f3dfc380 100644 --- a/api/badge.go +++ b/api/badge.go @@ -6,12 +6,13 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/util" "github.com/go-vela/types/constants" - "github.com/sirupsen/logrus" ) // swagger:operation GET /badge/{org}/{repo}/status.svg base GetBadge diff --git a/api/build/approve.go b/api/build/approve.go index 30006ab1c..c530a6e41 100644 --- a/api/build/approve.go +++ b/api/build/approve.go @@ -9,6 +9,8 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/queue" "github.com/go-vela/server/queue/models" @@ -18,7 +20,6 @@ import ( "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/constants" - "github.com/sirupsen/logrus" ) // swagger:operation POST /api/v1/repos/{org}/{repo}/builds/{build}/approve builds ApproveBuild diff --git a/api/build/auto_cancel.go b/api/build/auto_cancel.go index 53dc1b3eb..3e219d4b4 100644 --- a/api/build/auto_cancel.go +++ b/api/build/auto_cancel.go @@ -12,6 +12,7 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/internal/token" diff --git a/api/build/cancel.go b/api/build/cancel.go index 0126f819c..ad0ea30e7 100644 --- a/api/build/cancel.go +++ b/api/build/cancel.go @@ -12,6 +12,8 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/internal/token" "github.com/go-vela/server/router/middleware/build" @@ -21,7 +23,6 @@ import ( "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/constants" - "github.com/sirupsen/logrus" ) // swagger:operation DELETE /api/v1/repos/{org}/{repo}/builds/{build}/cancel builds CancelBuild diff --git a/api/build/clean.go b/api/build/clean.go index 96a186821..645b0bef3 100644 --- a/api/build/clean.go +++ b/api/build/clean.go @@ -7,10 +7,11 @@ import ( "fmt" "time" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // cleanBuild is a helper function to kill the build diff --git a/api/build/compile_publish.go b/api/build/compile_publish.go index e23e6d8b3..69d6098e0 100644 --- a/api/build/compile_publish.go +++ b/api/build/compile_publish.go @@ -11,6 +11,8 @@ import ( "strings" "time" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/compiler" "github.com/go-vela/server/database" @@ -22,7 +24,6 @@ import ( "github.com/go-vela/types/constants" "github.com/go-vela/types/library" "github.com/go-vela/types/pipeline" - "github.com/sirupsen/logrus" ) // CompileAndPublishConfig is a struct that contains information for the CompileAndPublish function. diff --git a/api/build/create.go b/api/build/create.go index 08027545e..2801ce0db 100644 --- a/api/build/create.go +++ b/api/build/create.go @@ -8,6 +8,8 @@ import ( "strings" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/compiler" "github.com/go-vela/server/database" "github.com/go-vela/server/internal" @@ -19,7 +21,6 @@ import ( "github.com/go-vela/server/util" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // swagger:operation POST /api/v1/repos/{org}/{repo}/builds builds CreateBuild diff --git a/api/build/delete.go b/api/build/delete.go index c1ce1de82..3da622da0 100644 --- a/api/build/delete.go +++ b/api/build/delete.go @@ -7,13 +7,14 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/sirupsen/logrus" ) // swagger:operation DELETE /api/v1/repos/{org}/{repo}/builds/{build} builds DeleteBuild diff --git a/api/build/enqueue.go b/api/build/enqueue.go index 4edce866c..cbc2054b5 100644 --- a/api/build/enqueue.go +++ b/api/build/enqueue.go @@ -7,10 +7,11 @@ import ( "encoding/json" "time" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/queue" "github.com/go-vela/server/queue/models" - "github.com/sirupsen/logrus" ) // Enqueue is a helper function that pushes a queue item (build, repo, user) to the queue. diff --git a/api/build/executable.go b/api/build/executable.go index 351314043..b855ee7bc 100644 --- a/api/build/executable.go +++ b/api/build/executable.go @@ -9,6 +9,8 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/claims" @@ -17,7 +19,6 @@ import ( "github.com/go-vela/server/util" "github.com/go-vela/types/library" "github.com/go-vela/types/pipeline" - "github.com/sirupsen/logrus" ) // swagger:operation GET /api/v1/repos/{org}/{repo}/builds/{build}/executable builds GetBuildExecutable diff --git a/api/build/get.go b/api/build/get.go index 135ca1bb4..afa0994d6 100644 --- a/api/build/get.go +++ b/api/build/get.go @@ -6,11 +6,12 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" - "github.com/sirupsen/logrus" ) // swagger:operation GET /api/v1/repos/{org}/{repo}/builds/{build} builds GetBuild diff --git a/api/build/get_id.go b/api/build/get_id.go index b3adbea95..b53827c47 100644 --- a/api/build/get_id.go +++ b/api/build/get_id.go @@ -8,13 +8,14 @@ import ( "strconv" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" "github.com/go-vela/server/util" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // swagger:operation GET /api/v1/search/builds/{id} builds GetBuildByID diff --git a/api/build/graph.go b/api/build/graph.go index fe6c9cf0d..454cdd27a 100644 --- a/api/build/graph.go +++ b/api/build/graph.go @@ -9,6 +9,8 @@ import ( "strings" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/compiler" "github.com/go-vela/server/database" "github.com/go-vela/server/internal" @@ -21,7 +23,6 @@ import ( "github.com/go-vela/types/constants" "github.com/go-vela/types/library" "github.com/go-vela/types/pipeline" - "github.com/sirupsen/logrus" ) // Graph contains nodes, and relationships between nodes, or edges. diff --git a/api/build/list_org.go b/api/build/list_org.go index 673879bc4..ed2c4e929 100644 --- a/api/build/list_org.go +++ b/api/build/list_org.go @@ -8,6 +8,8 @@ import ( "strconv" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/api" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/org" @@ -16,7 +18,6 @@ import ( "github.com/go-vela/server/util" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // swagger:operation GET /api/v1/repos/{org}/builds builds ListBuildsForOrg diff --git a/api/build/list_repo.go b/api/build/list_repo.go index a1a51d023..e8ed29845 100644 --- a/api/build/list_repo.go +++ b/api/build/list_repo.go @@ -9,6 +9,8 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/api" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/org" @@ -17,7 +19,6 @@ import ( "github.com/go-vela/server/util" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // swagger:operation GET /api/v1/repos/{org}/{repo}/builds builds ListBuildsForRepo diff --git a/api/build/restart.go b/api/build/restart.go index 6043b4fde..f52cf9c69 100644 --- a/api/build/restart.go +++ b/api/build/restart.go @@ -8,6 +8,8 @@ import ( "strings" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/compiler" "github.com/go-vela/server/database" "github.com/go-vela/server/internal" @@ -20,7 +22,6 @@ import ( "github.com/go-vela/server/scm" "github.com/go-vela/server/util" "github.com/go-vela/types/constants" - "github.com/sirupsen/logrus" ) // swagger:operation POST /api/v1/repos/{org}/{repo}/builds/{build} builds RestartBuild diff --git a/api/build/token.go b/api/build/token.go index 7365a72d4..4c6de18ec 100644 --- a/api/build/token.go +++ b/api/build/token.go @@ -9,6 +9,8 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/internal/token" "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/claims" @@ -17,7 +19,6 @@ import ( "github.com/go-vela/server/util" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // swagger:operation GET /api/v1/repos/{org}/{repo}/builds/{build}/token builds GetBuildToken diff --git a/api/build/update.go b/api/build/update.go index 6a09e397f..be3f0cdec 100644 --- a/api/build/update.go +++ b/api/build/update.go @@ -7,6 +7,8 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/claims" @@ -16,7 +18,6 @@ import ( "github.com/go-vela/server/util" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // swagger:operation PUT /api/v1/repos/{org}/{repo}/builds/{build} builds UpdateBuild diff --git a/api/deployment/create.go b/api/deployment/create.go index 4f5d0faf1..b0fb02156 100644 --- a/api/deployment/create.go +++ b/api/deployment/create.go @@ -8,6 +8,8 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" @@ -15,7 +17,6 @@ import ( "github.com/go-vela/server/scm" "github.com/go-vela/server/util" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // swagger:operation POST /api/v1/deployments/{org}/{repo} deployments CreateDeployment diff --git a/api/deployment/get.go b/api/deployment/get.go index 72456e79a..c881bc800 100644 --- a/api/deployment/get.go +++ b/api/deployment/get.go @@ -8,13 +8,14 @@ import ( "strconv" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" "github.com/go-vela/server/util" - "github.com/sirupsen/logrus" ) // swagger:operation GET /api/v1/deployments/{org}/{repo}/{deployment} deployments GetDeployment diff --git a/api/deployment/list.go b/api/deployment/list.go index 8b8c24798..55667fdac 100644 --- a/api/deployment/list.go +++ b/api/deployment/list.go @@ -8,13 +8,14 @@ import ( "strconv" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/api" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/sirupsen/logrus" ) // swagger:operation GET /api/v1/deployments/{org}/{repo} deployments ListDeployments diff --git a/api/hook/create.go b/api/hook/create.go index 569e43664..a039371c5 100644 --- a/api/hook/create.go +++ b/api/hook/create.go @@ -8,13 +8,14 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // swagger:operation POST /api/v1/hooks/{org}/{repo} webhook CreateHook diff --git a/api/hook/delete.go b/api/hook/delete.go index 86ef22312..e31909a9f 100644 --- a/api/hook/delete.go +++ b/api/hook/delete.go @@ -8,12 +8,13 @@ import ( "strconv" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/sirupsen/logrus" ) // swagger:operation DELETE /api/v1/hooks/{org}/{repo}/{hook} webhook DeleteHook diff --git a/api/hook/get.go b/api/hook/get.go index d3ff18793..849aa60f7 100644 --- a/api/hook/get.go +++ b/api/hook/get.go @@ -8,12 +8,13 @@ import ( "strconv" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/sirupsen/logrus" ) // swagger:operation GET /api/v1/hooks/{org}/{repo}/{hook} webhook GetHook diff --git a/api/hook/list.go b/api/hook/list.go index 902cd33cc..e7235dba2 100644 --- a/api/hook/list.go +++ b/api/hook/list.go @@ -8,13 +8,14 @@ import ( "strconv" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/api" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/sirupsen/logrus" ) // swagger:operation GET /api/v1/hooks/{org}/{repo} webhook ListHooks diff --git a/api/hook/redeliver.go b/api/hook/redeliver.go index 50f68e6eb..a860c1718 100644 --- a/api/hook/redeliver.go +++ b/api/hook/redeliver.go @@ -8,13 +8,14 @@ import ( "strconv" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" "github.com/go-vela/server/util" - "github.com/sirupsen/logrus" ) // swagger:operation POST /api/v1/hooks/{org}/{repo}/{hook}/redeliver webhook RedeliverHook diff --git a/api/hook/update.go b/api/hook/update.go index 74954dde1..8d662b31c 100644 --- a/api/hook/update.go +++ b/api/hook/update.go @@ -8,13 +8,14 @@ import ( "strconv" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // swagger:operation PUT /api/v1/hooks/{org}/{repo}/{hook} webhook UpdateHook diff --git a/api/log/create_service.go b/api/log/create_service.go index fb188aead..442714c27 100644 --- a/api/log/create_service.go +++ b/api/log/create_service.go @@ -8,6 +8,8 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/org" @@ -16,7 +18,6 @@ import ( "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // swagger:operation POST /api/v1/repos/{org}/{repo}/builds/{build}/services/{service}/logs services CreateServiceLog diff --git a/api/log/create_step.go b/api/log/create_step.go index 19c8030ef..c5ed5f49f 100644 --- a/api/log/create_step.go +++ b/api/log/create_step.go @@ -8,6 +8,8 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/org" @@ -16,7 +18,6 @@ import ( "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // swagger:operation POST /api/v1/repos/{org}/{repo}/builds/{build}/steps/{step}/logs steps CreateStepLog diff --git a/api/log/delete_service.go b/api/log/delete_service.go index 788fe1f8d..9893d60d3 100644 --- a/api/log/delete_service.go +++ b/api/log/delete_service.go @@ -8,6 +8,8 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/org" @@ -15,7 +17,6 @@ import ( "github.com/go-vela/server/router/middleware/service" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/sirupsen/logrus" ) // swagger:operation DELETE /api/v1/repos/{org}/{repo}/builds/{build}/services/{service}/logs services DeleteServiceLog diff --git a/api/log/delete_step.go b/api/log/delete_step.go index 7209637ff..ebf505f1f 100644 --- a/api/log/delete_step.go +++ b/api/log/delete_step.go @@ -8,6 +8,8 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/org" @@ -15,7 +17,6 @@ import ( "github.com/go-vela/server/router/middleware/step" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/sirupsen/logrus" ) // swagger:operation DELETE /api/v1/repos/{org}/{repo}/builds/{build}/steps/{step}/logs steps DeleteStepLog diff --git a/api/log/get_service.go b/api/log/get_service.go index 62500eb3c..193850e90 100644 --- a/api/log/get_service.go +++ b/api/log/get_service.go @@ -8,6 +8,8 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/org" @@ -15,7 +17,6 @@ import ( "github.com/go-vela/server/router/middleware/service" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/sirupsen/logrus" ) // swagger:operation GET /api/v1/repos/{org}/{repo}/builds/{build}/services/{service}/logs services GetServiceLog diff --git a/api/log/get_step.go b/api/log/get_step.go index 2e2798918..2e8b524be 100644 --- a/api/log/get_step.go +++ b/api/log/get_step.go @@ -8,6 +8,8 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/org" @@ -15,7 +17,6 @@ import ( "github.com/go-vela/server/router/middleware/step" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/sirupsen/logrus" ) // swagger:operation GET /api/v1/repos/{org}/{repo}/builds/{build}/steps/{step}/logs steps GetStepLog diff --git a/api/log/list_build.go b/api/log/list_build.go index 6cb2e5130..5fc996ef0 100644 --- a/api/log/list_build.go +++ b/api/log/list_build.go @@ -8,6 +8,8 @@ import ( "strconv" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/api" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" @@ -15,7 +17,6 @@ import ( "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/sirupsen/logrus" ) // swagger:operation GET /api/v1/repos/{org}/{repo}/builds/{build}/logs builds ListLogsForBuild diff --git a/api/log/update_service.go b/api/log/update_service.go index 7e1ca5a5b..6d36b9bea 100644 --- a/api/log/update_service.go +++ b/api/log/update_service.go @@ -8,6 +8,8 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/org" @@ -16,7 +18,6 @@ import ( "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // swagger:operation PUT /api/v1/repos/{org}/{repo}/builds/{build}/services/{service}/logs services UpdateServiceLog diff --git a/api/log/update_step.go b/api/log/update_step.go index d6f0370ec..c34596a0f 100644 --- a/api/log/update_step.go +++ b/api/log/update_step.go @@ -8,6 +8,8 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/org" @@ -16,7 +18,6 @@ import ( "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // swagger:operation PUT /api/v1/repos/{org}/{repo}/builds/{build}/steps/{step}/logs steps UpdateStepLog diff --git a/api/metrics.go b/api/metrics.go index b562f7a1d..4a3323315 100644 --- a/api/metrics.go +++ b/api/metrics.go @@ -7,13 +7,14 @@ import ( "time" "github.com/gin-gonic/gin" - "github.com/go-vela/server/database" - "github.com/go-vela/server/queue" - "github.com/go-vela/types/constants" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/sirupsen/logrus" + + "github.com/go-vela/server/database" + "github.com/go-vela/server/queue" + "github.com/go-vela/types/constants" ) // MetricsQueryParameters holds query parameter information pertaining to requested metrics. diff --git a/api/pipeline/compile.go b/api/pipeline/compile.go index c3027edcf..4585451ba 100644 --- a/api/pipeline/compile.go +++ b/api/pipeline/compile.go @@ -8,6 +8,8 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/compiler" "github.com/go-vela/server/internal" "github.com/go-vela/server/router/middleware/org" @@ -16,7 +18,6 @@ import ( "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/pipeline" - "github.com/sirupsen/logrus" ) // swagger:operation POST /api/v1/pipelines/{org}/{repo}/{pipeline}/compile pipelines CompilePipeline diff --git a/api/pipeline/compile_test.go b/api/pipeline/compile_test.go index c65ce1d0b..e1ebd89d4 100644 --- a/api/pipeline/compile_test.go +++ b/api/pipeline/compile_test.go @@ -9,8 +9,9 @@ import ( "testing" "github.com/gin-gonic/gin" - "github.com/go-vela/types/pipeline" "github.com/google/go-cmp/cmp" + + "github.com/go-vela/types/pipeline" ) // TestPrepareRuleData tests the prepareRuleData function. diff --git a/api/pipeline/create.go b/api/pipeline/create.go index 240b59c57..1092a4051 100644 --- a/api/pipeline/create.go +++ b/api/pipeline/create.go @@ -7,13 +7,14 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // swagger:operation POST /api/v1/pipelines/{org}/{repo} pipelines CreatePipeline diff --git a/api/pipeline/delete.go b/api/pipeline/delete.go index d6ca9936e..b59f1adc3 100644 --- a/api/pipeline/delete.go +++ b/api/pipeline/delete.go @@ -7,13 +7,14 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/pipeline" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/sirupsen/logrus" ) // swagger:operation DELETE /api/v1/pipelines/{org}/{repo}/{pipeline} pipelines DeletePipeline diff --git a/api/pipeline/expand.go b/api/pipeline/expand.go index a47ca84d6..17e62181c 100644 --- a/api/pipeline/expand.go +++ b/api/pipeline/expand.go @@ -8,6 +8,8 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/compiler" "github.com/go-vela/server/internal" "github.com/go-vela/server/router/middleware/org" @@ -15,7 +17,6 @@ import ( "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/sirupsen/logrus" ) // swagger:operation POST /api/v1/pipelines/{org}/{repo}/{pipeline}/expand pipelines ExpandPipeline diff --git a/api/pipeline/get.go b/api/pipeline/get.go index 8e8b9cf16..69739f523 100644 --- a/api/pipeline/get.go +++ b/api/pipeline/get.go @@ -6,11 +6,12 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/pipeline" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" - "github.com/sirupsen/logrus" ) // swagger:operation GET /api/v1/pipelines/{org}/{repo}/{pipeline} pipelines GetPipeline diff --git a/api/pipeline/list.go b/api/pipeline/list.go index ebb83ad54..0ffdcff95 100644 --- a/api/pipeline/list.go +++ b/api/pipeline/list.go @@ -8,13 +8,14 @@ import ( "strconv" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/api" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/sirupsen/logrus" ) // swagger:operation GET /api/v1/pipelines/{org}/{repo} pipelines ListPipelines diff --git a/api/pipeline/output.go b/api/pipeline/output.go index b7e260ed3..e9d49483f 100644 --- a/api/pipeline/output.go +++ b/api/pipeline/output.go @@ -7,6 +7,7 @@ import ( "strings" "github.com/gin-gonic/gin" + "github.com/go-vela/server/util" ) diff --git a/api/pipeline/template.go b/api/pipeline/template.go index 8114d7f72..66c8cd627 100644 --- a/api/pipeline/template.go +++ b/api/pipeline/template.go @@ -8,6 +8,8 @@ import ( "strings" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/compiler" "github.com/go-vela/server/compiler/registry/github" "github.com/go-vela/server/internal" @@ -19,7 +21,6 @@ import ( "github.com/go-vela/server/util" "github.com/go-vela/types/library" "github.com/go-vela/types/yaml" - "github.com/sirupsen/logrus" ) // swagger:operation GET /api/v1/pipelines/{org}/{repo}/{pipeline}/templates pipelines GetTemplates diff --git a/api/pipeline/update.go b/api/pipeline/update.go index 075d00265..f5230fbe8 100644 --- a/api/pipeline/update.go +++ b/api/pipeline/update.go @@ -7,6 +7,8 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/pipeline" @@ -14,7 +16,6 @@ import ( "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // swagger:operation PUT /api/v1/pipelines/{org}/{repo}/{pipeline} pipelines UpdatePipeline diff --git a/api/pipeline/validate.go b/api/pipeline/validate.go index 2754b24c9..b7f43664d 100644 --- a/api/pipeline/validate.go +++ b/api/pipeline/validate.go @@ -7,6 +7,8 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/compiler" "github.com/go-vela/server/internal" "github.com/go-vela/server/router/middleware/org" @@ -14,7 +16,6 @@ import ( "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/sirupsen/logrus" ) // swagger:operation POST /api/v1/pipelines/{org}/{repo}/{pipeline}/validate pipelines ValidatePipeline diff --git a/api/queue/queue.go b/api/queue/queue.go index 78d4c170b..5c861572e 100644 --- a/api/queue/queue.go +++ b/api/queue/queue.go @@ -6,9 +6,10 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/router/middleware/claims" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // swagger:operation POST /api/v1/queue/info queue Info diff --git a/api/repo/chown.go b/api/repo/chown.go index 9e1bf98ab..f68a4fac6 100644 --- a/api/repo/chown.go +++ b/api/repo/chown.go @@ -7,12 +7,13 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/sirupsen/logrus" ) // swagger:operation PATCH /api/v1/repos/{org}/{repo}/chown repos ChownRepo diff --git a/api/repo/create.go b/api/repo/create.go index 636b955b3..824f7d0f5 100644 --- a/api/repo/create.go +++ b/api/repo/create.go @@ -9,6 +9,9 @@ import ( "strings" "github.com/gin-gonic/gin" + "github.com/google/uuid" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/api/types/actions" "github.com/go-vela/server/database" @@ -17,8 +20,6 @@ import ( "github.com/go-vela/server/util" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/google/uuid" - "github.com/sirupsen/logrus" ) // swagger:operation POST /api/v1/repos repos CreateRepo diff --git a/api/repo/delete.go b/api/repo/delete.go index 445a9af92..7a70ceac4 100644 --- a/api/repo/delete.go +++ b/api/repo/delete.go @@ -7,13 +7,14 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" "github.com/go-vela/server/util" - "github.com/sirupsen/logrus" ) // swagger:operation DELETE /api/v1/repos/{org}/{repo} repos DeleteRepo diff --git a/api/repo/get.go b/api/repo/get.go index d8b1fdebb..61df846d4 100644 --- a/api/repo/get.go +++ b/api/repo/get.go @@ -6,10 +6,11 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" - "github.com/sirupsen/logrus" ) // swagger:operation GET /api/v1/repos/{org}/{repo} repos GetRepo diff --git a/api/repo/list.go b/api/repo/list.go index 7b7f788f6..010ae0cfe 100644 --- a/api/repo/list.go +++ b/api/repo/list.go @@ -8,11 +8,12 @@ import ( "strconv" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/api" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/sirupsen/logrus" ) // swagger:operation GET /api/v1/repos repos ListRepos diff --git a/api/repo/list_org.go b/api/repo/list_org.go index e2b5b411b..565082f97 100644 --- a/api/repo/list_org.go +++ b/api/repo/list_org.go @@ -8,6 +8,8 @@ import ( "strconv" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/api" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/org" @@ -15,7 +17,6 @@ import ( "github.com/go-vela/server/scm" "github.com/go-vela/server/util" "github.com/go-vela/types/constants" - "github.com/sirupsen/logrus" ) // swagger:operation GET /api/v1/repos/{org} repos ListReposForOrg diff --git a/api/repo/repair.go b/api/repo/repair.go index 9d6e99b32..1e3eefb33 100644 --- a/api/repo/repair.go +++ b/api/repo/repair.go @@ -7,6 +7,8 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + wh "github.com/go-vela/server/api/webhook" "github.com/go-vela/server/database" "github.com/go-vela/server/internal" @@ -15,7 +17,6 @@ import ( "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" "github.com/go-vela/server/util" - "github.com/sirupsen/logrus" ) // swagger:operation PATCH /api/v1/repos/{org}/{repo}/repair repos RepairRepo diff --git a/api/repo/update.go b/api/repo/update.go index db179371a..82fd02922 100644 --- a/api/repo/update.go +++ b/api/repo/update.go @@ -9,6 +9,9 @@ import ( "strings" "github.com/gin-gonic/gin" + "github.com/google/uuid" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/org" @@ -17,8 +20,6 @@ import ( "github.com/go-vela/server/scm" "github.com/go-vela/server/util" "github.com/go-vela/types/constants" - "github.com/google/uuid" - "github.com/sirupsen/logrus" ) // swagger:operation PUT /api/v1/repos/{org}/{repo} repos UpdateRepo diff --git a/api/schedule/create.go b/api/schedule/create.go index 88df46a75..7a9439b8c 100644 --- a/api/schedule/create.go +++ b/api/schedule/create.go @@ -9,12 +9,13 @@ import ( "github.com/adhocore/gronx" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // swagger:operation POST /api/v1/schedules/{org}/{repo} schedules CreateSchedule diff --git a/api/schedule/delete.go b/api/schedule/delete.go index 3e7eea10d..73c60a8c0 100644 --- a/api/schedule/delete.go +++ b/api/schedule/delete.go @@ -7,13 +7,14 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/schedule" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/sirupsen/logrus" ) // swagger:operation DELETE /api/v1/repos/{org}/{repo}/{schedule} schedules DeleteSchedule diff --git a/api/schedule/get.go b/api/schedule/get.go index 902b06b21..d9ff954b2 100644 --- a/api/schedule/get.go +++ b/api/schedule/get.go @@ -6,11 +6,12 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/schedule" "github.com/go-vela/server/router/middleware/user" - "github.com/sirupsen/logrus" ) // swagger:operation GET /api/v1/schedules/{org}/{repo}/{schedule} schedules GetSchedule diff --git a/api/schedule/list.go b/api/schedule/list.go index cd47a56e1..c6c424647 100644 --- a/api/schedule/list.go +++ b/api/schedule/list.go @@ -8,11 +8,12 @@ import ( "strconv" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/api" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/util" - "github.com/sirupsen/logrus" ) // swagger:operation GET /api/v1/schedules/{org}/{repo} schedules ListSchedules diff --git a/api/schedule/update.go b/api/schedule/update.go index d1ff1e44f..41da289ec 100644 --- a/api/schedule/update.go +++ b/api/schedule/update.go @@ -8,13 +8,14 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/schedule" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // swagger:operation PUT /api/v1/schedules/{org}/{repo}/{schedule} schedules UpdateSchedule diff --git a/api/scm/sync.go b/api/scm/sync.go index 2033c9a49..9520fb143 100644 --- a/api/scm/sync.go +++ b/api/scm/sync.go @@ -8,13 +8,14 @@ import ( "strings" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" "github.com/go-vela/server/util" - "github.com/sirupsen/logrus" ) // swagger:operation PATCH /api/v1/scm/repos/{org}/{repo}/sync scm SyncRepo diff --git a/api/scm/sync_org.go b/api/scm/sync_org.go index 0c5628bef..b1162503c 100644 --- a/api/scm/sync_org.go +++ b/api/scm/sync_org.go @@ -7,13 +7,14 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" "github.com/go-vela/server/util" - "github.com/sirupsen/logrus" ) // swagger:operation PATCH /api/v1/scm/orgs/{org}/sync scm SyncReposForOrg diff --git a/api/secret/create.go b/api/secret/create.go index e398647c6..fd44f1779 100644 --- a/api/secret/create.go +++ b/api/secret/create.go @@ -9,6 +9,8 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" "github.com/go-vela/server/secret" @@ -16,7 +18,6 @@ import ( "github.com/go-vela/types/constants" "github.com/go-vela/types/library" "github.com/go-vela/types/library/actions" - "github.com/sirupsen/logrus" ) // diff --git a/api/secret/delete.go b/api/secret/delete.go index 5257b82a9..dd4db4145 100644 --- a/api/secret/delete.go +++ b/api/secret/delete.go @@ -8,11 +8,12 @@ import ( "strings" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/secret" "github.com/go-vela/server/util" "github.com/go-vela/types/constants" - "github.com/sirupsen/logrus" ) // diff --git a/api/secret/get.go b/api/secret/get.go index 74cad449f..44c379f8b 100644 --- a/api/secret/get.go +++ b/api/secret/get.go @@ -8,12 +8,13 @@ import ( "strings" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/router/middleware/claims" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/secret" "github.com/go-vela/server/util" "github.com/go-vela/types/constants" - "github.com/sirupsen/logrus" ) // diff --git a/api/secret/list.go b/api/secret/list.go index a3870597f..c142b89a6 100644 --- a/api/secret/list.go +++ b/api/secret/list.go @@ -9,6 +9,8 @@ import ( "strings" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/api" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" @@ -16,7 +18,6 @@ import ( "github.com/go-vela/server/util" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // diff --git a/api/secret/update.go b/api/secret/update.go index aecadcc86..cb012c719 100644 --- a/api/secret/update.go +++ b/api/secret/update.go @@ -9,12 +9,13 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/secret" "github.com/go-vela/server/util" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // diff --git a/api/service/create.go b/api/service/create.go index e43f66a0f..2ccb9e314 100644 --- a/api/service/create.go +++ b/api/service/create.go @@ -8,6 +8,8 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/org" @@ -16,7 +18,6 @@ import ( "github.com/go-vela/server/util" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // swagger:operation POST /api/v1/repos/{org}/{repo}/builds/{build}/services services CreateService diff --git a/api/service/delete.go b/api/service/delete.go index ff885e440..915804a27 100644 --- a/api/service/delete.go +++ b/api/service/delete.go @@ -7,6 +7,8 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/org" @@ -14,7 +16,6 @@ import ( "github.com/go-vela/server/router/middleware/service" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/sirupsen/logrus" ) // diff --git a/api/service/get.go b/api/service/get.go index 5ac4503b8..b81b69735 100644 --- a/api/service/get.go +++ b/api/service/get.go @@ -6,12 +6,13 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/service" "github.com/go-vela/server/router/middleware/user" - "github.com/sirupsen/logrus" ) // diff --git a/api/service/list.go b/api/service/list.go index d5e37cfef..6697a7282 100644 --- a/api/service/list.go +++ b/api/service/list.go @@ -8,6 +8,8 @@ import ( "strconv" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/api" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" @@ -15,7 +17,6 @@ import ( "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/sirupsen/logrus" ) // swagger:operation GET /api/v1/repos/{org}/{repo}/builds/{build}/services services ListServices diff --git a/api/service/update.go b/api/service/update.go index c391e6a86..a539270e3 100644 --- a/api/service/update.go +++ b/api/service/update.go @@ -7,6 +7,8 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/org" @@ -15,7 +17,6 @@ import ( "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // diff --git a/api/step/create.go b/api/step/create.go index f8b9ef2f8..2218d214d 100644 --- a/api/step/create.go +++ b/api/step/create.go @@ -8,6 +8,8 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/org" @@ -16,7 +18,6 @@ import ( "github.com/go-vela/server/util" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // swagger:operation POST /api/v1/repos/{org}/{repo}/builds/{build}/steps steps CreateStep diff --git a/api/step/delete.go b/api/step/delete.go index 574e873c7..8d735717a 100644 --- a/api/step/delete.go +++ b/api/step/delete.go @@ -7,6 +7,8 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/org" @@ -14,7 +16,6 @@ import ( "github.com/go-vela/server/router/middleware/step" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/sirupsen/logrus" ) // swagger:operation DELETE /api/v1/repos/{org}/{repo}/builds/{build}/steps/{step} steps DeleteStep diff --git a/api/step/get.go b/api/step/get.go index 51f1894c6..9582b5928 100644 --- a/api/step/get.go +++ b/api/step/get.go @@ -6,12 +6,13 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/step" "github.com/go-vela/server/router/middleware/user" - "github.com/sirupsen/logrus" ) // swagger:operation GET /api/v1/repos/{org}/{repo}/builds/{build}/steps/{step} steps GetStep diff --git a/api/step/list.go b/api/step/list.go index 42c45cac8..603d7083b 100644 --- a/api/step/list.go +++ b/api/step/list.go @@ -8,6 +8,8 @@ import ( "strconv" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/api" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" @@ -15,7 +17,6 @@ import ( "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/sirupsen/logrus" ) // swagger:operation GET /api/v1/repos/{org}/{repo}/builds/{build}/steps steps ListSteps diff --git a/api/step/plan.go b/api/step/plan.go index eb7d9dda9..7e493aab6 100644 --- a/api/step/plan.go +++ b/api/step/plan.go @@ -7,13 +7,14 @@ import ( "fmt" "time" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/scm" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" "github.com/go-vela/types/pipeline" - "github.com/sirupsen/logrus" ) // PlanSteps is a helper function to plan all steps diff --git a/api/step/update.go b/api/step/update.go index 7dc97efac..cb767de4e 100644 --- a/api/step/update.go +++ b/api/step/update.go @@ -7,6 +7,8 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/org" @@ -17,7 +19,6 @@ import ( "github.com/go-vela/server/util" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // swagger:operation PUT /api/v1/repos/{org}/{repo}/builds/{build}/steps/{step} steps UpdateStep diff --git a/api/types/events_test.go b/api/types/events_test.go index 45b003398..447a84c54 100644 --- a/api/types/events_test.go +++ b/api/types/events_test.go @@ -6,9 +6,10 @@ import ( "reflect" "testing" + "github.com/google/go-cmp/cmp" + "github.com/go-vela/server/api/types/actions" "github.com/go-vela/types/constants" - "github.com/google/go-cmp/cmp" ) func TestTypes_Events_Getters(t *testing.T) { diff --git a/api/types/repo_test.go b/api/types/repo_test.go index b0554d742..bbbd6ee91 100644 --- a/api/types/repo_test.go +++ b/api/types/repo_test.go @@ -7,9 +7,10 @@ import ( "reflect" "testing" + "github.com/google/go-cmp/cmp" + "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/google/go-cmp/cmp" ) func TestTypes_Repo_Environment(t *testing.T) { diff --git a/api/user/create.go b/api/user/create.go index 575e73c88..43d7037bc 100644 --- a/api/user/create.go +++ b/api/user/create.go @@ -7,11 +7,12 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // swagger:operation POST /api/v1/users users CreateUser diff --git a/api/user/create_token.go b/api/user/create_token.go index 9f57fde9a..e1b8fa9c0 100644 --- a/api/user/create_token.go +++ b/api/user/create_token.go @@ -8,12 +8,13 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/internal/token" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // swagger:operation POST /api/v1/user/token users CreateToken diff --git a/api/user/delete.go b/api/user/delete.go index 36393d24a..fd32d75d0 100644 --- a/api/user/delete.go +++ b/api/user/delete.go @@ -7,10 +7,11 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/sirupsen/logrus" ) // swagger:operation DELETE /api/v1/users/{user} users DeleteUser diff --git a/api/user/delete_token.go b/api/user/delete_token.go index adb554015..b0caa2ac1 100644 --- a/api/user/delete_token.go +++ b/api/user/delete_token.go @@ -8,12 +8,13 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/internal/token" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // swagger:operation DELETE /api/v1/user/token users DeleteToken diff --git a/api/user/get.go b/api/user/get.go index e888ff804..488cd9705 100644 --- a/api/user/get.go +++ b/api/user/get.go @@ -7,10 +7,11 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/sirupsen/logrus" ) // swagger:operation GET /api/v1/users/{user} users GetUser diff --git a/api/user/get_current.go b/api/user/get_current.go index 641576df0..455a4e8e7 100644 --- a/api/user/get_current.go +++ b/api/user/get_current.go @@ -6,8 +6,9 @@ import ( "net/http" "github.com/gin-gonic/gin" - "github.com/go-vela/server/router/middleware/user" "github.com/sirupsen/logrus" + + "github.com/go-vela/server/router/middleware/user" ) // swagger:operation GET /api/v1/user users GetCurrentUser diff --git a/api/user/get_source.go b/api/user/get_source.go index b52e3950f..d0b666090 100644 --- a/api/user/get_source.go +++ b/api/user/get_source.go @@ -7,12 +7,13 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" "github.com/go-vela/server/util" - "github.com/sirupsen/logrus" ) // swagger:operation GET /api/v1/user/source/repos users GetSourceRepos diff --git a/api/user/list.go b/api/user/list.go index a62ae57aa..55f67f64e 100644 --- a/api/user/list.go +++ b/api/user/list.go @@ -8,11 +8,12 @@ import ( "strconv" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/api" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/sirupsen/logrus" ) // swagger:operation GET /api/v1/users users ListUsers diff --git a/api/user/update.go b/api/user/update.go index 0535da1f5..09767d94c 100644 --- a/api/user/update.go +++ b/api/user/update.go @@ -7,11 +7,12 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // swagger:operation PUT /api/v1/users/{user} users UpdateUser diff --git a/api/user/update_current.go b/api/user/update_current.go index ab56023ad..bd3cb9a85 100644 --- a/api/user/update_current.go +++ b/api/user/update_current.go @@ -7,11 +7,12 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // swagger:operation PUT /api/v1/user users UpdateCurrentUser diff --git a/api/webhook/post.go b/api/webhook/post.go index 3f1b3bba7..82db4a899 100644 --- a/api/webhook/post.go +++ b/api/webhook/post.go @@ -14,6 +14,9 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "gorm.io/gorm" + "github.com/go-vela/server/api/build" "github.com/go-vela/server/api/types" "github.com/go-vela/server/compiler" @@ -24,8 +27,6 @@ import ( "github.com/go-vela/server/util" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" - "gorm.io/gorm" ) var baseErr = "unable to process webhook" diff --git a/api/worker/create.go b/api/worker/create.go index 38f9eb786..557cb1858 100644 --- a/api/worker/create.go +++ b/api/worker/create.go @@ -9,6 +9,8 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/internal/token" @@ -17,7 +19,6 @@ import ( "github.com/go-vela/server/util" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // swagger:operation POST /api/v1/workers workers CreateWorker diff --git a/api/worker/delete.go b/api/worker/delete.go index cde6c743a..ebb718aeb 100644 --- a/api/worker/delete.go +++ b/api/worker/delete.go @@ -7,11 +7,12 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/router/middleware/worker" "github.com/go-vela/server/util" - "github.com/sirupsen/logrus" ) // swagger:operation DELETE /api/v1/workers/{worker} workers DeleteWorker diff --git a/api/worker/get.go b/api/worker/get.go index b7bebd149..ab277514f 100644 --- a/api/worker/get.go +++ b/api/worker/get.go @@ -7,12 +7,13 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/router/middleware/worker" "github.com/go-vela/server/util" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // swagger:operation GET /api/v1/workers/{worker} workers GetWorker diff --git a/api/worker/list.go b/api/worker/list.go index 82673eccf..656745efa 100644 --- a/api/worker/list.go +++ b/api/worker/list.go @@ -9,11 +9,12 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // swagger:operation GET /api/v1/workers workers ListWorkers diff --git a/api/worker/refresh.go b/api/worker/refresh.go index 15826f6d6..4aff87a17 100644 --- a/api/worker/refresh.go +++ b/api/worker/refresh.go @@ -9,6 +9,8 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/internal/token" "github.com/go-vela/server/router/middleware/claims" @@ -16,7 +18,6 @@ import ( "github.com/go-vela/server/util" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // swagger:operation POST /api/v1/workers/{worker}/refresh workers RefreshWorkerAuth diff --git a/api/worker/update.go b/api/worker/update.go index e5b842a0d..db187b7c0 100644 --- a/api/worker/update.go +++ b/api/worker/update.go @@ -7,12 +7,13 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/router/middleware/worker" "github.com/go-vela/server/util" - "github.com/sirupsen/logrus" ) // swagger:operation PUT /api/v1/workers/{worker} workers UpdateWorker diff --git a/cmd/vela-server/compiler.go b/cmd/vela-server/compiler.go index 4e85f046a..872f3fbd0 100644 --- a/cmd/vela-server/compiler.go +++ b/cmd/vela-server/compiler.go @@ -3,14 +3,12 @@ package main import ( + "github.com/sirupsen/logrus" + "github.com/urfave/cli/v2" + "github.com/go-vela/server/compiler" "github.com/go-vela/server/compiler/native" - "github.com/go-vela/types/constants" - - "github.com/sirupsen/logrus" - - "github.com/urfave/cli/v2" ) // helper function to setup the queue from the CLI arguments. diff --git a/cmd/vela-server/main.go b/cmd/vela-server/main.go index 715c821a2..5ce4c7bd7 100644 --- a/cmd/vela-server/main.go +++ b/cmd/vela-server/main.go @@ -8,17 +8,17 @@ import ( "os" "time" - "github.com/go-vela/types/constants" + "github.com/sirupsen/logrus" + "github.com/urfave/cli/v2" + + _ "github.com/joho/godotenv/autoload" "github.com/go-vela/server/database" "github.com/go-vela/server/queue" "github.com/go-vela/server/scm" "github.com/go-vela/server/secret" "github.com/go-vela/server/version" - "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" - - _ "github.com/joho/godotenv/autoload" + "github.com/go-vela/types/constants" ) //nolint:funlen // ignore line length diff --git a/cmd/vela-server/metadata.go b/cmd/vela-server/metadata.go index 4e24723cb..f14d9ee12 100644 --- a/cmd/vela-server/metadata.go +++ b/cmd/vela-server/metadata.go @@ -5,11 +5,10 @@ package main import ( "net/url" - "github.com/go-vela/server/internal" - "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + + "github.com/go-vela/server/internal" ) // helper function to setup the metadata from the CLI arguments. diff --git a/cmd/vela-server/queue.go b/cmd/vela-server/queue.go index 8b8767e56..7a3a74c41 100644 --- a/cmd/vela-server/queue.go +++ b/cmd/vela-server/queue.go @@ -3,11 +3,10 @@ package main import ( - "github.com/go-vela/server/queue" - "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + + "github.com/go-vela/server/queue" ) // helper function to setup the queue from the CLI arguments. diff --git a/cmd/vela-server/schedule.go b/cmd/vela-server/schedule.go index 89a0abece..dda61bdea 100644 --- a/cmd/vela-server/schedule.go +++ b/cmd/vela-server/schedule.go @@ -9,6 +9,9 @@ import ( "time" "github.com/adhocore/gronx" + "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/util/wait" + "github.com/go-vela/server/api/build" "github.com/go-vela/server/compiler" "github.com/go-vela/server/database" @@ -18,9 +21,6 @@ import ( "github.com/go-vela/server/util" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" - - "k8s.io/apimachinery/pkg/util/wait" ) const ( diff --git a/cmd/vela-server/scm.go b/cmd/vela-server/scm.go index 3a7e0ef73..4cf76a740 100644 --- a/cmd/vela-server/scm.go +++ b/cmd/vela-server/scm.go @@ -3,10 +3,10 @@ package main import ( - "github.com/go-vela/server/scm" "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" + + "github.com/go-vela/server/scm" ) // helper function to setup the scm from the CLI arguments. diff --git a/cmd/vela-server/secret.go b/cmd/vela-server/secret.go index 1b0e22ef8..88312bd6d 100644 --- a/cmd/vela-server/secret.go +++ b/cmd/vela-server/secret.go @@ -3,13 +3,12 @@ package main import ( + "github.com/sirupsen/logrus" + "github.com/urfave/cli/v2" + "github.com/go-vela/server/database" "github.com/go-vela/server/secret" "github.com/go-vela/types/constants" - - "github.com/sirupsen/logrus" - - "github.com/urfave/cli/v2" ) // helper function to setup the secrets engines from the CLI arguments. diff --git a/cmd/vela-server/server.go b/cmd/vela-server/server.go index 1910c2d70..7f25a43df 100644 --- a/cmd/vela-server/server.go +++ b/cmd/vela-server/server.go @@ -13,14 +13,14 @@ import ( "time" "github.com/gin-gonic/gin" - "github.com/go-vela/server/database" - "github.com/go-vela/server/router" - "github.com/go-vela/server/router/middleware" "github.com/sirupsen/logrus" "github.com/urfave/cli/v2" "golang.org/x/sync/errgroup" - "k8s.io/apimachinery/pkg/util/wait" + + "github.com/go-vela/server/database" + "github.com/go-vela/server/router" + "github.com/go-vela/server/router/middleware" ) func server(c *cli.Context) error { diff --git a/cmd/vela-server/token.go b/cmd/vela-server/token.go index 39b1600a6..04a756fca 100644 --- a/cmd/vela-server/token.go +++ b/cmd/vela-server/token.go @@ -4,9 +4,7 @@ package main import ( "github.com/golang-jwt/jwt/v5" - "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" "github.com/go-vela/server/internal/token" diff --git a/cmd/vela-server/validate.go b/cmd/vela-server/validate.go index 26b8eda89..3ceb2b330 100644 --- a/cmd/vela-server/validate.go +++ b/cmd/vela-server/validate.go @@ -6,10 +6,10 @@ import ( "fmt" "strings" - "github.com/go-vela/types/constants" - "github.com/sirupsen/logrus" "github.com/urfave/cli/v2" + + "github.com/go-vela/types/constants" ) func validate(c *cli.Context) error { diff --git a/compiler/native/clone_test.go b/compiler/native/clone_test.go index 662576d53..120e3524f 100644 --- a/compiler/native/clone_test.go +++ b/compiler/native/clone_test.go @@ -7,8 +7,9 @@ import ( "reflect" "testing" - "github.com/go-vela/types/yaml" "github.com/urfave/cli/v2" + + "github.com/go-vela/types/yaml" ) const defaultCloneImage = "target/vela-git:latest" diff --git a/compiler/native/compile.go b/compiler/native/compile.go index cbea8185e..d5cb1d49b 100644 --- a/compiler/native/compile.go +++ b/compiler/native/compile.go @@ -12,17 +12,16 @@ import ( "strings" "time" - "github.com/go-vela/types/constants" - yml "github.com/buildkite/yaml" - api "github.com/go-vela/server/api/types" + "github.com/hashicorp/go-cleanhttp" + "github.com/hashicorp/go-retryablehttp" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/types/constants" "github.com/go-vela/types/library" "github.com/go-vela/types/pipeline" "github.com/go-vela/types/raw" "github.com/go-vela/types/yaml" - "github.com/hashicorp/go-cleanhttp" - "github.com/hashicorp/go-retryablehttp" ) // ModifyRequest contains the payload passed to the modification endpoint. @@ -300,8 +299,6 @@ func (c *client) compileInline(p *yaml.Build, depth int) (*yaml.Build, error) { } // compileSteps executes the workflow for converting a YAML pipeline into an executable struct. -// -//nolint:dupl,lll // linter thinks the steps and stages workflows are identical func (c *client) compileSteps(p *yaml.Build, _pipeline *library.Pipeline, tmpls map[string]*yaml.Template, r *pipeline.RuleData) (*pipeline.Build, *library.Pipeline, error) { var err error @@ -397,8 +394,6 @@ func (c *client) compileSteps(p *yaml.Build, _pipeline *library.Pipeline, tmpls } // compileStages executes the workflow for converting a YAML pipeline into an executable struct. -// -//nolint:dupl,lll // linter thinks the steps and stages workflows are identical func (c *client) compileStages(p *yaml.Build, _pipeline *library.Pipeline, tmpls map[string]*yaml.Template, r *pipeline.RuleData) (*pipeline.Build, *library.Pipeline, error) { var err error diff --git a/compiler/native/compile_test.go b/compiler/native/compile_test.go index 4d77cd148..86db5f595 100644 --- a/compiler/native/compile_test.go +++ b/compiler/native/compile_test.go @@ -9,28 +9,22 @@ import ( "net/http/httptest" "os" "path/filepath" - - api "github.com/go-vela/server/api/types" - "github.com/go-vela/server/internal" - "github.com/go-vela/types/constants" - "github.com/go-vela/types/raw" - - "github.com/google/go-github/v61/github" - "testing" "time" + yml "github.com/buildkite/yaml" + "github.com/gin-gonic/gin" "github.com/google/go-cmp/cmp" + "github.com/google/go-github/v61/github" + "github.com/urfave/cli/v2" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/internal" + "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/go-vela/types/yaml" - "github.com/go-vela/types/pipeline" - - "github.com/gin-gonic/gin" - "github.com/urfave/cli/v2" - - yml "github.com/buildkite/yaml" + "github.com/go-vela/types/raw" + "github.com/go-vela/types/yaml" ) func TestNative_Compile_StagesPipeline(t *testing.T) { diff --git a/compiler/native/environment_test.go b/compiler/native/environment_test.go index cfacbd880..2d715ae8a 100644 --- a/compiler/native/environment_test.go +++ b/compiler/native/environment_test.go @@ -8,15 +8,14 @@ import ( "strings" "testing" - api "github.com/go-vela/server/api/types" - "github.com/go-vela/server/internal" - "github.com/go-vela/types/raw" "github.com/google/go-cmp/cmp" + "github.com/urfave/cli/v2" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/internal" "github.com/go-vela/types/library" + "github.com/go-vela/types/raw" "github.com/go-vela/types/yaml" - - "github.com/urfave/cli/v2" ) func TestNative_EnvironmentStages(t *testing.T) { diff --git a/compiler/native/expand.go b/compiler/native/expand.go index f3bac6edc..e69066ef7 100644 --- a/compiler/native/expand.go +++ b/compiler/native/expand.go @@ -6,17 +6,16 @@ import ( "fmt" "strings" - "github.com/go-vela/types/constants" - "github.com/go-vela/types/pipeline" + "github.com/sirupsen/logrus" + "github.com/spf13/afero" "github.com/go-vela/server/compiler/registry" "github.com/go-vela/server/compiler/template/native" "github.com/go-vela/server/compiler/template/starlark" - "github.com/spf13/afero" - + "github.com/go-vela/types/constants" + "github.com/go-vela/types/pipeline" "github.com/go-vela/types/raw" "github.com/go-vela/types/yaml" - "github.com/sirupsen/logrus" ) // ExpandStages injects the template for each diff --git a/compiler/native/expand_test.go b/compiler/native/expand_test.go index 8400bd6a4..c43eb14bd 100644 --- a/compiler/native/expand_test.go +++ b/compiler/native/expand_test.go @@ -9,15 +9,15 @@ import ( "reflect" "testing" + "github.com/gin-gonic/gin" + "github.com/google/go-cmp/cmp" + "github.com/urfave/cli/v2" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/library" "github.com/go-vela/types/pipeline" "github.com/go-vela/types/raw" "github.com/go-vela/types/yaml" - "github.com/google/go-cmp/cmp" - - "github.com/gin-gonic/gin" - "github.com/urfave/cli/v2" ) func TestNative_ExpandStages(t *testing.T) { diff --git a/compiler/native/initialize_test.go b/compiler/native/initialize_test.go index 6a0b2d31c..33276ffdb 100644 --- a/compiler/native/initialize_test.go +++ b/compiler/native/initialize_test.go @@ -7,8 +7,9 @@ import ( "reflect" "testing" - "github.com/go-vela/types/yaml" "github.com/urfave/cli/v2" + + "github.com/go-vela/types/yaml" ) func TestNative_InitStage(t *testing.T) { diff --git a/compiler/native/native.go b/compiler/native/native.go index 04db6b72c..b4b756c52 100644 --- a/compiler/native/native.go +++ b/compiler/native/native.go @@ -5,17 +5,15 @@ package native import ( "time" + "github.com/sirupsen/logrus" + "github.com/urfave/cli/v2" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/compiler" - "github.com/go-vela/server/internal" - "github.com/go-vela/server/compiler/registry" "github.com/go-vela/server/compiler/registry/github" - + "github.com/go-vela/server/internal" "github.com/go-vela/types/library" - - "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" ) type ModificationConfig struct { diff --git a/compiler/native/native_test.go b/compiler/native/native_test.go index db0859c02..a426aa3e9 100644 --- a/compiler/native/native_test.go +++ b/compiler/native/native_test.go @@ -7,13 +7,12 @@ import ( "reflect" "testing" + "github.com/urfave/cli/v2" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/compiler/registry/github" "github.com/go-vela/server/internal" - "github.com/go-vela/types/library" - - "github.com/urfave/cli/v2" ) func TestNative_New(t *testing.T) { diff --git a/compiler/native/parse.go b/compiler/native/parse.go index 83a401ddf..9ccd525f1 100644 --- a/compiler/native/parse.go +++ b/compiler/native/parse.go @@ -7,12 +7,12 @@ import ( "io" "os" + "github.com/buildkite/yaml" + "github.com/go-vela/server/compiler/template/native" "github.com/go-vela/server/compiler/template/starlark" "github.com/go-vela/types/constants" types "github.com/go-vela/types/yaml" - - "github.com/buildkite/yaml" ) // ParseRaw converts an object to a string. diff --git a/compiler/native/parse_test.go b/compiler/native/parse_test.go index a24d3bf34..dfe691fdb 100644 --- a/compiler/native/parse_test.go +++ b/compiler/native/parse_test.go @@ -10,14 +10,13 @@ import ( "reflect" "testing" + "github.com/google/go-cmp/cmp" + "github.com/urfave/cli/v2" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/raw" "github.com/go-vela/types/yaml" - "github.com/google/go-cmp/cmp" - - "github.com/urfave/cli/v2" ) func TestNative_Parse_Metadata_Bytes(t *testing.T) { diff --git a/compiler/native/script_test.go b/compiler/native/script_test.go index 2ce2ada59..308023e77 100644 --- a/compiler/native/script_test.go +++ b/compiler/native/script_test.go @@ -7,10 +7,10 @@ import ( "reflect" "testing" - "github.com/go-vela/types/yaml" "github.com/google/go-cmp/cmp" - "github.com/urfave/cli/v2" + + "github.com/go-vela/types/yaml" ) func TestNative_ScriptStages(t *testing.T) { diff --git a/compiler/native/substitute.go b/compiler/native/substitute.go index e143cfc1b..9bbc717cd 100644 --- a/compiler/native/substitute.go +++ b/compiler/native/substitute.go @@ -7,7 +7,6 @@ import ( "strings" "github.com/buildkite/yaml" - "github.com/drone/envsubst" types "github.com/go-vela/types/yaml" diff --git a/compiler/native/substitute_test.go b/compiler/native/substitute_test.go index a02d59f8f..459bb2896 100644 --- a/compiler/native/substitute_test.go +++ b/compiler/native/substitute_test.go @@ -6,10 +6,10 @@ import ( "flag" "testing" + "github.com/google/go-cmp/cmp" "github.com/urfave/cli/v2" "github.com/go-vela/types/yaml" - "github.com/google/go-cmp/cmp" ) func Test_client_SubstituteStages(t *testing.T) { diff --git a/compiler/native/transform_test.go b/compiler/native/transform_test.go index 82ec72d3d..e8d596be3 100644 --- a/compiler/native/transform_test.go +++ b/compiler/native/transform_test.go @@ -7,11 +7,11 @@ import ( "reflect" "testing" + "github.com/urfave/cli/v2" + "github.com/go-vela/server/internal" "github.com/go-vela/types/pipeline" "github.com/go-vela/types/yaml" - - "github.com/urfave/cli/v2" ) func TestNative_TransformStages(t *testing.T) { diff --git a/compiler/native/validate_test.go b/compiler/native/validate_test.go index 453af288a..85896b4a1 100644 --- a/compiler/native/validate_test.go +++ b/compiler/native/validate_test.go @@ -7,10 +7,10 @@ import ( "fmt" "testing" + "github.com/urfave/cli/v2" + "github.com/go-vela/types/raw" "github.com/go-vela/types/yaml" - - "github.com/urfave/cli/v2" ) func TestNative_Validate_NoVersion(t *testing.T) { diff --git a/compiler/registry/github/parse.go b/compiler/registry/github/parse.go index 45657ed0a..30908e75b 100644 --- a/compiler/registry/github/parse.go +++ b/compiler/registry/github/parse.go @@ -6,9 +6,9 @@ import ( "fmt" "strings" - "github.com/go-vela/server/compiler/registry" - "github.com/goware/urlx" + + "github.com/go-vela/server/compiler/registry" ) // Parse creates the registry source object from diff --git a/compiler/registry/github/template.go b/compiler/registry/github/template.go index b375c151f..f0e26e489 100644 --- a/compiler/registry/github/template.go +++ b/compiler/registry/github/template.go @@ -7,11 +7,10 @@ import ( "fmt" "net/http" - "github.com/go-vela/server/compiler/registry" + "github.com/google/go-github/v61/github" + "github.com/go-vela/server/compiler/registry" "github.com/go-vela/types/library" - - "github.com/google/go-github/v61/github" ) // Template captures the templated pipeline configuration from the GitHub repo. diff --git a/compiler/registry/github/template_test.go b/compiler/registry/github/template_test.go index dd55fda7d..9e2ce6562 100644 --- a/compiler/registry/github/template_test.go +++ b/compiler/registry/github/template_test.go @@ -9,11 +9,10 @@ import ( "reflect" "testing" - "github.com/go-vela/server/compiler/registry" + "github.com/gin-gonic/gin" + "github.com/go-vela/server/compiler/registry" "github.com/go-vela/types/library" - - "github.com/gin-gonic/gin" ) func TestGithub_Template(t *testing.T) { diff --git a/compiler/template/native/render.go b/compiler/template/native/render.go index d4185a3d3..a31f642b6 100644 --- a/compiler/template/native/render.go +++ b/compiler/template/native/render.go @@ -7,13 +7,11 @@ import ( "fmt" "text/template" - "github.com/go-vela/types/raw" - - types "github.com/go-vela/types/yaml" - "github.com/Masterminds/sprig/v3" - "github.com/buildkite/yaml" + + "github.com/go-vela/types/raw" + types "github.com/go-vela/types/yaml" ) // Render combines the template with the step in the yaml pipeline. diff --git a/compiler/template/starlark/convert.go b/compiler/template/starlark/convert.go index 9e7bfa70a..d571cd0ef 100644 --- a/compiler/template/starlark/convert.go +++ b/compiler/template/starlark/convert.go @@ -5,8 +5,9 @@ package starlark import ( "strings" - "github.com/go-vela/types/raw" "go.starlark.net/starlark" + + "github.com/go-vela/types/raw" ) // convertTemplateVars takes template variables and converts diff --git a/compiler/template/starlark/convert_test.go b/compiler/template/starlark/convert_test.go index 49101117e..3e868a4ba 100644 --- a/compiler/template/starlark/convert_test.go +++ b/compiler/template/starlark/convert_test.go @@ -6,8 +6,9 @@ import ( "reflect" "testing" - "github.com/go-vela/types/raw" "go.starlark.net/starlark" + + "github.com/go-vela/types/raw" ) func TestStarlark_Render_convertTemplateVars(t *testing.T) { diff --git a/compiler/template/starlark/render.go b/compiler/template/starlark/render.go index 4ff2c59ed..93b37cd78 100644 --- a/compiler/template/starlark/render.go +++ b/compiler/template/starlark/render.go @@ -7,12 +7,12 @@ import ( "errors" "fmt" - "github.com/go-vela/types/raw" + yaml "github.com/buildkite/yaml" + "go.starlark.net/starlark" "go.starlark.net/starlarkstruct" - yaml "github.com/buildkite/yaml" + "github.com/go-vela/types/raw" types "github.com/go-vela/types/yaml" - "go.starlark.net/starlark" ) var ( diff --git a/compiler/template/starlark/render_test.go b/compiler/template/starlark/render_test.go index d07a74a6f..a730f1088 100644 --- a/compiler/template/starlark/render_test.go +++ b/compiler/template/starlark/render_test.go @@ -7,9 +7,10 @@ import ( "testing" goyaml "github.com/buildkite/yaml" + "github.com/google/go-cmp/cmp" + "github.com/go-vela/types/raw" "github.com/go-vela/types/yaml" - "github.com/google/go-cmp/cmp" ) func TestStarlark_Render(t *testing.T) { diff --git a/database/build/build.go b/database/build/build.go index 8342471e7..1d1a42d97 100644 --- a/database/build/build.go +++ b/database/build/build.go @@ -6,10 +6,10 @@ import ( "context" "fmt" - "github.com/go-vela/types/constants" "github.com/sirupsen/logrus" - "gorm.io/gorm" + + "github.com/go-vela/types/constants" ) type ( diff --git a/database/build/build_test.go b/database/build/build_test.go index 419e9443c..5971b5d48 100644 --- a/database/build/build_test.go +++ b/database/build/build_test.go @@ -10,14 +10,14 @@ import ( "time" "github.com/DATA-DOG/go-sqlmock" - api "github.com/go-vela/server/api/types" - "github.com/go-vela/types/library" - "github.com/go-vela/types/raw" "github.com/sirupsen/logrus" - "gorm.io/driver/postgres" "gorm.io/driver/sqlite" "gorm.io/gorm" + + api "github.com/go-vela/server/api/types" + "github.com/go-vela/types/library" + "github.com/go-vela/types/raw" ) func TestBuild_New(t *testing.T) { diff --git a/database/build/clean.go b/database/build/clean.go index 8e8f17836..4559bac5f 100644 --- a/database/build/clean.go +++ b/database/build/clean.go @@ -6,10 +6,11 @@ import ( "context" "time" + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // CleanBuilds updates builds to an error with a provided message with a created timestamp prior to a defined moment. diff --git a/database/build/count_deployment.go b/database/build/count_deployment.go index da3b23927..08cf80951 100644 --- a/database/build/count_deployment.go +++ b/database/build/count_deployment.go @@ -5,9 +5,10 @@ package build import ( "context" + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // CountBuildsForDeployment gets the count of builds by deployment URL from the database. diff --git a/database/build/count_org.go b/database/build/count_org.go index 1d01a2cde..2f2a93119 100644 --- a/database/build/count_org.go +++ b/database/build/count_org.go @@ -5,8 +5,9 @@ package build import ( "context" - "github.com/go-vela/types/constants" "github.com/sirupsen/logrus" + + "github.com/go-vela/types/constants" ) // CountBuildsForOrg gets the count of builds by org name from the database. diff --git a/database/build/count_org_test.go b/database/build/count_org_test.go index 968b1d7c2..fb6461261 100644 --- a/database/build/count_org_test.go +++ b/database/build/count_org_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/repo" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" diff --git a/database/build/count_repo.go b/database/build/count_repo.go index 342e49491..cb12e4fdc 100644 --- a/database/build/count_repo.go +++ b/database/build/count_repo.go @@ -5,9 +5,10 @@ package build import ( "context" + "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/sirupsen/logrus" ) // CountBuildsForRepo gets the count of builds by repo ID from the database. diff --git a/database/build/create.go b/database/build/create.go index 02b09ab2d..1c04548b5 100644 --- a/database/build/create.go +++ b/database/build/create.go @@ -6,10 +6,11 @@ package build import ( "context" + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // CreateBuild creates a new build in the database. diff --git a/database/build/delete.go b/database/build/delete.go index 9d49f3c12..78bc11f71 100644 --- a/database/build/delete.go +++ b/database/build/delete.go @@ -5,10 +5,11 @@ package build import ( "context" + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // DeleteBuild deletes an existing build from the database. diff --git a/database/build/get_repo.go b/database/build/get_repo.go index 17dfdcb41..3b3ae9998 100644 --- a/database/build/get_repo.go +++ b/database/build/get_repo.go @@ -5,11 +5,12 @@ package build import ( "context" + "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // GetBuildForRepo gets a build by repo ID and number from the database. diff --git a/database/build/get_repo_test.go b/database/build/get_repo_test.go index ca714d017..906f35aee 100644 --- a/database/build/get_repo_test.go +++ b/database/build/get_repo_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/build/get_test.go b/database/build/get_test.go index d48efa243..4df407ef7 100644 --- a/database/build/get_test.go +++ b/database/build/get_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/build/last_repo.go b/database/build/last_repo.go index d92e3eea5..3900e62d0 100644 --- a/database/build/last_repo.go +++ b/database/build/last_repo.go @@ -6,13 +6,13 @@ import ( "context" "errors" + "github.com/sirupsen/logrus" + "gorm.io/gorm" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" - - "gorm.io/gorm" ) // LastBuildForRepo gets the last build by repo ID and branch from the database. diff --git a/database/build/last_repo_test.go b/database/build/last_repo_test.go index 5e3d9d216..5755d1318 100644 --- a/database/build/last_repo_test.go +++ b/database/build/last_repo_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/build/list_org.go b/database/build/list_org.go index 6fed59519..ef7ef140a 100644 --- a/database/build/list_org.go +++ b/database/build/list_org.go @@ -5,10 +5,11 @@ package build import ( "context" + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // ListBuildsForOrg gets a list of builds by org name from the database. diff --git a/database/build/list_org_test.go b/database/build/list_org_test.go index 6b8df4c19..925acbf96 100644 --- a/database/build/list_org_test.go +++ b/database/build/list_org_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/repo" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" diff --git a/database/build/list_pending_running_repo_test.go b/database/build/list_pending_running_repo_test.go index d6b2d5a4f..76a04b5de 100644 --- a/database/build/list_pending_running_repo_test.go +++ b/database/build/list_pending_running_repo_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/repo" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" diff --git a/database/build/list_pending_running_test.go b/database/build/list_pending_running_test.go index b7144a815..006c13184 100644 --- a/database/build/list_pending_running_test.go +++ b/database/build/list_pending_running_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/repo" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" diff --git a/database/build/list_repo.go b/database/build/list_repo.go index f8d7a0c00..87f8c3389 100644 --- a/database/build/list_repo.go +++ b/database/build/list_repo.go @@ -5,11 +5,12 @@ package build import ( "context" + "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // ListBuildsForRepo gets a list of builds by repo ID from the database. diff --git a/database/build/list_repo_test.go b/database/build/list_repo_test.go index 90b54988a..1f0e0fb9d 100644 --- a/database/build/list_repo_test.go +++ b/database/build/list_repo_test.go @@ -9,6 +9,7 @@ import ( "time" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/build/list_test.go b/database/build/list_test.go index 2579ac937..ec645ace1 100644 --- a/database/build/list_test.go +++ b/database/build/list_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/build/opts.go b/database/build/opts.go index 7792f9a12..b3a68e3c7 100644 --- a/database/build/opts.go +++ b/database/build/opts.go @@ -6,7 +6,6 @@ import ( "context" "github.com/sirupsen/logrus" - "gorm.io/gorm" ) diff --git a/database/build/opts_test.go b/database/build/opts_test.go index 43fea307f..949651dac 100644 --- a/database/build/opts_test.go +++ b/database/build/opts_test.go @@ -8,7 +8,6 @@ import ( "testing" "github.com/sirupsen/logrus" - "gorm.io/gorm" ) diff --git a/database/build/update.go b/database/build/update.go index ec647a879..ff5519fc9 100644 --- a/database/build/update.go +++ b/database/build/update.go @@ -6,10 +6,11 @@ package build import ( "context" + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // UpdateBuild updates an existing build in the database. diff --git a/database/close_test.go b/database/close_test.go index 7813513aa..f89d93451 100644 --- a/database/close_test.go +++ b/database/close_test.go @@ -6,7 +6,6 @@ import ( "testing" "github.com/sirupsen/logrus" - "gorm.io/gorm" ) diff --git a/database/database.go b/database/database.go index 3fc1adb94..8f873f776 100644 --- a/database/database.go +++ b/database/database.go @@ -7,6 +7,11 @@ import ( "fmt" "time" + "github.com/sirupsen/logrus" + "gorm.io/driver/postgres" + "gorm.io/driver/sqlite" + "gorm.io/gorm" + "github.com/go-vela/server/database/build" "github.com/go-vela/server/database/deployment" "github.com/go-vela/server/database/executable" @@ -21,11 +26,6 @@ import ( "github.com/go-vela/server/database/user" "github.com/go-vela/server/database/worker" "github.com/go-vela/types/constants" - "github.com/sirupsen/logrus" - - "gorm.io/driver/postgres" - "gorm.io/driver/sqlite" - "gorm.io/gorm" ) type ( diff --git a/database/database_test.go b/database/database_test.go index a2ea86848..26ea7e471 100644 --- a/database/database_test.go +++ b/database/database_test.go @@ -8,7 +8,6 @@ import ( "github.com/DATA-DOG/go-sqlmock" "github.com/sirupsen/logrus" - "gorm.io/driver/postgres" "gorm.io/driver/sqlite" "gorm.io/gorm" diff --git a/database/deployment/count_repo.go b/database/deployment/count_repo.go index c9eef1aad..6b70fff8f 100644 --- a/database/deployment/count_repo.go +++ b/database/deployment/count_repo.go @@ -5,9 +5,10 @@ package deployment import ( "context" + "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/sirupsen/logrus" ) // CountDeploymentsForRepo gets the count of deployments by repo ID from the database. diff --git a/database/deployment/count_repo_test.go b/database/deployment/count_repo_test.go index 586ca6ffb..d358aad3f 100644 --- a/database/deployment/count_repo_test.go +++ b/database/deployment/count_repo_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/deployment/count_test.go b/database/deployment/count_test.go index 5576be750..78a07afeb 100644 --- a/database/deployment/count_test.go +++ b/database/deployment/count_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" "github.com/go-vela/types/raw" ) diff --git a/database/deployment/create.go b/database/deployment/create.go index 467ca7cbd..6ce17e9a8 100644 --- a/database/deployment/create.go +++ b/database/deployment/create.go @@ -5,10 +5,11 @@ package deployment import ( "context" + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // CreateDeployment creates a new deployment in the database. diff --git a/database/deployment/create_test.go b/database/deployment/create_test.go index 5f584f3b7..f915eea0b 100644 --- a/database/deployment/create_test.go +++ b/database/deployment/create_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/deployment/delete.go b/database/deployment/delete.go index 73e2658b9..f50cb9033 100644 --- a/database/deployment/delete.go +++ b/database/deployment/delete.go @@ -4,10 +4,12 @@ package deployment import ( "context" + + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // DeleteDeployment deletes an existing deployment from the database. diff --git a/database/deployment/delete_test.go b/database/deployment/delete_test.go index 2fcd4c68f..5b984bbd7 100644 --- a/database/deployment/delete_test.go +++ b/database/deployment/delete_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/deployment/deployment.go b/database/deployment/deployment.go index 20df5e838..63f661452 100644 --- a/database/deployment/deployment.go +++ b/database/deployment/deployment.go @@ -6,10 +6,10 @@ import ( "context" "fmt" - "github.com/go-vela/types/constants" "github.com/sirupsen/logrus" - "gorm.io/gorm" + + "github.com/go-vela/types/constants" ) type ( diff --git a/database/deployment/deployment_test.go b/database/deployment/deployment_test.go index 60265211d..1aabcb6c3 100644 --- a/database/deployment/deployment_test.go +++ b/database/deployment/deployment_test.go @@ -7,14 +7,14 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" - api "github.com/go-vela/server/api/types" - "github.com/go-vela/types/library" - "github.com/go-vela/types/raw" "github.com/sirupsen/logrus" - "gorm.io/driver/postgres" "gorm.io/driver/sqlite" "gorm.io/gorm" + + api "github.com/go-vela/server/api/types" + "github.com/go-vela/types/library" + "github.com/go-vela/types/raw" ) func TestDeployment_New(t *testing.T) { diff --git a/database/deployment/get_repo.go b/database/deployment/get_repo.go index a359bbcb7..f000afcda 100644 --- a/database/deployment/get_repo.go +++ b/database/deployment/get_repo.go @@ -6,11 +6,12 @@ import ( "context" "strconv" + "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // GetDeploymentForRepo gets a deployment by repo ID and number from the database. diff --git a/database/deployment/get_repo_test.go b/database/deployment/get_repo_test.go index 289b3ad87..72f258182 100644 --- a/database/deployment/get_repo_test.go +++ b/database/deployment/get_repo_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/deployment/get_test.go b/database/deployment/get_test.go index b557e9330..0fdb289c9 100644 --- a/database/deployment/get_test.go +++ b/database/deployment/get_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/deployment/list_repo.go b/database/deployment/list_repo.go index 76c973e6d..71fe1ebe5 100644 --- a/database/deployment/list_repo.go +++ b/database/deployment/list_repo.go @@ -6,11 +6,12 @@ import ( "context" "strconv" + "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // ListDeploymentsForRepo gets a list of deployments by repo ID from the database. diff --git a/database/deployment/list_repo_test.go b/database/deployment/list_repo_test.go index a62948b17..377ee8af3 100644 --- a/database/deployment/list_repo_test.go +++ b/database/deployment/list_repo_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/deployment/list_test.go b/database/deployment/list_test.go index 203bebbe3..8b620eda4 100644 --- a/database/deployment/list_test.go +++ b/database/deployment/list_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/deployment/opts.go b/database/deployment/opts.go index db719b39d..95354e098 100644 --- a/database/deployment/opts.go +++ b/database/deployment/opts.go @@ -6,7 +6,6 @@ import ( "context" "github.com/sirupsen/logrus" - "gorm.io/gorm" ) diff --git a/database/deployment/opts_test.go b/database/deployment/opts_test.go index ad393db84..a2dd298b7 100644 --- a/database/deployment/opts_test.go +++ b/database/deployment/opts_test.go @@ -7,7 +7,6 @@ import ( "testing" "github.com/sirupsen/logrus" - "gorm.io/gorm" ) diff --git a/database/deployment/update.go b/database/deployment/update.go index b163516ff..191753cbf 100644 --- a/database/deployment/update.go +++ b/database/deployment/update.go @@ -4,10 +4,12 @@ package deployment import ( "context" + + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // UpdateDeployment updates an existing deployment in the database. diff --git a/database/deployment/update_test.go b/database/deployment/update_test.go index ca9b2548e..d8aaa574d 100644 --- a/database/deployment/update_test.go +++ b/database/deployment/update_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/executable/clean.go b/database/executable/clean.go index 34579f778..b6bd2580a 100644 --- a/database/executable/clean.go +++ b/database/executable/clean.go @@ -5,8 +5,9 @@ package executable import ( "context" - "github.com/go-vela/types/constants" "github.com/sirupsen/logrus" + + "github.com/go-vela/types/constants" ) const CleanExecutablesPostgres = ` diff --git a/database/executable/clean_test.go b/database/executable/clean_test.go index edcb0cf21..92c8be8e8 100644 --- a/database/executable/clean_test.go +++ b/database/executable/clean_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" diff --git a/database/executable/create.go b/database/executable/create.go index 1e240c495..b619da068 100644 --- a/database/executable/create.go +++ b/database/executable/create.go @@ -6,10 +6,11 @@ import ( "context" "fmt" + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // CreateBuildExecutable creates a new build executable in the database. diff --git a/database/executable/executable.go b/database/executable/executable.go index 6160cd39a..8ac0475ef 100644 --- a/database/executable/executable.go +++ b/database/executable/executable.go @@ -6,10 +6,10 @@ import ( "context" "fmt" - "github.com/go-vela/types/constants" "github.com/sirupsen/logrus" - "gorm.io/gorm" + + "github.com/go-vela/types/constants" ) type ( diff --git a/database/executable/executable_test.go b/database/executable/executable_test.go index 665ca6da5..2869001a8 100644 --- a/database/executable/executable_test.go +++ b/database/executable/executable_test.go @@ -8,13 +8,13 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" - "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" "github.com/sirupsen/logrus" - "gorm.io/driver/postgres" "gorm.io/driver/sqlite" "gorm.io/gorm" + + "github.com/go-vela/types/constants" + "github.com/go-vela/types/library" ) func TestExecutable_New(t *testing.T) { diff --git a/database/executable/opts.go b/database/executable/opts.go index 3f3bde340..c7beb136d 100644 --- a/database/executable/opts.go +++ b/database/executable/opts.go @@ -6,7 +6,6 @@ import ( "context" "github.com/sirupsen/logrus" - "gorm.io/gorm" ) diff --git a/database/executable/opts_test.go b/database/executable/opts_test.go index a2e1331bd..43626c093 100644 --- a/database/executable/opts_test.go +++ b/database/executable/opts_test.go @@ -8,7 +8,6 @@ import ( "testing" "github.com/sirupsen/logrus" - "gorm.io/gorm" ) diff --git a/database/executable/pop.go b/database/executable/pop.go index bd8e19ddb..2696e565e 100644 --- a/database/executable/pop.go +++ b/database/executable/pop.go @@ -5,10 +5,11 @@ package executable import ( "context" + "gorm.io/gorm/clause" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "gorm.io/gorm/clause" ) // PopBuildExecutable pops a build executable by build_id from the database. diff --git a/database/executable/pop_test.go b/database/executable/pop_test.go index 1f6954316..6826b2feb 100644 --- a/database/executable/pop_test.go +++ b/database/executable/pop_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/flags.go b/database/flags.go index 852387b39..8655c1808 100644 --- a/database/flags.go +++ b/database/flags.go @@ -5,8 +5,9 @@ package database import ( "time" - "github.com/go-vela/types/constants" "github.com/urfave/cli/v2" + + "github.com/go-vela/types/constants" ) // Flags represents all supported command line interface (CLI) flags for the database. diff --git a/database/hook/count_repo.go b/database/hook/count_repo.go index 28549dec9..62bee12a4 100644 --- a/database/hook/count_repo.go +++ b/database/hook/count_repo.go @@ -5,9 +5,10 @@ package hook import ( "context" + "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/sirupsen/logrus" ) // CountHooksForRepo gets the count of hooks by repo ID from the database. diff --git a/database/hook/create.go b/database/hook/create.go index 3ddbd4a9b..d71e89e51 100644 --- a/database/hook/create.go +++ b/database/hook/create.go @@ -5,10 +5,11 @@ package hook import ( "context" + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // CreateHook creates a new hook in the database. diff --git a/database/hook/delete.go b/database/hook/delete.go index 96b00b12c..dca1f900e 100644 --- a/database/hook/delete.go +++ b/database/hook/delete.go @@ -5,10 +5,11 @@ package hook import ( "context" + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // DeleteHook deletes an existing hook from the database. diff --git a/database/hook/get_repo.go b/database/hook/get_repo.go index af5d2b9bc..26fe2c0fb 100644 --- a/database/hook/get_repo.go +++ b/database/hook/get_repo.go @@ -5,11 +5,12 @@ package hook import ( "context" + "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // GetHookForRepo gets a hook by repo ID and number from the database. diff --git a/database/hook/get_repo_test.go b/database/hook/get_repo_test.go index f52eb1bd4..2ee8de362 100644 --- a/database/hook/get_repo_test.go +++ b/database/hook/get_repo_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/hook/get_test.go b/database/hook/get_test.go index e5183fd62..004baa3fe 100644 --- a/database/hook/get_test.go +++ b/database/hook/get_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/hook/get_webhook_test.go b/database/hook/get_webhook_test.go index 57ced48f5..57bd3628f 100644 --- a/database/hook/get_webhook_test.go +++ b/database/hook/get_webhook_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/hook/hook.go b/database/hook/hook.go index ff0358f23..22816ac83 100644 --- a/database/hook/hook.go +++ b/database/hook/hook.go @@ -6,10 +6,10 @@ import ( "context" "fmt" - "github.com/go-vela/types/constants" "github.com/sirupsen/logrus" - "gorm.io/gorm" + + "github.com/go-vela/types/constants" ) type ( diff --git a/database/hook/hook_test.go b/database/hook/hook_test.go index 50b689c00..cb66db823 100644 --- a/database/hook/hook_test.go +++ b/database/hook/hook_test.go @@ -7,13 +7,13 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" - api "github.com/go-vela/server/api/types" - "github.com/go-vela/types/library" "github.com/sirupsen/logrus" - "gorm.io/driver/postgres" "gorm.io/driver/sqlite" "gorm.io/gorm" + + api "github.com/go-vela/server/api/types" + "github.com/go-vela/types/library" ) func TestHook_New(t *testing.T) { diff --git a/database/hook/last_repo.go b/database/hook/last_repo.go index 76fb7cbf0..388e8e464 100644 --- a/database/hook/last_repo.go +++ b/database/hook/last_repo.go @@ -6,13 +6,13 @@ import ( "context" "errors" + "github.com/sirupsen/logrus" + "gorm.io/gorm" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" - - "gorm.io/gorm" ) // LastHookForRepo gets the last hook by repo ID from the database. diff --git a/database/hook/last_repo_test.go b/database/hook/last_repo_test.go index d7409cc8e..a9366d259 100644 --- a/database/hook/last_repo_test.go +++ b/database/hook/last_repo_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/hook/list_repo.go b/database/hook/list_repo.go index 3a2ec497f..b8afd447f 100644 --- a/database/hook/list_repo.go +++ b/database/hook/list_repo.go @@ -5,11 +5,12 @@ package hook import ( "context" + "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // ListHooksForRepo gets a list of hooks by repo ID from the database. diff --git a/database/hook/list_repo_test.go b/database/hook/list_repo_test.go index b2967a1f0..c9698c0eb 100644 --- a/database/hook/list_repo_test.go +++ b/database/hook/list_repo_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/hook/list_test.go b/database/hook/list_test.go index 299585167..79c788e0a 100644 --- a/database/hook/list_test.go +++ b/database/hook/list_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/hook/opts.go b/database/hook/opts.go index e91c5ec6b..36b88b499 100644 --- a/database/hook/opts.go +++ b/database/hook/opts.go @@ -6,7 +6,6 @@ import ( "context" "github.com/sirupsen/logrus" - "gorm.io/gorm" ) diff --git a/database/hook/opts_test.go b/database/hook/opts_test.go index cb3c37760..834717e40 100644 --- a/database/hook/opts_test.go +++ b/database/hook/opts_test.go @@ -8,7 +8,6 @@ import ( "testing" "github.com/sirupsen/logrus" - "gorm.io/gorm" ) diff --git a/database/hook/update.go b/database/hook/update.go index e990bbc9c..6c24bfd24 100644 --- a/database/hook/update.go +++ b/database/hook/update.go @@ -5,10 +5,11 @@ package hook import ( "context" + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // UpdateHook updates an existing hook in the database. diff --git a/database/integration_test.go b/database/integration_test.go index e1a0c1432..e7cf44571 100644 --- a/database/integration_test.go +++ b/database/integration_test.go @@ -10,6 +10,8 @@ import ( "testing" "time" + "github.com/google/go-cmp/cmp" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database/build" "github.com/go-vela/server/database/deployment" @@ -27,7 +29,6 @@ import ( "github.com/go-vela/types/constants" "github.com/go-vela/types/library" "github.com/go-vela/types/raw" - "github.com/google/go-cmp/cmp" ) // Resources represents the object containing test resources. diff --git a/database/log/create_test.go b/database/log/create_test.go index 80514837c..9f6852ab9 100644 --- a/database/log/create_test.go +++ b/database/log/create_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/log/get_service_test.go b/database/log/get_service_test.go index e6c9cde8c..6b7c89529 100644 --- a/database/log/get_service_test.go +++ b/database/log/get_service_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/log/get_step_test.go b/database/log/get_step_test.go index 5eea62f56..5606ef79b 100644 --- a/database/log/get_step_test.go +++ b/database/log/get_step_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/log/get_test.go b/database/log/get_test.go index db88112b0..33028ad7d 100644 --- a/database/log/get_test.go +++ b/database/log/get_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/log/list_build_test.go b/database/log/list_build_test.go index f18765ec3..04f4f6efc 100644 --- a/database/log/list_build_test.go +++ b/database/log/list_build_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/log/list_test.go b/database/log/list_test.go index 1bcf1759e..605ed26df 100644 --- a/database/log/list_test.go +++ b/database/log/list_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/log/log.go b/database/log/log.go index 0b8378d8f..a0fa23e5f 100644 --- a/database/log/log.go +++ b/database/log/log.go @@ -6,10 +6,10 @@ import ( "context" "fmt" - "github.com/go-vela/types/constants" "github.com/sirupsen/logrus" - "gorm.io/gorm" + + "github.com/go-vela/types/constants" ) type ( diff --git a/database/log/log_test.go b/database/log/log_test.go index f8b5bcadf..86862bbc2 100644 --- a/database/log/log_test.go +++ b/database/log/log_test.go @@ -8,12 +8,12 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" - "github.com/go-vela/types/library" "github.com/sirupsen/logrus" - "gorm.io/driver/postgres" "gorm.io/driver/sqlite" "gorm.io/gorm" + + "github.com/go-vela/types/library" ) func TestLog_New(t *testing.T) { diff --git a/database/log/opts.go b/database/log/opts.go index 03a913d2b..8ad73c6dd 100644 --- a/database/log/opts.go +++ b/database/log/opts.go @@ -6,7 +6,6 @@ import ( "context" "github.com/sirupsen/logrus" - "gorm.io/gorm" ) diff --git a/database/log/opts_test.go b/database/log/opts_test.go index d2a098e15..6e63d0736 100644 --- a/database/log/opts_test.go +++ b/database/log/opts_test.go @@ -8,7 +8,6 @@ import ( "testing" "github.com/sirupsen/logrus" - "gorm.io/gorm" ) diff --git a/database/log/update_test.go b/database/log/update_test.go index 3550e0c94..67f3313bc 100644 --- a/database/log/update_test.go +++ b/database/log/update_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/pipeline/count_repo.go b/database/pipeline/count_repo.go index 00cecda46..e2d5a2285 100644 --- a/database/pipeline/count_repo.go +++ b/database/pipeline/count_repo.go @@ -5,9 +5,10 @@ package pipeline import ( "context" + "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/sirupsen/logrus" ) // CountPipelinesForRepo gets the count of pipelines by repo ID from the database. diff --git a/database/pipeline/count_repo_test.go b/database/pipeline/count_repo_test.go index d4776cd77..729b25955 100644 --- a/database/pipeline/count_repo_test.go +++ b/database/pipeline/count_repo_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + api "github.com/go-vela/server/api/types" ) diff --git a/database/pipeline/create.go b/database/pipeline/create.go index d3ba17711..4ee770b52 100644 --- a/database/pipeline/create.go +++ b/database/pipeline/create.go @@ -5,10 +5,11 @@ package pipeline import ( "context" + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // CreatePipeline creates a new pipeline in the database. diff --git a/database/pipeline/delete.go b/database/pipeline/delete.go index 1f62c3048..bba60b2bd 100644 --- a/database/pipeline/delete.go +++ b/database/pipeline/delete.go @@ -5,10 +5,11 @@ package pipeline import ( "context" + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // DeletePipeline deletes an existing pipeline from the database. diff --git a/database/pipeline/get_repo.go b/database/pipeline/get_repo.go index b5581df56..428e1d84a 100644 --- a/database/pipeline/get_repo.go +++ b/database/pipeline/get_repo.go @@ -5,11 +5,12 @@ package pipeline import ( "context" + "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // GetPipelineForRepo gets a pipeline by number and repo ID from the database. diff --git a/database/pipeline/get_repo_test.go b/database/pipeline/get_repo_test.go index fd4a5dea8..69ffe7751 100644 --- a/database/pipeline/get_repo_test.go +++ b/database/pipeline/get_repo_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/library" ) diff --git a/database/pipeline/get_test.go b/database/pipeline/get_test.go index d90404c33..614b6a7c9 100644 --- a/database/pipeline/get_test.go +++ b/database/pipeline/get_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/pipeline/list_repo.go b/database/pipeline/list_repo.go index f4ccc6a3e..9893ee499 100644 --- a/database/pipeline/list_repo.go +++ b/database/pipeline/list_repo.go @@ -5,11 +5,12 @@ package pipeline import ( "context" + "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // ListPipelinesForRepo gets a list of pipelines by repo ID from the database. diff --git a/database/pipeline/list_repo_test.go b/database/pipeline/list_repo_test.go index 909605f19..7daa96547 100644 --- a/database/pipeline/list_repo_test.go +++ b/database/pipeline/list_repo_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/library" ) diff --git a/database/pipeline/list_test.go b/database/pipeline/list_test.go index 02779e483..f356afe82 100644 --- a/database/pipeline/list_test.go +++ b/database/pipeline/list_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/pipeline/opts.go b/database/pipeline/opts.go index a05c92633..609181652 100644 --- a/database/pipeline/opts.go +++ b/database/pipeline/opts.go @@ -6,7 +6,6 @@ import ( "context" "github.com/sirupsen/logrus" - "gorm.io/gorm" ) diff --git a/database/pipeline/opts_test.go b/database/pipeline/opts_test.go index 782c9af93..168bfef46 100644 --- a/database/pipeline/opts_test.go +++ b/database/pipeline/opts_test.go @@ -8,7 +8,6 @@ import ( "testing" "github.com/sirupsen/logrus" - "gorm.io/gorm" ) diff --git a/database/pipeline/pipeline.go b/database/pipeline/pipeline.go index c900123ae..0860a64f6 100644 --- a/database/pipeline/pipeline.go +++ b/database/pipeline/pipeline.go @@ -6,10 +6,10 @@ import ( "context" "fmt" - "github.com/go-vela/types/constants" "github.com/sirupsen/logrus" - "gorm.io/gorm" + + "github.com/go-vela/types/constants" ) type ( diff --git a/database/pipeline/pipeline_test.go b/database/pipeline/pipeline_test.go index 01582a62a..76abee9ed 100644 --- a/database/pipeline/pipeline_test.go +++ b/database/pipeline/pipeline_test.go @@ -9,12 +9,12 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" - "github.com/go-vela/types/library" "github.com/sirupsen/logrus" - "gorm.io/driver/postgres" "gorm.io/driver/sqlite" "gorm.io/gorm" + + "github.com/go-vela/types/library" ) func TestPipeline_New(t *testing.T) { diff --git a/database/pipeline/update.go b/database/pipeline/update.go index 5b12db3b1..37353d853 100644 --- a/database/pipeline/update.go +++ b/database/pipeline/update.go @@ -5,10 +5,11 @@ package pipeline import ( "context" + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // UpdatePipeline updates an existing pipeline in the database. diff --git a/database/repo/count_org.go b/database/repo/count_org.go index 145042b55..339dfd664 100644 --- a/database/repo/count_org.go +++ b/database/repo/count_org.go @@ -5,8 +5,9 @@ package repo import ( "context" - "github.com/go-vela/types/constants" "github.com/sirupsen/logrus" + + "github.com/go-vela/types/constants" ) // CountReposForOrg gets the count of repos by org name from the database. diff --git a/database/repo/count_user.go b/database/repo/count_user.go index 5cd71f2f0..20963a311 100644 --- a/database/repo/count_user.go +++ b/database/repo/count_user.go @@ -5,9 +5,10 @@ package repo import ( "context" + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // CountReposForUser gets the count of repos by user ID from the database. diff --git a/database/repo/count_user_test.go b/database/repo/count_user_test.go index f62b43ff6..0fff8c479 100644 --- a/database/repo/count_user_test.go +++ b/database/repo/count_user_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/repo/create.go b/database/repo/create.go index f716bf518..fcfd837c6 100644 --- a/database/repo/create.go +++ b/database/repo/create.go @@ -7,9 +7,10 @@ import ( "context" "fmt" + "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/sirupsen/logrus" ) // CreateRepo creates a new repo in the database. diff --git a/database/repo/delete.go b/database/repo/delete.go index c31dd43e3..357404048 100644 --- a/database/repo/delete.go +++ b/database/repo/delete.go @@ -5,9 +5,10 @@ package repo import ( "context" + "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/sirupsen/logrus" ) // DeleteRepo deletes an existing repo from the database. diff --git a/database/repo/get_org.go b/database/repo/get_org.go index 186624276..889b5b812 100644 --- a/database/repo/get_org.go +++ b/database/repo/get_org.go @@ -5,9 +5,10 @@ package repo import ( "context" + "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/sirupsen/logrus" ) // GetRepoForOrg gets a repo by org and repo name from the database. diff --git a/database/repo/get_org_test.go b/database/repo/get_org_test.go index 9df07c42d..327201876 100644 --- a/database/repo/get_org_test.go +++ b/database/repo/get_org_test.go @@ -7,10 +7,11 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/google/go-cmp/cmp" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" - "github.com/google/go-cmp/cmp" ) func TestRepo_Engine_GetRepoForOrg(t *testing.T) { diff --git a/database/repo/get_test.go b/database/repo/get_test.go index 281d079b5..600f2a830 100644 --- a/database/repo/get_test.go +++ b/database/repo/get_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" diff --git a/database/repo/list_org.go b/database/repo/list_org.go index 646f9b184..32529268e 100644 --- a/database/repo/list_org.go +++ b/database/repo/list_org.go @@ -5,9 +5,10 @@ package repo import ( "context" + "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/sirupsen/logrus" ) // ListReposForOrg gets a list of repos by org name from the database. diff --git a/database/repo/list_org_test.go b/database/repo/list_org_test.go index 8f790d72b..ca93ca17e 100644 --- a/database/repo/list_org_test.go +++ b/database/repo/list_org_test.go @@ -8,11 +8,12 @@ import ( "time" "github.com/DATA-DOG/go-sqlmock" + "github.com/google/go-cmp/cmp" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/google/go-cmp/cmp" ) func TestRepo_Engine_ListReposForOrg(t *testing.T) { diff --git a/database/repo/list_test.go b/database/repo/list_test.go index 8d3dd2c76..68d426897 100644 --- a/database/repo/list_test.go +++ b/database/repo/list_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" diff --git a/database/repo/list_user.go b/database/repo/list_user.go index 76c5d8d7d..75e1904c8 100644 --- a/database/repo/list_user.go +++ b/database/repo/list_user.go @@ -5,10 +5,11 @@ package repo import ( "context" + "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // ListReposForUser gets a list of repos by user ID from the database. diff --git a/database/repo/list_user_test.go b/database/repo/list_user_test.go index 4ac0112c0..49db2638e 100644 --- a/database/repo/list_user_test.go +++ b/database/repo/list_user_test.go @@ -9,6 +9,7 @@ import ( "time" "github.com/DATA-DOG/go-sqlmock" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" diff --git a/database/repo/opts.go b/database/repo/opts.go index f65dcc368..5dcf5be98 100644 --- a/database/repo/opts.go +++ b/database/repo/opts.go @@ -6,7 +6,6 @@ import ( "context" "github.com/sirupsen/logrus" - "gorm.io/gorm" ) diff --git a/database/repo/opts_test.go b/database/repo/opts_test.go index b9788a457..8641eaf57 100644 --- a/database/repo/opts_test.go +++ b/database/repo/opts_test.go @@ -8,7 +8,6 @@ import ( "testing" "github.com/sirupsen/logrus" - "gorm.io/gorm" ) diff --git a/database/repo/repo.go b/database/repo/repo.go index 40a755723..1e920f181 100644 --- a/database/repo/repo.go +++ b/database/repo/repo.go @@ -9,14 +9,14 @@ import ( "errors" "fmt" + "github.com/lib/pq" + "github.com/sirupsen/logrus" + "gorm.io/gorm" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/util" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" - "github.com/lib/pq" - "github.com/sirupsen/logrus" - - "gorm.io/gorm" ) var ( diff --git a/database/repo/repo_test.go b/database/repo/repo_test.go index 92d1228a4..5de5f9177 100644 --- a/database/repo/repo_test.go +++ b/database/repo/repo_test.go @@ -8,14 +8,14 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" - api "github.com/go-vela/server/api/types" - "github.com/go-vela/server/api/types/actions" - "github.com/go-vela/types/library" "github.com/sirupsen/logrus" - "gorm.io/driver/postgres" "gorm.io/driver/sqlite" "gorm.io/gorm" + + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/api/types/actions" + "github.com/go-vela/types/library" ) func TestRepo_New(t *testing.T) { diff --git a/database/repo/update.go b/database/repo/update.go index 14ff985f7..8bbcefbc9 100644 --- a/database/repo/update.go +++ b/database/repo/update.go @@ -7,9 +7,10 @@ import ( "context" "fmt" + "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/sirupsen/logrus" ) // UpdateRepo updates an existing repo in the database. diff --git a/database/repo/update_test.go b/database/repo/update_test.go index e36a44ad2..2d2a61f4a 100644 --- a/database/repo/update_test.go +++ b/database/repo/update_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" ) diff --git a/database/resource_test.go b/database/resource_test.go index 6f20fb4f5..5819739c4 100644 --- a/database/resource_test.go +++ b/database/resource_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/build" "github.com/go-vela/server/database/deployment" "github.com/go-vela/server/database/executable" diff --git a/database/schedule/count.go b/database/schedule/count.go index e86b99a41..b61b6d028 100644 --- a/database/schedule/count.go +++ b/database/schedule/count.go @@ -4,6 +4,7 @@ package schedule import ( "context" + "github.com/go-vela/types/constants" ) diff --git a/database/schedule/count_active.go b/database/schedule/count_active.go index cc78e37a6..6e46ee253 100644 --- a/database/schedule/count_active.go +++ b/database/schedule/count_active.go @@ -4,6 +4,7 @@ package schedule import ( "context" + "github.com/go-vela/types/constants" ) diff --git a/database/schedule/count_repo.go b/database/schedule/count_repo.go index e876dda57..80c1cd47a 100644 --- a/database/schedule/count_repo.go +++ b/database/schedule/count_repo.go @@ -5,9 +5,10 @@ package schedule import ( "context" + "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/sirupsen/logrus" ) // CountSchedulesForRepo gets the count of schedules by repo ID from the database. diff --git a/database/schedule/create.go b/database/schedule/create.go index 9bc2079eb..4822adca5 100644 --- a/database/schedule/create.go +++ b/database/schedule/create.go @@ -6,10 +6,11 @@ package schedule import ( "context" + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // CreateSchedule creates a new schedule in the database. diff --git a/database/schedule/delete.go b/database/schedule/delete.go index 66e489d25..0d3386da1 100644 --- a/database/schedule/delete.go +++ b/database/schedule/delete.go @@ -4,10 +4,12 @@ package schedule import ( "context" + + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // DeleteSchedule deletes an existing schedule from the database. diff --git a/database/schedule/get.go b/database/schedule/get.go index 9f352d72b..518bbd339 100644 --- a/database/schedule/get.go +++ b/database/schedule/get.go @@ -4,6 +4,7 @@ package schedule import ( "context" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" diff --git a/database/schedule/get_repo.go b/database/schedule/get_repo.go index 3d8efbf0d..6bc362e3d 100644 --- a/database/schedule/get_repo.go +++ b/database/schedule/get_repo.go @@ -5,11 +5,12 @@ package schedule import ( "context" + "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // GetScheduleForRepo gets a schedule by repo ID and name from the database. diff --git a/database/schedule/get_repo_test.go b/database/schedule/get_repo_test.go index 3745976b7..0d6a6184c 100644 --- a/database/schedule/get_repo_test.go +++ b/database/schedule/get_repo_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/schedule/get_test.go b/database/schedule/get_test.go index d229f8cf1..3c62b8908 100644 --- a/database/schedule/get_test.go +++ b/database/schedule/get_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/schedule/list.go b/database/schedule/list.go index 4904a1149..f3196651f 100644 --- a/database/schedule/list.go +++ b/database/schedule/list.go @@ -4,6 +4,7 @@ package schedule import ( "context" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" diff --git a/database/schedule/list_active.go b/database/schedule/list_active.go index 07616a7de..b91ad63e8 100644 --- a/database/schedule/list_active.go +++ b/database/schedule/list_active.go @@ -4,6 +4,7 @@ package schedule import ( "context" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" diff --git a/database/schedule/list_active_test.go b/database/schedule/list_active_test.go index 7c604f10f..8154780bd 100644 --- a/database/schedule/list_active_test.go +++ b/database/schedule/list_active_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/schedule/list_repo.go b/database/schedule/list_repo.go index 6c4435a03..9f3de5e5a 100644 --- a/database/schedule/list_repo.go +++ b/database/schedule/list_repo.go @@ -5,11 +5,12 @@ package schedule import ( "context" + "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // ListSchedulesForRepo gets a list of schedules by repo ID from the database. diff --git a/database/schedule/list_repo_test.go b/database/schedule/list_repo_test.go index 890f0f393..4753a2b34 100644 --- a/database/schedule/list_repo_test.go +++ b/database/schedule/list_repo_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/schedule/list_test.go b/database/schedule/list_test.go index 463a9dfd9..d8a5b2ae8 100644 --- a/database/schedule/list_test.go +++ b/database/schedule/list_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/schedule/opts.go b/database/schedule/opts.go index f5f596d26..7eb9c2adb 100644 --- a/database/schedule/opts.go +++ b/database/schedule/opts.go @@ -4,8 +4,8 @@ package schedule import ( "context" - "github.com/sirupsen/logrus" + "github.com/sirupsen/logrus" "gorm.io/gorm" ) diff --git a/database/schedule/opts_test.go b/database/schedule/opts_test.go index 93a2d3565..05e63ca54 100644 --- a/database/schedule/opts_test.go +++ b/database/schedule/opts_test.go @@ -7,7 +7,6 @@ import ( "testing" "github.com/sirupsen/logrus" - "gorm.io/gorm" ) diff --git a/database/schedule/schedule.go b/database/schedule/schedule.go index a55bd2eb9..b338d2f95 100644 --- a/database/schedule/schedule.go +++ b/database/schedule/schedule.go @@ -6,10 +6,10 @@ import ( "context" "fmt" - "github.com/go-vela/types/constants" "github.com/sirupsen/logrus" - "gorm.io/gorm" + + "github.com/go-vela/types/constants" ) type ( diff --git a/database/schedule/schedule_test.go b/database/schedule/schedule_test.go index 45663008b..5c227f4c2 100644 --- a/database/schedule/schedule_test.go +++ b/database/schedule/schedule_test.go @@ -10,13 +10,13 @@ import ( "time" "github.com/DATA-DOG/go-sqlmock" - api "github.com/go-vela/server/api/types" - "github.com/go-vela/types/library" "github.com/sirupsen/logrus" - "gorm.io/driver/postgres" "gorm.io/driver/sqlite" "gorm.io/gorm" + + api "github.com/go-vela/server/api/types" + "github.com/go-vela/types/library" ) func TestSchedule_New(t *testing.T) { diff --git a/database/schedule/update.go b/database/schedule/update.go index 87a0e5a9e..ca90e13b4 100644 --- a/database/schedule/update.go +++ b/database/schedule/update.go @@ -5,10 +5,11 @@ package schedule import ( "context" + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // UpdateSchedule updates an existing schedule in the database. diff --git a/database/secret/count_org.go b/database/secret/count_org.go index 79dec8c44..e6fdc7fcb 100644 --- a/database/secret/count_org.go +++ b/database/secret/count_org.go @@ -5,8 +5,9 @@ package secret import ( "context" - "github.com/go-vela/types/constants" "github.com/sirupsen/logrus" + + "github.com/go-vela/types/constants" ) // CountSecretsForOrg gets the count of secrets by org name from the database. diff --git a/database/secret/count_org_test.go b/database/secret/count_org_test.go index 500d29878..22f8543f8 100644 --- a/database/secret/count_org_test.go +++ b/database/secret/count_org_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/constants" ) diff --git a/database/secret/count_repo.go b/database/secret/count_repo.go index c248e5ee5..f734054a5 100644 --- a/database/secret/count_repo.go +++ b/database/secret/count_repo.go @@ -5,9 +5,10 @@ package secret import ( "context" + "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/sirupsen/logrus" ) // CountSecretsForRepo gets the count of secrets by org and repo name from the database. diff --git a/database/secret/count_repo_test.go b/database/secret/count_repo_test.go index fd5afacb4..c925853f8 100644 --- a/database/secret/count_repo_test.go +++ b/database/secret/count_repo_test.go @@ -7,9 +7,9 @@ import ( "reflect" "testing" - "github.com/go-vela/types/constants" - "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/types/constants" ) func TestSecret_Engine_CountSecretsForRepo(t *testing.T) { diff --git a/database/secret/count_team.go b/database/secret/count_team.go index 2dcce27ef..55445b504 100644 --- a/database/secret/count_team.go +++ b/database/secret/count_team.go @@ -6,8 +6,9 @@ import ( "context" "strings" - "github.com/go-vela/types/constants" "github.com/sirupsen/logrus" + + "github.com/go-vela/types/constants" ) // CountSecretsForTeam gets the count of secrets by org and team name from the database. diff --git a/database/secret/count_team_test.go b/database/secret/count_team_test.go index 07db848e9..071e7902f 100644 --- a/database/secret/count_team_test.go +++ b/database/secret/count_team_test.go @@ -7,9 +7,9 @@ import ( "reflect" "testing" - "github.com/go-vela/types/constants" - "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/types/constants" ) func TestSecret_Engine_CountSecretsForTeam(t *testing.T) { diff --git a/database/secret/create.go b/database/secret/create.go index 4c8853bd8..c8b0400d1 100644 --- a/database/secret/create.go +++ b/database/secret/create.go @@ -7,10 +7,11 @@ import ( "context" "fmt" + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // CreateSecret creates a new secret in the database. diff --git a/database/secret/create_test.go b/database/secret/create_test.go index 210a57b99..7ec36795b 100644 --- a/database/secret/create_test.go +++ b/database/secret/create_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/secret/delete.go b/database/secret/delete.go index b4068faec..5b3653ba1 100644 --- a/database/secret/delete.go +++ b/database/secret/delete.go @@ -5,10 +5,11 @@ package secret import ( "context" + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // DeleteSecret deletes an existing secret from the database. diff --git a/database/secret/delete_test.go b/database/secret/delete_test.go index 0c078c98f..57db11e88 100644 --- a/database/secret/delete_test.go +++ b/database/secret/delete_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/secret/get_org.go b/database/secret/get_org.go index 950368735..fec7ff1ef 100644 --- a/database/secret/get_org.go +++ b/database/secret/get_org.go @@ -5,10 +5,11 @@ package secret import ( "context" + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // GetSecretForOrg gets a secret by org name from the database. diff --git a/database/secret/get_org_test.go b/database/secret/get_org_test.go index 51ca298d2..af127fab3 100644 --- a/database/secret/get_org_test.go +++ b/database/secret/get_org_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/constants" "github.com/go-vela/types/library" ) diff --git a/database/secret/get_repo.go b/database/secret/get_repo.go index d1ae48e7f..6edacafd1 100644 --- a/database/secret/get_repo.go +++ b/database/secret/get_repo.go @@ -5,11 +5,12 @@ package secret import ( "context" + "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // GetSecretForRepo gets a secret by org and repo name from the database. diff --git a/database/secret/get_repo_test.go b/database/secret/get_repo_test.go index fb1c1ca9b..99ea7610d 100644 --- a/database/secret/get_repo_test.go +++ b/database/secret/get_repo_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/constants" "github.com/go-vela/types/library" ) diff --git a/database/secret/get_team.go b/database/secret/get_team.go index b11a9fd41..74e4a57f9 100644 --- a/database/secret/get_team.go +++ b/database/secret/get_team.go @@ -5,10 +5,11 @@ package secret import ( "context" + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // GetSecretForTeam gets a secret by org and team name from the database. diff --git a/database/secret/get_team_test.go b/database/secret/get_team_test.go index f34e6f2b6..96e3bf880 100644 --- a/database/secret/get_team_test.go +++ b/database/secret/get_team_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/constants" "github.com/go-vela/types/library" ) diff --git a/database/secret/get_test.go b/database/secret/get_test.go index 16e456c12..0d38aa679 100644 --- a/database/secret/get_test.go +++ b/database/secret/get_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/secret/list_org.go b/database/secret/list_org.go index bb57d4eb3..63cf5f899 100644 --- a/database/secret/list_org.go +++ b/database/secret/list_org.go @@ -5,10 +5,11 @@ package secret import ( "context" + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // ListSecretsForOrg gets a list of secrets by org name from the database. diff --git a/database/secret/list_org_test.go b/database/secret/list_org_test.go index 14493ef38..f3a95f0cd 100644 --- a/database/secret/list_org_test.go +++ b/database/secret/list_org_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/constants" "github.com/go-vela/types/library" ) diff --git a/database/secret/list_repo.go b/database/secret/list_repo.go index a2731e321..0be77454c 100644 --- a/database/secret/list_repo.go +++ b/database/secret/list_repo.go @@ -5,11 +5,12 @@ package secret import ( "context" + "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // ListSecretsForRepo gets a list of secrets by org name from the database. diff --git a/database/secret/list_repo_test.go b/database/secret/list_repo_test.go index 304520c3e..1b70c1bda 100644 --- a/database/secret/list_repo_test.go +++ b/database/secret/list_repo_test.go @@ -7,9 +7,9 @@ import ( "reflect" "testing" - "github.com/go-vela/types/constants" - "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/types/constants" "github.com/go-vela/types/library" ) diff --git a/database/secret/list_team.go b/database/secret/list_team.go index 1f5e317c5..f9a17c2fd 100644 --- a/database/secret/list_team.go +++ b/database/secret/list_team.go @@ -6,10 +6,11 @@ import ( "context" "strings" + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // ListSecretsForTeam gets a list of secrets by org and team name from the database. diff --git a/database/secret/list_team_test.go b/database/secret/list_team_test.go index 89b40b237..81708949a 100644 --- a/database/secret/list_team_test.go +++ b/database/secret/list_team_test.go @@ -7,9 +7,9 @@ import ( "reflect" "testing" - "github.com/go-vela/types/constants" - "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/types/constants" "github.com/go-vela/types/library" ) diff --git a/database/secret/list_test.go b/database/secret/list_test.go index c050d452d..aa72d5baf 100644 --- a/database/secret/list_test.go +++ b/database/secret/list_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/secret/opts.go b/database/secret/opts.go index cb1589d32..2a6216989 100644 --- a/database/secret/opts.go +++ b/database/secret/opts.go @@ -6,7 +6,6 @@ import ( "context" "github.com/sirupsen/logrus" - "gorm.io/gorm" ) diff --git a/database/secret/opts_test.go b/database/secret/opts_test.go index f446c09f2..7865daef9 100644 --- a/database/secret/opts_test.go +++ b/database/secret/opts_test.go @@ -8,7 +8,6 @@ import ( "testing" "github.com/sirupsen/logrus" - "gorm.io/gorm" ) diff --git a/database/secret/secret.go b/database/secret/secret.go index 7cf9981c8..55e20b59f 100644 --- a/database/secret/secret.go +++ b/database/secret/secret.go @@ -6,10 +6,10 @@ import ( "context" "fmt" - "github.com/go-vela/types/constants" "github.com/sirupsen/logrus" - "gorm.io/gorm" + + "github.com/go-vela/types/constants" ) type ( diff --git a/database/secret/secret_test.go b/database/secret/secret_test.go index cbbefd9e2..fdc10818c 100644 --- a/database/secret/secret_test.go +++ b/database/secret/secret_test.go @@ -9,14 +9,14 @@ import ( "time" "github.com/DATA-DOG/go-sqlmock" - api "github.com/go-vela/server/api/types" - "github.com/go-vela/types/library" - "github.com/go-vela/types/library/actions" "github.com/sirupsen/logrus" - "gorm.io/driver/postgres" "gorm.io/driver/sqlite" "gorm.io/gorm" + + api "github.com/go-vela/server/api/types" + "github.com/go-vela/types/library" + "github.com/go-vela/types/library/actions" ) func TestSecret_New(t *testing.T) { diff --git a/database/secret/update.go b/database/secret/update.go index 04fc98b84..641a8a3e3 100644 --- a/database/secret/update.go +++ b/database/secret/update.go @@ -7,10 +7,11 @@ import ( "context" "fmt" + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // UpdateSecret updates an existing secret in the database. diff --git a/database/secret/update_test.go b/database/secret/update_test.go index 0502de911..11b6245a1 100644 --- a/database/secret/update_test.go +++ b/database/secret/update_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/service/clean.go b/database/service/clean.go index e9e42de58..b4becb0ad 100644 --- a/database/service/clean.go +++ b/database/service/clean.go @@ -6,10 +6,11 @@ import ( "context" "time" + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // CleanServices updates services to an error with a created timestamp prior to a defined moment. diff --git a/database/service/count_build.go b/database/service/count_build.go index a70c326d2..f1d9f1e36 100644 --- a/database/service/count_build.go +++ b/database/service/count_build.go @@ -5,9 +5,10 @@ package service import ( "context" + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // CountServicesForBuild gets the count of services by build ID from the database. diff --git a/database/service/create.go b/database/service/create.go index dc5726dea..6d2ec8f74 100644 --- a/database/service/create.go +++ b/database/service/create.go @@ -5,10 +5,11 @@ package service import ( "context" + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // CreateService creates a new service in the database. diff --git a/database/service/delete.go b/database/service/delete.go index 90fc552f6..5762fbb8d 100644 --- a/database/service/delete.go +++ b/database/service/delete.go @@ -5,10 +5,11 @@ package service import ( "context" + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // DeleteService deletes an existing service from the database. diff --git a/database/service/get_build.go b/database/service/get_build.go index 8822743f8..cc4109762 100644 --- a/database/service/get_build.go +++ b/database/service/get_build.go @@ -5,10 +5,11 @@ package service import ( "context" + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // GetServiceForBuild gets a service by number and build ID from the database. diff --git a/database/service/get_build_test.go b/database/service/get_build_test.go index b8f859649..af26ee7d0 100644 --- a/database/service/get_build_test.go +++ b/database/service/get_build_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/service/get_test.go b/database/service/get_test.go index 8aa8961e5..edeb82b9e 100644 --- a/database/service/get_test.go +++ b/database/service/get_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/service/list_build.go b/database/service/list_build.go index b273835f8..020f53fa0 100644 --- a/database/service/list_build.go +++ b/database/service/list_build.go @@ -5,10 +5,11 @@ package service import ( "context" + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // ListServicesForBuild gets a list of all services from the database. diff --git a/database/service/list_build_test.go b/database/service/list_build_test.go index f33e98ac3..283f7fe5b 100644 --- a/database/service/list_build_test.go +++ b/database/service/list_build_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/service/list_test.go b/database/service/list_test.go index 24f718e94..6fcecdfd4 100644 --- a/database/service/list_test.go +++ b/database/service/list_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/service/opts.go b/database/service/opts.go index c06c6a931..6ed08ed22 100644 --- a/database/service/opts.go +++ b/database/service/opts.go @@ -6,7 +6,6 @@ import ( "context" "github.com/sirupsen/logrus" - "gorm.io/gorm" ) diff --git a/database/service/opts_test.go b/database/service/opts_test.go index 043d1e290..f34c53126 100644 --- a/database/service/opts_test.go +++ b/database/service/opts_test.go @@ -8,7 +8,6 @@ import ( "testing" "github.com/sirupsen/logrus" - "gorm.io/gorm" ) diff --git a/database/service/service.go b/database/service/service.go index 0f1b92b7d..f02f6ae6b 100644 --- a/database/service/service.go +++ b/database/service/service.go @@ -6,10 +6,10 @@ import ( "context" "fmt" - "github.com/go-vela/types/constants" "github.com/sirupsen/logrus" - "gorm.io/gorm" + + "github.com/go-vela/types/constants" ) type ( diff --git a/database/service/service_test.go b/database/service/service_test.go index e1f6f92f3..73a113568 100644 --- a/database/service/service_test.go +++ b/database/service/service_test.go @@ -9,12 +9,12 @@ import ( "time" "github.com/DATA-DOG/go-sqlmock" - "github.com/go-vela/types/library" "github.com/sirupsen/logrus" - "gorm.io/driver/postgres" "gorm.io/driver/sqlite" "gorm.io/gorm" + + "github.com/go-vela/types/library" ) func TestService_New(t *testing.T) { diff --git a/database/service/update.go b/database/service/update.go index 677a2c71c..da6417aab 100644 --- a/database/service/update.go +++ b/database/service/update.go @@ -5,10 +5,11 @@ package service import ( "context" + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // UpdateService updates an existing service in the database. diff --git a/database/step/clean.go b/database/step/clean.go index 0dc685709..3e75c906b 100644 --- a/database/step/clean.go +++ b/database/step/clean.go @@ -6,10 +6,11 @@ import ( "context" "time" + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // CleanSteps updates steps to an error with a created timestamp prior to a defined moment. diff --git a/database/step/count.go b/database/step/count.go index b47668bd0..12ef7afc4 100644 --- a/database/step/count.go +++ b/database/step/count.go @@ -4,6 +4,7 @@ package step import ( "context" + "github.com/go-vela/types/constants" ) diff --git a/database/step/count_build.go b/database/step/count_build.go index 8da485331..595811112 100644 --- a/database/step/count_build.go +++ b/database/step/count_build.go @@ -4,9 +4,11 @@ package step import ( "context" + + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // CountStepsForBuild gets the count of steps by build ID from the database. diff --git a/database/step/create.go b/database/step/create.go index a4ab98cfe..99c9987b4 100644 --- a/database/step/create.go +++ b/database/step/create.go @@ -4,10 +4,12 @@ package step import ( "context" + + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // CreateStep creates a new step in the database. diff --git a/database/step/delete.go b/database/step/delete.go index 5b185a447..98e895def 100644 --- a/database/step/delete.go +++ b/database/step/delete.go @@ -4,10 +4,12 @@ package step import ( "context" + + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // DeleteStep deletes an existing step from the database. diff --git a/database/step/get.go b/database/step/get.go index 8884fe51a..d75217f58 100644 --- a/database/step/get.go +++ b/database/step/get.go @@ -4,6 +4,7 @@ package step import ( "context" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" diff --git a/database/step/get_build.go b/database/step/get_build.go index 6be0d3cb1..99ed00026 100644 --- a/database/step/get_build.go +++ b/database/step/get_build.go @@ -4,10 +4,12 @@ package step import ( "context" + + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // GetStepForBuild gets a step by number and build ID from the database. diff --git a/database/step/get_build_test.go b/database/step/get_build_test.go index b372a0c50..1906dc3f1 100644 --- a/database/step/get_build_test.go +++ b/database/step/get_build_test.go @@ -7,8 +7,9 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" - "github.com/go-vela/types/library" "github.com/google/go-cmp/cmp" + + "github.com/go-vela/types/library" ) func TestStep_Engine_GetStepForBuild(t *testing.T) { diff --git a/database/step/get_test.go b/database/step/get_test.go index 7e17a744c..a9e5106a1 100644 --- a/database/step/get_test.go +++ b/database/step/get_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/step/interface.go b/database/step/interface.go index 70bbc1c72..3c41017a9 100644 --- a/database/step/interface.go +++ b/database/step/interface.go @@ -4,6 +4,7 @@ package step import ( "context" + "github.com/go-vela/types/library" ) diff --git a/database/step/list.go b/database/step/list.go index b4dd0a329..afbb9f818 100644 --- a/database/step/list.go +++ b/database/step/list.go @@ -4,6 +4,7 @@ package step import ( "context" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" diff --git a/database/step/list_build.go b/database/step/list_build.go index 0a446af27..dbf8a717a 100644 --- a/database/step/list_build.go +++ b/database/step/list_build.go @@ -4,10 +4,12 @@ package step import ( "context" + + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // ListStepsForBuild gets a list of all steps from the database. diff --git a/database/step/list_build_test.go b/database/step/list_build_test.go index dbee0b395..46fda88a4 100644 --- a/database/step/list_build_test.go +++ b/database/step/list_build_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/step/list_test.go b/database/step/list_test.go index 2f8323faf..bed53585c 100644 --- a/database/step/list_test.go +++ b/database/step/list_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/step/opts.go b/database/step/opts.go index 50fdc6eb6..520c60d8d 100644 --- a/database/step/opts.go +++ b/database/step/opts.go @@ -4,8 +4,8 @@ package step import ( "context" - "github.com/sirupsen/logrus" + "github.com/sirupsen/logrus" "gorm.io/gorm" ) diff --git a/database/step/opts_test.go b/database/step/opts_test.go index 6338b2f51..f3fcc3797 100644 --- a/database/step/opts_test.go +++ b/database/step/opts_test.go @@ -8,7 +8,6 @@ import ( "testing" "github.com/sirupsen/logrus" - "gorm.io/gorm" ) diff --git a/database/step/step.go b/database/step/step.go index 96e3989ab..edb3cb26e 100644 --- a/database/step/step.go +++ b/database/step/step.go @@ -6,10 +6,10 @@ import ( "context" "fmt" - "github.com/go-vela/types/constants" "github.com/sirupsen/logrus" - "gorm.io/gorm" + + "github.com/go-vela/types/constants" ) type ( diff --git a/database/step/step_test.go b/database/step/step_test.go index e3101147d..861937831 100644 --- a/database/step/step_test.go +++ b/database/step/step_test.go @@ -9,12 +9,12 @@ import ( "time" "github.com/DATA-DOG/go-sqlmock" - "github.com/go-vela/types/library" "github.com/sirupsen/logrus" - "gorm.io/driver/postgres" "gorm.io/driver/sqlite" "gorm.io/gorm" + + "github.com/go-vela/types/library" ) func TestStep_New(t *testing.T) { diff --git a/database/step/update.go b/database/step/update.go index 2417c87a0..57fee9e74 100644 --- a/database/step/update.go +++ b/database/step/update.go @@ -4,10 +4,12 @@ package step import ( "context" + + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // UpdateStep updates an existing step in the database. diff --git a/database/user/create.go b/database/user/create.go index 6010d1e8f..fdd289f34 100644 --- a/database/user/create.go +++ b/database/user/create.go @@ -7,10 +7,11 @@ import ( "context" "fmt" + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // CreateUser creates a new user in the database. diff --git a/database/user/delete.go b/database/user/delete.go index 5747bf404..ed3d9491e 100644 --- a/database/user/delete.go +++ b/database/user/delete.go @@ -5,10 +5,11 @@ package user import ( "context" + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // DeleteUser deletes an existing user from the database. diff --git a/database/user/get_name.go b/database/user/get_name.go index d23ce1611..6caf2d745 100644 --- a/database/user/get_name.go +++ b/database/user/get_name.go @@ -5,10 +5,11 @@ package user import ( "context" + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // GetUserForName gets a user by name from the database. diff --git a/database/user/get_name_test.go b/database/user/get_name_test.go index 621a75c87..3deed039e 100644 --- a/database/user/get_name_test.go +++ b/database/user/get_name_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/user/get_test.go b/database/user/get_test.go index f879b8bd9..c8f00fba5 100644 --- a/database/user/get_test.go +++ b/database/user/get_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/user/list_lite_test.go b/database/user/list_lite_test.go index 431b7705b..aeacb0676 100644 --- a/database/user/list_lite_test.go +++ b/database/user/list_lite_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/user/list_test.go b/database/user/list_test.go index da61b5b67..0472037ed 100644 --- a/database/user/list_test.go +++ b/database/user/list_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/types/library" ) diff --git a/database/user/opts.go b/database/user/opts.go index 4901e5be3..96bdf8b38 100644 --- a/database/user/opts.go +++ b/database/user/opts.go @@ -6,7 +6,6 @@ import ( "context" "github.com/sirupsen/logrus" - "gorm.io/gorm" ) diff --git a/database/user/opts_test.go b/database/user/opts_test.go index 77c74506c..05df3e33e 100644 --- a/database/user/opts_test.go +++ b/database/user/opts_test.go @@ -8,7 +8,6 @@ import ( "testing" "github.com/sirupsen/logrus" - "gorm.io/gorm" ) diff --git a/database/user/update.go b/database/user/update.go index 043ed71de..e321aba17 100644 --- a/database/user/update.go +++ b/database/user/update.go @@ -7,10 +7,11 @@ import ( "context" "fmt" + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // UpdateUser updates an existing user in the database. diff --git a/database/user/user.go b/database/user/user.go index 2cf13feb2..23948bfb3 100644 --- a/database/user/user.go +++ b/database/user/user.go @@ -6,10 +6,10 @@ import ( "context" "fmt" - "github.com/go-vela/types/constants" "github.com/sirupsen/logrus" - "gorm.io/gorm" + + "github.com/go-vela/types/constants" ) type ( diff --git a/database/user/user_test.go b/database/user/user_test.go index a3ab4ff11..267a961e3 100644 --- a/database/user/user_test.go +++ b/database/user/user_test.go @@ -8,12 +8,12 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" - "github.com/go-vela/types/library" "github.com/sirupsen/logrus" - "gorm.io/driver/postgres" "gorm.io/driver/sqlite" "gorm.io/gorm" + + "github.com/go-vela/types/library" ) func TestUser_New(t *testing.T) { diff --git a/database/validate.go b/database/validate.go index 4c519d081..8025b325e 100644 --- a/database/validate.go +++ b/database/validate.go @@ -6,8 +6,9 @@ import ( "fmt" "strings" - "github.com/go-vela/types/constants" "github.com/sirupsen/logrus" + + "github.com/go-vela/types/constants" ) // Validate verifies the required fields from the provided configuration are populated correctly. diff --git a/database/worker/create.go b/database/worker/create.go index 131bb393f..43232a71d 100644 --- a/database/worker/create.go +++ b/database/worker/create.go @@ -5,9 +5,10 @@ package worker import ( "context" + "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/sirupsen/logrus" ) // CreateWorker creates a new worker in the database. diff --git a/database/worker/delete.go b/database/worker/delete.go index ee391567e..a20e46487 100644 --- a/database/worker/delete.go +++ b/database/worker/delete.go @@ -5,9 +5,10 @@ package worker import ( "context" + "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/sirupsen/logrus" ) // DeleteWorker deletes an existing worker from the database. diff --git a/database/worker/get_hostname.go b/database/worker/get_hostname.go index f596850af..6f046f8dd 100644 --- a/database/worker/get_hostname.go +++ b/database/worker/get_hostname.go @@ -5,9 +5,10 @@ package worker import ( "context" + "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/sirupsen/logrus" ) // GetWorkerForHostname gets a worker by hostname from the database. diff --git a/database/worker/get_hostname_test.go b/database/worker/get_hostname_test.go index 7d5043340..a65854eba 100644 --- a/database/worker/get_hostname_test.go +++ b/database/worker/get_hostname_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + api "github.com/go-vela/server/api/types" ) diff --git a/database/worker/get_test.go b/database/worker/get_test.go index 566f8232b..33d9c37e7 100644 --- a/database/worker/get_test.go +++ b/database/worker/get_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + api "github.com/go-vela/server/api/types" ) diff --git a/database/worker/list_test.go b/database/worker/list_test.go index 4de8883a6..948230b3b 100644 --- a/database/worker/list_test.go +++ b/database/worker/list_test.go @@ -8,8 +8,9 @@ import ( "time" "github.com/DATA-DOG/go-sqlmock" - api "github.com/go-vela/server/api/types" "github.com/google/go-cmp/cmp" + + api "github.com/go-vela/server/api/types" ) func TestWorker_Engine_ListWorkers(t *testing.T) { diff --git a/database/worker/opts.go b/database/worker/opts.go index 71048282b..b2f3a570a 100644 --- a/database/worker/opts.go +++ b/database/worker/opts.go @@ -6,7 +6,6 @@ import ( "context" "github.com/sirupsen/logrus" - "gorm.io/gorm" ) diff --git a/database/worker/opts_test.go b/database/worker/opts_test.go index f627d25ed..2484f6455 100644 --- a/database/worker/opts_test.go +++ b/database/worker/opts_test.go @@ -8,7 +8,6 @@ import ( "testing" "github.com/sirupsen/logrus" - "gorm.io/gorm" ) diff --git a/database/worker/update.go b/database/worker/update.go index 0349ffe85..4626ce746 100644 --- a/database/worker/update.go +++ b/database/worker/update.go @@ -5,9 +5,10 @@ package worker import ( "context" + "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/sirupsen/logrus" ) // UpdateWorker updates an existing worker in the database. diff --git a/database/worker/worker.go b/database/worker/worker.go index d12055ded..f05c7198c 100644 --- a/database/worker/worker.go +++ b/database/worker/worker.go @@ -9,14 +9,14 @@ import ( "fmt" "strconv" + "github.com/lib/pq" + "github.com/sirupsen/logrus" + "gorm.io/gorm" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/util" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/lib/pq" - "github.com/sirupsen/logrus" - - "gorm.io/gorm" ) var ( diff --git a/database/worker/worker_test.go b/database/worker/worker_test.go index 8c6896eb7..9a4201218 100644 --- a/database/worker/worker_test.go +++ b/database/worker/worker_test.go @@ -7,13 +7,13 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" - api "github.com/go-vela/server/api/types" - "github.com/go-vela/types/library" "github.com/sirupsen/logrus" - "gorm.io/driver/postgres" "gorm.io/driver/sqlite" "gorm.io/gorm" + + api "github.com/go-vela/server/api/types" + "github.com/go-vela/types/library" ) func TestWorker_New(t *testing.T) { diff --git a/internal/token/compose.go b/internal/token/compose.go index df3d9c652..4dd63860a 100644 --- a/internal/token/compose.go +++ b/internal/token/compose.go @@ -7,6 +7,7 @@ import ( "net/url" "github.com/gin-gonic/gin" + "github.com/go-vela/server/internal" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" diff --git a/internal/token/compose_test.go b/internal/token/compose_test.go index 44e06f3b5..3026730a5 100644 --- a/internal/token/compose_test.go +++ b/internal/token/compose_test.go @@ -9,11 +9,11 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/golang-jwt/jwt/v5" + "github.com/go-vela/server/internal" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - - jwt "github.com/golang-jwt/jwt/v5" ) func TestToken_Compose(t *testing.T) { diff --git a/internal/token/mint.go b/internal/token/mint.go index 22c9599b9..dab99ae46 100644 --- a/internal/token/mint.go +++ b/internal/token/mint.go @@ -7,9 +7,10 @@ import ( "fmt" "time" + "github.com/golang-jwt/jwt/v5" + "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/golang-jwt/jwt/v5" ) // Claims struct is an extension of the JWT standard claims. It diff --git a/internal/token/parse_test.go b/internal/token/parse_test.go index c1e5d3ac0..777a5fa01 100644 --- a/internal/token/parse_test.go +++ b/internal/token/parse_test.go @@ -8,10 +8,10 @@ import ( "time" "github.com/gin-gonic/gin" + jwt "github.com/golang-jwt/jwt/v5" + "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - - jwt "github.com/golang-jwt/jwt/v5" ) func TestTokenManager_ParseToken(t *testing.T) { diff --git a/internal/token/refresh.go b/internal/token/refresh.go index 678c5ccb0..257391230 100644 --- a/internal/token/refresh.go +++ b/internal/token/refresh.go @@ -6,6 +6,7 @@ import ( "fmt" "github.com/gin-gonic/gin" + "github.com/go-vela/server/database" "github.com/go-vela/types/constants" ) diff --git a/internal/token/refresh_test.go b/internal/token/refresh_test.go index 6618b88c9..bfc132c15 100644 --- a/internal/token/refresh_test.go +++ b/internal/token/refresh_test.go @@ -10,10 +10,11 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/golang-jwt/jwt/v5" + "github.com/go-vela/server/database" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/golang-jwt/jwt/v5" ) func TestTokenManager_Refresh(t *testing.T) { diff --git a/mock/server/authentication.go b/mock/server/authentication.go index 5c99ee8c9..094915768 100644 --- a/mock/server/authentication.go +++ b/mock/server/authentication.go @@ -7,6 +7,7 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/go-vela/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" diff --git a/mock/server/build.go b/mock/server/build.go index 4b5d8c1d4..1d15a5c10 100644 --- a/mock/server/build.go +++ b/mock/server/build.go @@ -9,6 +9,7 @@ import ( "strings" "github.com/gin-gonic/gin" + "github.com/go-vela/types" "github.com/go-vela/types/library" ) diff --git a/mock/server/deployment.go b/mock/server/deployment.go index 758d6d208..e68e24d07 100644 --- a/mock/server/deployment.go +++ b/mock/server/deployment.go @@ -9,6 +9,7 @@ import ( "strings" "github.com/gin-gonic/gin" + "github.com/go-vela/types" "github.com/go-vela/types/library" ) diff --git a/mock/server/hook.go b/mock/server/hook.go index b31967211..58078da99 100644 --- a/mock/server/hook.go +++ b/mock/server/hook.go @@ -10,6 +10,7 @@ import ( "strings" "github.com/gin-gonic/gin" + "github.com/go-vela/types" "github.com/go-vela/types/library" ) diff --git a/mock/server/log.go b/mock/server/log.go index fffefaedf..98b359b57 100644 --- a/mock/server/log.go +++ b/mock/server/log.go @@ -9,6 +9,7 @@ import ( "strings" "github.com/gin-gonic/gin" + "github.com/go-vela/types" "github.com/go-vela/types/library" ) diff --git a/mock/server/pipeline.go b/mock/server/pipeline.go index 73ee1b42f..0d90cf45d 100644 --- a/mock/server/pipeline.go +++ b/mock/server/pipeline.go @@ -8,13 +8,12 @@ import ( "net/http" "strings" - "github.com/go-vela/types/library" - + yml "github.com/buildkite/yaml" "github.com/gin-gonic/gin" + "github.com/go-vela/types" + "github.com/go-vela/types/library" "github.com/go-vela/types/yaml" - - yml "github.com/buildkite/yaml" ) const ( diff --git a/mock/server/repo.go b/mock/server/repo.go index 79b82b7df..aba7cbaf9 100644 --- a/mock/server/repo.go +++ b/mock/server/repo.go @@ -9,6 +9,7 @@ import ( "strings" "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types" ) diff --git a/mock/server/schedule.go b/mock/server/schedule.go index 0bc2fd017..417890cd7 100644 --- a/mock/server/schedule.go +++ b/mock/server/schedule.go @@ -9,6 +9,7 @@ import ( "strings" "github.com/gin-gonic/gin" + "github.com/go-vela/types" "github.com/go-vela/types/library" ) diff --git a/mock/server/scm.go b/mock/server/scm.go index 0dea97c37..e191da268 100644 --- a/mock/server/scm.go +++ b/mock/server/scm.go @@ -8,6 +8,7 @@ import ( "strings" "github.com/gin-gonic/gin" + "github.com/go-vela/types" ) diff --git a/mock/server/secret.go b/mock/server/secret.go index 5030ce3cd..6cd45047f 100644 --- a/mock/server/secret.go +++ b/mock/server/secret.go @@ -10,6 +10,7 @@ import ( "strings" "github.com/gin-gonic/gin" + "github.com/go-vela/types" "github.com/go-vela/types/library" ) diff --git a/mock/server/service.go b/mock/server/service.go index a4111611a..c42e97dd6 100644 --- a/mock/server/service.go +++ b/mock/server/service.go @@ -10,6 +10,7 @@ import ( "strings" "github.com/gin-gonic/gin" + "github.com/go-vela/types" "github.com/go-vela/types/library" ) diff --git a/mock/server/step.go b/mock/server/step.go index 75fcdacf4..ff4c32ce8 100644 --- a/mock/server/step.go +++ b/mock/server/step.go @@ -10,6 +10,7 @@ import ( "strings" "github.com/gin-gonic/gin" + "github.com/go-vela/types" "github.com/go-vela/types/library" ) diff --git a/mock/server/user.go b/mock/server/user.go index 1ec672b47..ea2a5fc78 100644 --- a/mock/server/user.go +++ b/mock/server/user.go @@ -10,6 +10,7 @@ import ( "strings" "github.com/gin-gonic/gin" + "github.com/go-vela/types" "github.com/go-vela/types/library" ) diff --git a/mock/server/worker.go b/mock/server/worker.go index edc758460..6e5e6ac5e 100644 --- a/mock/server/worker.go +++ b/mock/server/worker.go @@ -9,6 +9,7 @@ import ( "strings" "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types" "github.com/go-vela/types/library" diff --git a/queue/flags.go b/queue/flags.go index 6fc3a6f19..35e5745f5 100644 --- a/queue/flags.go +++ b/queue/flags.go @@ -5,8 +5,9 @@ package queue import ( "time" - "github.com/go-vela/types/constants" "github.com/urfave/cli/v2" + + "github.com/go-vela/types/constants" ) // Flags represents all supported command line diff --git a/queue/queue.go b/queue/queue.go index 8288375e1..fe2946f1b 100644 --- a/queue/queue.go +++ b/queue/queue.go @@ -5,8 +5,9 @@ package queue import ( "fmt" - "github.com/go-vela/types/constants" "github.com/sirupsen/logrus" + + "github.com/go-vela/types/constants" ) // New creates and returns a Vela service capable of diff --git a/queue/redis/driver_test.go b/queue/redis/driver_test.go index e9736d326..8ed67a3a5 100644 --- a/queue/redis/driver_test.go +++ b/queue/redis/driver_test.go @@ -9,6 +9,7 @@ import ( "time" "github.com/alicebob/miniredis/v2" + "github.com/go-vela/types/constants" ) diff --git a/queue/redis/length_test.go b/queue/redis/length_test.go index 3f27ce60f..cf02377aa 100644 --- a/queue/redis/length_test.go +++ b/queue/redis/length_test.go @@ -7,8 +7,9 @@ import ( "reflect" "testing" - "github.com/go-vela/server/queue/models" "gopkg.in/square/go-jose.v2/json" + + "github.com/go-vela/server/queue/models" ) func TestRedis_Length(t *testing.T) { diff --git a/queue/redis/ping_test.go b/queue/redis/ping_test.go index 29f84ee26..d069370f2 100644 --- a/queue/redis/ping_test.go +++ b/queue/redis/ping_test.go @@ -5,9 +5,10 @@ package redis import ( "context" "fmt" - "github.com/alicebob/miniredis/v2" "testing" "time" + + "github.com/alicebob/miniredis/v2" ) func TestRedis_Ping_Good(t *testing.T) { diff --git a/queue/redis/pop.go b/queue/redis/pop.go index bd5872c9a..4d1af3921 100644 --- a/queue/redis/pop.go +++ b/queue/redis/pop.go @@ -7,9 +7,10 @@ import ( "encoding/json" "errors" - "github.com/go-vela/server/queue/models" "github.com/redis/go-redis/v9" "golang.org/x/crypto/nacl/sign" + + "github.com/go-vela/server/queue/models" ) // Pop grabs an item from the specified channel off the queue. diff --git a/queue/redis/pop_test.go b/queue/redis/pop_test.go index e95f828ab..a5ae4fd0b 100644 --- a/queue/redis/pop_test.go +++ b/queue/redis/pop_test.go @@ -7,10 +7,11 @@ import ( "testing" "time" - "github.com/go-vela/server/queue/models" "github.com/google/go-cmp/cmp" "golang.org/x/crypto/nacl/sign" "gopkg.in/square/go-jose.v2/json" + + "github.com/go-vela/server/queue/models" ) func TestRedis_Pop(t *testing.T) { diff --git a/queue/redis/redis.go b/queue/redis/redis.go index 643cb51e2..5a789ed58 100644 --- a/queue/redis/redis.go +++ b/queue/redis/redis.go @@ -6,7 +6,6 @@ import ( "context" "fmt" "strings" - "time" "github.com/alicebob/miniredis/v2" diff --git a/queue/redis/redis_test.go b/queue/redis/redis_test.go index ee4a35a9b..cecfe08cf 100644 --- a/queue/redis/redis_test.go +++ b/queue/redis/redis_test.go @@ -8,6 +8,7 @@ import ( "time" "github.com/alicebob/miniredis/v2" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/library" ) diff --git a/queue/setup.go b/queue/setup.go index f240c9fe6..cdac822ea 100644 --- a/queue/setup.go +++ b/queue/setup.go @@ -7,9 +7,10 @@ import ( "strings" "time" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/queue/redis" "github.com/go-vela/types/constants" - "github.com/sirupsen/logrus" ) // Setup represents the configuration necessary for diff --git a/router/admin.go b/router/admin.go index cc321346e..c279445eb 100644 --- a/router/admin.go +++ b/router/admin.go @@ -4,6 +4,7 @@ package router import ( "github.com/gin-gonic/gin" + "github.com/go-vela/server/api/admin" "github.com/go-vela/server/router/middleware/perm" ) diff --git a/router/build.go b/router/build.go index 2464dba84..44091b1f0 100644 --- a/router/build.go +++ b/router/build.go @@ -4,6 +4,7 @@ package router import ( "github.com/gin-gonic/gin" + "github.com/go-vela/server/api/build" "github.com/go-vela/server/api/log" "github.com/go-vela/server/router/middleware" diff --git a/router/deployment.go b/router/deployment.go index 4269da663..0f7640561 100644 --- a/router/deployment.go +++ b/router/deployment.go @@ -4,9 +4,9 @@ package router import ( "github.com/gin-gonic/gin" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/api/deployment" + "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/perm" "github.com/go-vela/server/router/middleware/repo" ) diff --git a/router/hook.go b/router/hook.go index 503ad77c1..69816fa4c 100644 --- a/router/hook.go +++ b/router/hook.go @@ -4,6 +4,7 @@ package router import ( "github.com/gin-gonic/gin" + "github.com/go-vela/server/api/hook" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/perm" diff --git a/router/log.go b/router/log.go index 6fbea4888..9806aca82 100644 --- a/router/log.go +++ b/router/log.go @@ -4,6 +4,7 @@ package router import ( "github.com/gin-gonic/gin" + "github.com/go-vela/server/api/log" "github.com/go-vela/server/router/middleware/perm" ) diff --git a/router/middleware/auth/auth.go b/router/middleware/auth/auth.go index 09e9319c2..53ed6a8eb 100644 --- a/router/middleware/auth/auth.go +++ b/router/middleware/auth/auth.go @@ -6,9 +6,9 @@ import ( "fmt" "net/http" - "github.com/go-vela/types/constants" - "github.com/golang-jwt/jwt/v5/request" + + "github.com/go-vela/types/constants" ) // RetrieveAccessToken gets the passed in access token from the header in the request. diff --git a/router/middleware/build/build.go b/router/middleware/build/build.go index 70eba1b9a..3c574e3e0 100644 --- a/router/middleware/build/build.go +++ b/router/middleware/build/build.go @@ -8,13 +8,14 @@ import ( "strconv" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // Retrieve gets the build in the given context. diff --git a/router/middleware/build/build_test.go b/router/middleware/build/build_test.go index b3be6b0c3..624e01497 100644 --- a/router/middleware/build/build_test.go +++ b/router/middleware/build/build_test.go @@ -10,6 +10,7 @@ import ( "testing" "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/org" diff --git a/router/middleware/build/context_test.go b/router/middleware/build/context_test.go index 43dd8fe5f..66fd2d88b 100644 --- a/router/middleware/build/context_test.go +++ b/router/middleware/build/context_test.go @@ -5,9 +5,9 @@ package build import ( "testing" - "github.com/go-vela/types/library" - "github.com/gin-gonic/gin" + + "github.com/go-vela/types/library" ) func TestBuild_FromContext(t *testing.T) { diff --git a/router/middleware/claims/claims.go b/router/middleware/claims/claims.go index a81a456fe..75a30caa0 100644 --- a/router/middleware/claims/claims.go +++ b/router/middleware/claims/claims.go @@ -6,12 +6,12 @@ import ( "net/http" "strings" + "github.com/gin-gonic/gin" + "github.com/go-vela/server/internal/token" "github.com/go-vela/server/router/middleware/auth" "github.com/go-vela/server/util" "github.com/go-vela/types/constants" - - "github.com/gin-gonic/gin" ) // Retrieve gets the claims in the given context. diff --git a/router/middleware/claims/claims_test.go b/router/middleware/claims/claims_test.go index 2eb89b3bd..ac1cd4554 100644 --- a/router/middleware/claims/claims_test.go +++ b/router/middleware/claims/claims_test.go @@ -13,11 +13,12 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/golang-jwt/jwt/v5" + "github.com/go-vela/server/database" "github.com/go-vela/server/internal/token" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/golang-jwt/jwt/v5" ) func TestClaims_Retrieve(t *testing.T) { diff --git a/router/middleware/claims/context_test.go b/router/middleware/claims/context_test.go index 55bbf9241..b4f91baac 100644 --- a/router/middleware/claims/context_test.go +++ b/router/middleware/claims/context_test.go @@ -6,11 +6,11 @@ import ( "testing" "time" - "github.com/go-vela/server/internal/token" - "github.com/go-vela/types/constants" + "github.com/gin-gonic/gin" "github.com/golang-jwt/jwt/v5" - "github.com/gin-gonic/gin" + "github.com/go-vela/server/internal/token" + "github.com/go-vela/types/constants" ) func TestClaims_FromContext(t *testing.T) { diff --git a/router/middleware/compiler.go b/router/middleware/compiler.go index 503040192..be25a9992 100644 --- a/router/middleware/compiler.go +++ b/router/middleware/compiler.go @@ -4,6 +4,7 @@ package middleware import ( "github.com/gin-gonic/gin" + "github.com/go-vela/server/compiler" ) diff --git a/router/middleware/compiler_test.go b/router/middleware/compiler_test.go index 8a64f5176..517de8881 100644 --- a/router/middleware/compiler_test.go +++ b/router/middleware/compiler_test.go @@ -9,12 +9,11 @@ import ( "reflect" "testing" - "github.com/go-vela/server/compiler" - "github.com/go-vela/server/compiler/native" - "github.com/gin-gonic/gin" - "github.com/urfave/cli/v2" + + "github.com/go-vela/server/compiler" + "github.com/go-vela/server/compiler/native" ) func TestMiddleware_CompilerNative(t *testing.T) { diff --git a/router/middleware/database.go b/router/middleware/database.go index 38755fa89..e5ce7ec98 100644 --- a/router/middleware/database.go +++ b/router/middleware/database.go @@ -4,6 +4,7 @@ package middleware import ( "github.com/gin-gonic/gin" + "github.com/go-vela/server/database" ) diff --git a/router/middleware/database_test.go b/router/middleware/database_test.go index 8b7cca49c..96a52c449 100644 --- a/router/middleware/database_test.go +++ b/router/middleware/database_test.go @@ -9,6 +9,7 @@ import ( "testing" "github.com/gin-gonic/gin" + "github.com/go-vela/server/database" ) diff --git a/router/middleware/default_repo_settings_test.go b/router/middleware/default_repo_settings_test.go index 1e5a1b744..75cc7a02a 100644 --- a/router/middleware/default_repo_settings_test.go +++ b/router/middleware/default_repo_settings_test.go @@ -8,9 +8,9 @@ import ( "reflect" "testing" - "github.com/go-vela/types/constants" - "github.com/gin-gonic/gin" + + "github.com/go-vela/types/constants" ) func TestMiddleware_DefaultRepoEvents(t *testing.T) { diff --git a/router/middleware/executors/context_test.go b/router/middleware/executors/context_test.go index f7e080d61..b84b2598b 100644 --- a/router/middleware/executors/context_test.go +++ b/router/middleware/executors/context_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" ) diff --git a/router/middleware/executors/executor_test.go b/router/middleware/executors/executor_test.go index 423336a10..8ce9dc58a 100644 --- a/router/middleware/executors/executor_test.go +++ b/router/middleware/executors/executor_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" ) diff --git a/router/middleware/executors/executors.go b/router/middleware/executors/executors.go index 8ea9de2c1..21616d64a 100644 --- a/router/middleware/executors/executors.go +++ b/router/middleware/executors/executors.go @@ -12,6 +12,7 @@ import ( "time" "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/internal/token" diff --git a/router/middleware/header.go b/router/middleware/header.go index 980243f16..c65a003af 100644 --- a/router/middleware/header.go +++ b/router/middleware/header.go @@ -7,6 +7,7 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/go-vela/server/internal" "github.com/go-vela/server/version" ) diff --git a/router/middleware/header_test.go b/router/middleware/header_test.go index dfa18e063..bd6d41fc5 100644 --- a/router/middleware/header_test.go +++ b/router/middleware/header_test.go @@ -11,6 +11,7 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/go-vela/server/internal" ) diff --git a/router/middleware/logger.go b/router/middleware/logger.go index 4f85a397e..f7205ebe2 100644 --- a/router/middleware/logger.go +++ b/router/middleware/logger.go @@ -6,6 +6,8 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" @@ -15,7 +17,6 @@ import ( "github.com/go-vela/server/router/middleware/worker" "github.com/go-vela/server/util" "github.com/go-vela/types/constants" - "github.com/sirupsen/logrus" ) // This file, in part, reproduces portions of diff --git a/router/middleware/logger_test.go b/router/middleware/logger_test.go index 18677ae7c..46993f221 100644 --- a/router/middleware/logger_test.go +++ b/router/middleware/logger_test.go @@ -14,6 +14,9 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/sirupsen/logrus/hooks/test" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/repo" @@ -22,8 +25,6 @@ import ( "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/router/middleware/worker" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" - "github.com/sirupsen/logrus/hooks/test" ) func TestMiddleware_Logger(t *testing.T) { diff --git a/router/middleware/metadata.go b/router/middleware/metadata.go index 672491d1d..d1d6122a2 100644 --- a/router/middleware/metadata.go +++ b/router/middleware/metadata.go @@ -4,6 +4,7 @@ package middleware import ( "github.com/gin-gonic/gin" + "github.com/go-vela/server/internal" ) diff --git a/router/middleware/metadata_test.go b/router/middleware/metadata_test.go index 8e955805b..6e3161c96 100644 --- a/router/middleware/metadata_test.go +++ b/router/middleware/metadata_test.go @@ -9,6 +9,7 @@ import ( "testing" "github.com/gin-gonic/gin" + "github.com/go-vela/server/internal" ) diff --git a/router/middleware/org/org.go b/router/middleware/org/org.go index b53c223d8..70efcdfc9 100644 --- a/router/middleware/org/org.go +++ b/router/middleware/org/org.go @@ -7,6 +7,7 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/go-vela/server/util" ) diff --git a/router/middleware/org/org_test.go b/router/middleware/org/org_test.go index a54d9ad33..f540a8623 100644 --- a/router/middleware/org/org_test.go +++ b/router/middleware/org/org_test.go @@ -10,6 +10,7 @@ import ( "testing" "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" ) diff --git a/router/middleware/perm/perm.go b/router/middleware/perm/perm.go index 3cac40571..f32d34dea 100644 --- a/router/middleware/perm/perm.go +++ b/router/middleware/perm/perm.go @@ -8,6 +8,8 @@ import ( "strings" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/claims" "github.com/go-vela/server/router/middleware/org" @@ -16,7 +18,6 @@ import ( "github.com/go-vela/server/scm" "github.com/go-vela/server/util" "github.com/go-vela/types/constants" - "github.com/sirupsen/logrus" ) // MustPlatformAdmin ensures the user has admin access to the platform. diff --git a/router/middleware/perm/perm_test.go b/router/middleware/perm/perm_test.go index 0628457e1..adf53ffe2 100644 --- a/router/middleware/perm/perm_test.go +++ b/router/middleware/perm/perm_test.go @@ -11,6 +11,8 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/golang-jwt/jwt/v5" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/internal/token" @@ -23,7 +25,6 @@ import ( "github.com/go-vela/server/scm/github" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/golang-jwt/jwt/v5" ) func TestPerm_MustPlatformAdmin(t *testing.T) { diff --git a/router/middleware/pipeline/context_test.go b/router/middleware/pipeline/context_test.go index d9379d943..4ec7c6607 100644 --- a/router/middleware/pipeline/context_test.go +++ b/router/middleware/pipeline/context_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/gin-gonic/gin" + "github.com/go-vela/types/library" ) diff --git a/router/middleware/pipeline/pipeline.go b/router/middleware/pipeline/pipeline.go index b8f3b819a..c8d8fc4dc 100644 --- a/router/middleware/pipeline/pipeline.go +++ b/router/middleware/pipeline/pipeline.go @@ -7,6 +7,8 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/compiler" "github.com/go-vela/server/database" "github.com/go-vela/server/internal" @@ -16,7 +18,6 @@ import ( "github.com/go-vela/server/scm" "github.com/go-vela/server/util" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // Retrieve gets the pipeline in the given context. diff --git a/router/middleware/pipeline/pipeline_test.go b/router/middleware/pipeline/pipeline_test.go index 552a40989..c4356f6dc 100644 --- a/router/middleware/pipeline/pipeline_test.go +++ b/router/middleware/pipeline/pipeline_test.go @@ -13,6 +13,9 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/golang-jwt/jwt/v5" + "github.com/urfave/cli/v2" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/compiler" "github.com/go-vela/server/compiler/native" @@ -27,8 +30,6 @@ import ( "github.com/go-vela/server/scm/github" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/golang-jwt/jwt/v5" - "github.com/urfave/cli/v2" ) func TestPipeline_Retrieve(t *testing.T) { diff --git a/router/middleware/queue.go b/router/middleware/queue.go index 0ebbe72ca..7f157ccb3 100644 --- a/router/middleware/queue.go +++ b/router/middleware/queue.go @@ -4,6 +4,7 @@ package middleware import ( "github.com/gin-gonic/gin" + "github.com/go-vela/server/queue" ) diff --git a/router/middleware/queue_test.go b/router/middleware/queue_test.go index 2f6a05fa6..af42c5422 100644 --- a/router/middleware/queue_test.go +++ b/router/middleware/queue_test.go @@ -8,10 +8,10 @@ import ( "reflect" "testing" + "github.com/gin-gonic/gin" + "github.com/go-vela/server/queue" "github.com/go-vela/server/queue/redis" - - "github.com/gin-gonic/gin" ) func TestMiddleware_Queue(t *testing.T) { diff --git a/router/middleware/repo/context_test.go b/router/middleware/repo/context_test.go index c02923ab8..2dd3c8ab8 100644 --- a/router/middleware/repo/context_test.go +++ b/router/middleware/repo/context_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" ) diff --git a/router/middleware/repo/repo.go b/router/middleware/repo/repo.go index f6f51cad7..448bc13ed 100644 --- a/router/middleware/repo/repo.go +++ b/router/middleware/repo/repo.go @@ -7,12 +7,13 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/sirupsen/logrus" ) // Retrieve gets the repo in the given context. diff --git a/router/middleware/repo/repo_test.go b/router/middleware/repo/repo_test.go index 64321b409..41595e60f 100644 --- a/router/middleware/repo/repo_test.go +++ b/router/middleware/repo/repo_test.go @@ -9,12 +9,12 @@ import ( "reflect" "testing" + "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/types/library" - - "github.com/gin-gonic/gin" - "github.com/go-vela/server/database" ) func TestRepo_Retrieve(t *testing.T) { diff --git a/router/middleware/schedule/context_test.go b/router/middleware/schedule/context_test.go index c75974fa0..066a3a6cc 100644 --- a/router/middleware/schedule/context_test.go +++ b/router/middleware/schedule/context_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/gin-gonic/gin" + "github.com/go-vela/types/library" ) diff --git a/router/middleware/schedule/schedule.go b/router/middleware/schedule/schedule.go index 59de83e41..78c5f14e5 100644 --- a/router/middleware/schedule/schedule.go +++ b/router/middleware/schedule/schedule.go @@ -7,12 +7,13 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // Retrieve gets the schedule in the given context. diff --git a/router/middleware/scm.go b/router/middleware/scm.go index 3f6ddee87..d6b945d2f 100644 --- a/router/middleware/scm.go +++ b/router/middleware/scm.go @@ -4,6 +4,7 @@ package middleware import ( "github.com/gin-gonic/gin" + "github.com/go-vela/server/scm" ) diff --git a/router/middleware/scm_test.go b/router/middleware/scm_test.go index 2c37a3de9..2000b0d5d 100644 --- a/router/middleware/scm_test.go +++ b/router/middleware/scm_test.go @@ -8,10 +8,10 @@ import ( "reflect" "testing" + "github.com/gin-gonic/gin" + "github.com/go-vela/server/scm" "github.com/go-vela/server/scm/github" - - "github.com/gin-gonic/gin" ) func TestMiddleware_Scm(t *testing.T) { diff --git a/router/middleware/secret_test.go b/router/middleware/secret_test.go index 544cd28cf..c5f54bb6d 100644 --- a/router/middleware/secret_test.go +++ b/router/middleware/secret_test.go @@ -8,11 +8,11 @@ import ( "reflect" "testing" + "github.com/gin-gonic/gin" + "github.com/go-vela/server/database" "github.com/go-vela/server/secret" "github.com/go-vela/server/secret/native" - - "github.com/gin-gonic/gin" ) func TestMiddleware_Secret(t *testing.T) { diff --git a/router/middleware/secure_cookie_test.go b/router/middleware/secure_cookie_test.go index c7ceb83b9..560086bc5 100644 --- a/router/middleware/secure_cookie_test.go +++ b/router/middleware/secure_cookie_test.go @@ -7,9 +7,8 @@ import ( "net/http/httptest" "testing" - "github.com/go-playground/assert/v2" - "github.com/gin-gonic/gin" + "github.com/go-playground/assert/v2" ) func TestCookie_SecureCookie(t *testing.T) { diff --git a/router/middleware/service/context_test.go b/router/middleware/service/context_test.go index 6751bc92f..8c1cc74f4 100644 --- a/router/middleware/service/context_test.go +++ b/router/middleware/service/context_test.go @@ -5,9 +5,9 @@ package service import ( "testing" - "github.com/go-vela/types/library" - "github.com/gin-gonic/gin" + + "github.com/go-vela/types/library" ) func TestService_FromContext(t *testing.T) { diff --git a/router/middleware/service/service.go b/router/middleware/service/service.go index 1d974f4e6..32142e16b 100644 --- a/router/middleware/service/service.go +++ b/router/middleware/service/service.go @@ -8,6 +8,8 @@ import ( "strconv" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/org" @@ -15,7 +17,6 @@ import ( "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // Retrieve gets the service in the given context. diff --git a/router/middleware/service/service_test.go b/router/middleware/service/service_test.go index 612f1e55f..1d0b8fda7 100644 --- a/router/middleware/service/service_test.go +++ b/router/middleware/service/service_test.go @@ -10,6 +10,7 @@ import ( "testing" "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" diff --git a/router/middleware/step/context_test.go b/router/middleware/step/context_test.go index 1b7932db2..c42feb41c 100644 --- a/router/middleware/step/context_test.go +++ b/router/middleware/step/context_test.go @@ -5,9 +5,9 @@ package step import ( "testing" - "github.com/go-vela/types/library" - "github.com/gin-gonic/gin" + + "github.com/go-vela/types/library" ) func TestStep_FromContext(t *testing.T) { diff --git a/router/middleware/step/step.go b/router/middleware/step/step.go index 89ba1aa1f..77a710585 100644 --- a/router/middleware/step/step.go +++ b/router/middleware/step/step.go @@ -8,6 +8,8 @@ import ( "strconv" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/org" @@ -15,7 +17,6 @@ import ( "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // Retrieve gets the step in the given context. diff --git a/router/middleware/step/step_test.go b/router/middleware/step/step_test.go index ee02d4a8a..265ce5306 100644 --- a/router/middleware/step/step_test.go +++ b/router/middleware/step/step_test.go @@ -10,6 +10,7 @@ import ( "testing" "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" diff --git a/router/middleware/token_manager_test.go b/router/middleware/token_manager_test.go index 9a26f9b43..8f8bb4fa2 100644 --- a/router/middleware/token_manager_test.go +++ b/router/middleware/token_manager_test.go @@ -8,9 +8,9 @@ import ( "reflect" "testing" - "github.com/go-vela/server/internal/token" - "github.com/gin-gonic/gin" + + "github.com/go-vela/server/internal/token" ) func TestMiddleware_TokenManager(t *testing.T) { diff --git a/router/middleware/user/context_test.go b/router/middleware/user/context_test.go index ced7cd896..50d502ac2 100644 --- a/router/middleware/user/context_test.go +++ b/router/middleware/user/context_test.go @@ -5,9 +5,9 @@ package user import ( "testing" - "github.com/go-vela/types/library" - "github.com/gin-gonic/gin" + + "github.com/go-vela/types/library" ) func TestUser_FromContext(t *testing.T) { diff --git a/router/middleware/user/user.go b/router/middleware/user/user.go index 71fdc1a2d..ad8676b21 100644 --- a/router/middleware/user/user.go +++ b/router/middleware/user/user.go @@ -6,15 +6,14 @@ import ( "net/http" "strings" + "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/claims" "github.com/go-vela/server/util" - "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - - "github.com/gin-gonic/gin" - "github.com/sirupsen/logrus" ) // Retrieve gets the user in the given context. diff --git a/router/middleware/user/user_test.go b/router/middleware/user/user_test.go index d84a18847..d8d97121c 100644 --- a/router/middleware/user/user_test.go +++ b/router/middleware/user/user_test.go @@ -12,6 +12,8 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/golang-jwt/jwt/v5" + "github.com/go-vela/server/database" "github.com/go-vela/server/internal/token" "github.com/go-vela/server/router/middleware/claims" @@ -19,7 +21,6 @@ import ( "github.com/go-vela/server/scm/github" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/golang-jwt/jwt/v5" ) func TestUser_Retrieve(t *testing.T) { diff --git a/router/middleware/webhook_validation_test.go b/router/middleware/webhook_validation_test.go index cb8a65639..f70d1fbdc 100644 --- a/router/middleware/webhook_validation_test.go +++ b/router/middleware/webhook_validation_test.go @@ -7,9 +7,8 @@ import ( "net/http/httptest" "testing" - "github.com/go-playground/assert/v2" - "github.com/gin-gonic/gin" + "github.com/go-playground/assert/v2" ) func TestWebhook_WebhookValidation(t *testing.T) { diff --git a/router/middleware/worker/context_test.go b/router/middleware/worker/context_test.go index 6fd731e90..3eb58d513 100644 --- a/router/middleware/worker/context_test.go +++ b/router/middleware/worker/context_test.go @@ -5,9 +5,9 @@ package worker import ( "testing" - api "github.com/go-vela/server/api/types" - "github.com/gin-gonic/gin" + + api "github.com/go-vela/server/api/types" ) func TestWorker_FromContext(t *testing.T) { diff --git a/router/middleware/worker/worker.go b/router/middleware/worker/worker.go index 5a78d14a4..d46ad1a1a 100644 --- a/router/middleware/worker/worker.go +++ b/router/middleware/worker/worker.go @@ -7,10 +7,11 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/util" - "github.com/sirupsen/logrus" ) // Retrieve gets the worker in the given context. diff --git a/router/middleware/worker/worker_test.go b/router/middleware/worker/worker_test.go index 277ed8c09..a59f11190 100644 --- a/router/middleware/worker/worker_test.go +++ b/router/middleware/worker/worker_test.go @@ -10,6 +10,7 @@ import ( "testing" "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/types/library" diff --git a/router/pipeline.go b/router/pipeline.go index 7d11a4e2e..fd982d8f7 100644 --- a/router/pipeline.go +++ b/router/pipeline.go @@ -4,6 +4,7 @@ package router import ( "github.com/gin-gonic/gin" + "github.com/go-vela/server/api/pipeline" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/perm" diff --git a/router/queue.go b/router/queue.go index ca408ffe3..90452c2a8 100644 --- a/router/queue.go +++ b/router/queue.go @@ -4,6 +4,7 @@ package router import ( "github.com/gin-gonic/gin" + "github.com/go-vela/server/api/queue" "github.com/go-vela/server/router/middleware/perm" ) diff --git a/router/repo.go b/router/repo.go index 0ed7d1be1..3cd7ecc9f 100644 --- a/router/repo.go +++ b/router/repo.go @@ -4,6 +4,7 @@ package router import ( "github.com/gin-gonic/gin" + "github.com/go-vela/server/api/build" "github.com/go-vela/server/api/repo" "github.com/go-vela/server/router/middleware" diff --git a/router/router.go b/router/router.go index 57f8e3d09..8f0559ba7 100644 --- a/router/router.go +++ b/router/router.go @@ -31,6 +31,7 @@ package router import ( "github.com/gin-gonic/gin" + "github.com/go-vela/server/api" "github.com/go-vela/server/api/auth" "github.com/go-vela/server/api/webhook" diff --git a/router/schedule.go b/router/schedule.go index 4a94f7737..49abaca33 100644 --- a/router/schedule.go +++ b/router/schedule.go @@ -4,6 +4,7 @@ package router import ( "github.com/gin-gonic/gin" + "github.com/go-vela/server/api/schedule" "github.com/go-vela/server/router/middleware" "github.com/go-vela/server/router/middleware/org" diff --git a/router/scm.go b/router/scm.go index 10c1cea81..1b0a7c96d 100644 --- a/router/scm.go +++ b/router/scm.go @@ -4,6 +4,7 @@ package router import ( "github.com/gin-gonic/gin" + "github.com/go-vela/server/api/scm" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" diff --git a/router/search.go b/router/search.go index f5679048d..d62db11b4 100644 --- a/router/search.go +++ b/router/search.go @@ -4,6 +4,7 @@ package router import ( "github.com/gin-gonic/gin" + "github.com/go-vela/server/api/build" ) diff --git a/router/secret.go b/router/secret.go index 419a0cab6..bb103ca5c 100644 --- a/router/secret.go +++ b/router/secret.go @@ -3,10 +3,10 @@ package router import ( + "github.com/gin-gonic/gin" + "github.com/go-vela/server/api/secret" "github.com/go-vela/server/router/middleware/perm" - - "github.com/gin-gonic/gin" ) // SecretHandlers is a function that extends the provided base router group diff --git a/router/service.go b/router/service.go index 683a38b6f..48787d19d 100644 --- a/router/service.go +++ b/router/service.go @@ -5,6 +5,7 @@ package router import ( "github.com/gin-gonic/gin" + "github.com/go-vela/server/api/service" "github.com/go-vela/server/router/middleware" "github.com/go-vela/server/router/middleware/perm" diff --git a/router/step.go b/router/step.go index d26f70385..934e61d81 100644 --- a/router/step.go +++ b/router/step.go @@ -5,6 +5,7 @@ package router import ( "github.com/gin-gonic/gin" + "github.com/go-vela/server/api/step" "github.com/go-vela/server/router/middleware" "github.com/go-vela/server/router/middleware/perm" diff --git a/router/user.go b/router/user.go index 8f8e68fcc..64f41b6a5 100644 --- a/router/user.go +++ b/router/user.go @@ -4,6 +4,7 @@ package router import ( "github.com/gin-gonic/gin" + "github.com/go-vela/server/api/user" "github.com/go-vela/server/router/middleware/perm" ) diff --git a/router/worker.go b/router/worker.go index 9ab61ead0..648d1efdf 100644 --- a/router/worker.go +++ b/router/worker.go @@ -4,6 +4,7 @@ package router import ( "github.com/gin-gonic/gin" + "github.com/go-vela/server/api/worker" "github.com/go-vela/server/router/middleware" "github.com/go-vela/server/router/middleware/perm" diff --git a/scm/context_test.go b/scm/context_test.go index e98afa30c..6a54a456f 100644 --- a/scm/context_test.go +++ b/scm/context_test.go @@ -7,9 +7,9 @@ import ( "net/http/httptest" "testing" - "github.com/go-vela/server/scm/github" - "github.com/gin-gonic/gin" + + "github.com/go-vela/server/scm/github" ) func TestSCM_FromContext(t *testing.T) { diff --git a/scm/flags.go b/scm/flags.go index 84a9e879c..2a64f7e14 100644 --- a/scm/flags.go +++ b/scm/flags.go @@ -3,8 +3,9 @@ package scm import ( - "github.com/go-vela/types/constants" "github.com/urfave/cli/v2" + + "github.com/go-vela/types/constants" ) // Flags represents all supported command line diff --git a/scm/github/access.go b/scm/github/access.go index f6b185356..40b9b9de1 100644 --- a/scm/github/access.go +++ b/scm/github/access.go @@ -6,10 +6,10 @@ import ( "context" "strings" + "github.com/google/go-github/v61/github" "github.com/sirupsen/logrus" "github.com/go-vela/types/library" - "github.com/google/go-github/v61/github" ) // OrgAccess captures the user's access level for an org. diff --git a/scm/github/authentication.go b/scm/github/authentication.go index d41cd5a8c..1e76770fb 100644 --- a/scm/github/authentication.go +++ b/scm/github/authentication.go @@ -10,9 +10,10 @@ import ( "net/url" "strings" + "github.com/google/go-github/v61/github" + "github.com/go-vela/server/random" "github.com/go-vela/types/library" - "github.com/google/go-github/v61/github" ) // Authorize uses the given access token to authorize the user. diff --git a/scm/github/authentication_test.go b/scm/github/authentication_test.go index 47c524e4d..8c076b0c5 100644 --- a/scm/github/authentication_test.go +++ b/scm/github/authentication_test.go @@ -3,14 +3,14 @@ package github import ( + _context "context" "net/http" "net/http/httptest" "reflect" "testing" - _context "context" - "github.com/gin-gonic/gin" + "github.com/go-vela/types/library" ) diff --git a/scm/github/changeset.go b/scm/github/changeset.go index b99a00371..c36fe3c8f 100644 --- a/scm/github/changeset.go +++ b/scm/github/changeset.go @@ -6,10 +6,10 @@ import ( "context" "fmt" + "github.com/google/go-github/v61/github" "github.com/sirupsen/logrus" api "github.com/go-vela/server/api/types" - "github.com/google/go-github/v61/github" ) // Changeset captures the list of files changed for a commit. diff --git a/scm/github/deployment.go b/scm/github/deployment.go index ce0db052d..331164411 100644 --- a/scm/github/deployment.go +++ b/scm/github/deployment.go @@ -6,12 +6,12 @@ import ( "context" "encoding/json" + "github.com/google/go-github/v61/github" "github.com/sirupsen/logrus" api "github.com/go-vela/server/api/types" "github.com/go-vela/types/library" "github.com/go-vela/types/raw" - "github.com/google/go-github/v61/github" ) // GetDeployment gets a deployment from the GitHub repo. diff --git a/scm/github/github.go b/scm/github/github.go index 4c9910653..86129c2ab 100644 --- a/scm/github/github.go +++ b/scm/github/github.go @@ -9,7 +9,6 @@ import ( "github.com/google/go-github/v61/github" "github.com/sirupsen/logrus" - "golang.org/x/oauth2" ) diff --git a/scm/github/repo.go b/scm/github/repo.go index 7a2d973f8..ced606756 100644 --- a/scm/github/repo.go +++ b/scm/github/repo.go @@ -10,12 +10,12 @@ import ( "strings" "time" + "github.com/google/go-github/v61/github" "github.com/sirupsen/logrus" api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/google/go-github/v61/github" ) // ConfigBackoff is a wrapper for Config that will retry five times if the function diff --git a/scm/github/webhook.go b/scm/github/webhook.go index 47aefee38..cd9ba0479 100644 --- a/scm/github/webhook.go +++ b/scm/github/webhook.go @@ -13,13 +13,13 @@ import ( "strings" "time" + "github.com/google/go-github/v61/github" "github.com/sirupsen/logrus" api "github.com/go-vela/server/api/types" "github.com/go-vela/server/internal" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/google/go-github/v61/github" ) // ProcessWebhook parses the webhook from a repo. diff --git a/scm/github/webhook_test.go b/scm/github/webhook_test.go index 50aea20b4..ec3f0466c 100644 --- a/scm/github/webhook_test.go +++ b/scm/github/webhook_test.go @@ -13,13 +13,13 @@ import ( "time" "github.com/gin-gonic/gin" - api "github.com/go-vela/server/api/types" - "github.com/go-vela/server/internal" - "github.com/go-vela/types/raw" "github.com/google/go-cmp/cmp" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/internal" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" + "github.com/go-vela/types/raw" ) func TestGithub_ProcessWebhook_Push(t *testing.T) { diff --git a/scm/scm.go b/scm/scm.go index 1614d80ea..e45b33576 100644 --- a/scm/scm.go +++ b/scm/scm.go @@ -5,9 +5,9 @@ package scm import ( "fmt" - "github.com/go-vela/types/constants" - "github.com/sirupsen/logrus" + + "github.com/go-vela/types/constants" ) // New creates and returns a Vela service capable of diff --git a/scm/setup.go b/scm/setup.go index b779e8ab2..3b4082f7f 100644 --- a/scm/setup.go +++ b/scm/setup.go @@ -6,10 +6,10 @@ import ( "fmt" "strings" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/scm/github" "github.com/go-vela/types/constants" - - "github.com/sirupsen/logrus" ) // Setup represents the configuration necessary for diff --git a/secret/context_test.go b/secret/context_test.go index 4e92573e7..becf8cea1 100644 --- a/secret/context_test.go +++ b/secret/context_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/gin-gonic/gin" + "github.com/go-vela/server/database" "github.com/go-vela/server/secret/native" ) diff --git a/secret/native/count.go b/secret/native/count.go index 379391d1b..460ee077b 100644 --- a/secret/native/count.go +++ b/secret/native/count.go @@ -6,9 +6,10 @@ import ( "context" "fmt" + "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/sirupsen/logrus" ) // Count counts a list of secrets. diff --git a/secret/native/create.go b/secret/native/create.go index 7d0f026c8..698b25740 100644 --- a/secret/native/create.go +++ b/secret/native/create.go @@ -6,9 +6,10 @@ import ( "context" "fmt" + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // Create creates a new secret. diff --git a/secret/native/delete.go b/secret/native/delete.go index 54662a9f6..d0fbdc458 100644 --- a/secret/native/delete.go +++ b/secret/native/delete.go @@ -6,8 +6,9 @@ import ( "context" "fmt" - "github.com/go-vela/types/constants" "github.com/sirupsen/logrus" + + "github.com/go-vela/types/constants" ) // Delete deletes a secret. diff --git a/secret/native/get.go b/secret/native/get.go index 059ee917e..da22376e6 100644 --- a/secret/native/get.go +++ b/secret/native/get.go @@ -6,10 +6,11 @@ import ( "context" "fmt" + "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // Get captures a secret. diff --git a/secret/native/list.go b/secret/native/list.go index ab6f7d57b..f1acfc069 100644 --- a/secret/native/list.go +++ b/secret/native/list.go @@ -6,10 +6,11 @@ import ( "context" "fmt" + "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // List captures a list of secrets. diff --git a/secret/native/native.go b/secret/native/native.go index fb4319673..10b62659a 100644 --- a/secret/native/native.go +++ b/secret/native/native.go @@ -3,8 +3,9 @@ package native import ( - "github.com/go-vela/server/database" "github.com/sirupsen/logrus" + + "github.com/go-vela/server/database" ) // client represents a struct to hold native secret setup. diff --git a/secret/native/update.go b/secret/native/update.go index bce00e936..43bfcc011 100644 --- a/secret/native/update.go +++ b/secret/native/update.go @@ -6,9 +6,10 @@ import ( "context" "fmt" + "github.com/sirupsen/logrus" + "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/sirupsen/logrus" ) // Update updates an existing secret. diff --git a/secret/secret.go b/secret/secret.go index 75496e449..7dadc4b05 100644 --- a/secret/secret.go +++ b/secret/secret.go @@ -5,9 +5,9 @@ package secret import ( "fmt" - "github.com/go-vela/types/constants" - "github.com/sirupsen/logrus" + + "github.com/go-vela/types/constants" ) // New creates and returns a Vela service capable of diff --git a/secret/setup.go b/secret/setup.go index 2e6e4b6b7..8a9917c0a 100644 --- a/secret/setup.go +++ b/secret/setup.go @@ -7,11 +7,12 @@ import ( "strings" "time" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/database" "github.com/go-vela/server/secret/native" "github.com/go-vela/server/secret/vault" "github.com/go-vela/types/constants" - "github.com/sirupsen/logrus" ) // Setup represents the configuration necessary for diff --git a/secret/vault/count.go b/secret/vault/count.go index a6995d2ee..907165cea 100644 --- a/secret/vault/count.go +++ b/secret/vault/count.go @@ -7,10 +7,10 @@ import ( "fmt" "strings" + "github.com/hashicorp/vault/api" "github.com/sirupsen/logrus" "github.com/go-vela/types/constants" - "github.com/hashicorp/vault/api" ) // Count counts a list of secrets. @@ -34,7 +34,6 @@ func (c *client) Count(ctx context.Context, sType, org, name string, _ []string) c.Logger.WithFields(fields).Tracef("counting vault %s secrets for %s/%s", sType, org, name) - //nolint:staticcheck // ignore false positive vault := new(api.Secret) count := 0 diff --git a/secret/vault/create_test.go b/secret/vault/create_test.go index dc0d5226f..1de42e2bf 100644 --- a/secret/vault/create_test.go +++ b/secret/vault/create_test.go @@ -9,9 +9,9 @@ import ( "reflect" "testing" - "github.com/go-vela/types/library" - "github.com/gin-gonic/gin" + + "github.com/go-vela/types/library" ) func TestVault_Create_Org(t *testing.T) { diff --git a/secret/vault/get.go b/secret/vault/get.go index eeba1e996..fcd083006 100644 --- a/secret/vault/get.go +++ b/secret/vault/get.go @@ -7,11 +7,11 @@ import ( "fmt" "strings" + "github.com/hashicorp/vault/api" "github.com/sirupsen/logrus" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/hashicorp/vault/api" ) // Get captures a secret. diff --git a/secret/vault/get_test.go b/secret/vault/get_test.go index 5af08f22a..4b64b8ed7 100644 --- a/secret/vault/get_test.go +++ b/secret/vault/get_test.go @@ -9,9 +9,9 @@ import ( "reflect" "testing" - "github.com/go-vela/types/library" - "github.com/gin-gonic/gin" + + "github.com/go-vela/types/library" ) func TestVault_Get_Org(t *testing.T) { diff --git a/secret/vault/list.go b/secret/vault/list.go index be5638e41..b42d00d66 100644 --- a/secret/vault/list.go +++ b/secret/vault/list.go @@ -7,11 +7,11 @@ import ( "fmt" "strings" + "github.com/hashicorp/vault/api" "github.com/sirupsen/logrus" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" - "github.com/hashicorp/vault/api" ) // List captures a list of secrets. @@ -42,7 +42,7 @@ func (c *client) List(ctx context.Context, sType, org, name string, _, _ int, _ var err error s := []*library.Secret{} - //nolint:staticcheck // ignore false positive + vault := new(api.Secret) // capture the list of secrets from the Vault service diff --git a/secret/vault/list_test.go b/secret/vault/list_test.go index 9a6eb352e..990c4f020 100644 --- a/secret/vault/list_test.go +++ b/secret/vault/list_test.go @@ -9,9 +9,9 @@ import ( "reflect" "testing" - "github.com/go-vela/types/library" - "github.com/gin-gonic/gin" + + "github.com/go-vela/types/library" ) func TestVault_List_Org(t *testing.T) { diff --git a/secret/vault/update_test.go b/secret/vault/update_test.go index 4a525c1ab..39fea7d41 100644 --- a/secret/vault/update_test.go +++ b/secret/vault/update_test.go @@ -9,9 +9,9 @@ import ( "reflect" "testing" - "github.com/go-vela/types/library" - "github.com/gin-gonic/gin" + + "github.com/go-vela/types/library" ) func TestVault_Update_Org(t *testing.T) { diff --git a/secret/vault/vault.go b/secret/vault/vault.go index 2cbf34b34..63745833f 100644 --- a/secret/vault/vault.go +++ b/secret/vault/vault.go @@ -8,11 +8,12 @@ import ( "time" "github.com/aws/aws-sdk-go/service/sts/stsiface" - "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" "github.com/hashicorp/vault/api" "github.com/pkg/errors" "github.com/sirupsen/logrus" + + "github.com/go-vela/types/constants" + "github.com/go-vela/types/library" ) const ( diff --git a/secret/vault/vault_test.go b/secret/vault/vault_test.go index 2bbb666bb..a60d7bd75 100644 --- a/secret/vault/vault_test.go +++ b/secret/vault/vault_test.go @@ -10,9 +10,10 @@ import ( "strings" "testing" - "github.com/go-vela/types/library" "github.com/google/go-cmp/cmp" "github.com/hashicorp/vault/api" + + "github.com/go-vela/types/library" ) func TestVault_New(t *testing.T) { diff --git a/util/util.go b/util/util.go index 60d709765..b4a1a29ae 100644 --- a/util/util.go +++ b/util/util.go @@ -8,10 +8,10 @@ import ( "net/url" "strings" - api "github.com/go-vela/server/api/types" + "github.com/gin-gonic/gin" "github.com/microcosm-cc/bluemonday" - "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types" ) diff --git a/version/version.go b/version/version.go index f6dfde329..f363d79b4 100644 --- a/version/version.go +++ b/version/version.go @@ -7,8 +7,9 @@ import ( "runtime" "github.com/Masterminds/semver/v3" - "github.com/go-vela/types/version" "github.com/sirupsen/logrus" + + "github.com/go-vela/types/version" ) var ( From 37bdad3c0770f288481c6f88c829ee58703583fa Mon Sep 17 00:00:00 2001 From: David May <49894298+wass3rw3rk@users.noreply.github.com> Date: Thu, 11 Apr 2024 15:11:03 -0500 Subject: [PATCH 30/71] chore(linter): remove goimports (#1104) having both goimports and gci could create conflicts --- .golangci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.golangci.yml b/.golangci.yml index 5e05f9822..5b27708f8 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -83,7 +83,6 @@ linters: - godot # checks if comments end in a period - gofmt # checks whether code was gofmt-ed - goheader # checks is file header matches to pattern - - goimports # fixes imports and formats code in same style as gofmt - gomoddirectives # manage the use of 'replace', 'retract', and 'excludes' directives in go.mod - goprintffuncname # checks that printf-like functions are named with f at the end - gosec # inspects code for security problems From fe803f80646bfc75e531ec486725e3cd5b5dee5a Mon Sep 17 00:00:00 2001 From: dave vader <48764154+plyr4@users.noreply.github.com> Date: Fri, 12 Apr 2024 12:20:36 -0500 Subject: [PATCH 31/71] fix: nil panic after CompileAndPublish (#1105) --- api/build/compile_publish.go | 2 ++ api/webhook/post.go | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/api/build/compile_publish.go b/api/build/compile_publish.go index 69d6098e0..a9d52645f 100644 --- a/api/build/compile_publish.go +++ b/api/build/compile_publish.go @@ -426,6 +426,8 @@ func CompileAndPublish( // error out the build CleanBuild(c, database, b, nil, nil, retErr) + util.HandleError(c, http.StatusBadRequest, retErr) + return nil, nil, retErr } diff --git a/api/webhook/post.go b/api/webhook/post.go index 82db4a899..f964398d7 100644 --- a/api/webhook/post.go +++ b/api/webhook/post.go @@ -309,6 +309,11 @@ func PostWebhook(c *gin.Context) { queue.FromContext(c), ) + // error handling done in CompileAndPublish + if err != nil { + return + } + // capture the build and repo from the items b, repo = item.Build, item.Repo From 04f930869c93b4a6bef0f1233f9f59d081ec0b8b Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Fri, 12 Apr 2024 14:08:45 -0400 Subject: [PATCH 32/71] refactor(user)!: migrate from types repo (#1106) * refactor(user): migrate from types repo * make clean * remove extra lines from auto fix linter --- api/admin/user.go | 4 +- api/auth/get_token.go | 3 +- api/build/skip.go | 2 - api/types/executor.go | 2 +- api/types/repo.go | 50 ++- api/types/repo_test.go | 3 +- api/types/user.go | 252 +++++++++++++ api/types/user_test.go | 194 ++++++++++ api/user/create.go | 4 +- api/user/update.go | 4 +- api/user/update_current.go | 4 +- compiler/engine.go | 2 +- compiler/native/environment.go | 2 +- compiler/native/environment_test.go | 36 +- compiler/native/native.go | 4 +- compiler/native/native_test.go | 2 +- compiler/registry/github/template.go | 4 +- compiler/registry/github/template_test.go | 12 +- compiler/registry/registry.go | 6 +- database/integration_test.go | 18 +- database/repo/count_org_test.go | 4 +- database/repo/count_test.go | 4 +- database/repo/count_user.go | 4 +- database/repo/count_user_test.go | 8 +- database/repo/create_test.go | 2 +- database/repo/delete_test.go | 2 +- database/repo/get_org_test.go | 6 +- database/repo/get_test.go | 6 +- database/repo/interface.go | 5 +- database/repo/list_org_test.go | 8 +- database/repo/list_test.go | 8 +- database/repo/list_user.go | 3 +- database/repo/list_user_test.go | 8 +- database/repo/repo.go | 6 +- database/repo/repo_test.go | 372 +++++++++++++++++++- database/repo/update_test.go | 2 +- database/schedule/create.go | 1 - database/user/count_test.go | 6 +- database/user/create.go | 13 +- database/user/create_test.go | 9 +- database/user/delete.go | 11 +- database/user/delete_test.go | 3 +- database/user/get.go | 13 +- database/user/get_name.go | 13 +- database/user/get_name_test.go | 8 +- database/user/get_test.go | 8 +- database/user/interface.go | 16 +- database/user/list.go | 17 +- database/user/list_lite.go | 15 +- database/user/list_lite_test.go | 16 +- database/user/list_test.go | 14 +- database/user/table.go | 2 - database/user/update.go | 15 +- database/user/update_test.go | 9 +- database/user/user.go | 232 ++++++++++++ database/user/user_test.go | 279 ++++++++++++++- internal/token/compose.go | 4 +- internal/token/compose_test.go | 5 +- internal/token/mint.go | 4 +- internal/token/parse_test.go | 22 +- internal/token/refresh_test.go | 8 +- mock/server/user.go | 10 +- mock/server/user_test.go | 4 +- queue/models/item_test.go | 4 +- queue/redis/redis_test.go | 3 +- router/middleware/build/build_test.go | 6 +- router/middleware/claims/claims_test.go | 8 +- router/middleware/logger_test.go | 2 +- router/middleware/perm/perm_test.go | 91 ++--- router/middleware/pipeline/pipeline_test.go | 9 +- router/middleware/repo/repo_test.go | 4 +- router/middleware/service/service_test.go | 6 +- router/middleware/step/step_test.go | 10 +- router/middleware/user/context.go | 8 +- router/middleware/user/context_test.go | 6 +- router/middleware/user/user.go | 6 +- router/middleware/user/user_test.go | 15 +- scm/github/access.go | 10 +- scm/github/access_test.go | 26 +- scm/github/authentication.go | 10 +- scm/github/authentication_test.go | 6 +- scm/github/changeset_test.go | 5 +- scm/github/deployment.go | 8 +- scm/github/deployment_test.go | 2 +- scm/github/org.go | 4 +- scm/github/org_test.go | 8 +- scm/github/repo.go | 22 +- scm/github/repo_test.go | 64 ++-- scm/github/webhook.go | 2 +- scm/github/webhook_test.go | 4 +- scm/service.go | 46 +-- 91 files changed, 1714 insertions(+), 494 deletions(-) create mode 100644 api/types/user.go create mode 100644 api/types/user_test.go diff --git a/api/admin/user.go b/api/admin/user.go index cc276220d..7e5db6072 100644 --- a/api/admin/user.go +++ b/api/admin/user.go @@ -10,9 +10,9 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/util" - "github.com/go-vela/types/library" ) // swagger:operation PUT /api/v1/admin/user admin AdminUpdateUser @@ -54,7 +54,7 @@ func UpdateUser(c *gin.Context) { ctx := c.Request.Context() // capture body from API request - input := new(library.User) + input := new(types.User) err := c.Bind(input) if err != nil { diff --git a/api/auth/get_token.go b/api/auth/get_token.go index d1d076631..82fe08892 100644 --- a/api/auth/get_token.go +++ b/api/auth/get_token.go @@ -8,6 +8,7 @@ import ( "github.com/gin-gonic/gin" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/internal/token" "github.com/go-vela/server/scm" @@ -102,7 +103,7 @@ func GetAuthToken(c *gin.Context) { // create a new user account if len(u.GetName()) == 0 || err != nil { // create the user account - u := new(library.User) + u := new(types.User) u.SetName(newUser.GetName()) u.SetToken(newUser.GetToken()) u.SetActive(true) diff --git a/api/build/skip.go b/api/build/skip.go index 0987e99f6..8e8965c57 100644 --- a/api/build/skip.go +++ b/api/build/skip.go @@ -8,8 +8,6 @@ import ( // SkipEmptyBuild checks if the build should be skipped due to it // not containing any steps besides init or clone. -// -//nolint:goconst // ignore init and clone constants func SkipEmptyBuild(p *pipeline.Build) string { if len(p.Stages) == 1 { if p.Stages[0].Name == "init" { diff --git a/api/types/executor.go b/api/types/executor.go index d1dce126c..706862f24 100644 --- a/api/types/executor.go +++ b/api/types/executor.go @@ -10,7 +10,7 @@ import ( "github.com/go-vela/types/pipeline" ) -// Executor is the library representation of an executor for a worker. +// Executor is the API representation of an executor for a worker. // // swagger:model Executor type Executor struct { diff --git a/api/types/repo.go b/api/types/repo.go index fe0ad1028..bfad93623 100644 --- a/api/types/repo.go +++ b/api/types/repo.go @@ -5,35 +5,33 @@ package types import ( "fmt" "strings" - - "github.com/go-vela/types/library" ) // Repo is the API representation of a repo. // // swagger:model Repo type Repo struct { - ID *int64 `json:"id,omitempty"` - Owner *library.User `json:"owner,omitempty"` - Hash *string `json:"-"` - Org *string `json:"org,omitempty"` - Name *string `json:"name,omitempty"` - FullName *string `json:"full_name,omitempty"` - Link *string `json:"link,omitempty"` - Clone *string `json:"clone,omitempty"` - Branch *string `json:"branch,omitempty"` - Topics *[]string `json:"topics,omitempty"` - BuildLimit *int64 `json:"build_limit,omitempty"` - Timeout *int64 `json:"timeout,omitempty"` - Counter *int `json:"counter,omitempty"` - Visibility *string `json:"visibility,omitempty"` - Private *bool `json:"private,omitempty"` - Trusted *bool `json:"trusted,omitempty"` - Active *bool `json:"active,omitempty"` - AllowEvents *Events `json:"allow_events,omitempty"` - PipelineType *string `json:"pipeline_type,omitempty"` - PreviousName *string `json:"previous_name,omitempty"` - ApproveBuild *string `json:"approve_build,omitempty"` + ID *int64 `json:"id,omitempty"` + Owner *User `json:"owner,omitempty"` + Hash *string `json:"-"` + Org *string `json:"org,omitempty"` + Name *string `json:"name,omitempty"` + FullName *string `json:"full_name,omitempty"` + Link *string `json:"link,omitempty"` + Clone *string `json:"clone,omitempty"` + Branch *string `json:"branch,omitempty"` + Topics *[]string `json:"topics,omitempty"` + BuildLimit *int64 `json:"build_limit,omitempty"` + Timeout *int64 `json:"timeout,omitempty"` + Counter *int `json:"counter,omitempty"` + Visibility *string `json:"visibility,omitempty"` + Private *bool `json:"private,omitempty"` + Trusted *bool `json:"trusted,omitempty"` + Active *bool `json:"active,omitempty"` + AllowEvents *Events `json:"allow_events,omitempty"` + PipelineType *string `json:"pipeline_type,omitempty"` + PreviousName *string `json:"previous_name,omitempty"` + ApproveBuild *string `json:"approve_build,omitempty"` } // Environment returns a list of environment variables @@ -91,10 +89,10 @@ func (r *Repo) GetID() int64 { // // 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) GetOwner() *library.User { +func (r *Repo) GetOwner() *User { // return zero value if Repo type or Owner field is nil if r == nil || r.Owner == nil { - return new(library.User) + return new(User) } return r.Owner @@ -364,7 +362,7 @@ func (r *Repo) SetID(v int64) { // // When the provided Repo type is nil, it // will set nothing and immediately return. -func (r *Repo) SetOwner(v *library.User) { +func (r *Repo) SetOwner(v *User) { // return if Repo type is nil if r == nil { return diff --git a/api/types/repo_test.go b/api/types/repo_test.go index bbbd6ee91..c632b471d 100644 --- a/api/types/repo_test.go +++ b/api/types/repo_test.go @@ -10,7 +10,6 @@ import ( "github.com/google/go-cmp/cmp" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" ) func TestTypes_Repo_Environment(t *testing.T) { @@ -343,7 +342,7 @@ func testRepo() *Repo { e, _ := testEvents() - owner := new(library.User) + owner := new(User) owner.SetID(1) owner.SetName("octocat") diff --git a/api/types/user.go b/api/types/user.go new file mode 100644 index 000000000..277426d3e --- /dev/null +++ b/api/types/user.go @@ -0,0 +1,252 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "fmt" + + "github.com/go-vela/types/constants" +) + +// User is the API representation of a user. +// +// swagger:model User +type User struct { + ID *int64 `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + RefreshToken *string `json:"-"` + Token *string `json:"-"` + Favorites *[]string `json:"favorites,omitempty"` + Active *bool `json:"active,omitempty"` + Admin *bool `json:"admin,omitempty"` +} + +// Sanitize creates a duplicate of the User without the token values. +func (u *User) Sanitize() *User { + // create a variable since constants can not be addressable + // + // https://golang.org/ref/spec#Address_operators + value := constants.SecretMask + + return &User{ + ID: u.ID, + Name: u.Name, + RefreshToken: &value, + Token: &value, + Favorites: u.Favorites, + Active: u.Active, + Admin: u.Admin, + } +} + +// Environment returns a list of environment variables +// provided from the fields of the User type. +func (u *User) Environment() map[string]string { + return map[string]string{ + "VELA_USER_ACTIVE": ToString(u.GetActive()), + "VELA_USER_ADMIN": ToString(u.GetAdmin()), + "VELA_USER_FAVORITES": ToString(u.GetFavorites()), + "VELA_USER_NAME": ToString(u.GetName()), + } +} + +// GetID returns the ID field. +// +// When the provided User type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (u *User) GetID() int64 { + // return zero value if User type or ID field is nil + if u == nil || u.ID == nil { + return 0 + } + + return *u.ID +} + +// GetName returns the Name field. +// +// When the provided User type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (u *User) GetName() string { + // return zero value if User type or Name field is nil + if u == nil || u.Name == nil { + return "" + } + + return *u.Name +} + +// GetRefreshToken returns the RefreshToken field. +// +// When the provided User type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (u *User) GetRefreshToken() string { + // return zero value if User type or RefreshToken field is nil + if u == nil || u.RefreshToken == nil { + return "" + } + + return *u.RefreshToken +} + +// GetToken returns the Token field. +// +// When the provided User type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (u *User) GetToken() string { + // return zero value if User type or Token field is nil + if u == nil || u.Token == nil { + return "" + } + + return *u.Token +} + +// GetActive returns the Active field. +// +// When the provided User type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (u *User) GetActive() bool { + // return zero value if User type or Active field is nil + if u == nil || u.Active == nil { + return false + } + + return *u.Active +} + +// GetAdmin returns the Admin field. +// +// When the provided User type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (u *User) GetAdmin() bool { + // return zero value if User type or Admin field is nil + if u == nil || u.Admin == nil { + return false + } + + return *u.Admin +} + +// GetFavorites returns the Favorites field. +// +// When the provided User type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (u *User) GetFavorites() []string { + // return zero value if User type or Favorites field is nil + if u == nil || u.Favorites == nil { + return []string{} + } + + return *u.Favorites +} + +// SetID sets the ID field. +// +// When the provided User type is nil, it +// will set nothing and immediately return. +func (u *User) SetID(v int64) { + // return if User type is nil + if u == nil { + return + } + + u.ID = &v +} + +// SetName sets the Name field. +// +// When the provided User type is nil, it +// will set nothing and immediately return. +func (u *User) SetName(v string) { + // return if User type is nil + if u == nil { + return + } + + u.Name = &v +} + +// SetRefreshToken sets the RefreshToken field. +// +// When the provided User type is nil, it +// will set nothing and immediately return. +func (u *User) SetRefreshToken(v string) { + // return if User type is nil + if u == nil { + return + } + + u.RefreshToken = &v +} + +// SetToken sets the Token field. +// +// When the provided User type is nil, it +// will set nothing and immediately return. +func (u *User) SetToken(v string) { + // return if User type is nil + if u == nil { + return + } + + u.Token = &v +} + +// SetActive sets the Active field. +// +// When the provided User type is nil, it +// will set nothing and immediately return. +func (u *User) SetActive(v bool) { + // return if User type is nil + if u == nil { + return + } + + u.Active = &v +} + +// SetAdmin sets the Admin field. +// +// When the provided User type is nil, it +// will set nothing and immediately return. +func (u *User) SetAdmin(v bool) { + // return if User type is nil + if u == nil { + return + } + + u.Admin = &v +} + +// SetFavorites sets the Favorites field. +// +// When the provided User type is nil, it +// will set nothing and immediately return. +func (u *User) SetFavorites(v []string) { + // return if User type is nil + if u == nil { + return + } + + u.Favorites = &v +} + +// String implements the Stringer interface for the User type. +func (u *User) String() string { + return fmt.Sprintf(`{ + Active: %t, + Admin: %t, + Favorites: %s, + ID: %d, + Name: %s, + Token: %s, +}`, + u.GetActive(), + u.GetAdmin(), + u.GetFavorites(), + u.GetID(), + u.GetName(), + u.GetToken(), + ) +} diff --git a/api/types/user_test.go b/api/types/user_test.go new file mode 100644 index 000000000..de7c3575d --- /dev/null +++ b/api/types/user_test.go @@ -0,0 +1,194 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "fmt" + "reflect" + "testing" + + "github.com/go-vela/types/constants" +) + +func TestTypes_User_Sanitize(t *testing.T) { + // setup types + u := testUser() + + want := testUser() + want.SetToken(constants.SecretMask) + want.SetRefreshToken(constants.SecretMask) + + // run test + got := u.Sanitize() + + if !reflect.DeepEqual(got, want) { + t.Errorf("Sanitize is %v, want %v", got, want) + } +} + +func TestTypes_User_Environment(t *testing.T) { + // setup types + want := map[string]string{ + "VELA_USER_ACTIVE": "true", + "VELA_USER_ADMIN": "false", + "VELA_USER_FAVORITES": "[\"github/octocat\"]", + "VELA_USER_NAME": "octocat", + } + + // run test + got := testUser().Environment() + + if !reflect.DeepEqual(got, want) { + t.Errorf("Environment is %v, want %v", got, want) + } +} + +func TestTypes_User_Getters(t *testing.T) { + // setup tests + tests := []struct { + user *User + want *User + }{ + { + user: testUser(), + want: testUser(), + }, + { + user: new(User), + want: new(User), + }, + } + + // run tests + for _, test := range tests { + if test.user.GetID() != test.want.GetID() { + t.Errorf("GetID is %v, want %v", test.user.GetID(), test.want.GetID()) + } + + if test.user.GetName() != test.want.GetName() { + t.Errorf("GetName is %v, want %v", test.user.GetName(), test.want.GetName()) + } + + if test.user.GetRefreshToken() != test.want.GetRefreshToken() { + t.Errorf("GetRefreshToken is %v, want %v", test.user.GetRefreshToken(), test.want.GetRefreshToken()) + } + + if test.user.GetToken() != test.want.GetToken() { + t.Errorf("GetToken is %v, want %v", test.user.GetToken(), test.want.GetToken()) + } + + if !reflect.DeepEqual(test.user.GetFavorites(), test.want.GetFavorites()) { + t.Errorf("GetFavorites is %v, want %v", test.user.GetFavorites(), test.want.GetFavorites()) + } + + if test.user.GetActive() != test.want.GetActive() { + t.Errorf("GetActive is %v, want %v", test.user.GetActive(), test.want.GetActive()) + } + + if test.user.GetAdmin() != test.want.GetAdmin() { + t.Errorf("GetAdmin is %v, want %v", test.user.GetAdmin(), test.want.GetAdmin()) + } + } +} + +func TestTypes_User_Setters(t *testing.T) { + // setup types + var u *User + + // setup tests + tests := []struct { + user *User + want *User + }{ + { + user: testUser(), + want: testUser(), + }, + { + user: u, + want: new(User), + }, + } + + // run tests + for _, test := range tests { + test.user.SetID(test.want.GetID()) + test.user.SetName(test.want.GetName()) + test.user.SetRefreshToken(test.want.GetRefreshToken()) + test.user.SetToken(test.want.GetToken()) + test.user.SetFavorites(test.want.GetFavorites()) + test.user.SetActive(test.want.GetActive()) + test.user.SetAdmin(test.want.GetAdmin()) + + if test.user.GetID() != test.want.GetID() { + t.Errorf("SetID is %v, want %v", test.user.GetID(), test.want.GetID()) + } + + if test.user.GetName() != test.want.GetName() { + t.Errorf("SetName is %v, want %v", test.user.GetName(), test.want.GetName()) + } + + if test.user.GetRefreshToken() != test.want.GetRefreshToken() { + t.Errorf("SetRefreshToken is %v, want %v", test.user.GetRefreshToken(), test.want.GetRefreshToken()) + } + + if test.user.GetToken() != test.want.GetToken() { + t.Errorf("SetToken is %v, want %v", test.user.GetToken(), test.want.GetToken()) + } + + if !reflect.DeepEqual(test.user.GetFavorites(), test.want.GetFavorites()) { + t.Errorf("SetFavorites is %v, want %v", test.user.GetFavorites(), test.want.GetFavorites()) + } + + if test.user.GetActive() != test.want.GetActive() { + t.Errorf("SetActive is %v, want %v", test.user.GetActive(), test.want.GetActive()) + } + + if test.user.GetAdmin() != test.want.GetAdmin() { + t.Errorf("SetAdmin is %v, want %v", test.user.GetAdmin(), test.want.GetAdmin()) + } + } +} + +func TestTypes_User_String(t *testing.T) { + // setup types + u := testUser() + + want := fmt.Sprintf(`{ + Active: %t, + Admin: %t, + Favorites: %s, + ID: %d, + Name: %s, + Token: %s, +}`, + u.GetActive(), + u.GetAdmin(), + u.GetFavorites(), + u.GetID(), + u.GetName(), + u.GetToken(), + ) + + // run test + got := u.String() + + if !reflect.DeepEqual(got, want) { + t.Errorf("String is %v, want %v", got, want) + } +} + +// testUser is a test helper function to create a User +// type with all fields set to a fake value. +func testUser() *User { + u := new(User) + + u.SetID(1) + u.SetName("octocat") + u.SetToken("superSecretToken") + u.SetFavorites([]string{"github/octocat"}) + u.SetActive(true) + u.SetAdmin(false) + + return u +} diff --git a/api/user/create.go b/api/user/create.go index 43d7037bc..cd68556bf 100644 --- a/api/user/create.go +++ b/api/user/create.go @@ -9,10 +9,10 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/go-vela/types/library" ) // swagger:operation POST /api/v1/users users CreateUser @@ -53,7 +53,7 @@ func CreateUser(c *gin.Context) { ctx := c.Request.Context() // capture body from API request - input := new(library.User) + input := new(types.User) err := c.Bind(input) if err != nil { diff --git a/api/user/update.go b/api/user/update.go index 09767d94c..caec2ac08 100644 --- a/api/user/update.go +++ b/api/user/update.go @@ -9,10 +9,10 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/go-vela/types/library" ) // swagger:operation PUT /api/v1/users/{user} users UpdateUser @@ -70,7 +70,7 @@ func UpdateUser(c *gin.Context) { }).Infof("updating user %s", user) // capture body from API request - input := new(library.User) + input := new(types.User) err := c.Bind(input) if err != nil { diff --git a/api/user/update_current.go b/api/user/update_current.go index bd3cb9a85..792105a48 100644 --- a/api/user/update_current.go +++ b/api/user/update_current.go @@ -9,10 +9,10 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/go-vela/types/library" ) // swagger:operation PUT /api/v1/user users UpdateCurrentUser @@ -64,7 +64,7 @@ func UpdateCurrentUser(c *gin.Context) { }).Infof("updating current user %s", u.GetName()) // capture body from API request - input := new(library.User) + input := new(types.User) err := c.Bind(input) if err != nil { diff --git a/compiler/engine.go b/compiler/engine.go index 6ed310451..137d9000a 100644 --- a/compiler/engine.go +++ b/compiler/engine.go @@ -140,7 +140,7 @@ type Engine interface { WithRepo(*api.Repo) Engine // WithUser defines a function that sets // the library user type in the Engine. - WithUser(*library.User) Engine + WithUser(*api.User) Engine // WithLabel defines a function that sets // the label(s) in the Engine. WithLabels([]string) Engine diff --git a/compiler/native/environment.go b/compiler/native/environment.go index b6d9571b0..8b7972877 100644 --- a/compiler/native/environment.go +++ b/compiler/native/environment.go @@ -282,7 +282,7 @@ func appendMap(originalMap, otherMap map[string]string) map[string]string { } // helper function that creates the standard set of environment variables for a pipeline. -func environment(b *library.Build, m *internal.Metadata, r *api.Repo, u *library.User) map[string]string { +func environment(b *library.Build, m *internal.Metadata, r *api.Repo, u *api.User) map[string]string { // set default workspace workspace := constants.WorkspaceDefault notImplemented := "TODO" diff --git a/compiler/native/environment_test.go b/compiler/native/environment_test.go index 2d715ae8a..e41e02be4 100644 --- a/compiler/native/environment_test.go +++ b/compiler/native/environment_test.go @@ -580,7 +580,7 @@ func TestNative_environment(t *testing.T) { b *library.Build m *internal.Metadata r *api.Repo - u *library.User + u *api.User want map[string]string }{ // push @@ -588,8 +588,8 @@ func TestNative_environment(t *testing.T) { w: workspace, b: &library.Build{ID: &num64, RepoID: &num64, Number: &num, Parent: &num, Event: &push, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &str, BaseRef: &str}, m: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, - r: &api.Repo{ID: &num64, Owner: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, - u: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, + r: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, + u: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, want: map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "push", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "foo", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "push", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "foo", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_OWNER": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, }, // tag @@ -597,8 +597,8 @@ func TestNative_environment(t *testing.T) { w: workspace, b: &library.Build{ID: &num64, RepoID: &num64, Number: &num, Parent: &num, Event: &tag, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &tagref, BaseRef: &str}, m: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, - r: &api.Repo{ID: &num64, Owner: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, - u: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, + r: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, + u: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, want: map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "tag", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "refs/tags/1", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TAG": "1", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "tag", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "refs/tags/1", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TAG": "1", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_OWNER": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, }, // pull_request @@ -606,8 +606,8 @@ func TestNative_environment(t *testing.T) { w: workspace, b: &library.Build{ID: &num64, RepoID: &num64, Number: &num, Parent: &num, Event: &pull, EventAction: &pullact, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &pullref, BaseRef: &str}, m: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, - r: &api.Repo{ID: &num64, Owner: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, - u: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, + r: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, + u: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, want: map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "pull_request", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_PULL_REQUEST_NUMBER": "1", "BUILD_REF": "refs/pull/1/head", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "pull_request", "VELA_BUILD_EVENT_ACTION": "opened", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_PULL_REQUEST": "1", "VELA_BUILD_REF": "refs/pull/1/head", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_PULL_REQUEST": "1", "VELA_PULL_REQUEST_SOURCE": "", "VELA_PULL_REQUEST_TARGET": "foo", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_OWNER": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, }, // deployment @@ -615,8 +615,8 @@ func TestNative_environment(t *testing.T) { w: workspace, b: &library.Build{ID: &num64, RepoID: &num64, Number: &num, Parent: &num, Event: &deploy, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &target, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &pullref, BaseRef: &str}, m: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, - r: &api.Repo{ID: &num64, Owner: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, - u: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, + r: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, + u: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, want: map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "deployment", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "refs/pull/1/head", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TARGET": "production", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "deployment", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "refs/pull/1/head", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TARGET": "production", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DEPLOYMENT": "production", "VELA_DEPLOYMENT_NUMBER": "0", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_OWNER": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, }, } @@ -693,7 +693,7 @@ func Test_client_EnvironmentBuild(t *testing.T) { build *library.Build metadata *internal.Metadata repo *api.Repo - user *library.User + user *api.User } tests := []struct { @@ -704,28 +704,28 @@ func Test_client_EnvironmentBuild(t *testing.T) { {"push", fields{ build: &library.Build{ID: &num64, RepoID: &num64, Number: &num, Parent: &num, Event: &push, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &str, BaseRef: &str}, metadata: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, - repo: &api.Repo{ID: &num64, Owner: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, - user: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, + repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, + user: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "push", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "foo", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "push", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "foo", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_OWNER": "foo", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}}, {"tag", fields{ build: &library.Build{ID: &num64, RepoID: &num64, Number: &num, Parent: &num, Event: &tag, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &tagref, BaseRef: &str}, metadata: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, - repo: &api.Repo{ID: &num64, Owner: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, - user: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, + repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, + user: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "tag", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "refs/tags/1", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TAG": "1", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "tag", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "refs/tags/1", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TAG": "1", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_OWNER": "foo", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, }, {"pull_request", fields{ build: &library.Build{ID: &num64, RepoID: &num64, Number: &num, Parent: &num, Event: &pull, EventAction: &pullact, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &pullref, BaseRef: &str}, metadata: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, - repo: &api.Repo{ID: &num64, Owner: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, - user: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, + repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, + user: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "pull_request", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_PULL_REQUEST_NUMBER": "1", "BUILD_REF": "refs/pull/1/head", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "pull_request", "VELA_BUILD_EVENT_ACTION": "opened", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_PULL_REQUEST": "1", "VELA_BUILD_REF": "refs/pull/1/head", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_PULL_REQUEST": "1", "VELA_PULL_REQUEST_SOURCE": "", "VELA_PULL_REQUEST_TARGET": "foo", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_OWNER": "foo", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, }, {"deployment", fields{ build: &library.Build{ID: &num64, RepoID: &num64, Number: &num, Parent: &num, Event: &deploy, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &target, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &pullref, BaseRef: &str}, metadata: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, - repo: &api.Repo{ID: &num64, Owner: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, - user: &library.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, + repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, + user: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "deployment", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "refs/pull/1/head", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TARGET": "production", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "deployment", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "refs/pull/1/head", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TARGET": "production", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DEPLOYMENT": "production", "VELA_DEPLOYMENT_NUMBER": "0", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_OWNER": "foo", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, }, } diff --git a/compiler/native/native.go b/compiler/native/native.go index b4b756c52..b92cfd2ea 100644 --- a/compiler/native/native.go +++ b/compiler/native/native.go @@ -40,7 +40,7 @@ type client struct { localTemplates []string metadata *internal.Metadata repo *api.Repo - user *library.User + user *api.User labels []string } @@ -203,7 +203,7 @@ func (c *client) WithRepo(r *api.Repo) compiler.Engine { } // WithUser sets the library user type in the Engine. -func (c *client) WithUser(u *library.User) compiler.Engine { +func (c *client) WithUser(u *api.User) compiler.Engine { if u != nil { c.user = u } diff --git a/compiler/native/native_test.go b/compiler/native/native_test.go index a426aa3e9..5e84a6664 100644 --- a/compiler/native/native_test.go +++ b/compiler/native/native_test.go @@ -313,7 +313,7 @@ func TestNative_WithUser(t *testing.T) { c := cli.NewContext(nil, set, nil) id := int64(1) - u := &library.User{ID: &id} + u := &api.User{ID: &id} want, _ := New(c) want.user = u diff --git a/compiler/registry/github/template.go b/compiler/registry/github/template.go index f0e26e489..258c1ea95 100644 --- a/compiler/registry/github/template.go +++ b/compiler/registry/github/template.go @@ -9,12 +9,12 @@ import ( "github.com/google/go-github/v61/github" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/compiler/registry" - "github.com/go-vela/types/library" ) // Template captures the templated pipeline configuration from the GitHub repo. -func (c *client) Template(u *library.User, s *registry.Source) ([]byte, error) { +func (c *client) Template(u *api.User, s *registry.Source) ([]byte, error) { // use default GitHub OAuth client we provide cli := c.Github if u != nil { diff --git a/compiler/registry/github/template_test.go b/compiler/registry/github/template_test.go index 9e2ce6562..e6b3f2696 100644 --- a/compiler/registry/github/template_test.go +++ b/compiler/registry/github/template_test.go @@ -11,8 +11,8 @@ import ( "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/compiler/registry" - "github.com/go-vela/types/library" ) func TestGithub_Template(t *testing.T) { @@ -35,7 +35,7 @@ func TestGithub_Template(t *testing.T) { // setup types str := "foo" - u := &library.User{ + u := &api.User{ Name: &str, Token: &str, } @@ -96,7 +96,7 @@ func TestGithub_TemplateSourceRef(t *testing.T) { // setup types str := "foo" - u := &library.User{ + u := &api.User{ Name: &str, Token: &str, } @@ -162,7 +162,7 @@ func TestGithub_TemplateEmptySourceRef(t *testing.T) { // setup types str := "foo" - u := &library.User{ + u := &api.User{ Name: &str, Token: &str, } @@ -221,7 +221,7 @@ func TestGithub_Template_BadRequest(t *testing.T) { // setup types str := "foo" - u := &library.User{ + u := &api.User{ Name: &str, Token: &str, } @@ -271,7 +271,7 @@ func TestGithub_Template_NotFound(t *testing.T) { // setup types str := "foo" - u := &library.User{ + u := &api.User{ Name: &str, Token: &str, } diff --git a/compiler/registry/registry.go b/compiler/registry/registry.go index 2ea9caffe..e3116f979 100644 --- a/compiler/registry/registry.go +++ b/compiler/registry/registry.go @@ -2,7 +2,9 @@ package registry -import "github.com/go-vela/types/library" +import ( + api "github.com/go-vela/server/api/types" +) // Service represents the interface for Vela integrating // with the different supported template registries. @@ -13,5 +15,5 @@ type Service interface { // Template defines a function that captures the // templated pipeline configuration from a repo. - Template(*library.User, *Source) ([]byte, error) + Template(*api.User, *Source) ([]byte, error) } diff --git a/database/integration_test.go b/database/integration_test.go index e7cf44571..9019c0d2b 100644 --- a/database/integration_test.go +++ b/database/integration_test.go @@ -44,7 +44,7 @@ type Resources struct { Secrets []*library.Secret Services []*library.Service Steps []*library.Step - Users []*library.User + Users []*api.User Workers []*api.Worker } @@ -1811,27 +1811,25 @@ func testUsers(t *testing.T, db Interface, resources *Resources) { methods[element.Method(i).Name] = false } - userOne := new(library.User) + userOne := new(api.User) userOne.SetID(1) userOne.SetName("octocat") userOne.SetToken("") userOne.SetRefreshToken("") - userOne.SetHash("") userOne.SetFavorites(nil) userOne.SetActive(false) userOne.SetAdmin(false) - userTwo := new(library.User) + userTwo := new(api.User) userTwo.SetID(2) userTwo.SetName("octokitty") userTwo.SetToken("") userTwo.SetRefreshToken("") - userTwo.SetHash("") userTwo.SetFavorites(nil) userTwo.SetActive(false) userTwo.SetAdmin(false) - liteUsers := []*library.User{userOne, userTwo} + liteUsers := []*api.User{userOne, userTwo} // create the users for _, user := range resources.Users { @@ -2238,22 +2236,20 @@ func newResources() *Resources { pipelineTwo.SetTemplates(false) pipelineTwo.SetData([]byte("version: 1")) - userOne := new(library.User) + userOne := new(api.User) userOne.SetID(1) userOne.SetName("octocat") userOne.SetToken("superSecretToken") userOne.SetRefreshToken("superSecretRefreshToken") - userOne.SetHash("MzM4N2MzMDAtNmY4Mi00OTA5LWFhZDAtNWIzMTlkNTJkODMy") userOne.SetFavorites([]string{"github/octocat"}) userOne.SetActive(true) userOne.SetAdmin(false) - userTwo := new(library.User) + userTwo := new(api.User) userTwo.SetID(2) userTwo.SetName("octokitty") userTwo.SetToken("superSecretToken") userTwo.SetRefreshToken("superSecretRefreshToken") - userTwo.SetHash("MzM4N2MzMDAtNmY4Mi00OTA5LWFhZDAtNWIzMTlkNTJkODMy") userTwo.SetFavorites([]string{"github/octocat"}) userTwo.SetActive(true) userTwo.SetAdmin(false) @@ -2499,7 +2495,7 @@ func newResources() *Resources { Secrets: []*library.Secret{secretOrg, secretRepo, secretShared}, Services: []*library.Service{serviceOne, serviceTwo}, Steps: []*library.Step{stepOne, stepTwo}, - Users: []*library.User{userOne, userTwo}, + Users: []*api.User{userOne, userTwo}, Workers: []*api.Worker{workerOne, workerTwo}, } } diff --git a/database/repo/count_org_test.go b/database/repo/count_org_test.go index e77b39e28..650770e4a 100644 --- a/database/repo/count_org_test.go +++ b/database/repo/count_org_test.go @@ -12,7 +12,7 @@ import ( func TestRepo_Engine_CountReposForOrg(t *testing.T) { // setup types - _repoOne := testRepo() + _repoOne := testAPIRepo() _repoOne.SetID(1) _repoOne.GetOwner().SetID(1) _repoOne.SetHash("baz") @@ -21,7 +21,7 @@ func TestRepo_Engine_CountReposForOrg(t *testing.T) { _repoOne.SetFullName("foo/bar") _repoOne.SetVisibility("public") - _repoTwo := testRepo() + _repoTwo := testAPIRepo() _repoTwo.SetID(2) _repoTwo.GetOwner().SetID(1) _repoTwo.SetHash("baz") diff --git a/database/repo/count_test.go b/database/repo/count_test.go index 522779f92..f295d885e 100644 --- a/database/repo/count_test.go +++ b/database/repo/count_test.go @@ -12,7 +12,7 @@ import ( func TestRepo_Engine_CountRepos(t *testing.T) { // setup types - _repoOne := testRepo() + _repoOne := testAPIRepo() _repoOne.SetID(1) _repoOne.GetOwner().SetID(1) _repoOne.SetHash("baz") @@ -21,7 +21,7 @@ func TestRepo_Engine_CountRepos(t *testing.T) { _repoOne.SetFullName("foo/bar") _repoOne.SetVisibility("public") - _repoTwo := testRepo() + _repoTwo := testAPIRepo() _repoTwo.SetID(2) _repoTwo.GetOwner().SetID(1) _repoTwo.SetHash("baz") diff --git a/database/repo/count_user.go b/database/repo/count_user.go index 20963a311..b8ba89a12 100644 --- a/database/repo/count_user.go +++ b/database/repo/count_user.go @@ -7,12 +7,12 @@ import ( "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" ) // CountReposForUser gets the count of repos by user ID from the database. -func (e *engine) CountReposForUser(ctx context.Context, u *library.User, filters map[string]interface{}) (int64, error) { +func (e *engine) CountReposForUser(ctx context.Context, u *api.User, filters map[string]interface{}) (int64, error) { e.logger.WithFields(logrus.Fields{ "user": u.GetName(), }).Tracef("getting count of repos for user %s from the database", u.GetName()) diff --git a/database/repo/count_user_test.go b/database/repo/count_user_test.go index 0fff8c479..10d238c39 100644 --- a/database/repo/count_user_test.go +++ b/database/repo/count_user_test.go @@ -9,12 +9,12 @@ import ( "github.com/DATA-DOG/go-sqlmock" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" ) func TestRepo_Engine_CountReposForUser(t *testing.T) { // setup types - _repoOne := testRepo() + _repoOne := testAPIRepo() _repoOne.SetID(1) _repoOne.GetOwner().SetID(1) _repoOne.SetHash("baz") @@ -23,7 +23,7 @@ func TestRepo_Engine_CountReposForUser(t *testing.T) { _repoOne.SetFullName("foo/bar") _repoOne.SetVisibility("public") - _repoTwo := testRepo() + _repoTwo := testAPIRepo() _repoTwo.SetID(2) _repoTwo.GetOwner().SetID(1) _repoTwo.SetHash("baz") @@ -32,7 +32,7 @@ func TestRepo_Engine_CountReposForUser(t *testing.T) { _repoTwo.SetFullName("bar/foo") _repoTwo.SetVisibility("public") - _user := new(library.User) + _user := new(api.User) _user.SetID(1) _user.SetName("foo") _user.SetToken("bar") diff --git a/database/repo/create_test.go b/database/repo/create_test.go index ddd3d209d..67371ec5b 100644 --- a/database/repo/create_test.go +++ b/database/repo/create_test.go @@ -12,7 +12,7 @@ import ( func TestRepo_Engine_CreateRepo(t *testing.T) { // setup types - _repo := testRepo() + _repo := testAPIRepo() _repo.SetID(1) _repo.GetOwner().SetID(1) _repo.SetHash("baz") diff --git a/database/repo/delete_test.go b/database/repo/delete_test.go index 34038d5fc..8829da36e 100644 --- a/database/repo/delete_test.go +++ b/database/repo/delete_test.go @@ -11,7 +11,7 @@ import ( func TestRepo_Engine_DeleteRepo(t *testing.T) { // setup types - _repo := testRepo() + _repo := testAPIRepo() _repo.SetID(1) _repo.GetOwner().SetID(1) _repo.SetHash("baz") diff --git a/database/repo/get_org_test.go b/database/repo/get_org_test.go index 327201876..f864cc78a 100644 --- a/database/repo/get_org_test.go +++ b/database/repo/get_org_test.go @@ -10,13 +10,14 @@ import ( "github.com/google/go-cmp/cmp" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/user" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" ) func TestRepo_Engine_GetRepoForOrg(t *testing.T) { // setup types - _repo := testRepo() + _repo := testAPIRepo() _repo.SetID(1) _repo.SetHash("baz") _repo.SetOrg("foo") @@ -31,7 +32,6 @@ func TestRepo_Engine_GetRepoForOrg(t *testing.T) { _owner.SetID(1) _owner.SetName("foo") _owner.SetToken("bar") - _owner.SetHash("baz") _repo.SetOwner(_owner) @@ -64,7 +64,7 @@ func TestRepo_Engine_GetRepoForOrg(t *testing.T) { t.Errorf("unable to create build table for sqlite: %v", err) } - err = _sqlite.client.Table(constants.TableUser).Create(database.UserFromLibrary(_owner)).Error + err = _sqlite.client.Table(constants.TableUser).Create(user.FromAPI(_owner)).Error if err != nil { t.Errorf("unable to create test user for sqlite: %v", err) } diff --git a/database/repo/get_test.go b/database/repo/get_test.go index 600f2a830..eeb37b1bd 100644 --- a/database/repo/get_test.go +++ b/database/repo/get_test.go @@ -10,13 +10,14 @@ import ( "github.com/DATA-DOG/go-sqlmock" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/user" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" ) func TestRepo_Engine_GetRepo(t *testing.T) { // setup types - _repo := testRepo() + _repo := testAPIRepo() _repo.SetID(1) _repo.SetHash("baz") _repo.SetOrg("foo") @@ -31,7 +32,6 @@ func TestRepo_Engine_GetRepo(t *testing.T) { _owner.SetID(1) _owner.SetName("foo") _owner.SetToken("bar") - _owner.SetHash("baz") _repo.SetOwner(_owner) @@ -64,7 +64,7 @@ func TestRepo_Engine_GetRepo(t *testing.T) { t.Errorf("unable to create build table for sqlite: %v", err) } - err = _sqlite.client.Table(constants.TableUser).Create(database.UserFromLibrary(_owner)).Error + err = _sqlite.client.Table(constants.TableUser).Create(user.FromAPI(_owner)).Error if err != nil { t.Errorf("unable to create test user for sqlite: %v", err) } diff --git a/database/repo/interface.go b/database/repo/interface.go index f73a085b4..8c4a4e466 100644 --- a/database/repo/interface.go +++ b/database/repo/interface.go @@ -6,7 +6,6 @@ import ( "context" api "github.com/go-vela/server/api/types" - "github.com/go-vela/types/library" ) // RepoInterface represents the Vela interface for repo @@ -32,7 +31,7 @@ type RepoInterface interface { // CountReposForOrg defines a function that gets the count of repos by org name. CountReposForOrg(context.Context, string, map[string]interface{}) (int64, error) // CountReposForUser defines a function that gets the count of repos by user ID. - CountReposForUser(context.Context, *library.User, map[string]interface{}) (int64, error) + CountReposForUser(context.Context, *api.User, map[string]interface{}) (int64, error) // CreateRepo defines a function that creates a new repo. CreateRepo(context.Context, *api.Repo) (*api.Repo, error) // DeleteRepo defines a function that deletes an existing repo. @@ -46,7 +45,7 @@ type RepoInterface interface { // ListReposForOrg defines a function that gets a list of repos by org name. ListReposForOrg(context.Context, string, string, map[string]interface{}, int, int) ([]*api.Repo, int64, error) // ListReposForUser defines a function that gets a list of repos by user ID. - ListReposForUser(context.Context, *library.User, string, map[string]interface{}, int, int) ([]*api.Repo, int64, error) + ListReposForUser(context.Context, *api.User, string, map[string]interface{}, int, int) ([]*api.Repo, int64, error) // UpdateRepo defines a function that updates an existing repo. UpdateRepo(context.Context, *api.Repo) (*api.Repo, error) } diff --git a/database/repo/list_org_test.go b/database/repo/list_org_test.go index ca93ca17e..fb3414ed6 100644 --- a/database/repo/list_org_test.go +++ b/database/repo/list_org_test.go @@ -11,6 +11,7 @@ import ( "github.com/google/go-cmp/cmp" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/user" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" @@ -30,7 +31,7 @@ func TestRepo_Engine_ListReposForOrg(t *testing.T) { _buildTwo.SetNumber(1) _buildTwo.SetCreated(time.Now().UTC().Unix()) - _repoOne := testRepo() + _repoOne := testAPIRepo() _repoOne.SetID(1) _repoOne.SetHash("baz") _repoOne.SetOrg("foo") @@ -41,7 +42,7 @@ func TestRepo_Engine_ListReposForOrg(t *testing.T) { _repoOne.SetTopics([]string{}) _repoOne.SetAllowEvents(api.NewEventsFromMask(1)) - _repoTwo := testRepo() + _repoTwo := testAPIRepo() _repoTwo.SetID(2) _repoTwo.SetHash("bar") _repoTwo.SetOrg("foo") @@ -56,7 +57,6 @@ func TestRepo_Engine_ListReposForOrg(t *testing.T) { _owner.SetID(1) _owner.SetName("foo") _owner.SetToken("bar") - _owner.SetHash("baz") _repoOne.SetOwner(_owner) _repoTwo.SetOwner(_owner) @@ -137,7 +137,7 @@ func TestRepo_Engine_ListReposForOrg(t *testing.T) { t.Errorf("unable to create build table for sqlite: %v", err) } - err = _sqlite.client.Table(constants.TableUser).Create(database.UserFromLibrary(_owner)).Error + err = _sqlite.client.Table(constants.TableUser).Create(user.FromAPI(_owner)).Error if err != nil { t.Errorf("unable to create test user for sqlite: %v", err) } diff --git a/database/repo/list_test.go b/database/repo/list_test.go index 68d426897..81b7f33fb 100644 --- a/database/repo/list_test.go +++ b/database/repo/list_test.go @@ -10,13 +10,14 @@ import ( "github.com/DATA-DOG/go-sqlmock" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/user" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" ) func TestRepo_Engine_ListRepos(t *testing.T) { // setup types - _repoOne := testRepo() + _repoOne := testAPIRepo() _repoOne.SetID(1) _repoOne.SetHash("baz") _repoOne.SetOrg("foo") @@ -27,7 +28,7 @@ func TestRepo_Engine_ListRepos(t *testing.T) { _repoOne.SetTopics([]string{}) _repoOne.SetAllowEvents(api.NewEventsFromMask(1)) - _repoTwo := testRepo() + _repoTwo := testAPIRepo() _repoTwo.SetID(2) _repoTwo.SetHash("baz") _repoTwo.SetOrg("bar") @@ -42,7 +43,6 @@ func TestRepo_Engine_ListRepos(t *testing.T) { _owner.SetID(1) _owner.SetName("foo") _owner.SetToken("bar") - _owner.SetHash("baz") _repoOne.SetOwner(_owner) _repoTwo.SetOwner(_owner) @@ -88,7 +88,7 @@ func TestRepo_Engine_ListRepos(t *testing.T) { t.Errorf("unable to create build table for sqlite: %v", err) } - err = _sqlite.client.Table(constants.TableUser).Create(database.UserFromLibrary(_owner)).Error + err = _sqlite.client.Table(constants.TableUser).Create(user.FromAPI(_owner)).Error if err != nil { t.Errorf("unable to create test user for sqlite: %v", err) } diff --git a/database/repo/list_user.go b/database/repo/list_user.go index 75e1904c8..1f1c709a1 100644 --- a/database/repo/list_user.go +++ b/database/repo/list_user.go @@ -9,13 +9,12 @@ import ( api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" ) // ListReposForUser gets a list of repos by user ID from the database. // //nolint:lll // ignore long line length due to variable names -func (e *engine) ListReposForUser(ctx context.Context, u *library.User, sortBy string, filters map[string]interface{}, page, perPage int) ([]*api.Repo, int64, error) { +func (e *engine) ListReposForUser(ctx context.Context, u *api.User, sortBy string, filters map[string]interface{}, page, perPage int) ([]*api.Repo, int64, error) { e.logger.WithFields(logrus.Fields{ "user": u.GetName(), }).Tracef("listing repos for user %s from the database", u.GetName()) diff --git a/database/repo/list_user_test.go b/database/repo/list_user_test.go index 49db2638e..cc82ea5fd 100644 --- a/database/repo/list_user_test.go +++ b/database/repo/list_user_test.go @@ -11,6 +11,7 @@ import ( "github.com/DATA-DOG/go-sqlmock" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/user" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" @@ -30,7 +31,7 @@ func TestRepo_Engine_ListReposForUser(t *testing.T) { _buildTwo.SetNumber(1) _buildTwo.SetCreated(time.Now().UTC().Unix()) - _repoOne := testRepo() + _repoOne := testAPIRepo() _repoOne.SetID(1) _repoOne.GetOwner().SetID(1) _repoOne.SetHash("baz") @@ -42,7 +43,7 @@ func TestRepo_Engine_ListReposForUser(t *testing.T) { _repoOne.SetTopics([]string{}) _repoOne.SetAllowEvents(api.NewEventsFromMask(1)) - _repoTwo := testRepo() + _repoTwo := testAPIRepo() _repoTwo.SetID(2) _repoTwo.GetOwner().SetID(1) _repoTwo.SetHash("baz") @@ -58,7 +59,6 @@ func TestRepo_Engine_ListReposForUser(t *testing.T) { _owner.SetID(1) _owner.SetName("foo") _owner.SetToken("bar") - _owner.SetHash("baz") _repoOne.SetOwner(_owner) _repoTwo.SetOwner(_owner) @@ -139,7 +139,7 @@ func TestRepo_Engine_ListReposForUser(t *testing.T) { t.Errorf("unable to create build table for sqlite: %v", err) } - err = _sqlite.client.Table(constants.TableUser).Create(database.UserFromLibrary(_owner)).Error + err = _sqlite.client.Table(constants.TableUser).Create(user.FromAPI(_owner)).Error if err != nil { t.Errorf("unable to create test user for sqlite: %v", err) } diff --git a/database/repo/repo.go b/database/repo/repo.go index 1e920f181..ad892ba52 100644 --- a/database/repo/repo.go +++ b/database/repo/repo.go @@ -14,9 +14,9 @@ import ( "gorm.io/gorm" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/user" "github.com/go-vela/server/util" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" ) var ( @@ -100,7 +100,7 @@ type ( PreviousName sql.NullString `sql:"previous_name"` ApproveBuild sql.NullString `sql:"approve_build"` - Owner database.User `gorm:"foreignKey:UserID"` + Owner user.User `gorm:"foreignKey:UserID"` } ) @@ -293,7 +293,7 @@ func (r *Repo) ToAPI() *api.Repo { repo := new(api.Repo) repo.SetID(r.ID.Int64) - repo.SetOwner(r.Owner.ToLibrary()) + repo.SetOwner(r.Owner.ToAPI()) repo.SetHash(r.Hash.String) repo.SetOrg(r.Org.String) repo.SetName(r.Name.String) diff --git a/database/repo/repo_test.go b/database/repo/repo_test.go index 5de5f9177..e8de73915 100644 --- a/database/repo/repo_test.go +++ b/database/repo/repo_test.go @@ -3,11 +3,13 @@ package repo import ( + "database/sql" "database/sql/driver" "reflect" "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/google/go-cmp/cmp" "github.com/sirupsen/logrus" "gorm.io/driver/postgres" "gorm.io/driver/sqlite" @@ -15,7 +17,7 @@ import ( api "github.com/go-vela/server/api/types" "github.com/go-vela/server/api/types/actions" - "github.com/go-vela/types/library" + "github.com/go-vela/types/constants" ) func TestRepo_New(t *testing.T) { @@ -172,9 +174,9 @@ func testSqlite(t *testing.T) *engine { return _engine } -// testRepo is a test helper function to create an API +// testAPIRepo is a test helper function to create an API // Repo type with all fields set to their zero values. -func testRepo() *api.Repo { +func testAPIRepo() *api.Repo { return &api.Repo{ ID: new(int64), Owner: testOwner(), @@ -228,13 +230,12 @@ func testEvents() *api.Events { } } -func testOwner() *library.User { - return &library.User{ +func testOwner() *api.User { + return &api.User{ ID: new(int64), Name: new(string), RefreshToken: new(string), Token: new(string), - Hash: new(string), Favorites: new([]string), Active: new(bool), Admin: new(bool), @@ -252,3 +253,362 @@ type AnyArgument struct{} func (a AnyArgument) Match(_ driver.Value) bool { return true } + +func TestRepo_Decrypt(t *testing.T) { + // setup types + key := "C639A572E14D5075C526FDDD43E4ECF6" + encrypted := testRepo() + + err := encrypted.Encrypt(key) + if err != nil { + t.Errorf("unable to encrypt repo: %v", err) + } + + // setup tests + tests := []struct { + failure bool + key string + repo Repo + }{ + { + failure: false, + key: key, + repo: *encrypted, + }, + { + failure: true, + key: "", + repo: *encrypted, + }, + { + failure: true, + key: key, + repo: *testRepo(), + }, + } + + // run tests + for _, test := range tests { + err := test.repo.Decrypt(test.key) + + if test.failure { + if err == nil { + t.Errorf("Decrypt should have returned err") + } + + continue + } + + if err != nil { + t.Errorf("Decrypt returned err: %v", err) + } + } +} + +func TestRepo_Encrypt(t *testing.T) { + // setup types + key := "C639A572E14D5075C526FDDD43E4ECF6" + + // setup tests + tests := []struct { + failure bool + key string + repo *Repo + }{ + { + failure: false, + key: key, + repo: testRepo(), + }, + { + failure: true, + key: "", + repo: testRepo(), + }, + } + + // run tests + for _, test := range tests { + err := test.repo.Encrypt(test.key) + + if test.failure { + if err == nil { + t.Errorf("Encrypt should have returned err") + } + + continue + } + + if err != nil { + t.Errorf("Encrypt returned err: %v", err) + } + } +} + +func TestRepo_Nullify(t *testing.T) { + // setup types + var r *Repo + + want := &Repo{ + ID: sql.NullInt64{Int64: 0, Valid: false}, + UserID: sql.NullInt64{Int64: 0, Valid: false}, + Hash: sql.NullString{String: "", Valid: false}, + Org: sql.NullString{String: "", Valid: false}, + Name: sql.NullString{String: "", Valid: false}, + FullName: sql.NullString{String: "", Valid: false}, + Link: sql.NullString{String: "", Valid: false}, + Clone: sql.NullString{String: "", Valid: false}, + Branch: sql.NullString{String: "", Valid: false}, + Timeout: sql.NullInt64{Int64: 0, Valid: false}, + AllowEvents: sql.NullInt64{Int64: 0, Valid: false}, + Visibility: sql.NullString{String: "", Valid: false}, + PipelineType: sql.NullString{String: "", Valid: false}, + ApproveBuild: sql.NullString{String: "", Valid: false}, + } + + // setup tests + tests := []struct { + repo *Repo + want *Repo + }{ + { + repo: testRepo(), + want: testRepo(), + }, + { + repo: r, + want: nil, + }, + { + repo: new(Repo), + want: want, + }, + } + + // run tests + for _, test := range tests { + got := test.repo.Nullify() + + if !reflect.DeepEqual(got, test.want) { + t.Errorf("Nullify is %v, want %v", got, test.want) + } + } +} + +func TestRepo_ToAPI(t *testing.T) { + // setup types + want := new(api.Repo) + e := api.NewEventsFromMask(1) + owner := testOwner() + + want.SetID(1) + want.SetOwner(owner) + want.SetHash("superSecretHash") + want.SetOrg("github") + want.SetName("octocat") + want.SetFullName("github/octocat") + want.SetLink("https://github.com/github/octocat") + want.SetClone("https://github.com/github/octocat.git") + want.SetBranch("main") + want.SetTopics([]string{"cloud", "security"}) + want.SetBuildLimit(10) + want.SetTimeout(30) + want.SetCounter(0) + want.SetVisibility("public") + want.SetPrivate(false) + want.SetTrusted(false) + want.SetActive(true) + want.SetAllowEvents(e) + want.SetPipelineType("yaml") + want.SetPreviousName("oldName") + want.SetApproveBuild(constants.ApproveNever) + + // run test + got := testRepo().ToAPI() + + if !reflect.DeepEqual(got, want) { + t.Errorf("ToAPI is %v, want %v", got, want) + } +} + +func TestRepo_Validate(t *testing.T) { + // setup types + topics := []string{} + longTopic := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + + for len(topics) < 21 { + topics = append(topics, longTopic) + } + + // setup tests + tests := []struct { + failure bool + repo *Repo + }{ + { + failure: false, + repo: testRepo(), + }, + { // no user_id set for repo + failure: true, + repo: &Repo{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + Hash: sql.NullString{String: "superSecretHash", Valid: true}, + Org: sql.NullString{String: "github", Valid: true}, + Name: sql.NullString{String: "octocat", Valid: true}, + FullName: sql.NullString{String: "github/octocat", Valid: true}, + Visibility: sql.NullString{String: "public", Valid: true}, + }, + }, + { // no hash set for repo + failure: true, + repo: &Repo{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + UserID: sql.NullInt64{Int64: 1, Valid: true}, + Org: sql.NullString{String: "github", Valid: true}, + Name: sql.NullString{String: "octocat", Valid: true}, + FullName: sql.NullString{String: "github/octocat", Valid: true}, + Visibility: sql.NullString{String: "public", Valid: true}, + }, + }, + { // no org set for repo + failure: true, + repo: &Repo{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + UserID: sql.NullInt64{Int64: 1, Valid: true}, + Hash: sql.NullString{String: "superSecretHash", Valid: true}, + Name: sql.NullString{String: "octocat", Valid: true}, + FullName: sql.NullString{String: "github/octocat", Valid: true}, + Visibility: sql.NullString{String: "public", Valid: true}, + }, + }, + { // no name set for repo + failure: true, + repo: &Repo{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + UserID: sql.NullInt64{Int64: 1, Valid: true}, + Hash: sql.NullString{String: "superSecretHash", Valid: true}, + Org: sql.NullString{String: "github", Valid: true}, + FullName: sql.NullString{String: "github/octocat", Valid: true}, + Visibility: sql.NullString{String: "public", Valid: true}, + }, + }, + { // no full_name set for repo + failure: true, + repo: &Repo{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + UserID: sql.NullInt64{Int64: 1, Valid: true}, + Hash: sql.NullString{String: "superSecretHash", Valid: true}, + Org: sql.NullString{String: "github", Valid: true}, + Name: sql.NullString{String: "octocat", Valid: true}, + Visibility: sql.NullString{String: "public", Valid: true}, + }, + }, + { // no visibility set for repo + failure: true, + repo: &Repo{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + UserID: sql.NullInt64{Int64: 1, Valid: true}, + Hash: sql.NullString{String: "superSecretHash", Valid: true}, + Org: sql.NullString{String: "github", Valid: true}, + Name: sql.NullString{String: "octocat", Valid: true}, + FullName: sql.NullString{String: "github/octocat", Valid: true}, + }, + }, + { // topics exceed max size + failure: true, + repo: &Repo{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + UserID: sql.NullInt64{Int64: 1, Valid: true}, + Hash: sql.NullString{String: "superSecretHash", Valid: true}, + Org: sql.NullString{String: "github", Valid: true}, + Name: sql.NullString{String: "octocat", Valid: true}, + FullName: sql.NullString{String: "github/octocat", Valid: true}, + Topics: topics, + }, + }, + } + + // run tests + for _, test := range tests { + err := test.repo.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 TestRepo_FromAPI(t *testing.T) { + // setup types + r := new(api.Repo) + owner := testOwner() + owner.SetID(1) + + r.SetID(1) + r.SetOwner(owner) + r.SetHash("superSecretHash") + r.SetOrg("github") + r.SetName("octocat") + r.SetFullName("github/octocat") + r.SetLink("https://github.com/github/octocat") + r.SetClone("https://github.com/github/octocat.git") + r.SetBranch("main") + r.SetTopics([]string{"cloud", "security"}) + r.SetBuildLimit(10) + r.SetTimeout(30) + r.SetCounter(0) + r.SetVisibility("public") + r.SetPrivate(false) + r.SetTrusted(false) + r.SetActive(true) + r.SetAllowEvents(api.NewEventsFromMask(1)) + r.SetPipelineType("yaml") + r.SetPreviousName("oldName") + r.SetApproveBuild(constants.ApproveNever) + + want := testRepo() + + // run test + got := FromAPI(r) + + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("FromAPI() mismatch (-want +got):\n%s", diff) + } +} + +// testRepo is a test helper function to create a Repo +// type with all fields set to a fake value. +func testRepo() *Repo { + return &Repo{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + UserID: sql.NullInt64{Int64: 1, Valid: true}, + Hash: sql.NullString{String: "superSecretHash", Valid: true}, + Org: sql.NullString{String: "github", Valid: true}, + Name: sql.NullString{String: "octocat", Valid: true}, + FullName: sql.NullString{String: "github/octocat", Valid: true}, + Link: sql.NullString{String: "https://github.com/github/octocat", Valid: true}, + Clone: sql.NullString{String: "https://github.com/github/octocat.git", Valid: true}, + Branch: sql.NullString{String: "main", Valid: true}, + Topics: []string{"cloud", "security"}, + BuildLimit: sql.NullInt64{Int64: 10, Valid: true}, + Timeout: sql.NullInt64{Int64: 30, Valid: true}, + Counter: sql.NullInt32{Int32: 0, Valid: true}, + Visibility: sql.NullString{String: "public", Valid: true}, + Private: sql.NullBool{Bool: false, Valid: true}, + Trusted: sql.NullBool{Bool: false, Valid: true}, + Active: sql.NullBool{Bool: true, Valid: true}, + AllowEvents: sql.NullInt64{Int64: 1, Valid: true}, + PipelineType: sql.NullString{String: "yaml", Valid: true}, + PreviousName: sql.NullString{String: "oldName", Valid: true}, + ApproveBuild: sql.NullString{String: constants.ApproveNever, Valid: true}, + } +} diff --git a/database/repo/update_test.go b/database/repo/update_test.go index 2d2a61f4a..92e714567 100644 --- a/database/repo/update_test.go +++ b/database/repo/update_test.go @@ -15,7 +15,7 @@ import ( func TestRepo_Engine_UpdateRepo(t *testing.T) { // setup types - _repo := testRepo() + _repo := testAPIRepo() _repo.SetID(1) _repo.GetOwner().SetID(1) _repo.SetHash("baz") diff --git a/database/schedule/create.go b/database/schedule/create.go index 4822adca5..bb7ac2beb 100644 --- a/database/schedule/create.go +++ b/database/schedule/create.go @@ -1,6 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -//nolint:dupl // ignore similar code with update.go package schedule import ( diff --git a/database/user/count_test.go b/database/user/count_test.go index 78af924aa..fd88de828 100644 --- a/database/user/count_test.go +++ b/database/user/count_test.go @@ -12,17 +12,15 @@ import ( func TestUser_Engine_CountUsers(t *testing.T) { // setup types - _userOne := testUser() + _userOne := testAPIUser() _userOne.SetID(1) _userOne.SetName("foo") _userOne.SetToken("bar") - _userOne.SetHash("baz") - _userTwo := testUser() + _userTwo := testAPIUser() _userTwo.SetID(2) _userTwo.SetName("baz") _userTwo.SetToken("bar") - _userTwo.SetHash("foo") _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() diff --git a/database/user/create.go b/database/user/create.go index fdd289f34..cd6b9a761 100644 --- a/database/user/create.go +++ b/database/user/create.go @@ -9,21 +9,18 @@ import ( "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" ) // CreateUser creates a new user in the database. -func (e *engine) CreateUser(ctx context.Context, u *library.User) (*library.User, error) { +func (e *engine) CreateUser(ctx context.Context, u *api.User) (*api.User, error) { e.logger.WithFields(logrus.Fields{ "user": u.GetName(), }).Tracef("creating user %s in the database", u.GetName()) - // cast the library type to database type - // - // https://pkg.go.dev/github.com/go-vela/types/database#UserFromLibrary - user := database.UserFromLibrary(u) + // cast the API type to database type + user := FromAPI(u) // validate the necessary fields are populated // @@ -50,5 +47,5 @@ func (e *engine) CreateUser(ctx context.Context, u *library.User) (*library.User return nil, fmt.Errorf("unable to decrypt user %s: %w", u.GetName(), err) } - return user.ToLibrary(), result.Error + return user.ToAPI(), result.Error } diff --git a/database/user/create_test.go b/database/user/create_test.go index 283bdb443..c9a8acdf0 100644 --- a/database/user/create_test.go +++ b/database/user/create_test.go @@ -12,11 +12,10 @@ import ( func TestUser_Engine_CreateUser(t *testing.T) { // setup types - _user := testUser() + _user := testAPIUser() _user.SetID(1) _user.SetName("foo") _user.SetToken("bar") - _user.SetHash("baz") _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() @@ -26,9 +25,9 @@ func TestUser_Engine_CreateUser(t *testing.T) { // ensure the mock expects the query _mock.ExpectQuery(`INSERT INTO "users" -("name","refresh_token","token","hash","favorites","active","admin","id") -VALUES ($1,$2,$3,$4,$5,$6,$7,$8) RETURNING "id"`). - WithArgs("foo", AnyArgument{}, AnyArgument{}, AnyArgument{}, nil, false, false, 1). +("name","refresh_token","token","favorites","active","admin","id") +VALUES ($1,$2,$3,$4,$5,$6,$7) RETURNING "id"`). + WithArgs("foo", AnyArgument{}, AnyArgument{}, nil, false, false, 1). WillReturnRows(_rows) _sqlite := testSqlite(t) diff --git a/database/user/delete.go b/database/user/delete.go index ed3d9491e..848e08ca5 100644 --- a/database/user/delete.go +++ b/database/user/delete.go @@ -7,21 +7,18 @@ import ( "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" ) // DeleteUser deletes an existing user from the database. -func (e *engine) DeleteUser(ctx context.Context, u *library.User) error { +func (e *engine) DeleteUser(ctx context.Context, u *api.User) error { e.logger.WithFields(logrus.Fields{ "user": u.GetName(), }).Tracef("deleting user %s from the database", u.GetName()) - // cast the library type to database type - // - // https://pkg.go.dev/github.com/go-vela/types/database#UserFromLibrary - user := database.UserFromLibrary(u) + // cast the API type to database type + user := FromAPI(u) // send query to the database return e.client. diff --git a/database/user/delete_test.go b/database/user/delete_test.go index c06ccf5e2..6926929d9 100644 --- a/database/user/delete_test.go +++ b/database/user/delete_test.go @@ -11,11 +11,10 @@ import ( func TestUser_Engine_DeleteUser(t *testing.T) { // setup types - _user := testUser() + _user := testAPIUser() _user.SetID(1) _user.SetName("foo") _user.SetToken("bar") - _user.SetHash("baz") _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() diff --git a/database/user/get.go b/database/user/get.go index e488ce73f..90e16a46e 100644 --- a/database/user/get.go +++ b/database/user/get.go @@ -5,17 +5,16 @@ package user import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" ) // GetUser gets a user by ID from the database. -func (e *engine) GetUser(ctx context.Context, id int64) (*library.User, error) { +func (e *engine) GetUser(ctx context.Context, id int64) (*api.User, error) { e.logger.Tracef("getting user %d from the database", id) // variable to store query results - u := new(database.User) + u := new(User) // send query to the database and store result in variable err := e.client. @@ -28,8 +27,6 @@ func (e *engine) GetUser(ctx context.Context, id int64) (*library.User, error) { } // decrypt the fields for the user - // - // https://pkg.go.dev/github.com/go-vela/types/database#User.Decrypt err = u.Decrypt(e.config.EncryptionKey) if err != nil { // TODO: remove backwards compatibility before 1.x.x release @@ -41,7 +38,5 @@ func (e *engine) GetUser(ctx context.Context, id int64) (*library.User, error) { } // return the decrypted user - // - // https://pkg.go.dev/github.com/go-vela/types/database#User.ToLibrary - return u.ToLibrary(), nil + return u.ToAPI(), nil } diff --git a/database/user/get_name.go b/database/user/get_name.go index 6caf2d745..87dd13bea 100644 --- a/database/user/get_name.go +++ b/database/user/get_name.go @@ -7,19 +7,18 @@ import ( "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" ) // GetUserForName gets a user by name from the database. -func (e *engine) GetUserForName(ctx context.Context, name string) (*library.User, error) { +func (e *engine) GetUserForName(ctx context.Context, name string) (*api.User, error) { e.logger.WithFields(logrus.Fields{ "user": name, }).Tracef("getting user %s from the database", name) // variable to store query results - u := new(database.User) + u := new(User) // send query to the database and store result in variable err := e.client. @@ -32,8 +31,6 @@ func (e *engine) GetUserForName(ctx context.Context, name string) (*library.User } // decrypt the fields for the user - // - // https://pkg.go.dev/github.com/go-vela/types/database#User.Decrypt err = u.Decrypt(e.config.EncryptionKey) if err != nil { // TODO: remove backwards compatibility before 1.x.x release @@ -45,7 +42,5 @@ func (e *engine) GetUserForName(ctx context.Context, name string) (*library.User } // return the decrypted user - // - // https://pkg.go.dev/github.com/go-vela/types/database#User.ToLibrary - return u.ToLibrary(), nil + return u.ToAPI(), nil } diff --git a/database/user/get_name_test.go b/database/user/get_name_test.go index 3deed039e..86b812ca0 100644 --- a/database/user/get_name_test.go +++ b/database/user/get_name_test.go @@ -9,16 +9,16 @@ import ( "github.com/DATA-DOG/go-sqlmock" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" ) func TestUser_Engine_GetUserForName(t *testing.T) { // setup types - _user := testUser() + _user := testAPIUser() _user.SetID(1) _user.SetName("foo") _user.SetToken("bar") - _user.SetHash("baz") + _user.SetFavorites([]string{}) _postgres, _mock := testPostgres(t) @@ -45,7 +45,7 @@ func TestUser_Engine_GetUserForName(t *testing.T) { failure bool name string database *engine - want *library.User + want *api.User }{ { failure: false, diff --git a/database/user/get_test.go b/database/user/get_test.go index c8f00fba5..b92f2bee4 100644 --- a/database/user/get_test.go +++ b/database/user/get_test.go @@ -9,16 +9,16 @@ import ( "github.com/DATA-DOG/go-sqlmock" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" ) func TestUser_Engine_GetUser(t *testing.T) { // setup types - _user := testUser() + _user := testAPIUser() _user.SetID(1) _user.SetName("foo") _user.SetToken("bar") - _user.SetHash("baz") + _user.SetFavorites([]string{}) _postgres, _mock := testPostgres(t) @@ -45,7 +45,7 @@ func TestUser_Engine_GetUser(t *testing.T) { failure bool name string database *engine - want *library.User + want *api.User }{ { failure: false, diff --git a/database/user/interface.go b/database/user/interface.go index a5801d53a..55a1b2d62 100644 --- a/database/user/interface.go +++ b/database/user/interface.go @@ -5,7 +5,7 @@ package user import ( "context" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" ) // UserInterface represents the Vela interface for user @@ -29,17 +29,17 @@ type UserInterface interface { // CountUsers defines a function that gets the count of all users. CountUsers(context.Context) (int64, error) // CreateUser defines a function that creates a new user. - CreateUser(context.Context, *library.User) (*library.User, error) + CreateUser(context.Context, *api.User) (*api.User, error) // DeleteUser defines a function that deletes an existing user. - DeleteUser(context.Context, *library.User) error + DeleteUser(context.Context, *api.User) error // GetUser defines a function that gets a user by ID. - GetUser(context.Context, int64) (*library.User, error) + GetUser(context.Context, int64) (*api.User, error) // GetUserForName defines a function that gets a user by name. - GetUserForName(context.Context, string) (*library.User, error) + GetUserForName(context.Context, string) (*api.User, error) // ListUsers defines a function that gets a list of all users. - ListUsers(context.Context) ([]*library.User, error) + ListUsers(context.Context) ([]*api.User, error) // ListLiteUsers defines a function that gets a lite list of users. - ListLiteUsers(context.Context, int, int) ([]*library.User, int64, error) + ListLiteUsers(context.Context, int, int) ([]*api.User, int64, error) // UpdateUser defines a function that updates an existing user. - UpdateUser(context.Context, *library.User) (*library.User, error) + UpdateUser(context.Context, *api.User) (*api.User, error) } diff --git a/database/user/list.go b/database/user/list.go index aaa24644d..0fed81070 100644 --- a/database/user/list.go +++ b/database/user/list.go @@ -5,19 +5,18 @@ package user import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" ) // ListUsers gets a list of all users from the database. -func (e *engine) ListUsers(ctx context.Context) ([]*library.User, error) { +func (e *engine) ListUsers(ctx context.Context) ([]*api.User, error) { e.logger.Trace("listing all users from the database") // variables to store query results and return value count := int64(0) - u := new([]database.User) - users := []*library.User{} + u := new([]User) + users := []*api.User{} // count the results count, err := e.CountUsers(ctx) @@ -45,8 +44,6 @@ func (e *engine) ListUsers(ctx context.Context) ([]*library.User, error) { tmp := user // decrypt the fields for the user - // - // https://pkg.go.dev/github.com/go-vela/types/database#User.Decrypt err = tmp.Decrypt(e.config.EncryptionKey) if err != nil { // TODO: remove backwards compatibility before 1.x.x release @@ -57,10 +54,8 @@ func (e *engine) ListUsers(ctx context.Context) ([]*library.User, error) { e.logger.Errorf("unable to decrypt user %d: %v", tmp.ID.Int64, err) } - // convert query result to library type - // - // https://pkg.go.dev/github.com/go-vela/types/database#User.ToLibrary - users = append(users, tmp.ToLibrary()) + // convert query result to API type + users = append(users, tmp.ToAPI()) } return users, nil diff --git a/database/user/list_lite.go b/database/user/list_lite.go index 83a40be56..809b9c83f 100644 --- a/database/user/list_lite.go +++ b/database/user/list_lite.go @@ -5,21 +5,20 @@ package user import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" ) // ListLiteUsers gets a lite (only: id, name) list of users from the database. // //nolint:lll // ignore long line length due to variable names -func (e *engine) ListLiteUsers(ctx context.Context, page, perPage int) ([]*library.User, int64, error) { +func (e *engine) ListLiteUsers(ctx context.Context, page, perPage int) ([]*api.User, int64, error) { e.logger.Trace("listing lite users from the database") // variables to store query results and return values count := int64(0) - u := new([]database.User) - users := []*library.User{} + u := new([]User) + users := []*api.User{} // count the results count, err := e.CountUsers(ctx) @@ -51,10 +50,8 @@ func (e *engine) ListLiteUsers(ctx context.Context, page, perPage int) ([]*libra // https://golang.org/doc/faq#closures_and_goroutines tmp := user - // convert query result to library type - // - // https://pkg.go.dev/github.com/go-vela/types/database#User.ToLibrary - users = append(users, tmp.ToLibrary()) + // convert query result to API type + users = append(users, tmp.ToAPI()) } return users, count, nil diff --git a/database/user/list_lite_test.go b/database/user/list_lite_test.go index aeacb0676..780b1e29a 100644 --- a/database/user/list_lite_test.go +++ b/database/user/list_lite_test.go @@ -9,23 +9,21 @@ import ( "github.com/DATA-DOG/go-sqlmock" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" ) func TestUser_Engine_ListLiteUsers(t *testing.T) { // setup types - _userOne := testUser() + _userOne := testAPIUser() _userOne.SetID(1) _userOne.SetName("foo") _userOne.SetToken("bar") - _userOne.SetHash("baz") _userOne.SetFavorites([]string{}) - _userTwo := testUser() + _userTwo := testAPIUser() _userTwo.SetID(2) _userTwo.SetName("baz") _userTwo.SetToken("bar") - _userTwo.SetHash("foo") _userTwo.SetFavorites([]string{}) _postgres, _mock := testPostgres(t) @@ -62,12 +60,10 @@ func TestUser_Engine_ListLiteUsers(t *testing.T) { // empty fields not returned by query _userOne.RefreshToken = new(string) _userOne.Token = new(string) - _userOne.Hash = new(string) _userOne.Favorites = new([]string) _userTwo.RefreshToken = new(string) _userTwo.Token = new(string) - _userTwo.Hash = new(string) _userTwo.Favorites = new([]string) // setup tests @@ -75,19 +71,19 @@ func TestUser_Engine_ListLiteUsers(t *testing.T) { failure bool name string database *engine - want []*library.User + want []*api.User }{ { failure: false, name: "postgres", database: _postgres, - want: []*library.User{_userOne, _userTwo}, + want: []*api.User{_userOne, _userTwo}, }, { failure: false, name: "sqlite3", database: _sqlite, - want: []*library.User{_userTwo, _userOne}, + want: []*api.User{_userTwo, _userOne}, }, } diff --git a/database/user/list_test.go b/database/user/list_test.go index 0472037ed..556e02e57 100644 --- a/database/user/list_test.go +++ b/database/user/list_test.go @@ -9,23 +9,21 @@ import ( "github.com/DATA-DOG/go-sqlmock" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" ) func TestUser_Engine_ListUsers(t *testing.T) { // setup types - _userOne := testUser() + _userOne := testAPIUser() _userOne.SetID(1) _userOne.SetName("foo") _userOne.SetToken("bar") - _userOne.SetHash("baz") _userOne.SetFavorites([]string{}) - _userTwo := testUser() + _userTwo := testAPIUser() _userTwo.SetID(2) _userTwo.SetName("baz") _userTwo.SetToken("bar") - _userTwo.SetHash("foo") _userTwo.SetFavorites([]string{}) _postgres, _mock := testPostgres(t) @@ -64,19 +62,19 @@ func TestUser_Engine_ListUsers(t *testing.T) { failure bool name string database *engine - want []*library.User + want []*api.User }{ { failure: false, name: "postgres", database: _postgres, - want: []*library.User{_userOne, _userTwo}, + want: []*api.User{_userOne, _userTwo}, }, { failure: false, name: "sqlite3", database: _sqlite, - want: []*library.User{_userOne, _userTwo}, + want: []*api.User{_userOne, _userTwo}, }, } diff --git a/database/user/table.go b/database/user/table.go index 070546435..3ba809872 100644 --- a/database/user/table.go +++ b/database/user/table.go @@ -18,7 +18,6 @@ users ( name VARCHAR(250), refresh_token VARCHAR(500), token VARCHAR(500), - hash VARCHAR(500), favorites VARCHAR(5000), active BOOLEAN, admin BOOLEAN, @@ -35,7 +34,6 @@ users ( name TEXT, refresh_token TEXT, token TEXT, - hash TEXT, favorites TEXT, active BOOLEAN, admin BOOLEAN, diff --git a/database/user/update.go b/database/user/update.go index e321aba17..2779e6497 100644 --- a/database/user/update.go +++ b/database/user/update.go @@ -9,33 +9,26 @@ import ( "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" ) // UpdateUser updates an existing user in the database. -func (e *engine) UpdateUser(ctx context.Context, u *library.User) (*library.User, error) { +func (e *engine) UpdateUser(ctx context.Context, u *api.User) (*api.User, error) { e.logger.WithFields(logrus.Fields{ "user": u.GetName(), }).Tracef("updating user %s in the database", u.GetName()) // cast the library type to database type - // - // https://pkg.go.dev/github.com/go-vela/types/database#UserFromLibrary - user := database.UserFromLibrary(u) + user := FromAPI(u) // validate the necessary fields are populated - // - // https://pkg.go.dev/github.com/go-vela/types/database#User.Validate err := user.Validate() if err != nil { return nil, err } // encrypt the fields for the user - // - // https://pkg.go.dev/github.com/go-vela/types/database#User.Encrypt err = user.Encrypt(e.config.EncryptionKey) if err != nil { return nil, fmt.Errorf("unable to encrypt user %s: %w", u.GetName(), err) @@ -50,5 +43,5 @@ func (e *engine) UpdateUser(ctx context.Context, u *library.User) (*library.User return nil, fmt.Errorf("unable to decrypt user %s: %w", u.GetName(), err) } - return user.ToLibrary(), result.Error + return user.ToAPI(), result.Error } diff --git a/database/user/update_test.go b/database/user/update_test.go index 83b455d77..d84022b87 100644 --- a/database/user/update_test.go +++ b/database/user/update_test.go @@ -12,20 +12,19 @@ import ( func TestUser_Engine_UpdateUser(t *testing.T) { // setup types - _user := testUser() + _user := testAPIUser() _user.SetID(1) _user.SetName("foo") _user.SetToken("bar") - _user.SetHash("baz") _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() // ensure the mock expects the query _mock.ExpectExec(`UPDATE "users" -SET "name"=$1,"refresh_token"=$2,"token"=$3,"hash"=$4,"favorites"=$5,"active"=$6,"admin"=$7 -WHERE "id" = $8`). - WithArgs("foo", AnyArgument{}, AnyArgument{}, AnyArgument{}, nil, false, false, 1). +SET "name"=$1,"refresh_token"=$2,"token"=$3,"favorites"=$4,"active"=$5,"admin"=$6 +WHERE "id" = $7`). + WithArgs("foo", AnyArgument{}, AnyArgument{}, nil, false, false, 1). WillReturnResult(sqlmock.NewResult(1, 1)) _sqlite := testSqlite(t) diff --git a/database/user/user.go b/database/user/user.go index 23948bfb3..d961f71b0 100644 --- a/database/user/user.go +++ b/database/user/user.go @@ -4,14 +4,47 @@ package user import ( "context" + "database/sql" + "encoding/base64" + "errors" "fmt" + "regexp" + "github.com/lib/pq" "github.com/sirupsen/logrus" "gorm.io/gorm" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/util" "github.com/go-vela/types/constants" ) +var ( + // userRegex defines the regex pattern for validating + // the Name field for the User type. + userRegex = regexp.MustCompile("^[a-zA-Z0-9_-]{0,38}$") + + // ErrEmptyUserName defines the error type when a + // User type has an empty Name field provided. + ErrEmptyUserName = errors.New("empty user name provided") + + // ErrEmptyUserRefreshToken defines the error type when a + // User type has an empty RefreshToken field provided. + ErrEmptyUserRefreshToken = errors.New("empty user refresh token provided") + + // ErrEmptyUserToken defines the error type when a + // User type has an empty Token field provided. + ErrEmptyUserToken = errors.New("empty user token provided") + + // ErrInvalidUserName defines the error type when a + // User type has an invalid Name field provided. + ErrInvalidUserName = errors.New("invalid user name provided") + + // ErrExceededFavoritesLimit defines the error type when a + // User type has Favorites field provided that exceeds the database limit. + ErrExceededFavoritesLimit = errors.New("exceeded favorites limit") +) + type ( // config represents the settings required to create the engine that implements the UserInterface interface. config struct { @@ -38,6 +71,17 @@ type ( // https://pkg.go.dev/github.com/sirupsen/logrus#Entry logger *logrus.Entry } + + // User is the database representation of a user. + User struct { + ID sql.NullInt64 `sql:"id"` + Name sql.NullString `sql:"name"` + RefreshToken sql.NullString `sql:"refresh_token"` + Token sql.NullString `sql:"token"` + Favorites pq.StringArray `sql:"favorites" gorm:"type:varchar(5000)"` + Active sql.NullBool `sql:"active"` + Admin sql.NullBool `sql:"admin"` + } ) // New creates and returns a Vela service for integrating with users in the database. @@ -81,3 +125,191 @@ func New(opts ...EngineOpt) (*engine, error) { return e, nil } + +// Decrypt will manipulate the existing user tokens by +// base64 decoding them. Then, a AES-256 cipher +// block is created from the encryption key in order to +// decrypt the base64 decoded user tokens. +func (u *User) Decrypt(key string) error { + // base64 decode the encrypted user token + decoded, err := base64.StdEncoding.DecodeString(u.Token.String) + if err != nil { + return err + } + + // decrypt the base64 decoded user token + decrypted, err := util.Decrypt(key, decoded) + if err != nil { + return err + } + + // set the decrypted user token + u.Token = sql.NullString{ + String: string(decrypted), + Valid: true, + } + + // base64 decode the encrypted user refresh token + decoded, err = base64.StdEncoding.DecodeString(u.RefreshToken.String) + if err != nil { + return err + } + + // decrypt the base64 decoded user refresh token + decrypted, err = util.Decrypt(key, decoded) + if err != nil { + return err + } + + // set the decrypted user refresh token + u.RefreshToken = sql.NullString{ + String: string(decrypted), + Valid: true, + } + + return nil +} + +// Encrypt will manipulate the existing user tokens by +// creating a AES-256 cipher block from the encryption +// key in order to encrypt the user tokens. Then, the +// user tokens are base64 encoded for transport across +// network boundaries. +func (u *User) Encrypt(key string) error { + // encrypt the user token + encrypted, err := util.Encrypt(key, []byte(u.Token.String)) + if err != nil { + return err + } + + // base64 encode the encrypted user token to make it network safe + u.Token = sql.NullString{ + String: base64.StdEncoding.EncodeToString(encrypted), + Valid: true, + } + + // encrypt the user refresh token + encrypted, err = util.Encrypt(key, []byte(u.RefreshToken.String)) + if err != nil { + return err + } + + // base64 encode the encrypted user refresh token to make it network safe + u.RefreshToken = sql.NullString{ + String: base64.StdEncoding.EncodeToString(encrypted), + Valid: true, + } + + return nil +} + +// Nullify ensures the valid flag for +// the sql.Null types are properly set. +// +// When a field within the User type is the zero +// value for the field, the valid flag is set to +// false causing it to be NULL in the database. +func (u *User) Nullify() *User { + if u == nil { + return nil + } + + // check if the ID field should be false + if u.ID.Int64 == 0 { + u.ID.Valid = false + } + + // check if the Name field should be false + if len(u.Name.String) == 0 { + u.Name.Valid = false + } + + // check if the RefreshToken field should be false + if len(u.RefreshToken.String) == 0 { + u.RefreshToken.Valid = false + } + + // check if the Token field should be false + if len(u.Token.String) == 0 { + u.Token.Valid = false + } + + return u +} + +// ToAPI converts the User type +// to an API User type. +func (u *User) ToAPI() *api.User { + user := new(api.User) + + user.SetID(u.ID.Int64) + user.SetName(u.Name.String) + user.SetRefreshToken(u.RefreshToken.String) + user.SetToken(u.Token.String) + user.SetActive(u.Active.Bool) + user.SetAdmin(u.Admin.Bool) + user.SetFavorites(u.Favorites) + + return user +} + +// Validate verifies the necessary fields for +// the User type are populated correctly. +func (u *User) Validate() error { + // verify the Name field is populated + if len(u.Name.String) == 0 { + return ErrEmptyUserName + } + + // verify the Token field is populated + if len(u.Token.String) == 0 { + return ErrEmptyUserToken + } + + // verify the Name field is valid + if !userRegex.MatchString(u.Name.String) { + return ErrInvalidUserName + } + + // calculate total size of favorites + total := 0 + for _, f := range u.Favorites { + total += len(f) + } + + // verify the Favorites field is within the database constraints + // len is to factor in number of comma separators included in the database field, + // removing 1 due to the last item not having an appended comma + if (total + len(u.Favorites) - 1) > constants.FavoritesMaxSize { + return ErrExceededFavoritesLimit + } + + // ensure that all User string fields + // that can be returned as JSON are sanitized + // to avoid unsafe HTML content + u.Name = sql.NullString{String: util.Sanitize(u.Name.String), Valid: u.Name.Valid} + + // ensure that all Favorites are sanitized + // to avoid unsafe HTML content + for i, v := range u.Favorites { + u.Favorites[i] = util.Sanitize(v) + } + + return nil +} + +// FromAPI converts the API User type +// to a database User type. +func FromAPI(u *api.User) *User { + user := &User{ + ID: sql.NullInt64{Int64: u.GetID(), Valid: true}, + Name: sql.NullString{String: u.GetName(), Valid: true}, + RefreshToken: sql.NullString{String: u.GetRefreshToken(), Valid: true}, + Token: sql.NullString{String: u.GetToken(), Valid: true}, + Active: sql.NullBool{Bool: u.GetActive(), Valid: true}, + Admin: sql.NullBool{Bool: u.GetAdmin(), Valid: true}, + Favorites: pq.StringArray(u.GetFavorites()), + } + + return user.Nullify() +} diff --git a/database/user/user_test.go b/database/user/user_test.go index 267a961e3..08db61eef 100644 --- a/database/user/user_test.go +++ b/database/user/user_test.go @@ -3,8 +3,10 @@ package user import ( + "database/sql" "database/sql/driver" "reflect" + "strconv" "testing" "github.com/DATA-DOG/go-sqlmock" @@ -13,7 +15,7 @@ import ( "gorm.io/driver/sqlite" "gorm.io/gorm" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" ) func TestUser_New(t *testing.T) { @@ -170,15 +172,14 @@ func testSqlite(t *testing.T) *engine { return _engine } -// testUser is a test helper function to create a library +// testAPIUser is a test helper function to create an API // User type with all fields set to their zero values. -func testUser() *library.User { - return &library.User{ +func testAPIUser() *api.User { + return &api.User{ ID: new(int64), Name: new(string), RefreshToken: new(string), Token: new(string), - Hash: new(string), Favorites: new([]string), Active: new(bool), Admin: new(bool), @@ -196,3 +197,271 @@ type AnyArgument struct{} func (a AnyArgument) Match(_ driver.Value) bool { return true } + +func TestUser_Decrypt(t *testing.T) { + // setup types + key := "C639A572E14D5075C526FDDD43E4ECF6" + encrypted := testUser() + + err := encrypted.Encrypt(key) + if err != nil { + t.Errorf("unable to encrypt user: %v", err) + } + + // setup tests + tests := []struct { + failure bool + key string + user User + }{ + { + failure: false, + key: key, + user: *encrypted, + }, + { + failure: true, + key: "", + user: *encrypted, + }, + { + failure: true, + key: key, + user: *testUser(), + }, + } + + // run tests + for _, test := range tests { + err := test.user.Decrypt(test.key) + + if test.failure { + if err == nil { + t.Errorf("Decrypt should have returned err") + } + + continue + } + + if err != nil { + t.Errorf("Decrypt returned err: %v", err) + } + } +} + +func TestUser_Encrypt(t *testing.T) { + // setup types + key := "C639A572E14D5075C526FDDD43E4ECF6" + + // setup tests + tests := []struct { + failure bool + key string + user *User + }{ + { + failure: false, + key: key, + user: testUser(), + }, + { + failure: true, + key: "", + user: testUser(), + }, + } + + // run tests + for _, test := range tests { + err := test.user.Encrypt(test.key) + + if test.failure { + if err == nil { + t.Errorf("Encrypt should have returned err") + } + + continue + } + + if err != nil { + t.Errorf("Encrypt returned err: %v", err) + } + } +} + +func TestUser_Nullify(t *testing.T) { + // setup types + var u *User + + want := &User{ + ID: sql.NullInt64{Int64: 0, Valid: false}, + Name: sql.NullString{String: "", Valid: false}, + RefreshToken: sql.NullString{String: "", Valid: false}, + Token: sql.NullString{String: "", Valid: false}, + Active: sql.NullBool{Bool: false, Valid: false}, + Admin: sql.NullBool{Bool: false, Valid: false}, + } + + // setup tests + tests := []struct { + user *User + want *User + }{ + { + user: testUser(), + want: testUser(), + }, + { + user: u, + want: nil, + }, + { + user: new(User), + want: want, + }, + } + + // run tests + for _, test := range tests { + got := test.user.Nullify() + + if !reflect.DeepEqual(got, test.want) { + t.Errorf("Nullify is %v, want %v", got, test.want) + } + } +} + +func TestUser_ToAPI(t *testing.T) { + // setup types + want := new(api.User) + + want.SetID(1) + want.SetName("octocat") + want.SetRefreshToken("superSecretRefreshToken") + want.SetToken("superSecretToken") + want.SetFavorites([]string{"github/octocat"}) + want.SetActive(true) + want.SetAdmin(false) + + // run test + got := testUser().ToAPI() + + if !reflect.DeepEqual(got, want) { + t.Errorf("ToAPI is %v, want %v", got, want) + } +} + +func TestUser_Validate(t *testing.T) { + // setup tests + tests := []struct { + failure bool + user *User + }{ + { + failure: false, + user: testUser(), + }, + { // no name set for user + failure: true, + user: &User{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + Token: sql.NullString{String: "superSecretToken", Valid: true}, + }, + }, + { // no token set for user + failure: true, + user: &User{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + Name: sql.NullString{String: "octocat", Valid: true}, + }, + }, + { // invalid name set for user + failure: true, + user: &User{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + Name: sql.NullString{String: "!@#$%^&*()", Valid: true}, + RefreshToken: sql.NullString{String: "superSecretRefreshToken", Valid: true}, + Token: sql.NullString{String: "superSecretToken", Valid: true}, + }, + }, + { // invalid favorites set for user + failure: true, + user: &User{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + Name: sql.NullString{String: "octocat", Valid: true}, + Token: sql.NullString{String: "superSecretToken", Valid: true}, + Favorites: exceededFavorites(), + }, + }, + } + + // run tests + for _, test := range tests { + err := test.user.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 TestFromAPI(t *testing.T) { + // setup types + u := new(api.User) + + u.SetID(1) + u.SetName("octocat") + u.SetRefreshToken("superSecretRefreshToken") + u.SetToken("superSecretToken") + u.SetFavorites([]string{"github/octocat"}) + u.SetActive(true) + u.SetAdmin(false) + + want := testUser() + + // run test + got := FromAPI(u) + + if !reflect.DeepEqual(got, want) { + t.Errorf("FromAPI is %v, want %v", got, want) + } +} + +// testUser is a test helper function to create a User +// type with all fields set to a fake value. +func testUser() *User { + return &User{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + Name: sql.NullString{String: "octocat", Valid: true}, + RefreshToken: sql.NullString{String: "superSecretRefreshToken", Valid: true}, + Token: sql.NullString{String: "superSecretToken", Valid: true}, + Favorites: []string{"github/octocat"}, + Active: sql.NullBool{Bool: true, Valid: true}, + Admin: sql.NullBool{Bool: false, Valid: true}, + } +} + +// exceededFavorites returns a list of valid favorites that exceed the maximum size. +func exceededFavorites() []string { + // initialize empty favorites + favorites := []string{} + + // add enough favorites to exceed the character limit + for i := 0; i < 500; i++ { + // construct favorite + // use i to adhere to unique favorites + favorite := "github/octocat-" + strconv.Itoa(i) + + favorites = append(favorites, favorite) + } + + return favorites +} diff --git a/internal/token/compose.go b/internal/token/compose.go index 4dd63860a..8fa0a1c8b 100644 --- a/internal/token/compose.go +++ b/internal/token/compose.go @@ -8,9 +8,9 @@ import ( "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/internal" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" ) // Compose generates a refresh and access token pair unique @@ -19,7 +19,7 @@ import ( // guarantee the signature is unique per token. The refresh // token is returned to store with the user // in the database. -func (tm *Manager) Compose(c *gin.Context, u *library.User) (string, string, error) { +func (tm *Manager) Compose(c *gin.Context, u *api.User) (string, string, error) { // grab the metadata from the context to pull in provided // cookie duration information m := c.MustGet("metadata").(*internal.Metadata) diff --git a/internal/token/compose_test.go b/internal/token/compose_test.go index 3026730a5..0cbce444c 100644 --- a/internal/token/compose_test.go +++ b/internal/token/compose_test.go @@ -11,18 +11,17 @@ import ( "github.com/gin-gonic/gin" "github.com/golang-jwt/jwt/v5" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/internal" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" ) func TestToken_Compose(t *testing.T) { // setup types - u := new(library.User) + u := new(api.User) u.SetID(1) u.SetName("foo") u.SetToken("bar") - u.SetHash("baz") tm := &Manager{ PrivateKey: "123abc", diff --git a/internal/token/mint.go b/internal/token/mint.go index dab99ae46..f4a4338a7 100644 --- a/internal/token/mint.go +++ b/internal/token/mint.go @@ -9,8 +9,8 @@ import ( "github.com/golang-jwt/jwt/v5" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" ) // Claims struct is an extension of the JWT standard claims. It @@ -32,7 +32,7 @@ type MintTokenOpts struct { Repo string TokenDuration time.Duration TokenType string - User *library.User + User *api.User } // MintToken mints a Vela JWT Token given a set of options. diff --git a/internal/token/parse_test.go b/internal/token/parse_test.go index 777a5fa01..a3efd14ea 100644 --- a/internal/token/parse_test.go +++ b/internal/token/parse_test.go @@ -10,17 +10,16 @@ import ( "github.com/gin-gonic/gin" jwt "github.com/golang-jwt/jwt/v5" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" ) func TestTokenManager_ParseToken(t *testing.T) { // setup types - u := new(library.User) + u := new(api.User) u.SetID(1) u.SetName("foo") u.SetToken("bar") - u.SetHash("baz") tm := &Manager{ PrivateKey: "123abc", @@ -117,11 +116,10 @@ func TestTokenManager_ParseToken(t *testing.T) { func TestTokenManager_ParseToken_Error_NoParse(t *testing.T) { // setup types - u := new(library.User) + u := new(api.User) u.SetID(1) u.SetName("foo") u.SetToken("bar") - u.SetHash("baz") tm := &Manager{ PrivateKey: "123abc", @@ -143,11 +141,10 @@ func TestTokenManager_ParseToken_Error_NoParse(t *testing.T) { func TestTokenManager_ParseToken_Expired(t *testing.T) { // setup types - u := new(library.User) + u := new(api.User) u.SetID(1) u.SetName("foo") u.SetToken("bar") - u.SetHash("baz") tm := &Manager{ PrivateKey: "123abc", @@ -176,11 +173,10 @@ func TestTokenManager_ParseToken_Expired(t *testing.T) { func TestTokenManager_ParseToken_NoSubject(t *testing.T) { // setup types - u := new(library.User) + u := new(api.User) u.SetID(1) u.SetName("foo") u.SetToken("bar") - u.SetHash("baz") tm := &Manager{ PrivateKey: "123abc", @@ -217,11 +213,10 @@ func TestTokenManager_ParseToken_NoSubject(t *testing.T) { func TestTokenManager_ParseToken_Error_InvalidSignature(t *testing.T) { // setup types - u := new(library.User) + u := new(api.User) u.SetID(1) u.SetName("foo") u.SetToken("bar") - u.SetHash("baz") tm := &Manager{ PrivateKey: "123abc", @@ -259,11 +254,10 @@ func TestTokenManager_ParseToken_Error_InvalidSignature(t *testing.T) { func TestToken_Parse_AccessToken_NoExpiration(t *testing.T) { // setup types - u := new(library.User) + u := new(api.User) u.SetID(1) u.SetName("foo") u.SetToken("bar") - u.SetHash("baz") tm := &Manager{ PrivateKey: "123abc", @@ -280,7 +274,7 @@ func TestToken_Parse_AccessToken_NoExpiration(t *testing.T) { } tkn := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) - token, err := tkn.SignedString([]byte(u.GetHash())) + token, err := tkn.SignedString([]byte("123abc")) if err != nil { t.Errorf("Unable to create test token: %v", err) } diff --git a/internal/token/refresh_test.go b/internal/token/refresh_test.go index bfc132c15..139bb6634 100644 --- a/internal/token/refresh_test.go +++ b/internal/token/refresh_test.go @@ -12,18 +12,17 @@ import ( "github.com/gin-gonic/gin" "github.com/golang-jwt/jwt/v5" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" ) func TestTokenManager_Refresh(t *testing.T) { // setup types - u := new(library.User) + u := new(api.User) u.SetID(1) u.SetName("foo") u.SetToken("bar") - u.SetHash("baz") tm := &Manager{ PrivateKey: "123abc", @@ -80,11 +79,10 @@ func TestTokenManager_Refresh(t *testing.T) { func TestTokenManager_Refresh_Expired(t *testing.T) { // setup types - u := new(library.User) + u := new(api.User) u.SetID(1) u.SetName("foo") u.SetToken("bar") - u.SetHash("baz") tm := &Manager{ PrivateKey: "123abc", diff --git a/mock/server/user.go b/mock/server/user.go index ea2a5fc78..e2fb9511c 100644 --- a/mock/server/user.go +++ b/mock/server/user.go @@ -11,8 +11,8 @@ import ( "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types" - "github.com/go-vela/types/library" ) const ( @@ -51,7 +51,7 @@ const ( func getUsers(c *gin.Context) { data := []byte(UsersResp) - var body []library.User + var body []api.User _ = json.Unmarshal(data, &body) c.JSON(http.StatusOK, body) @@ -73,7 +73,7 @@ func getUser(c *gin.Context) { data := []byte(UserResp) - var body library.User + var body api.User _ = json.Unmarshal(data, &body) c.JSON(http.StatusOK, body) @@ -83,7 +83,7 @@ func getUser(c *gin.Context) { func addUser(c *gin.Context) { data := []byte(UserResp) - var body library.User + var body api.User _ = json.Unmarshal(data, &body) c.JSON(http.StatusCreated, body) @@ -107,7 +107,7 @@ func updateUser(c *gin.Context) { data := []byte(UserResp) - var body library.User + var body api.User _ = json.Unmarshal(data, &body) c.JSON(http.StatusOK, body) diff --git a/mock/server/user_test.go b/mock/server/user_test.go index 9fcf3484b..603ae0c72 100644 --- a/mock/server/user_test.go +++ b/mock/server/user_test.go @@ -7,11 +7,11 @@ import ( "reflect" "testing" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" ) func TestUser_ActiveUserResp(t *testing.T) { - testUser := library.User{} + testUser := api.User{} err := json.Unmarshal([]byte(UserResp), &testUser) if err != nil { diff --git a/queue/models/item_test.go b/queue/models/item_test.go index f6d34e19f..94be05c22 100644 --- a/queue/models/item_test.go +++ b/queue/models/item_test.go @@ -44,7 +44,7 @@ func TestTypes_ToItem(t *testing.T) { } r := &api.Repo{ ID: &num64, - Owner: &library.User{ + Owner: &api.User{ ID: &num64, Name: &str, Token: &str, @@ -91,7 +91,7 @@ func TestTypes_ToItem(t *testing.T) { }, Repo: &api.Repo{ ID: &num64, - Owner: &library.User{ + Owner: &api.User{ ID: &num64, Name: &str, Token: &str, diff --git a/queue/redis/redis_test.go b/queue/redis/redis_test.go index cecfe08cf..ee67e682e 100644 --- a/queue/redis/redis_test.go +++ b/queue/redis/redis_test.go @@ -76,11 +76,10 @@ var ( _repo = &api.Repo{ ID: Int64(1), - Owner: &library.User{ + Owner: &api.User{ ID: Int64(1), Name: String("octocat"), Token: nil, - Hash: nil, Active: Bool(true), Admin: Bool(false), }, diff --git a/router/middleware/build/build_test.go b/router/middleware/build/build_test.go index 624e01497..01cb48bd6 100644 --- a/router/middleware/build/build_test.go +++ b/router/middleware/build/build_test.go @@ -39,7 +39,7 @@ func TestBuild_Retrieve(t *testing.T) { func TestBuild_Establish(t *testing.T) { // setup types - owner := new(library.User) + owner := new(api.User) owner.SetID(1) r := new(api.Repo) @@ -163,7 +163,7 @@ func TestBuild_Establish_NoRepo(t *testing.T) { func TestBuild_Establish_NoBuildParameter(t *testing.T) { // setup types - owner := new(library.User) + owner := new(api.User) owner.SetID(1) r := new(api.Repo) @@ -214,7 +214,7 @@ func TestBuild_Establish_NoBuildParameter(t *testing.T) { func TestBuild_Establish_InvalidBuildParameter(t *testing.T) { // setup types - owner := new(library.User) + owner := new(api.User) owner.SetID(1) r := new(api.Repo) diff --git a/router/middleware/claims/claims_test.go b/router/middleware/claims/claims_test.go index ac1cd4554..4ef838a3d 100644 --- a/router/middleware/claims/claims_test.go +++ b/router/middleware/claims/claims_test.go @@ -15,10 +15,10 @@ import ( "github.com/gin-gonic/gin" "github.com/golang-jwt/jwt/v5" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/internal/token" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" ) func TestClaims_Retrieve(t *testing.T) { @@ -51,12 +51,11 @@ func TestClaims_Retrieve(t *testing.T) { func TestClaims_Establish(t *testing.T) { // setup types - user := new(library.User) + user := new(api.User) user.SetID(1) user.SetName("foo") user.SetRefreshToken("fresh") user.SetToken("bar") - user.SetHash("baz") user.SetActive(true) user.SetAdmin(false) user.SetFavorites([]string{}) @@ -262,10 +261,9 @@ func TestClaims_Establish_BadToken(t *testing.T) { context, engine := gin.CreateTestContext(resp) context.Request, _ = http.NewRequest(http.MethodGet, "/workers/host", nil) - u := new(library.User) + u := new(api.User) u.SetID(1) u.SetName("octocat") - u.SetHash("abc") // setup database db, err := database.NewTest() diff --git a/router/middleware/logger_test.go b/router/middleware/logger_test.go index 46993f221..1521eba32 100644 --- a/router/middleware/logger_test.go +++ b/router/middleware/logger_test.go @@ -55,7 +55,7 @@ func TestMiddleware_Logger(t *testing.T) { s.SetNumber(1) s.SetName("foo") - u := new(library.User) + u := new(api.User) u.SetID(1) u.SetName("foo") u.SetToken("bar") diff --git a/router/middleware/perm/perm_test.go b/router/middleware/perm/perm_test.go index adf53ffe2..b34293f91 100644 --- a/router/middleware/perm/perm_test.go +++ b/router/middleware/perm/perm_test.go @@ -38,11 +38,10 @@ func TestPerm_MustPlatformAdmin(t *testing.T) { UserRefreshTokenDuration: time.Minute * 30, } - u := new(library.User) + u := new(api.User) u.SetID(1) u.SetName("foob") u.SetToken("bar") - u.SetHash("baz") u.SetAdmin(true) mto := &token.MintTokenOpts{ @@ -120,11 +119,10 @@ func TestPerm_MustPlatformAdmin_NotAdmin(t *testing.T) { UserRefreshTokenDuration: time.Minute * 30, } - u := new(library.User) + u := new(api.User) u.SetID(1) u.SetName("foob") u.SetToken("bar") - u.SetHash("baz") u.SetAdmin(false) mto := &token.MintTokenOpts{ @@ -247,11 +245,10 @@ func TestPerm_MustWorkerRegisterToken_PlatAdmin(t *testing.T) { UserRefreshTokenDuration: time.Minute * 30, } - u := new(library.User) + u := new(api.User) u.SetID(1) u.SetName("vela-worker") u.SetToken("bar") - u.SetHash("baz") u.SetAdmin(true) mto := &token.MintTokenOpts{ @@ -399,7 +396,7 @@ func TestPerm_MustBuildAccess(t *testing.T) { // setup types secret := "superSecret" - owner := new(library.User) + owner := new(api.User) owner.SetID(1) r := new(api.Repo) @@ -488,7 +485,7 @@ func TestPerm_MustBuildAccess_PlatAdmin(t *testing.T) { // setup types secret := "superSecret" - owner := new(library.User) + owner := new(api.User) owner.SetID(1) r := new(api.Repo) @@ -505,11 +502,10 @@ func TestPerm_MustBuildAccess_PlatAdmin(t *testing.T) { b.SetRepoID(1) b.SetNumber(1) - u := new(library.User) + u := new(api.User) u.SetID(1) u.SetName("admin") u.SetToken("bar") - u.SetHash("baz") u.SetAdmin(true) tm := &token.Manager{ @@ -584,7 +580,7 @@ func TestPerm_MustBuildToken_WrongBuild(t *testing.T) { // setup types secret := "superSecret" - owner := new(library.User) + owner := new(api.User) owner.SetID(1) r := new(api.Repo) @@ -673,7 +669,7 @@ func TestPerm_MustSecretAdmin_BuildToken_Repo(t *testing.T) { // setup types secret := "superSecret" - owner := new(library.User) + owner := new(api.User) owner.SetID(1) r := new(api.Repo) @@ -759,7 +755,7 @@ func TestPerm_MustSecretAdmin_BuildToken_Org(t *testing.T) { // setup types secret := "superSecret" - owner := new(library.User) + owner := new(api.User) owner.SetID(1) r := new(api.Repo) @@ -845,7 +841,7 @@ func TestPerm_MustSecretAdmin_BuildToken_Shared(t *testing.T) { // setup types secret := "superSecret" - owner := new(library.User) + owner := new(api.User) owner.SetID(1) r := new(api.Repo) @@ -938,7 +934,7 @@ func TestPerm_MustAdmin(t *testing.T) { UserRefreshTokenDuration: time.Minute * 30, } - owner := new(library.User) + owner := new(api.User) owner.SetID(1) r := new(api.Repo) @@ -950,11 +946,10 @@ func TestPerm_MustAdmin(t *testing.T) { r.SetFullName("foo/bar") r.SetVisibility("public") - u := new(library.User) + u := new(api.User) u.SetID(1) u.SetName("foob") u.SetToken("bar") - u.SetHash("baz") u.SetAdmin(false) mto := &token.MintTokenOpts{ @@ -1039,7 +1034,7 @@ func TestPerm_MustAdmin_PlatAdmin(t *testing.T) { UserRefreshTokenDuration: time.Minute * 30, } - owner := new(library.User) + owner := new(api.User) owner.SetID(1) r := new(api.Repo) @@ -1051,11 +1046,10 @@ func TestPerm_MustAdmin_PlatAdmin(t *testing.T) { r.SetFullName("foo/bar") r.SetVisibility("public") - u := new(library.User) + u := new(api.User) u.SetID(1) u.SetName("foob") u.SetToken("bar") - u.SetHash("baz") u.SetAdmin(true) mto := &token.MintTokenOpts{ @@ -1140,7 +1134,7 @@ func TestPerm_MustAdmin_NotAdmin(t *testing.T) { UserRefreshTokenDuration: time.Minute * 30, } - owner := new(library.User) + owner := new(api.User) owner.SetID(1) r := new(api.Repo) @@ -1152,11 +1146,10 @@ func TestPerm_MustAdmin_NotAdmin(t *testing.T) { r.SetFullName("foo/bar") r.SetVisibility("public") - u := new(library.User) + u := new(api.User) u.SetID(1) u.SetName("foob") u.SetToken("bar") - u.SetHash("baz") u.SetAdmin(false) mto := &token.MintTokenOpts{ @@ -1241,7 +1234,7 @@ func TestPerm_MustWrite(t *testing.T) { UserRefreshTokenDuration: time.Minute * 30, } - owner := new(library.User) + owner := new(api.User) owner.SetID(1) r := new(api.Repo) @@ -1253,11 +1246,10 @@ func TestPerm_MustWrite(t *testing.T) { r.SetFullName("foo/bar") r.SetVisibility("public") - u := new(library.User) + u := new(api.User) u.SetID(1) u.SetName("foob") u.SetToken("bar") - u.SetHash("baz") u.SetAdmin(false) mto := &token.MintTokenOpts{ @@ -1342,7 +1334,7 @@ func TestPerm_MustWrite_PlatAdmin(t *testing.T) { UserRefreshTokenDuration: time.Minute * 30, } - owner := new(library.User) + owner := new(api.User) owner.SetID(1) r := new(api.Repo) @@ -1354,11 +1346,10 @@ func TestPerm_MustWrite_PlatAdmin(t *testing.T) { r.SetFullName("foo/bar") r.SetVisibility("public") - u := new(library.User) + u := new(api.User) u.SetID(1) u.SetName("foob") u.SetToken("bar") - u.SetHash("baz") u.SetAdmin(true) mto := &token.MintTokenOpts{ @@ -1443,7 +1434,7 @@ func TestPerm_MustWrite_RepoAdmin(t *testing.T) { UserRefreshTokenDuration: time.Minute * 30, } - owner := new(library.User) + owner := new(api.User) owner.SetID(1) r := new(api.Repo) @@ -1455,11 +1446,10 @@ func TestPerm_MustWrite_RepoAdmin(t *testing.T) { r.SetFullName("foo/bar") r.SetVisibility("public") - u := new(library.User) + u := new(api.User) u.SetID(1) u.SetName("foob") u.SetToken("bar") - u.SetHash("baz") u.SetAdmin(false) mto := &token.MintTokenOpts{ @@ -1544,7 +1534,7 @@ func TestPerm_MustWrite_NotWrite(t *testing.T) { UserRefreshTokenDuration: time.Minute * 30, } - owner := new(library.User) + owner := new(api.User) owner.SetID(1) r := new(api.Repo) @@ -1556,11 +1546,10 @@ func TestPerm_MustWrite_NotWrite(t *testing.T) { r.SetFullName("foo/bar") r.SetVisibility("public") - u := new(library.User) + u := new(api.User) u.SetID(1) u.SetName("foob") u.SetToken("bar") - u.SetHash("baz") u.SetAdmin(false) mto := &token.MintTokenOpts{ @@ -1645,7 +1634,7 @@ func TestPerm_MustRead(t *testing.T) { UserRefreshTokenDuration: time.Minute * 30, } - owner := new(library.User) + owner := new(api.User) owner.SetID(1) r := new(api.Repo) @@ -1657,11 +1646,10 @@ func TestPerm_MustRead(t *testing.T) { r.SetFullName("foo/bar") r.SetVisibility("private") - u := new(library.User) + u := new(api.User) u.SetID(1) u.SetName("foob") u.SetToken("bar") - u.SetHash("baz") u.SetAdmin(false) mto := &token.MintTokenOpts{ @@ -1746,7 +1734,7 @@ func TestPerm_MustRead_PlatAdmin(t *testing.T) { UserRefreshTokenDuration: time.Minute * 30, } - owner := new(library.User) + owner := new(api.User) owner.SetID(1) r := new(api.Repo) @@ -1758,11 +1746,10 @@ func TestPerm_MustRead_PlatAdmin(t *testing.T) { r.SetFullName("foo/bar") r.SetVisibility("private") - u := new(library.User) + u := new(api.User) u.SetID(1) u.SetName("foob") u.SetToken("bar") - u.SetHash("baz") u.SetAdmin(true) mto := &token.MintTokenOpts{ @@ -1847,7 +1834,7 @@ func TestPerm_MustRead_WorkerBuildToken(t *testing.T) { UserRefreshTokenDuration: time.Minute * 30, } - owner := new(library.User) + owner := new(api.User) owner.SetID(1) r := new(api.Repo) @@ -1936,7 +1923,7 @@ func TestPerm_MustRead_RepoAdmin(t *testing.T) { UserRefreshTokenDuration: time.Minute * 30, } - owner := new(library.User) + owner := new(api.User) owner.SetID(1) r := new(api.Repo) @@ -1948,11 +1935,10 @@ func TestPerm_MustRead_RepoAdmin(t *testing.T) { r.SetFullName("foo/bar") r.SetVisibility("private") - u := new(library.User) + u := new(api.User) u.SetID(1) u.SetName("foob") u.SetToken("bar") - u.SetHash("baz") u.SetAdmin(false) mto := &token.MintTokenOpts{ @@ -2037,7 +2023,7 @@ func TestPerm_MustRead_RepoWrite(t *testing.T) { UserRefreshTokenDuration: time.Minute * 30, } - owner := new(library.User) + owner := new(api.User) owner.SetID(1) r := new(api.Repo) @@ -2049,11 +2035,10 @@ func TestPerm_MustRead_RepoWrite(t *testing.T) { r.SetFullName("foo/bar") r.SetVisibility("private") - u := new(library.User) + u := new(api.User) u.SetID(1) u.SetName("foob") u.SetToken("bar") - u.SetHash("baz") u.SetAdmin(false) mto := &token.MintTokenOpts{ @@ -2138,7 +2123,7 @@ func TestPerm_MustRead_RepoPublic(t *testing.T) { UserRefreshTokenDuration: time.Minute * 30, } - owner := new(library.User) + owner := new(api.User) owner.SetID(1) r := new(api.Repo) @@ -2150,11 +2135,10 @@ func TestPerm_MustRead_RepoPublic(t *testing.T) { r.SetFullName("foo/bar") r.SetVisibility("public") - u := new(library.User) + u := new(api.User) u.SetID(1) u.SetName("foob") u.SetToken("bar") - u.SetHash("baz") u.SetAdmin(false) mto := &token.MintTokenOpts{ @@ -2239,7 +2223,7 @@ func TestPerm_MustRead_NotRead(t *testing.T) { UserRefreshTokenDuration: time.Minute * 30, } - owner := new(library.User) + owner := new(api.User) owner.SetID(1) r := new(api.Repo) @@ -2251,11 +2235,10 @@ func TestPerm_MustRead_NotRead(t *testing.T) { r.SetFullName("foo/bar") r.SetVisibility("private") - u := new(library.User) + u := new(api.User) u.SetID(1) u.SetName("foob") u.SetToken("bar") - u.SetHash("baz") u.SetAdmin(false) mto := &token.MintTokenOpts{ diff --git a/router/middleware/pipeline/pipeline_test.go b/router/middleware/pipeline/pipeline_test.go index c4356f6dc..489025859 100644 --- a/router/middleware/pipeline/pipeline_test.go +++ b/router/middleware/pipeline/pipeline_test.go @@ -68,7 +68,7 @@ func TestPipeline_Retrieve(t *testing.T) { func TestPipeline_Establish(t *testing.T) { // setup types - owner := new(library.User) + owner := new(api.User) owner.SetID(1) r := new(api.Repo) @@ -173,7 +173,7 @@ func TestPipeline_Establish_NoRepo(t *testing.T) { func TestPipeline_Establish_NoPipelineParameter(t *testing.T) { // setup types - owner := new(library.User) + owner := new(api.User) owner.SetID(1) r := new(api.Repo) @@ -233,7 +233,7 @@ func TestPipeline_Establish_NoPipeline(t *testing.T) { UserRefreshTokenDuration: time.Minute * 30, } - owner := new(library.User) + owner := new(api.User) owner.SetID(1) r := new(api.Repo) @@ -245,11 +245,10 @@ func TestPipeline_Establish_NoPipeline(t *testing.T) { r.SetFullName("foo/bar") r.SetVisibility("public") - u := new(library.User) + u := new(api.User) u.SetID(1) u.SetName("foo") u.SetToken("bar") - u.SetHash("baz") u.SetAdmin(true) m := &internal.Metadata{ diff --git a/router/middleware/repo/repo_test.go b/router/middleware/repo/repo_test.go index 41595e60f..261941d4f 100644 --- a/router/middleware/repo/repo_test.go +++ b/router/middleware/repo/repo_test.go @@ -14,7 +14,6 @@ import ( api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/org" - "github.com/go-vela/types/library" ) func TestRepo_Retrieve(t *testing.T) { @@ -37,13 +36,12 @@ func TestRepo_Retrieve(t *testing.T) { func TestRepo_Establish(t *testing.T) { // setup types - owner := new(library.User) + owner := new(api.User) owner.SetID(1) owner.SetName("foo") owner.SetActive(false) owner.SetAdmin(false) owner.SetFavorites([]string{}) - owner.SetHash("bar") owner.SetToken("baz") owner.SetRefreshToken("fresh") diff --git a/router/middleware/service/service_test.go b/router/middleware/service/service_test.go index 1d0b8fda7..fcf7fc585 100644 --- a/router/middleware/service/service_test.go +++ b/router/middleware/service/service_test.go @@ -39,7 +39,7 @@ func TestService_Retrieve(t *testing.T) { func TestService_Establish(t *testing.T) { // setup types - owner := new(library.User) + owner := new(api.User) owner.SetID(1) r := new(api.Repo) @@ -203,7 +203,7 @@ func TestService_Establish_NoBuild(t *testing.T) { func TestService_Establish_NoServiceParameter(t *testing.T) { // setup types - owner := new(library.User) + owner := new(api.User) owner.SetID(1) r := new(api.Repo) @@ -262,7 +262,7 @@ func TestService_Establish_NoServiceParameter(t *testing.T) { func TestService_Establish_InvalidServiceParameter(t *testing.T) { // setup types - owner := new(library.User) + owner := new(api.User) owner.SetID(1) r := new(api.Repo) diff --git a/router/middleware/step/step_test.go b/router/middleware/step/step_test.go index 265ce5306..6e26dd5ba 100644 --- a/router/middleware/step/step_test.go +++ b/router/middleware/step/step_test.go @@ -40,7 +40,7 @@ func TestStep_Retrieve(t *testing.T) { func TestStep_Establish(t *testing.T) { // setup types - owner := new(library.User) + owner := new(api.User) owner.SetID(1) r := new(api.Repo) @@ -158,7 +158,7 @@ func TestStep_Establish_NoRepo(t *testing.T) { func TestStep_Establish_NoBuild(t *testing.T) { // setup types - owner := new(library.User) + owner := new(api.User) owner.SetID(1) r := new(api.Repo) @@ -209,7 +209,7 @@ func TestStep_Establish_NoBuild(t *testing.T) { func TestStep_Establish_NoStepParameter(t *testing.T) { // setup types - owner := new(library.User) + owner := new(api.User) owner.SetID(1) r := new(api.Repo) @@ -268,7 +268,7 @@ func TestStep_Establish_NoStepParameter(t *testing.T) { func TestStep_Establish_InvalidStepParameter(t *testing.T) { // setup types - owner := new(library.User) + owner := new(api.User) owner.SetID(1) r := new(api.Repo) @@ -327,7 +327,7 @@ func TestStep_Establish_InvalidStepParameter(t *testing.T) { func TestStep_Establish_NoStep(t *testing.T) { // setup types - owner := new(library.User) + owner := new(api.User) owner.SetID(1) r := new(api.Repo) diff --git a/router/middleware/user/context.go b/router/middleware/user/context.go index 0b4a54891..99a4fc3d7 100644 --- a/router/middleware/user/context.go +++ b/router/middleware/user/context.go @@ -5,7 +5,7 @@ package user import ( "context" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" ) const key = "user" @@ -16,13 +16,13 @@ type Setter interface { } // FromContext returns the User associated with this context. -func FromContext(c context.Context) *library.User { +func FromContext(c context.Context) *api.User { value := c.Value(key) if value == nil { return nil } - u, ok := value.(*library.User) + u, ok := value.(*api.User) if !ok { return nil } @@ -32,6 +32,6 @@ func FromContext(c context.Context) *library.User { // ToContext adds the User to this context if it supports // the Setter interface. -func ToContext(c Setter, u *library.User) { +func ToContext(c Setter, u *api.User) { c.Set(key, u) } diff --git a/router/middleware/user/context_test.go b/router/middleware/user/context_test.go index 50d502ac2..29f400329 100644 --- a/router/middleware/user/context_test.go +++ b/router/middleware/user/context_test.go @@ -7,13 +7,13 @@ import ( "github.com/gin-gonic/gin" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" ) func TestUser_FromContext(t *testing.T) { // setup types uID := int64(1) - want := &library.User{ID: &uID} + want := &api.User{ID: &uID} // setup context gin.SetMode(gin.TestMode) @@ -72,7 +72,7 @@ func TestUser_FromContext_Empty(t *testing.T) { func TestUser_ToContext(t *testing.T) { // setup types uID := int64(1) - want := &library.User{ID: &uID} + want := &api.User{ID: &uID} // setup context gin.SetMode(gin.TestMode) diff --git a/router/middleware/user/user.go b/router/middleware/user/user.go index ad8676b21..89b286b08 100644 --- a/router/middleware/user/user.go +++ b/router/middleware/user/user.go @@ -9,15 +9,15 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/claims" "github.com/go-vela/server/util" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" ) // Retrieve gets the user in the given context. -func Retrieve(c *gin.Context) *library.User { +func Retrieve(c *gin.Context) *api.User { return FromContext(c) } @@ -29,7 +29,7 @@ func Establish() gin.HandlerFunc { // if token is not a user token or claims were not retrieved, establish empty user to better handle nil checks if cl == nil || !strings.EqualFold(cl.TokenType, constants.UserAccessTokenType) { - u := new(library.User) + u := new(api.User) ToContext(c, u) c.Next() diff --git a/router/middleware/user/user_test.go b/router/middleware/user/user_test.go index d8d97121c..04e4499b2 100644 --- a/router/middleware/user/user_test.go +++ b/router/middleware/user/user_test.go @@ -14,18 +14,18 @@ import ( "github.com/gin-gonic/gin" "github.com/golang-jwt/jwt/v5" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/internal/token" "github.com/go-vela/server/router/middleware/claims" "github.com/go-vela/server/scm" "github.com/go-vela/server/scm/github" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" ) func TestUser_Retrieve(t *testing.T) { // setup types - want := new(library.User) + want := new(api.User) want.SetID(1) // setup context @@ -53,17 +53,16 @@ func TestUser_Establish(t *testing.T) { UserRefreshTokenDuration: time.Minute * 30, } - want := new(library.User) + want := new(api.User) want.SetID(1) want.SetName("foo") want.SetRefreshToken("fresh") want.SetToken("bar") - want.SetHash("baz") want.SetActive(false) want.SetAdmin(false) want.SetFavorites([]string{}) - got := new(library.User) + got := new(api.User) gin.SetMode(gin.TestMode) @@ -189,9 +188,9 @@ func TestUser_Establish_DiffTokenType(t *testing.T) { UserRefreshTokenDuration: time.Minute * 30, } - want := new(library.User) + want := new(api.User) - got := new(library.User) + got := new(api.User) // setup context gin.SetMode(gin.TestMode) @@ -280,7 +279,7 @@ func TestUser_Establish_NoUser(t *testing.T) { UserRefreshTokenDuration: time.Minute * 30, } - u := new(library.User) + u := new(api.User) u.SetID(1) u.SetName("foo") diff --git a/scm/github/access.go b/scm/github/access.go index 40b9b9de1..bec1307d3 100644 --- a/scm/github/access.go +++ b/scm/github/access.go @@ -9,11 +9,11 @@ import ( "github.com/google/go-github/v61/github" "github.com/sirupsen/logrus" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" ) // OrgAccess captures the user's access level for an org. -func (c *client) OrgAccess(ctx context.Context, u *library.User, org string) (string, error) { +func (c *client) OrgAccess(ctx context.Context, u *api.User, org string) (string, error) { c.Logger.WithFields(logrus.Fields{ "org": org, "user": u.GetName(), @@ -81,7 +81,7 @@ func (c *client) RepoAccess(ctx context.Context, name, token, org, repo string) } // TeamAccess captures the user's access level for a team. -func (c *client) TeamAccess(ctx context.Context, u *library.User, org, team string) (string, error) { +func (c *client) TeamAccess(ctx context.Context, u *api.User, org, team string) (string, error) { c.Logger.WithFields(logrus.Fields{ "org": org, "team": team, @@ -143,7 +143,7 @@ func (c *client) TeamAccess(ctx context.Context, u *library.User, org, team stri } // ListUsersTeamsForOrg captures the user's teams for an org. -func (c *client) ListUsersTeamsForOrg(ctx context.Context, u *library.User, org string) ([]string, error) { +func (c *client) ListUsersTeamsForOrg(ctx context.Context, u *api.User, org string) ([]string, error) { c.Logger.WithFields(logrus.Fields{ "org": org, "user": u.GetName(), @@ -187,7 +187,7 @@ func (c *client) ListUsersTeamsForOrg(ctx context.Context, u *library.User, org } // RepoContributor lists all contributors from a repository and checks if the sender is one of the contributors. -func (c *client) RepoContributor(ctx context.Context, owner *library.User, sender, org, repo string) (bool, error) { +func (c *client) RepoContributor(ctx context.Context, owner *api.User, sender, org, repo string) (bool, error) { c.Logger.WithFields(logrus.Fields{ "org": org, "repo": repo, diff --git a/scm/github/access_test.go b/scm/github/access_test.go index 77ba7e347..c730c1f4d 100644 --- a/scm/github/access_test.go +++ b/scm/github/access_test.go @@ -11,7 +11,7 @@ import ( "github.com/gin-gonic/gin" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" ) func TestGithub_OrgAccess_Admin(t *testing.T) { @@ -34,7 +34,7 @@ func TestGithub_OrgAccess_Admin(t *testing.T) { // setup types want := "admin" - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -76,7 +76,7 @@ func TestGithub_OrgAccess_Member(t *testing.T) { // setup types want := "member" - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -106,7 +106,7 @@ func TestGithub_OrgAccess_NotFound(t *testing.T) { // setup types want := "" - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -144,7 +144,7 @@ func TestGithub_OrgAccess_Pending(t *testing.T) { // setup types want := "" - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -174,7 +174,7 @@ func TestGithub_OrgAccess_Personal(t *testing.T) { // setup types want := "admin" - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -212,7 +212,7 @@ func TestGithub_RepoAccess_Admin(t *testing.T) { // setup types want := "admin" - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -242,7 +242,7 @@ func TestGithub_RepoAccess_NotFound(t *testing.T) { // setup types want := "" - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -280,7 +280,7 @@ func TestGithub_TeamAccess_Admin(t *testing.T) { // setup types want := "admin" - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -322,7 +322,7 @@ func TestGithub_TeamAccess_NoAccess(t *testing.T) { // setup types want := "" - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -352,7 +352,7 @@ func TestGithub_TeamAccess_NotFound(t *testing.T) { // setup types want := "" - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -390,7 +390,7 @@ func TestGithub_TeamList(t *testing.T) { // setup types want := []string{"Justice League", "octocat"} - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -436,7 +436,7 @@ func TestGithub_RepoContributor(t *testing.T) { defer s.Close() // setup types - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") diff --git a/scm/github/authentication.go b/scm/github/authentication.go index 1e76770fb..f152abb95 100644 --- a/scm/github/authentication.go +++ b/scm/github/authentication.go @@ -12,8 +12,8 @@ import ( "github.com/google/go-github/v61/github" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/random" - "github.com/go-vela/types/library" ) // Authorize uses the given access token to authorize the user. @@ -56,7 +56,7 @@ func (c *client) Login(ctx context.Context, w http.ResponseWriter, r *http.Reque // Authenticate completes the authentication workflow for the session // and returns the remote user details. -func (c *client) Authenticate(ctx context.Context, w http.ResponseWriter, r *http.Request, oAuthState string) (*library.User, error) { +func (c *client) Authenticate(ctx context.Context, w http.ResponseWriter, r *http.Request, oAuthState string) (*api.User, error) { c.Logger.Trace("authenticating user") // get the OAuth code @@ -89,7 +89,7 @@ func (c *client) Authenticate(ctx context.Context, w http.ResponseWriter, r *htt return nil, err } - return &library.User{ + return &api.User{ Name: &u, Token: &token.AccessToken, }, nil @@ -97,7 +97,7 @@ func (c *client) Authenticate(ctx context.Context, w http.ResponseWriter, r *htt // AuthenticateToken completes the authentication workflow // for the session and returns the remote user details. -func (c *client) AuthenticateToken(ctx context.Context, r *http.Request) (*library.User, error) { +func (c *client) AuthenticateToken(ctx context.Context, r *http.Request) (*api.User, error) { c.Logger.Trace("authenticating user via token") token := r.Header.Get("Token") @@ -120,7 +120,7 @@ func (c *client) AuthenticateToken(ctx context.Context, r *http.Request) (*libra return nil, err } - return &library.User{ + return &api.User{ Name: &u, Token: &token, }, nil diff --git a/scm/github/authentication_test.go b/scm/github/authentication_test.go index 8c076b0c5..12b9b91b2 100644 --- a/scm/github/authentication_test.go +++ b/scm/github/authentication_test.go @@ -11,7 +11,7 @@ import ( "github.com/gin-gonic/gin" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" ) func TestGithub_Authenticate(t *testing.T) { @@ -38,7 +38,7 @@ func TestGithub_Authenticate(t *testing.T) { defer s.Close() // setup types - want := new(library.User) + want := new(api.User) want.SetName("octocat") want.SetToken("foo") @@ -326,7 +326,7 @@ func TestGithub_AuthenticateToken(t *testing.T) { defer s.Close() // setup types - want := new(library.User) + want := new(api.User) want.SetName("octocat") want.SetToken("foo") diff --git a/scm/github/changeset_test.go b/scm/github/changeset_test.go index 713f08f9a..c3c411769 100644 --- a/scm/github/changeset_test.go +++ b/scm/github/changeset_test.go @@ -12,7 +12,6 @@ import ( "github.com/gin-gonic/gin" api "github.com/go-vela/server/api/types" - "github.com/go-vela/types/library" ) func TestGithub_Changeset(t *testing.T) { @@ -35,7 +34,7 @@ func TestGithub_Changeset(t *testing.T) { // setup types want := []string{"file1.txt"} - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -82,7 +81,7 @@ func TestGithub_ChangesetPR(t *testing.T) { // setup types want := []string{"file1.txt"} - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") diff --git a/scm/github/deployment.go b/scm/github/deployment.go index 331164411..24d0f083e 100644 --- a/scm/github/deployment.go +++ b/scm/github/deployment.go @@ -15,7 +15,7 @@ import ( ) // GetDeployment gets a deployment from the GitHub repo. -func (c *client) GetDeployment(ctx context.Context, u *library.User, r *api.Repo, id int64) (*library.Deployment, error) { +func (c *client) GetDeployment(ctx context.Context, u *api.User, r *api.Repo, id int64) (*library.Deployment, error) { c.Logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), @@ -56,7 +56,7 @@ func (c *client) GetDeployment(ctx context.Context, u *library.User, r *api.Repo } // GetDeploymentCount counts a list of deployments from the GitHub repo. -func (c *client) GetDeploymentCount(ctx context.Context, u *library.User, r *api.Repo) (int64, error) { +func (c *client) GetDeploymentCount(ctx context.Context, u *api.User, r *api.Repo) (int64, error) { c.Logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), @@ -98,7 +98,7 @@ func (c *client) GetDeploymentCount(ctx context.Context, u *library.User, r *api } // GetDeploymentList gets a list of deployments from the GitHub repo. -func (c *client) GetDeploymentList(ctx context.Context, u *library.User, r *api.Repo, page, perPage int) ([]*library.Deployment, error) { +func (c *client) GetDeploymentList(ctx context.Context, u *api.User, r *api.Repo, page, perPage int) ([]*library.Deployment, error) { c.Logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), @@ -156,7 +156,7 @@ func (c *client) GetDeploymentList(ctx context.Context, u *library.User, r *api. } // CreateDeployment creates a new deployment for the GitHub repo. -func (c *client) CreateDeployment(ctx context.Context, u *library.User, r *api.Repo, d *library.Deployment) error { +func (c *client) CreateDeployment(ctx context.Context, u *api.User, r *api.Repo, d *library.Deployment) error { c.Logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), diff --git a/scm/github/deployment_test.go b/scm/github/deployment_test.go index 622dacfb4..f985194ee 100644 --- a/scm/github/deployment_test.go +++ b/scm/github/deployment_test.go @@ -32,7 +32,7 @@ func TestGithub_CreateDeployment(t *testing.T) { defer s.Close() // setup types - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") diff --git a/scm/github/org.go b/scm/github/org.go index 48b3701a8..2ac0ba714 100644 --- a/scm/github/org.go +++ b/scm/github/org.go @@ -8,11 +8,11 @@ import ( "github.com/sirupsen/logrus" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" ) // GetOrgName gets org name from Github. -func (c *client) GetOrgName(ctx context.Context, u *library.User, o string) (string, error) { +func (c *client) GetOrgName(ctx context.Context, u *api.User, o string) (string, error) { c.Logger.WithFields(logrus.Fields{ "org": o, "user": u.GetName(), diff --git a/scm/github/org_test.go b/scm/github/org_test.go index b9d64e84a..75e8d3ed1 100644 --- a/scm/github/org_test.go +++ b/scm/github/org_test.go @@ -11,7 +11,7 @@ import ( "github.com/gin-gonic/gin" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" ) func TestGithub_GetOrgName(t *testing.T) { @@ -32,7 +32,7 @@ func TestGithub_GetOrgName(t *testing.T) { defer s.Close() // setup types - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -74,7 +74,7 @@ func TestGithub_GetOrgName_Personal(t *testing.T) { defer s.Close() // setup types - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -115,7 +115,7 @@ func TestGithub_GetOrgName_Fail(t *testing.T) { defer s.Close() // setup types - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") diff --git a/scm/github/repo.go b/scm/github/repo.go index ced606756..712dada46 100644 --- a/scm/github/repo.go +++ b/scm/github/repo.go @@ -20,7 +20,7 @@ import ( // ConfigBackoff is a wrapper for Config that will retry five times if the function // fails to retrieve the yaml/yml file. -func (c *client) ConfigBackoff(ctx context.Context, u *library.User, r *api.Repo, ref string) (data []byte, err error) { +func (c *client) ConfigBackoff(ctx context.Context, u *api.User, r *api.Repo, ref string) (data []byte, err error) { // number of times to retry retryLimit := 5 @@ -48,7 +48,7 @@ func (c *client) ConfigBackoff(ctx context.Context, u *library.User, r *api.Repo } // Config gets the pipeline configuration from the GitHub repo. -func (c *client) Config(ctx context.Context, u *library.User, r *api.Repo, ref string) ([]byte, error) { +func (c *client) Config(ctx context.Context, u *api.User, r *api.Repo, ref string) ([]byte, error) { c.Logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), @@ -95,7 +95,7 @@ func (c *client) Config(ctx context.Context, u *library.User, r *api.Repo, ref s } // Disable deactivates a repo by deleting the webhook. -func (c *client) Disable(ctx context.Context, u *library.User, org, name string) error { +func (c *client) Disable(ctx context.Context, u *api.User, org, name string) error { c.Logger.WithFields(logrus.Fields{ "org": org, "repo": name, @@ -150,7 +150,7 @@ func (c *client) Disable(ctx context.Context, u *library.User, org, name string) } // Enable activates a repo by creating the webhook. -func (c *client) Enable(ctx context.Context, u *library.User, r *api.Repo, h *library.Hook) (*library.Hook, string, error) { +func (c *client) Enable(ctx context.Context, u *api.User, r *api.Repo, h *library.Hook) (*library.Hook, string, error) { c.Logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), @@ -224,7 +224,7 @@ func (c *client) Enable(ctx context.Context, u *library.User, r *api.Repo, h *li } // Update edits a repo webhook. -func (c *client) Update(ctx context.Context, u *library.User, r *api.Repo, hookID int64) (bool, error) { +func (c *client) Update(ctx context.Context, u *api.User, r *api.Repo, hookID int64) (bool, error) { c.Logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), @@ -281,7 +281,7 @@ func (c *client) Update(ctx context.Context, u *library.User, r *api.Repo, hookI } // Status sends the commit status for the given SHA from the GitHub repo. -func (c *client) Status(ctx context.Context, u *library.User, b *library.Build, org, name string) error { +func (c *client) Status(ctx context.Context, u *api.User, b *library.Build, org, name string) error { c.Logger.WithFields(logrus.Fields{ "build": b.GetNumber(), "org": org, @@ -394,7 +394,7 @@ func (c *client) Status(ctx context.Context, u *library.User, b *library.Build, } // StepStatus sends the commit status for the given SHA to the GitHub repo with the step as the context. -func (c *client) StepStatus(ctx context.Context, u *library.User, b *library.Build, s *library.Step, org, name string) error { +func (c *client) StepStatus(ctx context.Context, u *api.User, b *library.Build, s *library.Step, org, name string) error { c.Logger.WithFields(logrus.Fields{ "build": b.GetNumber(), "org": org, @@ -463,7 +463,7 @@ func (c *client) StepStatus(ctx context.Context, u *library.User, b *library.Bui } // GetRepo gets repo information from Github. -func (c *client) GetRepo(ctx context.Context, u *library.User, r *api.Repo) (*api.Repo, int, error) { +func (c *client) GetRepo(ctx context.Context, u *api.User, r *api.Repo) (*api.Repo, int, error) { c.Logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), @@ -483,7 +483,7 @@ func (c *client) GetRepo(ctx context.Context, u *library.User, r *api.Repo) (*ap } // GetOrgAndRepoName returns the name of the org and the repository in the SCM. -func (c *client) GetOrgAndRepoName(ctx context.Context, u *library.User, o string, r string) (string, string, error) { +func (c *client) GetOrgAndRepoName(ctx context.Context, u *api.User, o string, r string) (string, string, error) { c.Logger.WithFields(logrus.Fields{ "org": o, "repo": r, @@ -503,7 +503,7 @@ func (c *client) GetOrgAndRepoName(ctx context.Context, u *library.User, o strin } // ListUserRepos returns a list of all repos the user has access to. -func (c *client) ListUserRepos(ctx context.Context, u *library.User) ([]*api.Repo, error) { +func (c *client) ListUserRepos(ctx context.Context, u *api.User) ([]*api.Repo, error) { c.Logger.WithFields(logrus.Fields{ "user": u.GetName(), }).Tracef("listing source repositories for %s", u.GetName()) @@ -605,7 +605,7 @@ func (c *client) GetPullRequest(ctx context.Context, r *api.Repo, number int) (s } // GetHTMLURL retrieves the html_url from repository contents from the GitHub repo. -func (c *client) GetHTMLURL(ctx context.Context, u *library.User, org, repo, name, ref string) (string, error) { +func (c *client) GetHTMLURL(ctx context.Context, u *api.User, org, repo, name, ref string) (string, error) { c.Logger.WithFields(logrus.Fields{ "org": org, "repo": repo, diff --git a/scm/github/repo_test.go b/scm/github/repo_test.go index 64d86cb21..d7c073892 100644 --- a/scm/github/repo_test.go +++ b/scm/github/repo_test.go @@ -47,7 +47,7 @@ func TestGithub_Config_YML(t *testing.T) { } // setup types - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -108,7 +108,7 @@ func TestGithub_ConfigBackoff_YML(t *testing.T) { } // setup types - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -162,7 +162,7 @@ func TestGithub_Config_YAML(t *testing.T) { } // setup types - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -216,7 +216,7 @@ func TestGithub_Config_Star(t *testing.T) { } // setup types - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -276,7 +276,7 @@ func TestGithub_Config_Star_Prefer(t *testing.T) { } // setup types - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -331,7 +331,7 @@ func TestGithub_Config_Py(t *testing.T) { } // setup types - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -381,7 +381,7 @@ func TestGithub_Config_YAML_BadRequest(t *testing.T) { defer s.Close() // setup types - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -423,7 +423,7 @@ func TestGithub_Config_NotFound(t *testing.T) { defer s.Close() // setup types - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -472,7 +472,7 @@ func TestGithub_Config_BadEncoding(t *testing.T) { defer s.Close() // setup types - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -519,7 +519,7 @@ func TestGithub_Disable(t *testing.T) { defer s.Close() // setup types - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -553,7 +553,7 @@ func TestGithub_Disable_NotFoundHooks(t *testing.T) { defer s.Close() // setup types - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -592,7 +592,7 @@ func TestGithub_Disable_HooksButNotFound(t *testing.T) { defer s.Close() // setup types - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -634,7 +634,7 @@ func TestGithub_Disable_MultipleHooks(t *testing.T) { defer s.Close() // setup types - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -674,7 +674,7 @@ func TestGithub_Enable(t *testing.T) { defer s.Close() // setup types - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -728,7 +728,7 @@ func TestGithub_Update(t *testing.T) { defer s.Close() // setup types - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -771,7 +771,7 @@ func TestGithub_Update_webhookExists_True(t *testing.T) { defer s.Close() // setup types - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -808,7 +808,7 @@ func TestGithub_Update_webhookExists_False(t *testing.T) { defer s.Close() // setup types - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -846,7 +846,7 @@ func TestGithub_Status_Deployment(t *testing.T) { defer s.Close() // setup types - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -891,7 +891,7 @@ func TestGithub_Status_Running(t *testing.T) { defer s.Close() // setup types - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -952,7 +952,7 @@ func TestGithub_Status_Success(t *testing.T) { defer s.Close() // setup types - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -1013,7 +1013,7 @@ func TestGithub_Status_Failure(t *testing.T) { defer s.Close() // setup types - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -1074,7 +1074,7 @@ func TestGithub_Status_Killed(t *testing.T) { defer s.Close() // setup types - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -1135,7 +1135,7 @@ func TestGithub_Status_Skipped(t *testing.T) { defer s.Close() // setup types - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -1196,7 +1196,7 @@ func TestGithub_Status_Error(t *testing.T) { defer s.Close() // setup types - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -1257,7 +1257,7 @@ func TestGithub_GetRepo(t *testing.T) { defer s.Close() // setup types - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -1311,7 +1311,7 @@ func TestGithub_GetRepo_Fail(t *testing.T) { defer s.Close() // setup types - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -1351,7 +1351,7 @@ func TestGithub_GetOrgAndRepoName(t *testing.T) { defer s.Close() // setup types - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -1397,7 +1397,7 @@ func TestGithub_GetOrgAndRepoName_Fail(t *testing.T) { defer s.Close() // setup types - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -1429,7 +1429,7 @@ func TestGithub_ListUserRepos(t *testing.T) { defer s.Close() // setup types - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -1477,7 +1477,7 @@ func TestGithub_ListUserRepos_Ineligible(t *testing.T) { defer s.Close() // setup types - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -1514,7 +1514,7 @@ func TestGithub_GetPullRequest(t *testing.T) { defer s.Close() // setup types - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") @@ -1571,7 +1571,7 @@ func TestGithub_GetBranch(t *testing.T) { defer s.Close() // setup types - u := new(library.User) + u := new(api.User) u.SetName("foo") u.SetToken("bar") diff --git a/scm/github/webhook.go b/scm/github/webhook.go index cd9ba0479..315d2ec45 100644 --- a/scm/github/webhook.go +++ b/scm/github/webhook.go @@ -99,7 +99,7 @@ func (c *client) VerifyWebhook(ctx context.Context, request *http.Request, r *ap } // RedeliverWebhook redelivers webhooks from GitHub. -func (c *client) RedeliverWebhook(ctx context.Context, u *library.User, r *api.Repo, h *library.Hook) error { +func (c *client) RedeliverWebhook(ctx context.Context, u *api.User, r *api.Repo, h *library.Hook) error { // create GitHub OAuth client with user's token //nolint:contextcheck // do not need to pass context in this instance client := c.newClientToken(*u.Token) diff --git a/scm/github/webhook_test.go b/scm/github/webhook_test.go index ec3f0466c..41a6a8153 100644 --- a/scm/github/webhook_test.go +++ b/scm/github/webhook_test.go @@ -1467,7 +1467,7 @@ func TestGithub_Redeliver_Webhook(t *testing.T) { defer s.Close() // setup types - u := new(library.User) + u := new(api.User) u.SetName("octocat") u.SetToken("foo") @@ -1511,7 +1511,7 @@ func TestGithub_GetDeliveryID(t *testing.T) { defer s.Close() // setup types - u := new(library.User) + u := new(api.User) u.SetName("octocat") u.SetToken("foo") diff --git a/scm/service.go b/scm/service.go index b04a8cd5e..f8f2bc14e 100644 --- a/scm/service.go +++ b/scm/service.go @@ -27,11 +27,11 @@ type Service interface { Authorize(context.Context, string) (string, error) // Authenticate defines a function that completes // the OAuth workflow for the session. - Authenticate(context.Context, http.ResponseWriter, *http.Request, string) (*library.User, error) + Authenticate(context.Context, http.ResponseWriter, *http.Request, string) (*api.User, error) // AuthenticateToken defines a function that completes // the OAuth workflow for the session using PAT Token - AuthenticateToken(context.Context, *http.Request) (*library.User, error) + AuthenticateToken(context.Context, *http.Request) (*api.User, error) // ValidateOAuthToken defines a function that validates // an OAuth access token was created by Vela @@ -45,22 +45,22 @@ type Service interface { // OrgAccess defines a function that captures // the user's access level for an org. - OrgAccess(context.Context, *library.User, string) (string, error) + OrgAccess(context.Context, *api.User, string) (string, error) // RepoAccess defines a function that captures // the user's access level for a repo. RepoAccess(context.Context, string, string, string, string) (string, error) // TeamAccess defines a function that captures // the user's access level for a team. - TeamAccess(context.Context, *library.User, string, string) (string, error) + TeamAccess(context.Context, *api.User, string, string) (string, error) // RepoContributor defines a function that captures // whether the user is a contributor for a repo. - RepoContributor(context.Context, *library.User, string, string, string) (bool, error) + RepoContributor(context.Context, *api.User, string, string, string) (bool, error) // Teams SCM Interface Functions // ListUsersTeamsForOrg defines a function that captures // the user's teams for an org - ListUsersTeamsForOrg(context.Context, *library.User, string) ([]string, error) + ListUsersTeamsForOrg(context.Context, *api.User, string) ([]string, error) // Changeset SCM Interface Functions @@ -79,44 +79,44 @@ type Service interface { // GetDeployment defines a function that // gets a deployment by number and repo. - GetDeployment(context.Context, *library.User, *api.Repo, int64) (*library.Deployment, error) + GetDeployment(context.Context, *api.User, *api.Repo, int64) (*library.Deployment, error) // GetDeploymentCount defines a function that // counts a list of all deployment for a repo. - GetDeploymentCount(context.Context, *library.User, *api.Repo) (int64, error) + GetDeploymentCount(context.Context, *api.User, *api.Repo) (int64, error) // GetDeploymentList defines a function that gets // a list of all deployments for a repo. - GetDeploymentList(context.Context, *library.User, *api.Repo, int, int) ([]*library.Deployment, error) + GetDeploymentList(context.Context, *api.User, *api.Repo, int, int) ([]*library.Deployment, error) // CreateDeployment defines a function that // creates a new deployment. - CreateDeployment(context.Context, *library.User, *api.Repo, *library.Deployment) error + CreateDeployment(context.Context, *api.User, *api.Repo, *library.Deployment) error // Repo SCM Interface Functions // Config defines a function that captures // the pipeline configuration from a repo. - Config(context.Context, *library.User, *api.Repo, string) ([]byte, error) + Config(context.Context, *api.User, *api.Repo, string) ([]byte, error) // ConfigBackoff is a truncated constant backoff wrapper for Config. // Retry again in five seconds if Config fails to retrieve yaml/yml file. // Will return an error after five failed attempts. - ConfigBackoff(context.Context, *library.User, *api.Repo, string) ([]byte, error) + ConfigBackoff(context.Context, *api.User, *api.Repo, string) ([]byte, error) // Disable defines a function that deactivates // a repo by destroying the webhook. - Disable(context.Context, *library.User, string, string) error + Disable(context.Context, *api.User, string, string) error // Enable defines a function that activates // a repo by creating the webhook. - Enable(context.Context, *library.User, *api.Repo, *library.Hook) (*library.Hook, string, error) + Enable(context.Context, *api.User, *api.Repo, *library.Hook) (*library.Hook, string, error) // Update defines a function that updates // a webhook for a specified repo. - Update(context.Context, *library.User, *api.Repo, int64) (bool, error) + Update(context.Context, *api.User, *api.Repo, int64) (bool, error) // Status defines a function that sends the // commit status for the given SHA from a repo. - Status(context.Context, *library.User, *library.Build, string, string) error + Status(context.Context, *api.User, *library.Build, string, string) error // StepStatus defines a function that sends the // commit status for the given SHA for a specified step context. - StepStatus(context.Context, *library.User, *library.Build, *library.Step, string, string) error + StepStatus(context.Context, *api.User, *library.Build, *library.Step, string, string) error // ListUserRepos defines a function that retrieves // all repos with admin rights for the user. - ListUserRepos(context.Context, *library.User) ([]*api.Repo, error) + ListUserRepos(context.Context, *api.User) ([]*api.Repo, error) // GetBranch defines a function that retrieves // a branch for a repo. GetBranch(context.Context, *api.Repo, string) (string, string, error) @@ -125,16 +125,16 @@ type Service interface { GetPullRequest(context.Context, *api.Repo, int) (string, string, string, string, error) // GetRepo defines a function that retrieves // details for a repo. - GetRepo(context.Context, *library.User, *api.Repo) (*api.Repo, int, error) + GetRepo(context.Context, *api.User, *api.Repo) (*api.Repo, int, error) // GetOrgAndRepoName defines a function that retrieves // the name of the org and repo in the SCM. - GetOrgAndRepoName(context.Context, *library.User, string, string) (string, string, error) + GetOrgAndRepoName(context.Context, *api.User, string, string) (string, string, error) // GetOrg defines a function that retrieves // the name for an org in the SCM. - GetOrgName(context.Context, *library.User, string) (string, error) + GetOrgName(context.Context, *api.User, string) (string, error) // GetHTMLURL defines a function that retrieves // a repository file's html_url. - GetHTMLURL(context.Context, *library.User, string, string, string, string) (string, error) + GetHTMLURL(context.Context, *api.User, string, string, string, string) (string, error) // Webhook SCM Interface Functions @@ -146,7 +146,7 @@ type Service interface { VerifyWebhook(context.Context, *http.Request, *api.Repo) error // RedeliverWebhook defines a function that // redelivers the webhook from the SCM. - RedeliverWebhook(context.Context, *library.User, *api.Repo, *library.Hook) error + RedeliverWebhook(context.Context, *api.User, *api.Repo, *library.Hook) error // TODO: Add convert functions to interface? } From 7263f25533bfbe2dc79c9abf1805b519f1f9d7f5 Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Tue, 16 Apr 2024 10:40:33 -0400 Subject: [PATCH 33/71] fix: return code in CompileAndPublish rather than handleError (#1107) * fix: return code in CompileAndPublish rather than handleError * style check * add return on errors for create and restart * update responses for create and restart to not mention webhooks --- api/build/compile_publish.go | 77 +++++++++++------------------------- api/build/create.go | 27 ++++++++----- api/build/restart.go | 24 +++++++---- api/webhook/post.go | 44 ++++++++++++--------- cmd/vela-server/schedule.go | 3 +- 5 files changed, 82 insertions(+), 93 deletions(-) diff --git a/api/build/compile_publish.go b/api/build/compile_publish.go index a9d52645f..cc6d121e4 100644 --- a/api/build/compile_publish.go +++ b/api/build/compile_publish.go @@ -20,7 +20,6 @@ import ( "github.com/go-vela/server/queue" "github.com/go-vela/server/queue/models" "github.com/go-vela/server/scm" - "github.com/go-vela/server/util" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" "github.com/go-vela/types/pipeline" @@ -50,7 +49,7 @@ func CompileAndPublish( scm scm.Service, compiler compiler.Engine, queue queue.Service, -) (*pipeline.Build, *models.Item, error) { +) (*pipeline.Build, *models.Item, int, error) { logrus.Debugf("generating queue items for build %s/%d", cfg.Repo.GetFullName(), cfg.Build.GetNumber()) // assign variables from form for readibility @@ -63,9 +62,8 @@ func CompileAndPublish( _, err := scm.RepoAccess(c, u.GetName(), u.GetToken(), r.GetOrg(), r.GetName()) if err != nil { retErr := fmt.Errorf("unable to publish build to queue: repository owner %s no longer has write access to repository %s", u.GetName(), r.GetFullName()) - util.HandleError(c, http.StatusUnauthorized, retErr) - return nil, nil, retErr + return nil, nil, http.StatusUnauthorized, retErr } // get pull request number from build if event is pull_request or issue_comment @@ -74,28 +72,19 @@ func CompileAndPublish( prNum, err = getPRNumberFromBuild(b) if err != nil { retErr := fmt.Errorf("%s: failed to get pull request number for %s: %w", baseErr, r.GetFullName(), err) - util.HandleError(c, http.StatusBadRequest, retErr) - return nil, nil, retErr + return nil, nil, http.StatusBadRequest, retErr } } // if the event is issue_comment and the issue is a pull request, // call SCM for more data not provided in webhook payload if strings.EqualFold(cfg.Source, "webhook") && strings.EqualFold(b.GetEvent(), constants.EventComment) { - if err != nil { - retErr := fmt.Errorf("%s: failed to get pull request number for %s: %w", baseErr, r.GetFullName(), err) - util.HandleError(c, http.StatusBadRequest, retErr) - - return nil, nil, retErr - } - commit, branch, baseref, headref, err := scm.GetPullRequest(c, r, prNum) if err != nil { retErr := fmt.Errorf("%s: failed to get pull request info for %s: %w", baseErr, r.GetFullName(), err) - util.HandleError(c, http.StatusInternalServerError, retErr) - return nil, nil, retErr + return nil, nil, http.StatusInternalServerError, retErr } b.SetCommit(commit) @@ -110,9 +99,8 @@ func CompileAndPublish( _, commit, err := scm.GetBranch(c, r, b.GetBranch()) if err != nil { retErr := fmt.Errorf("failed to get commit for repo %s on %s branch: %w", r.GetFullName(), r.GetBranch(), err) - util.HandleError(c, http.StatusInternalServerError, retErr) - return nil, nil, retErr + return nil, nil, http.StatusInternalServerError, retErr } b.SetCommit(commit) @@ -127,9 +115,8 @@ func CompileAndPublish( builds, err := database.CountBuildsForRepo(c, r, filters) if err != nil { retErr := fmt.Errorf("%s: unable to get count of builds for repo %s", baseErr, r.GetFullName()) - util.HandleError(c, http.StatusBadRequest, retErr) - return nil, nil, retErr + return nil, nil, http.StatusInternalServerError, retErr } logrus.Debugf("currently %d builds running on repo %s", builds, r.GetFullName()) @@ -137,9 +124,8 @@ func CompileAndPublish( // check if the number of pending and running builds exceeds the limit for the repo if builds >= r.GetBuildLimit() { retErr := fmt.Errorf("%s: repo %s has exceeded the concurrent build limit of %d", baseErr, r.GetFullName(), r.GetBuildLimit()) - util.HandleError(c, http.StatusBadRequest, retErr) - return nil, nil, retErr + return nil, nil, http.StatusTooManyRequests, retErr } // update fields in build object @@ -166,9 +152,8 @@ func CompileAndPublish( files, err = scm.Changeset(c, r, b.GetCommit()) if err != nil { retErr := fmt.Errorf("%s: failed to get changeset for %s: %w", baseErr, r.GetFullName(), err) - util.HandleError(c, http.StatusInternalServerError, retErr) - return nil, nil, retErr + return nil, nil, http.StatusInternalServerError, retErr } } @@ -178,9 +163,8 @@ func CompileAndPublish( files, err = scm.ChangesetPR(c, r, prNum) if err != nil { retErr := fmt.Errorf("%s: failed to get changeset for %s: %w", baseErr, r.GetFullName(), err) - util.HandleError(c, http.StatusInternalServerError, retErr) - return nil, nil, retErr + return nil, nil, http.StatusInternalServerError, retErr } } @@ -218,9 +202,7 @@ func CompileAndPublish( if err != nil { retErr := fmt.Errorf("%s: unable to get pipeline configuration for %s: %w", baseErr, r.GetFullName(), err) - util.HandleError(c, http.StatusNotFound, retErr) - - return nil, nil, retErr + return nil, nil, http.StatusNotFound, retErr } } else { pipelineFile = pipeline.GetData() @@ -239,9 +221,7 @@ func CompileAndPublish( continue } - util.HandleError(c, http.StatusBadRequest, retErr) - - return nil, nil, retErr + return nil, nil, http.StatusInternalServerError, retErr } // update DB record of repo (repo) with any changes captured from webhook payload (r) @@ -290,10 +270,7 @@ func CompileAndPublish( // log the error for traceability logrus.Error(err.Error()) - retErr := fmt.Errorf("%s: %w", baseErr, err) - util.HandleError(c, http.StatusInternalServerError, retErr) - - return nil, nil, retErr + return nil, nil, http.StatusInternalServerError, fmt.Errorf("%s: %w", baseErr, err) } // reset the pipeline type for the repo @@ -320,6 +297,7 @@ func CompileAndPublish( &models.Item{ Build: b, }, + http.StatusOK, errors.New(skip) } @@ -343,9 +321,7 @@ func CompileAndPublish( continue } - util.HandleError(c, http.StatusBadRequest, retErr) - - return nil, nil, retErr + return nil, nil, http.StatusInternalServerError, retErr } } @@ -375,9 +351,7 @@ func CompileAndPublish( continue } - util.HandleError(c, http.StatusInternalServerError, retErr) - - return nil, nil, retErr + return nil, nil, http.StatusInternalServerError, retErr } // break the loop because everything was successful @@ -388,34 +362,30 @@ func CompileAndPublish( repo, err = database.UpdateRepo(c, repo) if err != nil { retErr := fmt.Errorf("%s: failed to update repo %s: %w", baseErr, repo.GetFullName(), err) - util.HandleError(c, http.StatusBadRequest, retErr) - return nil, nil, retErr + return nil, nil, http.StatusInternalServerError, retErr } // return error if pipeline didn't get populated if p == nil { retErr := fmt.Errorf("%s: failed to set pipeline for %s: %w", baseErr, repo.GetFullName(), err) - util.HandleError(c, http.StatusBadRequest, retErr) - return nil, nil, retErr + return nil, nil, http.StatusInternalServerError, retErr } // return error if build didn't get populated if b == nil { retErr := fmt.Errorf("%s: failed to set build for %s: %w", baseErr, repo.GetFullName(), err) - util.HandleError(c, http.StatusBadRequest, retErr) - return nil, nil, retErr + return nil, nil, http.StatusInternalServerError, retErr } // send API call to capture the triggered build b, err = database.GetBuildForRepo(c, repo, b.GetNumber()) if err != nil { retErr := fmt.Errorf("%s: failed to get new build %s/%d: %w", baseErr, repo.GetFullName(), b.GetNumber(), err) - util.HandleError(c, http.StatusInternalServerError, retErr) - return nil, nil, retErr + return nil, nil, http.StatusInternalServerError, retErr } // determine queue route @@ -426,9 +396,7 @@ func CompileAndPublish( // error out the build CleanBuild(c, database, b, nil, nil, retErr) - util.HandleError(c, http.StatusBadRequest, retErr) - - return nil, nil, retErr + return nil, nil, http.StatusBadRequest, retErr } // temporarily set host to the route before it gets picked up by a worker @@ -438,12 +406,11 @@ func CompileAndPublish( err = PublishBuildExecutable(c, database, p, b) if err != nil { retErr := fmt.Errorf("unable to publish build executable for %s/%d: %w", repo.GetFullName(), b.GetNumber(), err) - util.HandleError(c, http.StatusInternalServerError, retErr) - return nil, nil, retErr + return nil, nil, http.StatusInternalServerError, retErr } - return p, models.ToItem(b, repo), nil + return p, models.ToItem(b, repo), http.StatusCreated, nil } // getPRNumberFromBuild is a helper function to diff --git a/api/build/create.go b/api/build/create.go index 2801ce0db..dc8c81149 100644 --- a/api/build/create.go +++ b/api/build/create.go @@ -5,7 +5,6 @@ package build import ( "fmt" "net/http" - "strings" "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" @@ -19,7 +18,6 @@ import ( "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" "github.com/go-vela/server/util" - "github.com/go-vela/types/constants" "github.com/go-vela/types/library" ) @@ -51,24 +49,32 @@ import ( // - ApiKeyAuth: [] // responses: // '200': -// description: Request processed but build was skipped +// description: Successfully received request but build was skipped // schema: // type: string // '201': -// description: Successfully created the build +// description: Successfully created the build from request // type: json // schema: // "$ref": "#/definitions/Build" // '400': -// description: Unable to create the build +// description: Malformed request payload or improper pipeline configuration +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Repository owner does not have proper access // schema: // "$ref": "#/definitions/Error" // '404': -// description: Unable to create the build +// description: Unable to find resources for build +// schema: +// "$ref": "#/definitions/Error" +// '429': +// description: Concurrent build limit reached for repository // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to create the build +// description: Unable to receive the request or internal error while processing // schema: // "$ref": "#/definitions/Error" @@ -123,7 +129,7 @@ func CreateBuild(c *gin.Context) { Retries: 1, } - _, item, err := CompileAndPublish( + _, item, code, err := CompileAndPublish( c, config, database.FromContext(c), @@ -133,14 +139,15 @@ func CreateBuild(c *gin.Context) { ) // check if build was skipped - if err != nil && strings.EqualFold(item.Build.GetStatus(), constants.StatusSkipped) { + if err != nil && code == http.StatusOK { c.JSON(http.StatusOK, err.Error()) return } - // error handling done in CompileAndPublish if err != nil { + util.HandleError(c, code, err) + return } diff --git a/api/build/restart.go b/api/build/restart.go index f52cf9c69..51c1bc0ff 100644 --- a/api/build/restart.go +++ b/api/build/restart.go @@ -51,23 +51,32 @@ import ( // - ApiKeyAuth: [] // responses: // '200': -// description: Request processed but build was skipped +// description: Successfully received request but build was skipped // schema: // type: string // '201': -// description: Successfully restarted the build +// description: Successfully created the build from request +// type: json // schema: // "$ref": "#/definitions/Build" // '400': -// description: Unable to restart the build +// description: Malformed request payload or improper pipeline configuration +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Repository owner does not have proper access // schema: // "$ref": "#/definitions/Error" // '404': -// description: Unable to restart the build +// description: Unable to find resources for build +// schema: +// "$ref": "#/definitions/Error" +// '429': +// description: Concurrent build limit reached for repository // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to restart the build +// description: Unable to receive the request or internal error while processing // schema: // "$ref": "#/definitions/Error" @@ -120,7 +129,7 @@ func RestartBuild(c *gin.Context) { } // generate queue items - _, item, err := CompileAndPublish( + _, item, code, err := CompileAndPublish( c, config, database.FromContext(c), @@ -129,8 +138,9 @@ func RestartBuild(c *gin.Context) { queue.FromContext(c), ) - // error handling done in CompileAndPublish if err != nil { + util.HandleError(c, code, err) + return } diff --git a/api/webhook/post.go b/api/webhook/post.go index f964398d7..8f6ef750e 100644 --- a/api/webhook/post.go +++ b/api/webhook/post.go @@ -47,23 +47,32 @@ var baseErr = "unable to process webhook" // "$ref": "#/definitions/Webhook" // responses: // '200': -// description: Successfully received the webhook +// description: Successfully received the webhook but build was skipped +// schema: +// type: string +// '201': +// description: Successfully created the build from webhook +// type: json // schema: // "$ref": "#/definitions/Build" // '400': -// description: Malformed webhook payload +// description: Malformed webhook payload or improper pipeline configuration +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Repository owner does not have proper access // schema: // "$ref": "#/definitions/Error" // '404': // description: Unable to receive the webhook // schema: // "$ref": "#/definitions/Error" -// '401': -// description: Unauthenticated +// '429': +// description: Concurrent build limit reached for repository // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to receive the webhook +// description: Unable to receive the webhook or internal error while processing // schema: // "$ref": "#/definitions/Error" @@ -300,7 +309,7 @@ func PostWebhook(c *gin.Context) { } // generate the queue item - p, item, err := build.CompileAndPublish( + p, item, code, err := build.CompileAndPublish( c, config, database.FromContext(c), @@ -310,18 +319,7 @@ func PostWebhook(c *gin.Context) { ) // error handling done in CompileAndPublish - if err != nil { - return - } - - // capture the build and repo from the items - b, repo = item.Build, item.Repo - - // set hook build_id to the generated build id - h.SetBuildID(b.GetID()) - - // check if build was skipped - if err != nil && strings.EqualFold(b.GetStatus(), constants.StatusSkipped) { + if err != nil && code == http.StatusOK { h.SetStatus(constants.StatusSkipped) h.SetError(err.Error()) @@ -334,9 +332,17 @@ func PostWebhook(c *gin.Context) { h.SetStatus(constants.StatusFailure) h.SetError(err.Error()) + util.HandleError(c, code, err) + return } + // capture the build and repo from the items + b, repo = item.Build, item.Repo + + // set hook build_id to the generated build id + h.SetBuildID(b.GetID()) + // if event is deployment, update the deployment record to include this build if strings.EqualFold(b.GetEvent(), constants.EventDeploy) { d, err := database.FromContext(c).GetDeploymentForRepo(c, repo, webhook.Deployment.GetNumber()) @@ -382,7 +388,7 @@ func PostWebhook(c *gin.Context) { } } - c.JSON(http.StatusOK, b) + c.JSON(http.StatusCreated, b) // regardless of whether the build is published to queue, we want to attempt to auto-cancel if no errors defer func() { diff --git a/cmd/vela-server/schedule.go b/cmd/vela-server/schedule.go index dda61bdea..d069b05a4 100644 --- a/cmd/vela-server/schedule.go +++ b/cmd/vela-server/schedule.go @@ -179,7 +179,7 @@ func processSchedule(ctx context.Context, s *library.Schedule, compiler compiler Retries: 1, } - _, item, err := build.CompileAndPublish( + _, item, _, err := build.CompileAndPublish( ctx, config, database, @@ -188,7 +188,6 @@ func processSchedule(ctx context.Context, s *library.Schedule, compiler compiler queue, ) - // error handling done in CompileAndPublish if err != nil { return err } From 52c741c69b39aabc37295b42cfe87ad01ea4279e Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Tue, 16 Apr 2024 15:35:16 -0400 Subject: [PATCH 34/71] fix(repo): sanitize owner information (#1109) --- api/types/user.go | 2 -- api/types/user_test.go | 5 ++++- database/integration_test.go | 4 ++-- database/repo/count_user_test.go | 5 +---- database/repo/get_org_test.go | 1 - database/repo/get_test.go | 1 - database/repo/list_org_test.go | 1 - database/repo/list_test.go | 1 - database/repo/list_user_test.go | 1 - database/repo/repo.go | 2 +- database/repo/repo_test.go | 13 +++++++------ router/middleware/repo/repo_test.go | 7 +++---- 12 files changed, 18 insertions(+), 25 deletions(-) diff --git a/api/types/user.go b/api/types/user.go index 277426d3e..50e450030 100644 --- a/api/types/user.go +++ b/api/types/user.go @@ -33,9 +33,7 @@ func (u *User) Sanitize() *User { Name: u.Name, RefreshToken: &value, Token: &value, - Favorites: u.Favorites, Active: u.Active, - Admin: u.Admin, } } diff --git a/api/types/user_test.go b/api/types/user_test.go index de7c3575d..d2db92020 100644 --- a/api/types/user_test.go +++ b/api/types/user_test.go @@ -14,7 +14,10 @@ func TestTypes_User_Sanitize(t *testing.T) { // setup types u := testUser() - want := testUser() + want := new(User) + want.SetID(1) + want.SetName("octocat") + want.SetActive(true) want.SetToken(constants.SecretMask) want.SetRefreshToken(constants.SecretMask) diff --git a/database/integration_test.go b/database/integration_test.go index 9019c0d2b..c1fb14f57 100644 --- a/database/integration_test.go +++ b/database/integration_test.go @@ -2256,7 +2256,7 @@ func newResources() *Resources { repoOne := new(api.Repo) repoOne.SetID(1) - repoOne.SetOwner(userOne) + repoOne.SetOwner(userOne.Sanitize()) repoOne.SetHash("MzM4N2MzMDAtNmY4Mi00OTA5LWFhZDAtNWIzMTlkNTJkODMy") repoOne.SetOrg("github") repoOne.SetName("octocat") @@ -2279,7 +2279,7 @@ func newResources() *Resources { repoTwo := new(api.Repo) repoTwo.SetID(2) - repoTwo.SetOwner(userOne) + repoTwo.SetOwner(userOne.Sanitize()) repoTwo.SetHash("MzM4N2MzMDAtNmY4Mi00OTA5LWFhZDAtNWIzMTlkNTJkODMy") repoTwo.SetOrg("github") repoTwo.SetName("octokitty") diff --git a/database/repo/count_user_test.go b/database/repo/count_user_test.go index 10d238c39..8b420ea56 100644 --- a/database/repo/count_user_test.go +++ b/database/repo/count_user_test.go @@ -8,8 +8,6 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" - - api "github.com/go-vela/server/api/types" ) func TestRepo_Engine_CountReposForUser(t *testing.T) { @@ -32,10 +30,9 @@ func TestRepo_Engine_CountReposForUser(t *testing.T) { _repoTwo.SetFullName("bar/foo") _repoTwo.SetVisibility("public") - _user := new(api.User) + _user := testOwner() _user.SetID(1) _user.SetName("foo") - _user.SetToken("bar") _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() diff --git a/database/repo/get_org_test.go b/database/repo/get_org_test.go index f864cc78a..3cf2fd9a3 100644 --- a/database/repo/get_org_test.go +++ b/database/repo/get_org_test.go @@ -31,7 +31,6 @@ func TestRepo_Engine_GetRepoForOrg(t *testing.T) { _owner := testOwner() _owner.SetID(1) _owner.SetName("foo") - _owner.SetToken("bar") _repo.SetOwner(_owner) diff --git a/database/repo/get_test.go b/database/repo/get_test.go index eeb37b1bd..7d7618fd3 100644 --- a/database/repo/get_test.go +++ b/database/repo/get_test.go @@ -31,7 +31,6 @@ func TestRepo_Engine_GetRepo(t *testing.T) { _owner := testOwner() _owner.SetID(1) _owner.SetName("foo") - _owner.SetToken("bar") _repo.SetOwner(_owner) diff --git a/database/repo/list_org_test.go b/database/repo/list_org_test.go index fb3414ed6..47fa34e1b 100644 --- a/database/repo/list_org_test.go +++ b/database/repo/list_org_test.go @@ -56,7 +56,6 @@ func TestRepo_Engine_ListReposForOrg(t *testing.T) { _owner := testOwner() _owner.SetID(1) _owner.SetName("foo") - _owner.SetToken("bar") _repoOne.SetOwner(_owner) _repoTwo.SetOwner(_owner) diff --git a/database/repo/list_test.go b/database/repo/list_test.go index 81b7f33fb..84738be32 100644 --- a/database/repo/list_test.go +++ b/database/repo/list_test.go @@ -42,7 +42,6 @@ func TestRepo_Engine_ListRepos(t *testing.T) { _owner := testOwner() _owner.SetID(1) _owner.SetName("foo") - _owner.SetToken("bar") _repoOne.SetOwner(_owner) _repoTwo.SetOwner(_owner) diff --git a/database/repo/list_user_test.go b/database/repo/list_user_test.go index cc82ea5fd..d4e3152f5 100644 --- a/database/repo/list_user_test.go +++ b/database/repo/list_user_test.go @@ -58,7 +58,6 @@ func TestRepo_Engine_ListReposForUser(t *testing.T) { _owner := testOwner() _owner.SetID(1) _owner.SetName("foo") - _owner.SetToken("bar") _repoOne.SetOwner(_owner) _repoTwo.SetOwner(_owner) diff --git a/database/repo/repo.go b/database/repo/repo.go index ad892ba52..33e1cbf36 100644 --- a/database/repo/repo.go +++ b/database/repo/repo.go @@ -293,7 +293,7 @@ func (r *Repo) ToAPI() *api.Repo { repo := new(api.Repo) repo.SetID(r.ID.Int64) - repo.SetOwner(r.Owner.ToAPI()) + repo.SetOwner(r.Owner.ToAPI().Sanitize()) repo.SetHash(r.Hash.String) repo.SetOrg(r.Org.String) repo.SetName(r.Name.String) diff --git a/database/repo/repo_test.go b/database/repo/repo_test.go index e8de73915..4a179c6d8 100644 --- a/database/repo/repo_test.go +++ b/database/repo/repo_test.go @@ -230,15 +230,16 @@ func testEvents() *api.Events { } } +// testOwner is a helper function that returns a sanitized user. func testOwner() *api.User { + mask := constants.SecretMask + return &api.User{ ID: new(int64), Name: new(string), - RefreshToken: new(string), - Token: new(string), - Favorites: new([]string), + RefreshToken: &mask, + Token: &mask, Active: new(bool), - Admin: new(bool), } } @@ -426,8 +427,8 @@ func TestRepo_ToAPI(t *testing.T) { // run test got := testRepo().ToAPI() - if !reflect.DeepEqual(got, want) { - t.Errorf("ToAPI is %v, want %v", got, want) + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("ToAPI() mismatch (-want +got):\n%s", diff) } } diff --git a/router/middleware/repo/repo_test.go b/router/middleware/repo/repo_test.go index 261941d4f..6c683c5a5 100644 --- a/router/middleware/repo/repo_test.go +++ b/router/middleware/repo/repo_test.go @@ -14,6 +14,7 @@ import ( api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/org" + "github.com/go-vela/types/constants" ) func TestRepo_Retrieve(t *testing.T) { @@ -40,10 +41,8 @@ func TestRepo_Establish(t *testing.T) { owner.SetID(1) owner.SetName("foo") owner.SetActive(false) - owner.SetAdmin(false) - owner.SetFavorites([]string{}) - owner.SetToken("baz") - owner.SetRefreshToken("fresh") + owner.SetToken(constants.SecretMask) + owner.SetRefreshToken(constants.SecretMask) want := new(api.Repo) want.SetID(1) From 66b3088e54c7f3d134d43696d488532920e2ee54 Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Wed, 17 Apr 2024 16:55:05 -0400 Subject: [PATCH 35/71] feat(dashboards)!: server-side implementation of dashboards (#1028) * init commit * split up org and name on GET return * add sender * admin validation abstraction * add build link * feat: adding new user changes to server (#1021) Co-authored-by: Claire.Nicholas * some edits and list user + uuid usage * yep * sooooo many tests to add * add list build dashboard test and remove test json file * imports order and fix integration test * update swagger * make clean * fix spec * address feedback and fix more comments * address feedback and change admin set to use names * convert admin set to nested sanitized user list * fix a comment --------- Co-authored-by: claire1618 <55173466+claire1618@users.noreply.github.com> Co-authored-by: Claire.Nicholas --- api/dashboard/create.go | 190 ++++++++++++ api/dashboard/delete.go | 93 ++++++ api/dashboard/get.go | 132 ++++++++ api/dashboard/list_user.go | 102 +++++++ api/dashboard/update.go | 140 +++++++++ api/types/dashboard.go | 281 ++++++++++++++++++ api/types/dashboard_repo.go | 136 +++++++++ api/types/dashboard_repo_test.go | 126 ++++++++ api/types/dashboard_test.go | 174 +++++++++++ api/types/events.go | 2 +- api/types/user.go | 29 ++ api/types/user_test.go | 12 + api/user/update.go | 5 + api/user/update_current.go | 6 + constants/limit.go | 8 + constants/table.go | 8 + database/build/count_org_test.go | 3 +- database/build/interface.go | 2 + database/build/list_dashboard.go | 58 ++++ database/build/list_dashboard_test.go | 111 +++++++ database/build/list_org_test.go | 3 +- .../build/list_pending_running_repo_test.go | 3 +- database/build/list_pending_running_test.go | 3 +- database/dashboard/create.go | 31 ++ database/dashboard/create_test.go | 95 ++++++ database/dashboard/dashboard.go | 248 ++++++++++++++++ database/dashboard/dashboard_test.go | 219 ++++++++++++++ database/dashboard/delete.go | 27 ++ database/dashboard/delete_test.go | 77 +++++ database/dashboard/get.go | 30 ++ database/dashboard/get_test.go | 103 +++++++ database/dashboard/interface.go | 35 +++ database/dashboard/opts.go | 62 ++++ database/dashboard/opts_test.go | 208 +++++++++++++ database/dashboard/table.go | 60 ++++ database/dashboard/table_test.go | 58 ++++ database/dashboard/update.go | 34 +++ database/dashboard/update_test.go | 97 ++++++ database/database.go | 2 + database/integration_test.go | 167 +++++++++-- database/interface.go | 4 + database/repo/get_org_test.go | 3 +- database/repo/get_test.go | 3 +- database/repo/list_org_test.go | 2 +- database/repo/list_test.go | 3 +- database/repo/list_user_test.go | 2 +- database/resource.go | 11 + database/resource_test.go | 3 + database/user/create_test.go | 6 +- database/user/get_name_test.go | 5 +- database/user/get_test.go | 5 +- database/user/list_lite_test.go | 4 + database/user/list_test.go | 8 +- database/user/table.go | 2 + database/user/update_test.go | 6 +- database/user/user.go | 28 +- database/user/user_test.go | 31 +- mock/server/user.go | 9 +- router/dashboard.go | 29 ++ router/middleware/dashboard/context.go | 37 +++ router/middleware/dashboard/context_test.go | 88 ++++++ router/middleware/dashboard/dashboard.go | 61 ++++ router/middleware/dashboard/dashboard_test.go | 162 ++++++++++ router/middleware/user/user_test.go | 1 + router/router.go | 2 +- router/user.go | 5 +- 66 files changed, 3634 insertions(+), 66 deletions(-) create mode 100644 api/dashboard/create.go create mode 100644 api/dashboard/delete.go create mode 100644 api/dashboard/get.go create mode 100644 api/dashboard/list_user.go create mode 100644 api/dashboard/update.go create mode 100644 api/types/dashboard.go create mode 100644 api/types/dashboard_repo.go create mode 100644 api/types/dashboard_repo_test.go create mode 100644 api/types/dashboard_test.go create mode 100644 constants/limit.go create mode 100644 constants/table.go create mode 100644 database/build/list_dashboard.go create mode 100644 database/build/list_dashboard_test.go create mode 100644 database/dashboard/create.go create mode 100644 database/dashboard/create_test.go create mode 100644 database/dashboard/dashboard.go create mode 100644 database/dashboard/dashboard_test.go create mode 100644 database/dashboard/delete.go create mode 100644 database/dashboard/delete_test.go create mode 100644 database/dashboard/get.go create mode 100644 database/dashboard/get_test.go create mode 100644 database/dashboard/interface.go create mode 100644 database/dashboard/opts.go create mode 100644 database/dashboard/opts_test.go create mode 100644 database/dashboard/table.go create mode 100644 database/dashboard/table_test.go create mode 100644 database/dashboard/update.go create mode 100644 database/dashboard/update_test.go create mode 100644 router/dashboard.go create mode 100644 router/middleware/dashboard/context.go create mode 100644 router/middleware/dashboard/context_test.go create mode 100644 router/middleware/dashboard/dashboard.go create mode 100644 router/middleware/dashboard/dashboard_test.go diff --git a/api/dashboard/create.go b/api/dashboard/create.go new file mode 100644 index 000000000..c0e8f0029 --- /dev/null +++ b/api/dashboard/create.go @@ -0,0 +1,190 @@ +// SPDX-License-Identifier: Apache-2.0 + +package dashboard + +import ( + "context" + "fmt" + "net/http" + "strings" + "time" + + "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + + "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database" + "github.com/go-vela/server/router/middleware/user" + "github.com/go-vela/server/util" +) + +// swagger:operation POST /api/v1/dashboards dashboards CreateDashboard +// +// Create a dashboard in the configured backend +// +// --- +// produces: +// - application/json +// parameters: +// - in: body +// name: body +// description: Payload containing the dashboard to create +// required: true +// schema: +// "$ref": "#/definitions/Dashboard" +// security: +// - ApiKeyAuth: [] +// responses: +// '201': +// description: Successfully created dashboard +// schema: +// "$ref": "#/definitions/Dashboard" +// '400': +// description: Bad request when creating dashboard +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized to create dashboard +// schema: +// "$ref": "#/definitions/Error" +// '500': +// description: Server error when creating dashboard +// schema: +// "$ref": "#/definitions/Error" + +// CreateDashboard represents the API handler to +// create a dashboard in the configured backend. +func CreateDashboard(c *gin.Context) { + // capture middleware values + u := user.Retrieve(c) + + // capture body from API request + input := new(types.Dashboard) + + err := c.Bind(input) + if err != nil { + retErr := fmt.Errorf("unable to decode JSON for new dashboard: %w", err) + + util.HandleError(c, http.StatusBadRequest, retErr) + + return + } + + // ensure dashboard name is defined + if input.GetName() == "" { + util.HandleError(c, http.StatusBadRequest, fmt.Errorf("dashboard name must be set")) + + return + } + + // update engine logger with API metadata + // + // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields + logrus.WithFields(logrus.Fields{ + "user": u.GetName(), + }).Infof("creating new dashboard %s", input.GetName()) + + d := new(types.Dashboard) + + // update fields in dashboard object + d.SetCreatedBy(u.GetName()) + d.SetName(input.GetName()) + d.SetCreatedAt(time.Now().UTC().Unix()) + d.SetUpdatedAt(time.Now().UTC().Unix()) + d.SetUpdatedBy(u.GetName()) + + // validate admins to ensure they are all active users + admins, err := createAdminSet(c, u, input.GetAdmins()) + if err != nil { + util.HandleError(c, http.StatusBadRequest, err) + + return + } + + d.SetAdmins(admins) + + // validate repos to ensure they are all enabled + err = validateRepoSet(c, input.GetRepos()) + if err != nil { + util.HandleError(c, http.StatusBadRequest, err) + + return + } + + d.SetRepos(input.GetRepos()) + + // create dashboard in database + d, err = database.FromContext(c).CreateDashboard(c, d) + if err != nil { + retErr := fmt.Errorf("unable to create new dashboard %s: %w", d.GetName(), err) + + util.HandleError(c, http.StatusInternalServerError, retErr) + + return + } + + // add dashboard to claims' user's dashboard set + u.SetDashboards(append(u.GetDashboards(), d.GetID())) + + // update user in database + _, err = database.FromContext(c).UpdateUser(c, u) + if err != nil { + retErr := fmt.Errorf("unable to update user %s: %w", u.GetName(), err) + + util.HandleError(c, http.StatusInternalServerError, retErr) + + return + } + + c.JSON(http.StatusCreated, d) +} + +// createAdminSet takes a slice of users, cleanses it of duplicates and throws an error +// when a user is inactive or not found in the database. It returns a sanitized slice of admins. +func createAdminSet(c context.Context, caller *types.User, users []*types.User) ([]*types.User, error) { + // add user creating the dashboard to admin list + admins := []*types.User{caller.Sanitize()} + + dupMap := make(map[string]bool) + + // validate supplied admins are actual users + for _, u := range users { + if u.GetName() == caller.GetName() || dupMap[u.GetName()] { + continue + } + + dbUser, err := database.FromContext(c).GetUserForName(c, u.GetName()) + if err != nil || !dbUser.GetActive() { + return nil, fmt.Errorf("unable to create dashboard: %s is not an active user", u.GetName()) + } + + admins = append(admins, dbUser.Sanitize()) + + dupMap[dbUser.GetName()] = true + } + + return admins, nil +} + +// validateRepoSet is a helper function that confirms all dashboard repos exist and are enabled +// in the database while also confirming the IDs match when saving. +func validateRepoSet(c context.Context, repos []*types.DashboardRepo) error { + for _, repo := range repos { + // verify format (org/repo) + parts := strings.Split(repo.GetName(), "/") + if len(parts) != 2 { + return fmt.Errorf("unable to create dashboard: %s is not a valid repo", repo.GetName()) + } + + // fetch repo from database + dbRepo, err := database.FromContext(c).GetRepoForOrg(c, parts[0], parts[1]) + if err != nil || !dbRepo.GetActive() { + return fmt.Errorf("unable to create dashboard: could not get repo %s: %w", repo.GetName(), err) + } + + // override ID field if provided to match the database ID + repo.SetID(dbRepo.GetID()) + } + + return nil +} diff --git a/api/dashboard/delete.go b/api/dashboard/delete.go new file mode 100644 index 000000000..14e81ffa5 --- /dev/null +++ b/api/dashboard/delete.go @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: Apache-2.0 + +package dashboard + +import ( + "fmt" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + + "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database" + "github.com/go-vela/server/router/middleware/dashboard" + "github.com/go-vela/server/router/middleware/user" + "github.com/go-vela/server/util" +) + +// swagger:operation DELETE /api/v1/dashboards/{dashboard} dashboards DeleteDashboard +// +// Delete a dashboard in the configured backend +// +// --- +// produces: +// - application/json +// parameters: +// - in: path +// name: dashboard +// description: id of the dashboard +// required: true +// type: string +// security: +// - ApiKeyAuth: [] +// responses: +// '200': +// description: Successfully deleted dashboard +// schema: +// type: string +// '401': +// description: Unauthorized to delete dashboard +// schema: +// "$ref": "#/definitions/Error" +// '500': +// description: Server error when deleting dashboard +// schema: +// "$ref": "#/definitions/Error" + +// DeleteDashboard represents the API handler to remove +// a dashboard from the configured backend. +func DeleteDashboard(c *gin.Context) { + // capture middleware values + d := dashboard.Retrieve(c) + u := user.Retrieve(c) + + // update engine logger with API metadata + // + // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields + logrus.WithFields(logrus.Fields{ + "dashboard": d.GetID(), + "user": u.GetName(), + }).Infof("deleting dashboard %s", d.GetID()) + + if !isAdmin(d, u) { + retErr := fmt.Errorf("unable to delete dashboard %s: user is not an admin", d.GetID()) + + util.HandleError(c, http.StatusUnauthorized, retErr) + + return + } + + err := database.FromContext(c).DeleteDashboard(c, d) + if err != nil { + retErr := fmt.Errorf("error while deleting dashboard %s: %w", d.GetID(), err) + + util.HandleError(c, http.StatusInternalServerError, retErr) + + return + } + + c.JSON(http.StatusOK, fmt.Sprintf("dashboard %s deleted", d.GetName())) +} + +// isAdmin is a helper function that iterates through the dashboard admins +// and confirms if the user is in the slice. +func isAdmin(d *types.Dashboard, u *types.User) bool { + for _, admin := range d.GetAdmins() { + if admin.GetID() == u.GetID() { + return true + } + } + + return false +} diff --git a/api/dashboard/get.go b/api/dashboard/get.go new file mode 100644 index 000000000..f36f92ee4 --- /dev/null +++ b/api/dashboard/get.go @@ -0,0 +1,132 @@ +// SPDX-License-Identifier: Apache-2.0 + +package dashboard + +import ( + "context" + "fmt" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + + "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database" + "github.com/go-vela/server/router/middleware/dashboard" + "github.com/go-vela/server/router/middleware/user" + "github.com/go-vela/server/util" +) + +// swagger:operation GET /api/v1/dashboards/{dashboard} dashboards GetDashboard +// +// Get a dashboard in the configured backend +// +// --- +// produces: +// - application/json +// parameters: +// - in: path +// name: dashboard +// description: Dashboard id to retrieve +// required: true +// type: string +// security: +// - ApiKeyAuth: [] +// responses: +// '200': +// description: Successfully retrieved dashboard +// type: json +// schema: +// "$ref": "#/definitions/Dashboard" +// '401': +// description: Unauthorized to retrieve dashboard +// schema: +// "$ref": "#/definitions/Error" +// '500': +// description: Server error when retrieving dashboard +// schema: +// "$ref": "#/definitions/Error" + +// GetDashboard represents the API handler to capture +// a dashboard for a repo from the configured backend. +func GetDashboard(c *gin.Context) { + // capture middleware values + d := dashboard.Retrieve(c) + u := user.Retrieve(c) + + var err error + + // update engine logger with API metadata + // + // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields + logrus.WithFields(logrus.Fields{ + "dashboard": d.GetID(), + "user": u.GetName(), + }).Infof("reading dashboard %s", d.GetID()) + + // initialize DashCard and set dashboard to the dashboard info pulled from database + dashboard := new(types.DashCard) + dashboard.Dashboard = d + + // build RepoPartials referenced in the dashboard + dashboard.Repos, err = buildRepoPartials(c, d.GetRepos()) + if err != nil { + util.HandleError(c, http.StatusInternalServerError, err) + + return + } + + c.JSON(http.StatusOK, dashboard) +} + +// buildRepoPartials is a helper function which takes the dashboard repo list and builds +// a list of RepoPartials with information about the associated repository and its latest +// five builds. +func buildRepoPartials(c context.Context, repos []*types.DashboardRepo) ([]types.RepoPartial, error) { + var result []types.RepoPartial + + for _, r := range repos { + repo := types.RepoPartial{} + + // fetch repo from database + dbRepo, err := database.FromContext(c).GetRepo(c, r.GetID()) + if err != nil { + return nil, fmt.Errorf("unable to get repo %s for dashboard: %w", r.GetName(), err) + } + + // set values for RepoPartial + repo.Org = dbRepo.GetOrg() + repo.Name = dbRepo.GetName() + repo.Counter = dbRepo.GetCounter() + + // list last 5 builds for repo given the branch and event filters + builds, err := database.FromContext(c).ListBuildsForDashboardRepo(c, dbRepo, r.GetBranches(), r.GetEvents()) + if err != nil { + return nil, fmt.Errorf("unable to list builds for repo %s in dashboard: %w", dbRepo.GetFullName(), err) + } + + bPartials := []types.BuildPartial{} + + // populate BuildPartials with info from builds list + for _, build := range builds { + bPartial := types.BuildPartial{ + Number: build.GetNumber(), + Status: build.GetStatus(), + Started: build.GetStarted(), + Finished: build.GetFinished(), + Sender: build.GetSender(), + Branch: build.GetBranch(), + Event: build.GetEvent(), + Link: build.GetLink(), + } + + bPartials = append(bPartials, bPartial) + } + + repo.Builds = bPartials + + result = append(result, repo) + } + + return result, nil +} diff --git a/api/dashboard/list_user.go b/api/dashboard/list_user.go new file mode 100644 index 000000000..656704358 --- /dev/null +++ b/api/dashboard/list_user.go @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: Apache-2.0 + +package dashboard + +import ( + "errors" + "fmt" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + "gorm.io/gorm" + + "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database" + "github.com/go-vela/server/router/middleware/user" + "github.com/go-vela/server/util" +) + +// swagger:operation GET /api/v1/user/dashboards dashboards ListUserDashboards +// +// Get all dashboards for the current user in the configured backend +// +// --- +// produces: +// - application/json +// security: +// - ApiKeyAuth: [] +// responses: +// '200': +// description: Successfully retrieved user dashboards +// type: json +// schema: +// "$ref": "#/definitions/Dashboard" +// '400': +// description: Bad request to retrieve user dashboards +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized to retrieve user dashboards +// schema: +// "$ref": "#/definitions/Error" +// '500': +// description: Server error when retrieving user dashboards +// schema: +// "$ref": "#/definitions/Error" + +// ListUserDashboards represents the API handler to capture a list +// of dashboards for a user from the configured backend. +func ListUserDashboards(c *gin.Context) { + // capture middleware values + u := user.Retrieve(c) + + // update engine logger with API metadata + // + // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields + logrus.WithFields(logrus.Fields{ + "user": u.GetName(), + }).Infof("listing dashboards for user %s", u.GetName()) + + var dashCards []types.DashCard + + // iterate through user dashboards and build a list of DashCards + for _, dashboard := range u.GetDashboards() { + dashCard := types.DashCard{} + + d, err := database.FromContext(c).GetDashboard(c, dashboard) + if err != nil { + // check if the query returned a record not found error + if errors.Is(err, gorm.ErrRecordNotFound) { + d = new(types.Dashboard) + d.SetID(dashboard) + + dashCard.Dashboard = d + // if user dashboard has been deleted, append empty dashboard + // to set and continue + dashCards = append(dashCards, dashCard) + + continue + } + + retErr := fmt.Errorf("unable to get dashboard %s: %w", dashboard, err) + + util.HandleError(c, http.StatusBadRequest, retErr) + + return + } + + dashCard.Dashboard = d + + dashCard.Repos, err = buildRepoPartials(c, d.GetRepos()) + if err != nil { + util.HandleError(c, http.StatusInternalServerError, err) + + return + } + + dashCards = append(dashCards, dashCard) + } + + c.JSON(http.StatusOK, dashCards) +} diff --git a/api/dashboard/update.go b/api/dashboard/update.go new file mode 100644 index 000000000..7958ef72d --- /dev/null +++ b/api/dashboard/update.go @@ -0,0 +1,140 @@ +// SPDX-License-Identifier: Apache-2.0 + +package dashboard + +import ( + "fmt" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + + "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database" + "github.com/go-vela/server/router/middleware/dashboard" + "github.com/go-vela/server/router/middleware/user" + "github.com/go-vela/server/util" +) + +// swagger:operation PUT /api/v1/dashboards/{dashboard} dashboards UpdateDashboard +// +// Update a dashboard for the configured backend +// +// --- +// produces: +// - application/json +// parameters: +// - name: dashboard +// in: path +// description: ID of the dashboard +// required: true +// type: string +// - name: body +// in: body +// description: Payload containing the dashboard to update +// required: true +// schema: +// $ref: '#/definitions/Dashboard' +// security: +// - ApiKeyAuth: [] +// responses: +// '200': +// description: Successfully updated dashboard +// schema: +// "$ref": "#/definitions/Dashboard" +// '400': +// description: Bad request when updating dashboard +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized to update dashboard +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Unable to find dashboard +// schema: +// "$ref": "#/definitions/Error" +// '500': +// description: Error while updating dashboard +// schema: +// "$ref": "#/definitions/Error" + +// UpdateDashboard represents the API handler to update +// a dashboard in the configured backend. +func UpdateDashboard(c *gin.Context) { + // capture middleware values + d := dashboard.Retrieve(c) + u := user.Retrieve(c) + + if !isAdmin(d, u) { + retErr := fmt.Errorf("unable to update dashboard %s: user is not an admin", d.GetID()) + + util.HandleError(c, http.StatusUnauthorized, retErr) + + return + } + + // update engine logger with API metadata + // + // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields + logrus.WithFields(logrus.Fields{ + "dashboard": d.GetID(), + }).Infof("updating dashboard %s", d.GetID()) + + // capture body from API request + input := new(types.Dashboard) + + err := c.Bind(input) + if err != nil { + retErr := fmt.Errorf("unable to decode JSON for dashboard %s: %w", d.GetID(), err) + + util.HandleError(c, http.StatusBadRequest, retErr) + + return + } + + if input.GetName() != "" { + // update name if defined + d.SetName(input.GetName()) + } + + // validate admin set if supplied + if len(input.GetAdmins()) > 0 { + admins, err := createAdminSet(c, u, input.GetAdmins()) + if err != nil { + util.HandleError(c, http.StatusBadRequest, err) + + return + } + + d.SetAdmins(admins) + } + + // set the updated by field using claims + d.SetUpdatedBy(u.GetName()) + + // validate repo set if supplied + if len(input.GetRepos()) > 0 { + // validate supplied repo list + err = validateRepoSet(c, input.GetRepos()) + if err != nil { + util.HandleError(c, http.StatusBadRequest, err) + + return + } + + d.SetRepos(input.GetRepos()) + } + + // update the dashboard within the database + d, err = database.FromContext(c).UpdateDashboard(c, d) + if err != nil { + retErr := fmt.Errorf("unable to update dashboard %s: %w", input.GetID(), err) + + util.HandleError(c, http.StatusInternalServerError, retErr) + + return + } + + c.JSON(http.StatusOK, d) +} diff --git a/api/types/dashboard.go b/api/types/dashboard.go new file mode 100644 index 000000000..053942daf --- /dev/null +++ b/api/types/dashboard.go @@ -0,0 +1,281 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "fmt" +) + +// RepoPartial is an API type that holds all relevant information +// for a repository attached to a dashboard. +type RepoPartial struct { + Org string `json:"org,omitempty"` + Name string `json:"name,omitempty"` + Counter int `json:"counter,omitempty"` + Builds []BuildPartial `json:"builds,omitempty"` +} + +// BuildPartial is an API type that holds all relevant information +// for a build attached to a RepoPartial. +type BuildPartial struct { + Number int `json:"number,omitempty"` + Started int64 `json:"started,omitempty"` + Finished int64 `json:"finished,omitempty"` + Sender string `json:"sender,omitempty"` + Status string `json:"status,omitempty"` + Event string `json:"event,omitempty"` + Branch string `json:"branch,omitempty"` + Link string `json:"link,omitempty"` +} + +// DashCard is an API type that holds the dashboard information as +// well as a list of RepoPartials attached to the dashboard. +type DashCard struct { + Dashboard *Dashboard `json:"dashboard,omitempty"` + Repos []RepoPartial `json:"repos,omitempty"` +} + +// Dashboard is the API representation of a dashboard. +// +// swagger:model Dashboard +type Dashboard struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + Admins *[]*User `json:"admins,omitempty"` + Repos *[]*DashboardRepo `json:"repos,omitempty"` +} + +// GetID returns the ID field. +// +// When the provided Dashboard type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (d *Dashboard) GetID() string { + // return zero value if Dashboard type or ID field is nil + if d == nil || d.ID == nil { + return "" + } + + return *d.ID +} + +// GetName returns the Name field. +// +// When the provided Dashboard type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (d *Dashboard) GetName() string { + // return zero value if Dashboard type or Name field is nil + if d == nil || d.Name == nil { + return "" + } + + return *d.Name +} + +// GetCreatedAt returns the CreatedAt field. +// +// When the provided Dashboard type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (d *Dashboard) GetCreatedAt() int64 { + // return zero value if Dashboard 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 Dashboard type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (d *Dashboard) GetCreatedBy() string { + // return zero value if Dashboard type or CreatedBy field is nil + if d == nil || d.CreatedBy == nil { + return "" + } + + return *d.CreatedBy +} + +// GetUpdatedAt returns the UpdatedAt field. +// +// When the provided Dashboard type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (d *Dashboard) GetUpdatedAt() int64 { + // return zero value if Dashboard type or UpdatedAt field is nil + if d == nil || d.UpdatedAt == nil { + return 0 + } + + return *d.UpdatedAt +} + +// GetUpdatedBy returns the UpdatedBy field. +// +// When the provided Dashboard type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (d *Dashboard) GetUpdatedBy() string { + // return zero value if Dashboard type or UpdatedBy field is nil + if d == nil || d.UpdatedBy == nil { + return "" + } + + return *d.UpdatedBy +} + +// GetAdmins returns the Admins field. +// +// When the provided Dashboard type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (d *Dashboard) GetAdmins() []*User { + // return zero value if Dashboard type or Admins field is nil + if d == nil || d.Admins == nil { + return []*User{} + } + + return *d.Admins +} + +// GetRepos returns the Repos field. +// +// When the provided Dashboard type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (d *Dashboard) GetRepos() []*DashboardRepo { + // return zero value if Dashboard type or Repos field is nil + if d == nil || d.Repos == nil { + return []*DashboardRepo{} + } + + return *d.Repos +} + +// SetID sets the ID field. +// +// When the provided Dashboard type is nil, it +// will set nothing and immediately return. +func (d *Dashboard) SetID(v string) { + // return if Dashboard type is nil + if d == nil { + return + } + + d.ID = &v +} + +// SetName sets the Name field. +// +// When the provided Dashboard type is nil, it +// will set nothing and immediately return. +func (d *Dashboard) SetName(v string) { + // return if Dashboard type is nil + if d == nil { + return + } + + d.Name = &v +} + +// SetCreatedAt sets the CreatedAt field. +// +// When the provided Dashboard type is nil, it +// will set nothing and immediately return. +func (d *Dashboard) SetCreatedAt(v int64) { + // return if Dashboard type is nil + if d == nil { + return + } + + d.CreatedAt = &v +} + +// SetCreatedBy sets the CreatedBy field. +// +// When the provided Dashboard type is nil, it +// will set nothing and immediately return. +func (d *Dashboard) SetCreatedBy(v string) { + // return if Dashboard type is nil + if d == nil { + return + } + + d.CreatedBy = &v +} + +// SetUpdatedAt sets the UpdatedAt field. +// +// When the provided Dashboard type is nil, it +// will set nothing and immediately return. +func (d *Dashboard) SetUpdatedAt(v int64) { + // return if Dashboard type is nil + if d == nil { + return + } + + d.UpdatedAt = &v +} + +// SetUpdatedBy sets the UpdatedBy field. +// +// When the provided Dashboard type is nil, it +// will set nothing and immediately return. +func (d *Dashboard) SetUpdatedBy(v string) { + // return if Dashboard type is nil + if d == nil { + return + } + + d.UpdatedBy = &v +} + +// SetAdmins sets the Admins field. +// +// When the provided Dashboard type is nil, it +// will set nothing and immediately return. +func (d *Dashboard) SetAdmins(v []*User) { + // return if Dashboard type is nil + if d == nil { + return + } + + d.Admins = &v +} + +// SetRepos sets the Repos field. +// +// When the provided Dashboard type is nil, it +// will set nothing and immediately return. +func (d *Dashboard) SetRepos(v []*DashboardRepo) { + // return if Dashboard type is nil + if d == nil { + return + } + + d.Repos = &v +} + +// String implements the Stringer interface for the Dashboard type. +func (d *Dashboard) String() string { + return fmt.Sprintf(`{ + Name: %s, + ID: %s, + Admins: %v, + CreatedAt: %d, + CreatedBy: %s, + UpdatedAt: %d, + UpdatedBy: %s, + Repos: %v, +}`, + d.GetName(), + d.GetID(), + d.GetAdmins(), + d.GetCreatedAt(), + d.GetCreatedBy(), + d.GetUpdatedAt(), + d.GetUpdatedBy(), + d.GetRepos(), + ) +} diff --git a/api/types/dashboard_repo.go b/api/types/dashboard_repo.go new file mode 100644 index 000000000..4e1faa2bc --- /dev/null +++ b/api/types/dashboard_repo.go @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "fmt" +) + +// DashboardRepo is the API representation of a repo belonging to a Dashboard. +// +// swagger:model DashboardRepo +type DashboardRepo struct { + ID *int64 `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Branches *[]string `json:"branches,omitempty"` + Events *[]string `json:"events,omitempty"` +} + +// GetID returns the ID field. +// +// When the provided Dashboard type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (d *DashboardRepo) GetID() int64 { + // return zero value if Dashboard type or ID field is nil + if d == nil || d.ID == nil { + return 0 + } + + return *d.ID +} + +// GetName returns the Name field. +// +// When the provided Dashboard type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (d *DashboardRepo) GetName() string { + // return zero value if Dashboard type or ID field is nil + if d == nil || d.Name == nil { + return "" + } + + return *d.Name +} + +// GetBranches returns the Branches field. +// +// When the provided Dashboard type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (d *DashboardRepo) GetBranches() []string { + // return zero value if Dashboard type or Branches field is nil + if d == nil || d.Branches == nil { + return []string{} + } + + return *d.Branches +} + +// GetEvents returns the Events field. +// +// When the provided Dashboard type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (d *DashboardRepo) GetEvents() []string { + // return zero value if Dashboard type or Events field is nil + if d == nil || d.Events == nil { + return []string{} + } + + return *d.Events +} + +// SetID sets the ID field. +// +// When the provided Dashboard type is nil, it +// will set nothing and immediately return. +func (d *DashboardRepo) SetID(v int64) { + // return if Dashboard type is nil + if d == nil { + return + } + + d.ID = &v +} + +// SetName sets the Name field. +// +// When the provided Dashboard type is nil, it +// will set nothing and immediately return. +func (d *DashboardRepo) SetName(v string) { + // return if Dashboard type is nil + if d == nil { + return + } + + d.Name = &v +} + +// SetBranches sets the Branches field. +// +// When the provided Dashboard type is nil, it +// will set nothing and immediately return. +func (d *DashboardRepo) SetBranches(v []string) { + // return if Dashboard type is nil + if d == nil { + return + } + + d.Branches = &v +} + +// SetEvents sets the Events field. +// +// When the provided Dashboard type is nil, it +// will set nothing and immediately return. +func (d *DashboardRepo) SetEvents(v []string) { + // return if Dashboard type is nil + if d == nil { + return + } + + d.Events = &v +} + +// String implements the Stringer interface for the Dashboard type. +func (d *DashboardRepo) String() string { + return fmt.Sprintf(`{ + Name: %s, + ID: %d, + Branches: %v, + Events: %v, +}`, + d.GetName(), + d.GetID(), + d.GetBranches(), + d.GetEvents(), + ) +} diff --git a/api/types/dashboard_repo_test.go b/api/types/dashboard_repo_test.go new file mode 100644 index 000000000..892b698e3 --- /dev/null +++ b/api/types/dashboard_repo_test.go @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "fmt" + "reflect" + "testing" +) + +func TestTypes_DashboardRepo_Getters(t *testing.T) { + // setup tests + tests := []struct { + dashboardRepo *DashboardRepo + want *DashboardRepo + }{ + { + dashboardRepo: testDashboardRepo(), + want: testDashboardRepo(), + }, + { + dashboardRepo: new(DashboardRepo), + want: new(DashboardRepo), + }, + } + + // run tests + for _, test := range tests { + if test.dashboardRepo.GetID() != test.want.GetID() { + t.Errorf("GetID is %v, want %v", test.dashboardRepo.GetID(), test.want.GetID()) + } + + if test.dashboardRepo.GetName() != test.want.GetName() { + t.Errorf("GetName is %v, want %v", test.dashboardRepo.GetName(), test.want.GetName()) + } + + if !reflect.DeepEqual(test.dashboardRepo.GetBranches(), test.want.GetBranches()) { + t.Errorf("GetBranches is %v, want %v", test.dashboardRepo.GetBranches(), test.want.GetBranches()) + } + + if !reflect.DeepEqual(test.dashboardRepo.GetEvents(), test.want.GetEvents()) { + t.Errorf("GetEvents is %v, want %v", test.dashboardRepo.GetEvents(), test.want.GetEvents()) + } + } +} + +func TestTypes_DashboardRepo_Setters(t *testing.T) { + // setup types + var d *DashboardRepo + + // setup tests + tests := []struct { + dashboardRepo *DashboardRepo + want *DashboardRepo + }{ + { + dashboardRepo: testDashboardRepo(), + want: testDashboardRepo(), + }, + { + dashboardRepo: d, + want: new(DashboardRepo), + }, + } + + // run tests + for _, test := range tests { + test.dashboardRepo.SetID(test.want.GetID()) + test.dashboardRepo.SetName(test.want.GetName()) + test.dashboardRepo.SetBranches(test.want.GetBranches()) + test.dashboardRepo.SetEvents(test.want.GetEvents()) + + if test.dashboardRepo.GetID() != test.want.GetID() { + t.Errorf("SetID is %v, want %v", test.dashboardRepo.GetID(), test.want.GetID()) + } + + if test.dashboardRepo.GetName() != test.want.GetName() { + t.Errorf("SetName is %v, want %v", test.dashboardRepo.GetName(), test.want.GetName()) + } + + if !reflect.DeepEqual(test.dashboardRepo.GetBranches(), test.want.GetBranches()) { + t.Errorf("SetBranches is %v, want %v", test.dashboardRepo.GetBranches(), test.want.GetBranches()) + } + + if !reflect.DeepEqual(test.dashboardRepo.GetEvents(), test.want.GetEvents()) { + t.Errorf("SetEvents is %v, want %v", test.dashboardRepo.GetEvents(), test.want.GetEvents()) + } + } +} + +func TestTypes_DashboardRepo_String(t *testing.T) { + // setup types + d := testDashboardRepo() + + want := fmt.Sprintf(`{ + Name: %s, + ID: %d, + Branches: %v, + Events: %v, +}`, + d.GetName(), + d.GetID(), + d.GetBranches(), + d.GetEvents(), + ) + + // run test + got := d.String() + + if !reflect.DeepEqual(got, want) { + t.Errorf("String is %v, want %v", got, want) + } +} + +// testDashboardRepo is a test helper function to create a DashboardRepo +// type with all fields set to a fake value. +func testDashboardRepo() *DashboardRepo { + d := new(DashboardRepo) + + d.SetName("go-vela/server") + d.SetID(1) + d.SetBranches([]string{"main"}) + d.SetEvents([]string{"push", "tag"}) + + return d +} diff --git a/api/types/dashboard_test.go b/api/types/dashboard_test.go new file mode 100644 index 000000000..29f8a283c --- /dev/null +++ b/api/types/dashboard_test.go @@ -0,0 +1,174 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "fmt" + "reflect" + "testing" +) + +func TestTypes_Dashboard_Getters(t *testing.T) { + // setup tests + tests := []struct { + dashboard *Dashboard + want *Dashboard + }{ + { + dashboard: testDashboard(), + want: testDashboard(), + }, + { + dashboard: new(Dashboard), + want: new(Dashboard), + }, + } + + // run tests + for _, test := range tests { + if test.dashboard.GetID() != test.want.GetID() { + t.Errorf("GetID is %v, want %v", test.dashboard.GetID(), test.want.GetID()) + } + + if test.dashboard.GetName() != test.want.GetName() { + t.Errorf("GetName is %v, want %v", test.dashboard.GetName(), test.want.GetName()) + } + + if !reflect.DeepEqual(test.dashboard.GetAdmins(), test.want.GetAdmins()) { + t.Errorf("GetAdmins is %v, want %v", test.dashboard.GetAdmins(), test.want.GetAdmins()) + } + + if test.dashboard.GetCreatedAt() != test.want.GetCreatedAt() { + t.Errorf("GetCreatedAt is %v, want %v", test.dashboard.GetCreatedAt(), test.want.GetCreatedAt()) + } + + if test.dashboard.GetCreatedBy() != test.want.GetCreatedBy() { + t.Errorf("GetCreatedBy is %v, want %v", test.dashboard.GetCreatedBy(), test.want.GetCreatedBy()) + } + + if test.dashboard.GetUpdatedAt() != test.want.GetUpdatedAt() { + t.Errorf("GetUpdatedAt is %v, want %v", test.dashboard.GetUpdatedAt(), test.want.GetUpdatedAt()) + } + + if test.dashboard.GetUpdatedBy() != test.want.GetUpdatedBy() { + t.Errorf("GetUpdatedBy is %v, want %v", test.dashboard.GetUpdatedBy(), test.want.GetUpdatedBy()) + } + + if !reflect.DeepEqual(test.dashboard.GetRepos(), test.want.GetRepos()) { + t.Errorf("GetRepos is %v, want %v", test.dashboard.GetRepos(), test.want.GetRepos()) + } + } +} + +func TestTypes_Dashboard_Setters(t *testing.T) { + // setup types + var d *Dashboard + + // setup tests + tests := []struct { + dashboard *Dashboard + want *Dashboard + }{ + { + dashboard: testDashboard(), + want: testDashboard(), + }, + { + dashboard: d, + want: new(Dashboard), + }, + } + + // run tests + for _, test := range tests { + test.dashboard.SetID(test.want.GetID()) + test.dashboard.SetName(test.want.GetName()) + test.dashboard.SetAdmins(test.want.GetAdmins()) + test.dashboard.SetCreatedAt(test.want.GetCreatedAt()) + test.dashboard.SetCreatedBy(test.want.GetCreatedBy()) + test.dashboard.SetUpdatedAt(test.want.GetUpdatedAt()) + test.dashboard.SetUpdatedBy(test.want.GetUpdatedBy()) + test.dashboard.SetRepos(test.want.GetRepos()) + + if test.dashboard.GetID() != test.want.GetID() { + t.Errorf("SetID is %v, want %v", test.dashboard.GetID(), test.want.GetID()) + } + + if test.dashboard.GetName() != test.want.GetName() { + t.Errorf("SetName is %v, want %v", test.dashboard.GetName(), test.want.GetName()) + } + + if !reflect.DeepEqual(test.dashboard.GetAdmins(), test.want.GetAdmins()) { + t.Errorf("SetAdmins is %v, want %v", test.dashboard.GetAdmins(), test.want.GetAdmins()) + } + + if test.dashboard.GetCreatedAt() != test.want.GetCreatedAt() { + t.Errorf("SetCreatedAt is %v, want %v", test.dashboard.GetCreatedAt(), test.want.GetCreatedAt()) + } + + if test.dashboard.GetCreatedBy() != test.want.GetCreatedBy() { + t.Errorf("SetCreatedBy is %v, want %v", test.dashboard.GetCreatedBy(), test.want.GetCreatedBy()) + } + + if test.dashboard.GetUpdatedAt() != test.want.GetUpdatedAt() { + t.Errorf("SetUpdatedAt is %v, want %v", test.dashboard.GetUpdatedAt(), test.want.GetUpdatedAt()) + } + + if test.dashboard.GetUpdatedBy() != test.want.GetUpdatedBy() { + t.Errorf("SetUpdatedBy is %v, want %v", test.dashboard.GetUpdatedBy(), test.want.GetUpdatedBy()) + } + + if !reflect.DeepEqual(test.dashboard.GetRepos(), test.want.GetRepos()) { + t.Errorf("SetRepos is %v, want %v", test.dashboard.GetRepos(), test.want.GetRepos()) + } + } +} + +func TestTypes_Dashboard_String(t *testing.T) { + // setup types + d := testDashboard() + + want := fmt.Sprintf(`{ + Name: %s, + ID: %s, + Admins: %v, + CreatedAt: %d, + CreatedBy: %s, + UpdatedAt: %d, + UpdatedBy: %s, + Repos: %v, +}`, + d.GetName(), + d.GetID(), + d.GetAdmins(), + d.GetCreatedAt(), + d.GetCreatedBy(), + d.GetUpdatedAt(), + d.GetUpdatedBy(), + d.GetRepos(), + ) + + // run test + got := d.String() + + if !reflect.DeepEqual(got, want) { + t.Errorf("String is %v, want %v", got, want) + } +} + +// testDashboard is a test helper function to create a Dashboard +// type with all fields set to a fake value. +func testDashboard() *Dashboard { + d := new(Dashboard) + + d.SetID("123-abc") + d.SetName("vela") + d.SetAdmins([]*User{testUser()}) + d.SetCreatedAt(1) + d.SetCreatedBy("octocat") + d.SetUpdatedAt(2) + d.SetUpdatedBy("octokitty") + d.SetRepos([]*DashboardRepo{testDashboardRepo()}) + + return d +} diff --git a/api/types/events.go b/api/types/events.go index 589f4de46..2dc6f1e28 100644 --- a/api/types/events.go +++ b/api/types/events.go @@ -9,7 +9,7 @@ import ( "github.com/go-vela/types/constants" ) -// Events is the library representation of the various events that generate a +// Events is the API representation of the various events that generate a // webhook from the SCM. type Events struct { Push *actions.Push `json:"push"` diff --git a/api/types/user.go b/api/types/user.go index 50e450030..2bad2f3ea 100644 --- a/api/types/user.go +++ b/api/types/user.go @@ -19,6 +19,7 @@ type User struct { Favorites *[]string `json:"favorites,omitempty"` Active *bool `json:"active,omitempty"` Admin *bool `json:"admin,omitempty"` + Dashboards *[]string `json:"dashboards,omitempty"` } // Sanitize creates a duplicate of the User without the token values. @@ -139,6 +140,19 @@ func (u *User) GetFavorites() []string { return *u.Favorites } +// GetDashboards returns the Dashboards field. +// +// When the provided User type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (u *User) GetDashboards() []string { + // return zero value if User type or Favorites field is nil + if u == nil || u.Dashboards == nil { + return []string{} + } + + return *u.Dashboards +} + // SetID sets the ID field. // // When the provided User type is nil, it @@ -230,11 +244,25 @@ func (u *User) SetFavorites(v []string) { u.Favorites = &v } +// SetDashboard sets the Dashboard field. +// +// When the provided User type is nil, it +// will set nothing and immediately return. +func (u *User) SetDashboards(v []string) { + // return if User type is nil + if u == nil { + return + } + + u.Dashboards = &v +} + // String implements the Stringer interface for the User type. func (u *User) String() string { return fmt.Sprintf(`{ Active: %t, Admin: %t, + Dashboards: %s, Favorites: %s, ID: %d, Name: %s, @@ -242,6 +270,7 @@ func (u *User) String() string { }`, u.GetActive(), u.GetAdmin(), + u.GetDashboards(), u.GetFavorites(), u.GetID(), u.GetName(), diff --git a/api/types/user_test.go b/api/types/user_test.go index d2db92020..1da7acb2f 100644 --- a/api/types/user_test.go +++ b/api/types/user_test.go @@ -91,6 +91,10 @@ func TestTypes_User_Getters(t *testing.T) { if test.user.GetAdmin() != test.want.GetAdmin() { t.Errorf("GetAdmin is %v, want %v", test.user.GetAdmin(), test.want.GetAdmin()) } + + if !reflect.DeepEqual(test.user.GetDashboards(), test.want.GetDashboards()) { + t.Errorf("GetDashboards is %v, want %v", test.user.GetDashboards(), test.want.GetDashboards()) + } } } @@ -122,6 +126,7 @@ func TestTypes_User_Setters(t *testing.T) { test.user.SetFavorites(test.want.GetFavorites()) test.user.SetActive(test.want.GetActive()) test.user.SetAdmin(test.want.GetAdmin()) + test.user.SetDashboards(test.want.GetDashboards()) if test.user.GetID() != test.want.GetID() { t.Errorf("SetID is %v, want %v", test.user.GetID(), test.want.GetID()) @@ -150,6 +155,10 @@ func TestTypes_User_Setters(t *testing.T) { if test.user.GetAdmin() != test.want.GetAdmin() { t.Errorf("SetAdmin is %v, want %v", test.user.GetAdmin(), test.want.GetAdmin()) } + + if !reflect.DeepEqual(test.user.GetDashboards(), test.want.GetDashboards()) { + t.Errorf("SetDashboards is %v, want %v", test.user.GetDashboards(), test.want.GetDashboards()) + } } } @@ -160,6 +169,7 @@ func TestTypes_User_String(t *testing.T) { want := fmt.Sprintf(`{ Active: %t, Admin: %t, + Dashboards: %s, Favorites: %s, ID: %d, Name: %s, @@ -167,6 +177,7 @@ func TestTypes_User_String(t *testing.T) { }`, u.GetActive(), u.GetAdmin(), + u.GetDashboards(), u.GetFavorites(), u.GetID(), u.GetName(), @@ -192,6 +203,7 @@ func testUser() *User { u.SetFavorites([]string{"github/octocat"}) u.SetActive(true) u.SetAdmin(false) + u.SetDashboards([]string{"45bcf19b-c151-4e2d-b8c6-80a62ba2eae7", "ba657dab-bc6e-421f-9188-86272bd0069a"}) return u } diff --git a/api/user/update.go b/api/user/update.go index caec2ac08..3983abd0f 100644 --- a/api/user/update.go +++ b/api/user/update.go @@ -107,6 +107,11 @@ func UpdateUser(c *gin.Context) { u.SetFavorites(input.GetFavorites()) } + if input.Dashboards != nil { + // update dashboards if set + u.SetDashboards(input.GetDashboards()) + } + // send API call to update the user u, err = database.FromContext(c).UpdateUser(ctx, u) if err != nil { diff --git a/api/user/update_current.go b/api/user/update_current.go index 792105a48..dec97ba71 100644 --- a/api/user/update_current.go +++ b/api/user/update_current.go @@ -81,6 +81,12 @@ func UpdateCurrentUser(c *gin.Context) { u.SetFavorites(input.GetFavorites()) } + // update user fields if provided + if input.Dashboards != nil { + // update dashboards if set + u.SetDashboards(input.GetDashboards()) + } + // send API call to update the user u, err = database.FromContext(c).UpdateUser(ctx, u) if err != nil { diff --git a/constants/limit.go b/constants/limit.go new file mode 100644 index 000000000..046b6c19b --- /dev/null +++ b/constants/limit.go @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: Apache-2.0 +package constants + +// Limits and constraints. +const ( + // DashboardAdminMaxSize defines the maximum size in characters for dashboard admins. + DashboardAdminMaxSize = 5000 +) diff --git a/constants/table.go b/constants/table.go new file mode 100644 index 000000000..6d9ff76e8 --- /dev/null +++ b/constants/table.go @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: Apache-2.0 +package constants + +// Database tables. +const ( + // TableDashboard defines the table type for the database dashboards table. + TableDashboard = "dashboards" +) diff --git a/database/build/count_org_test.go b/database/build/count_org_test.go index fb6461261..635e7bd66 100644 --- a/database/build/count_org_test.go +++ b/database/build/count_org_test.go @@ -11,7 +11,6 @@ import ( "github.com/go-vela/server/database/repo" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" ) func TestBuild_Engine_CountBuildsForOrg(t *testing.T) { @@ -78,7 +77,7 @@ func TestBuild_Engine_CountBuildsForOrg(t *testing.T) { t.Errorf("unable to create test build for sqlite: %v", err) } - err = _sqlite.client.AutoMigrate(&database.Repo{}) + err = _sqlite.client.AutoMigrate(&repo.Repo{}) if err != nil { t.Errorf("unable to create repo table for sqlite: %v", err) } diff --git a/database/build/interface.go b/database/build/interface.go index 18c85d194..03c6918b7 100644 --- a/database/build/interface.go +++ b/database/build/interface.go @@ -53,6 +53,8 @@ type BuildInterface interface { ListBuilds(context.Context) ([]*library.Build, error) // ListBuildsForOrg defines a function that gets a list of builds by org name. ListBuildsForOrg(context.Context, string, map[string]interface{}, int, int) ([]*library.Build, int64, error) + // ListBuildsForDashboardRepo defines a function that gets a list of builds based on dashboard filters. + ListBuildsForDashboardRepo(context.Context, *api.Repo, []string, []string) ([]*library.Build, error) // ListBuildsForRepo defines a function that gets a list of builds by repo ID. ListBuildsForRepo(context.Context, *api.Repo, map[string]interface{}, int64, int64, int, int) ([]*library.Build, int64, error) // ListPendingAndRunningBuilds defines a function that gets a list of pending and running builds. diff --git a/database/build/list_dashboard.go b/database/build/list_dashboard.go new file mode 100644 index 000000000..d9f772873 --- /dev/null +++ b/database/build/list_dashboard.go @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: Apache-2.0 + +package build + +import ( + "context" + + "github.com/sirupsen/logrus" + + api "github.com/go-vela/server/api/types" + "github.com/go-vela/types/constants" + "github.com/go-vela/types/database" + "github.com/go-vela/types/library" +) + +// ListBuildsForDashboardRepo gets a list of builds by repo ID from the database. +func (e *engine) ListBuildsForDashboardRepo(ctx context.Context, r *api.Repo, branches, events []string) ([]*library.Build, error) { + e.logger.WithFields(logrus.Fields{ + "org": r.GetOrg(), + "repo": r.GetName(), + }).Tracef("listing builds for repo %s from the database", r.GetFullName()) + + // variables to store query results and return values + b := new([]database.Build) + builds := []*library.Build{} + + query := e.client.Table(constants.TableBuild).Where("repo_id = ?", r.GetID()) + + if len(branches) > 0 { + query = query.Where("branch IN (?)", branches) + } + + if len(events) > 0 { + query = query.Where("event IN (?)", events) + } + + err := query. + Order("number DESC"). + Limit(5). + Find(&b). + Error + if err != nil { + return nil, err + } + + // iterate through all query results + for _, build := range *b { + // https://golang.org/doc/faq#closures_and_goroutines + tmp := build + + // convert query result to library type + // + // https://pkg.go.dev/github.com/go-vela/types/database#Build.ToLibrary + builds = append(builds, tmp.ToLibrary()) + } + + return builds, nil +} diff --git a/database/build/list_dashboard_test.go b/database/build/list_dashboard_test.go new file mode 100644 index 000000000..e73242efb --- /dev/null +++ b/database/build/list_dashboard_test.go @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: Apache-2.0 + +package build + +import ( + "context" + "testing" + + "github.com/DATA-DOG/go-sqlmock" + "github.com/google/go-cmp/cmp" + + "github.com/go-vela/types/library" +) + +func TestBuild_Engine_ListBuildsForDashboardRepo(t *testing.T) { + // setup types + _buildOne := testBuild() + _buildOne.SetID(1) + _buildOne.SetRepoID(1) + _buildOne.SetNumber(1) + _buildOne.SetDeployPayload(nil) + _buildOne.SetCreated(1) + _buildOne.SetEvent("push") + _buildOne.SetBranch("main") + + _buildTwo := testBuild() + _buildTwo.SetID(2) + _buildTwo.SetRepoID(1) + _buildTwo.SetNumber(2) + _buildTwo.SetDeployPayload(nil) + _buildTwo.SetCreated(2) + _buildTwo.SetEvent("pull_request") + _buildTwo.SetBranch("main") + + _repo := testRepo() + _repo.SetID(1) + _repo.SetHash("baz") + _repo.SetOrg("foo") + _repo.SetName("bar") + _repo.SetFullName("foo/bar") + _repo.SetVisibility("public") + + _postgres, _mock := testPostgres(t) + defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() + + // create expected query result in mock + _rows := sqlmock.NewRows( + []string{"id", "repo_id", "pipeline_id", "number", "parent", "event", "event_action", "status", "error", "enqueued", "created", "started", "finished", "deploy", "deploy_payload", "clone", "source", "title", "message", "commit", "sender", "author", "email", "link", "branch", "ref", "base_ref", "head_ref", "host", "runtime", "distribution", "approved_at", "approved_by", "timestamp"}). + AddRow(2, 1, nil, 2, 0, "pull_request", "", "", "", 0, 2, 0, 0, "", nil, "", "", "", "", "", "", "", "", "", "main", "", "", "", "", "", "", 0, "", 0). + AddRow(1, 1, nil, 1, 0, "push", "", "", "", 0, 1, 0, 0, "", nil, "", "", "", "", "", "", "", "", "", "main", "", "", "", "", "", "", 0, "", 0) + + // ensure the mock expects the query + _mock.ExpectQuery(`SELECT * FROM "builds" WHERE repo_id = $1 AND branch IN ($2) AND event IN ($3,$4) ORDER BY number DESC LIMIT $5`).WithArgs(1, "main", "push", "pull_request", 5).WillReturnRows(_rows) + + _sqlite := testSqlite(t) + defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() + + _, err := _sqlite.CreateBuild(context.TODO(), _buildOne) + if err != nil { + t.Errorf("unable to create test build for sqlite: %v", err) + } + + _, err = _sqlite.CreateBuild(context.TODO(), _buildTwo) + if err != nil { + t.Errorf("unable to create test build for sqlite: %v", err) + } + + // setup tests + tests := []struct { + failure bool + name string + database *engine + want []*library.Build + }{ + { + failure: false, + name: "postgres", + database: _postgres, + want: []*library.Build{_buildTwo, _buildOne}, + }, + { + failure: false, + name: "sqlite3", + database: _sqlite, + want: []*library.Build{_buildTwo, _buildOne}, + }, + } + + // run tests + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got, err := test.database.ListBuildsForDashboardRepo(context.TODO(), _repo, []string{"main"}, []string{"push", "pull_request"}) + + if test.failure { + if err == nil { + t.Errorf("ListBuildsForRepo for %s should have returned err", test.name) + } + + return + } + + if err != nil { + t.Errorf("ListBuildsForRepo for %s returned err: %v", test.name, err) + } + + if diff := cmp.Diff(got, test.want); diff != "" { + t.Errorf("GetDashboard mismatch (-want +got):\n%s", diff) + } + }) + } +} diff --git a/database/build/list_org_test.go b/database/build/list_org_test.go index 925acbf96..488cf1e33 100644 --- a/database/build/list_org_test.go +++ b/database/build/list_org_test.go @@ -11,7 +11,6 @@ import ( "github.com/go-vela/server/database/repo" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" "github.com/go-vela/types/library" ) @@ -105,7 +104,7 @@ func TestBuild_Engine_ListBuildsForOrg(t *testing.T) { t.Errorf("unable to create test build for sqlite: %v", err) } - err = _sqlite.client.AutoMigrate(&database.Repo{}) + err = _sqlite.client.AutoMigrate(&repo.Repo{}) if err != nil { t.Errorf("unable to create repo table for sqlite: %v", err) } diff --git a/database/build/list_pending_running_repo_test.go b/database/build/list_pending_running_repo_test.go index 76a04b5de..8ea610fb6 100644 --- a/database/build/list_pending_running_repo_test.go +++ b/database/build/list_pending_running_repo_test.go @@ -11,7 +11,6 @@ import ( "github.com/go-vela/server/database/repo" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" "github.com/go-vela/types/library" ) @@ -89,7 +88,7 @@ func TestBuild_Engine_ListPendingAndRunningBuildsForRepo(t *testing.T) { t.Errorf("unable to create test build for sqlite: %v", err) } - err = _sqlite.client.AutoMigrate(&database.Repo{}) + err = _sqlite.client.AutoMigrate(&repo.Repo{}) if err != nil { t.Errorf("unable to create repo table for sqlite: %v", err) } diff --git a/database/build/list_pending_running_test.go b/database/build/list_pending_running_test.go index 006c13184..5b427702f 100644 --- a/database/build/list_pending_running_test.go +++ b/database/build/list_pending_running_test.go @@ -11,7 +11,6 @@ import ( "github.com/go-vela/server/database/repo" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" "github.com/go-vela/types/library" ) @@ -76,7 +75,7 @@ func TestBuild_Engine_ListPendingAndRunningBuilds(t *testing.T) { t.Errorf("unable to create test build for sqlite: %v", err) } - err = _sqlite.client.AutoMigrate(&database.Repo{}) + err = _sqlite.client.AutoMigrate(&repo.Repo{}) if err != nil { t.Errorf("unable to create repo table for sqlite: %v", err) } diff --git a/database/dashboard/create.go b/database/dashboard/create.go new file mode 100644 index 000000000..5e7ec7887 --- /dev/null +++ b/database/dashboard/create.go @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: Apache-2.0 + +package dashboard + +import ( + "context" + + "github.com/sirupsen/logrus" + + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/constants" +) + +// CreateDashboard creates a new dashboard in the database. +func (e *engine) CreateDashboard(ctx context.Context, d *api.Dashboard) (*api.Dashboard, error) { + e.logger.WithFields(logrus.Fields{ + "dashboard": d.GetName(), + }).Tracef("creating dashboard %s in the database", d.GetName()) + + dashboard := FromAPI(d) + + err := dashboard.Validate() + if err != nil { + return nil, err + } + + // send query to the database + result := e.client.Table(constants.TableDashboard).Create(dashboard) + + return dashboard.ToAPI(), result.Error +} diff --git a/database/dashboard/create_test.go b/database/dashboard/create_test.go new file mode 100644 index 000000000..041a39149 --- /dev/null +++ b/database/dashboard/create_test.go @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: Apache-2.0 + +package dashboard + +import ( + "context" + "reflect" + "testing" + + "github.com/DATA-DOG/go-sqlmock" + + api "github.com/go-vela/server/api/types" +) + +func TestDashboard_Engine_CreateDashboard(t *testing.T) { + // setup types + _dashRepo := new(api.DashboardRepo) + _dashRepo.SetID(1) + _dashRepo.SetBranches([]string{"main"}) + _dashRepo.SetEvents([]string{"push"}) + _dashRepos := []*api.DashboardRepo{_dashRepo} + + _admin := new(api.User) + _admin.SetID(1) + _admin.SetName("octocat") + _admin.SetActive(true) + _admins := []*api.User{_admin} + + _dashboard := testDashboard() + _dashboard.SetID("c8da1302-07d6-11ea-882f-4893bca275b8") + _dashboard.SetName("dash") + _dashboard.SetCreatedAt(1) + _dashboard.SetCreatedBy("user1") + _dashboard.SetUpdatedAt(1) + _dashboard.SetUpdatedBy("user2") + _dashboard.SetAdmins(_admins) + _dashboard.SetRepos(_dashRepos) + + _postgres, _mock := testPostgres(t) + defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() + + // create expected result in mock + _rows := sqlmock.NewRows([]string{"id"}).AddRow("c8da1302-07d6-11ea-882f-4893bca275b8") + + // ensure the mock expects the query + _mock.ExpectQuery(`INSERT INTO "dashboards" +("name","created_at","created_by","updated_at","updated_by","admins","repos","id") +VALUES ($1,$2,$3,$4,$5,$6,$7,$8) RETURNING "id"`). + WithArgs("dash", 1, "user1", 1, "user2", `[{"id":1,"name":"octocat","active":true}]`, `[{"id":1,"branches":["main"],"events":["push"]}]`, "c8da1302-07d6-11ea-882f-4893bca275b8"). + WillReturnRows(_rows) + + _sqlite := testSqlite(t) + defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() + + // setup tests + tests := []struct { + failure bool + name string + database *engine + }{ + { + failure: false, + name: "postgres", + database: _postgres, + }, + { + failure: false, + name: "sqlite3", + database: _sqlite, + }, + } + + // run tests + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got, err := test.database.CreateDashboard(context.TODO(), _dashboard) + + if test.failure { + if err == nil { + t.Errorf("CreateDashboard for %s should have returned err", test.name) + } + + return + } + + if err != nil { + t.Errorf("CreateDashboard for %s returned err: %v", test.name, err) + } + + if !reflect.DeepEqual(got, _dashboard) { + t.Errorf("CreateDashboard for %s returned %s, want %s", test.name, got, _dashboard) + } + }) + } +} diff --git a/database/dashboard/dashboard.go b/database/dashboard/dashboard.go new file mode 100644 index 000000000..321cfe609 --- /dev/null +++ b/database/dashboard/dashboard.go @@ -0,0 +1,248 @@ +// SPDX-License-Identifier: Apache-2.0 + +package dashboard + +import ( + "context" + "database/sql" + "database/sql/driver" + "encoding/json" + "errors" + "fmt" + + "github.com/google/uuid" + "github.com/sirupsen/logrus" + "gorm.io/gorm" + + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/constants" + "github.com/go-vela/server/util" +) + +var ( + // ErrEmptyDashName defines the error type when a + // User type has an empty Name field provided. + ErrEmptyDashName = errors.New("empty dashboard name provided") + + // ErrExceededAdminLimit defines the error type when a + // User type has Admins field provided that exceeds the database limit. + ErrExceededAdminLimit = errors.New("exceeded admins limit") +) + +type ( + // config represents the settings required to create the engine that implements the DashboardService interface. + config struct { + // specifies to skip creating tables and indexes for the Dashboard engine + SkipCreation bool + // specifies the driver for proper popping query + Driver string + } + + // engine represents the dashboard functionality that implements the DashboardService interface. + engine struct { + // engine configuration settings used in dashboard functions + config *config + + ctx context.Context + + // gorm.io/gorm database client used in dashboard functions + // + // https://pkg.go.dev/gorm.io/gorm#DB + client *gorm.DB + + // sirupsen/logrus logger used in dashboard functions + // + // https://pkg.go.dev/github.com/sirupsen/logrus#Entry + logger *logrus.Entry + } + + // Dashboard is the database representation of a dashboard. + Dashboard struct { + ID uuid.UUID `gorm:"type:uuid;default:uuid_generate_v4()"` + Name sql.NullString `sql:"name"` + CreatedAt sql.NullInt64 `sql:"created_at"` + CreatedBy sql.NullString `sql:"created_by"` + UpdatedAt sql.NullInt64 `sql:"updated_at"` + UpdatedBy sql.NullString `sql:"updated_by"` + Admins AdminsJSON + Repos DashReposJSON + } + + DashReposJSON []*api.DashboardRepo + AdminsJSON []*api.User +) + +// New creates and returns a Vela service for integrating with dashboards in the database. +// +//nolint:revive // ignore returning unexported engine +func New(opts ...EngineOpt) (*engine, error) { + // create new Dashboard engine + e := new(engine) + + // create new fields + e.client = new(gorm.DB) + e.config = new(config) + e.logger = new(logrus.Entry) + + // apply all provided configuration options + for _, opt := range opts { + err := opt(e) + if err != nil { + return nil, err + } + } + + // check if we should skip creating dashboard database objects + if e.config.SkipCreation { + e.logger.Warning("skipping creation of dashboards table and indexes in the database") + + return e, nil + } + + // create the dashboards table + err := e.CreateDashboardTable(e.ctx, e.client.Config.Dialector.Name()) + if err != nil { + return nil, fmt.Errorf("unable to create %s table: %w", constants.TableDashboard, err) + } + + return e, nil +} + +// Value - Implementation of valuer for database/sql for DashReposJSON. +func (r DashReposJSON) Value() (driver.Value, error) { + valueString, err := json.Marshal(r) + return string(valueString), err +} + +// Scan - Implement the database/sql scanner interface for DashReposJSON. +func (r *DashReposJSON) Scan(value interface{}) error { + switch v := value.(type) { + case []byte: + return json.Unmarshal(v, &r) + case string: + return json.Unmarshal([]byte(v), &r) + default: + return fmt.Errorf("wrong type for repos: %T", v) + } +} + +// Value - Implementation of valuer for database/sql for AdminsJSON. +func (a AdminsJSON) Value() (driver.Value, error) { + valueString, err := json.Marshal(a) + return string(valueString), err +} + +// Scan - Implement the database/sql scanner interface for AdminsJSON. +func (a *AdminsJSON) Scan(value interface{}) error { + switch v := value.(type) { + case []byte: + return json.Unmarshal(v, &a) + case string: + return json.Unmarshal([]byte(v), &a) + default: + return fmt.Errorf("wrong type for admins: %T", v) + } +} + +// Nullify ensures the valid flag for +// the sql.Null types are properly set. +// +// When a field within the Dashboard 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 *Dashboard) Nullify() *Dashboard { + if d == nil { + return nil + } + + // check if the Name field should be false + if len(d.Name.String) == 0 { + d.Name.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 + } + + // check if the UpdatedAt field should be false + if d.UpdatedAt.Int64 == 0 { + d.UpdatedAt.Valid = false + } + + // check if the UpdatedBy field should be false + if len(d.UpdatedBy.String) == 0 { + d.UpdatedBy.Valid = false + } + + return d +} + +// ToAPI converts the Dashboard type +// to an API Dashboard type. +func (d *Dashboard) ToAPI() *api.Dashboard { + dashboard := new(api.Dashboard) + + dashboard.SetID(d.ID.String()) + dashboard.SetName(d.Name.String) + dashboard.SetAdmins(d.Admins) + dashboard.SetCreatedAt(d.CreatedAt.Int64) + dashboard.SetCreatedBy(d.CreatedBy.String) + dashboard.SetUpdatedAt(d.UpdatedAt.Int64) + dashboard.SetUpdatedBy(d.UpdatedBy.String) + dashboard.SetRepos(d.Repos) + + return dashboard +} + +// Validate verifies the necessary fields for +// the Dashboard type are populated correctly. +func (d *Dashboard) Validate() error { + // verify the Name field is populated + if len(d.Name.String) == 0 { + return ErrEmptyDashName + } + + // ensure that all Dashboard string fields + // that can be returned as JSON are sanitized + // to avoid unsafe HTML content + d.Name = sql.NullString{String: util.Sanitize(d.Name.String), Valid: d.Name.Valid} + + return nil +} + +// FromAPI converts the API Dashboard type +// to a database Dashboard type. +func FromAPI(d *api.Dashboard) *Dashboard { + var ( + id uuid.UUID + err error + ) + + if d.GetID() == "" { + id = uuid.New() + } else { + id, err = uuid.Parse(d.GetID()) + if err != nil { + return nil + } + } + + dashboard := &Dashboard{ + ID: id, + Name: sql.NullString{String: d.GetName(), Valid: true}, + CreatedAt: sql.NullInt64{Int64: d.GetCreatedAt(), Valid: true}, + CreatedBy: sql.NullString{String: d.GetCreatedBy(), Valid: true}, + UpdatedAt: sql.NullInt64{Int64: d.GetUpdatedAt(), Valid: true}, + UpdatedBy: sql.NullString{String: d.GetUpdatedBy(), Valid: true}, + Admins: d.GetAdmins(), + Repos: d.GetRepos(), + } + + return dashboard.Nullify() +} diff --git a/database/dashboard/dashboard_test.go b/database/dashboard/dashboard_test.go new file mode 100644 index 000000000..3073fe299 --- /dev/null +++ b/database/dashboard/dashboard_test.go @@ -0,0 +1,219 @@ +// SPDX-License-Identifier: Apache-2.0 + +package dashboard + +import ( + "database/sql/driver" + "reflect" + "testing" + "time" + + "github.com/DATA-DOG/go-sqlmock" + "github.com/sirupsen/logrus" + "gorm.io/driver/postgres" + "gorm.io/driver/sqlite" + "gorm.io/gorm" + + api "github.com/go-vela/server/api/types" +) + +func TestDashboard_New(t *testing.T) { + // setup types + logger := logrus.NewEntry(logrus.StandardLogger()) + + _sql, _mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual)) + if err != nil { + t.Errorf("unable to create new SQL mock: %v", err) + } + defer _sql.Close() + + _mock.ExpectExec(CreatePostgresTable).WillReturnResult(sqlmock.NewResult(1, 1)) + + _config := &gorm.Config{SkipDefaultTransaction: true} + + _postgres, err := gorm.Open(postgres.New(postgres.Config{Conn: _sql}), _config) + if err != nil { + t.Errorf("unable to create new postgres database: %v", err) + } + + _sqlite, err := gorm.Open(sqlite.Open("file::memory:?cache=shared"), _config) + if err != nil { + t.Errorf("unable to create new sqlite database: %v", err) + } + + defer func() { _sql, _ := _sqlite.DB(); _sql.Close() }() + + // setup tests + tests := []struct { + failure bool + name string + client *gorm.DB + key string + logger *logrus.Entry + skipCreation bool + want *engine + }{ + { + failure: false, + name: "postgres", + client: _postgres, + key: "A1B2C3D4E5G6H7I8J9K0LMNOPQRSTUVW", + logger: logger, + skipCreation: false, + want: &engine{ + client: _postgres, + config: &config{SkipCreation: false}, + logger: logger, + }, + }, + { + failure: false, + name: "sqlite3", + client: _sqlite, + key: "A1B2C3D4E5G6H7I8J9K0LMNOPQRSTUVW", + logger: logger, + skipCreation: false, + want: &engine{ + client: _sqlite, + config: &config{SkipCreation: false}, + logger: logger, + }, + }, + } + + // run tests + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got, err := New( + WithClient(test.client), + WithLogger(test.logger), + WithSkipCreation(test.skipCreation), + ) + + if test.failure { + if err == nil { + t.Errorf("New for %s should have returned err", test.name) + } + + return + } + + if err != nil { + t.Errorf("New for %s returned err: %v", test.name, err) + } + + if !reflect.DeepEqual(got, test.want) { + t.Errorf("New for %s is %v, want %v", test.name, got, test.want) + } + }) + } +} + +// testPostgres is a helper function to create a Postgres engine for testing. +func testPostgres(t *testing.T) (*engine, sqlmock.Sqlmock) { + // create the new mock sql database + // + // https://pkg.go.dev/github.com/DATA-DOG/go-sqlmock#New + _sql, _mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual)) + if err != nil { + t.Errorf("unable to create new SQL mock: %v", err) + } + + _mock.ExpectExec(CreatePostgresTable).WillReturnResult(sqlmock.NewResult(1, 1)) + + // create the new mock Postgres database client + // + // https://pkg.go.dev/gorm.io/gorm#Open + _postgres, err := gorm.Open( + postgres.New(postgres.Config{Conn: _sql}), + &gorm.Config{SkipDefaultTransaction: true}, + ) + if err != nil { + t.Errorf("unable to create new postgres database: %v", err) + } + + _engine, err := New( + WithClient(_postgres), + WithLogger(logrus.NewEntry(logrus.StandardLogger())), + WithSkipCreation(false), + ) + if err != nil { + t.Errorf("unable to create new postgres dashboard engine: %v", err) + } + + return _engine, _mock +} + +// testSqlite is a helper function to create a Sqlite engine for testing. +func testSqlite(t *testing.T) *engine { + _sqlite, err := gorm.Open( + sqlite.Open("file::memory:?cache=shared"), + &gorm.Config{SkipDefaultTransaction: true}, + ) + if err != nil { + t.Errorf("unable to create new sqlite database: %v", err) + } + + _engine, err := New( + WithClient(_sqlite), + WithLogger(logrus.NewEntry(logrus.StandardLogger())), + WithSkipCreation(false), + ) + if err != nil { + t.Errorf("unable to create new sqlite dashboard engine: %v", err) + } + + return _engine +} + +// testAdmin is a test helper function to create an API +// User type wil all fields set to their zero values. +func testAdmins() *[]*api.User { + return &[]*api.User{ + { + ID: new(int64), + Name: new(string), + Active: new(bool), + }, + } +} + +// testDashboard is a test helper function to create a library +// Dashboard type with all fields set to their zero values. +func testDashboard() *api.Dashboard { + return &api.Dashboard{ + ID: new(string), + Name: new(string), + CreatedAt: new(int64), + CreatedBy: new(string), + UpdatedAt: new(int64), + UpdatedBy: new(string), + Admins: testAdmins(), + } +} + +func testDashboardRepo() *api.DashboardRepo { + return &api.DashboardRepo{ + ID: new(int64), + Branches: new([]string), + Events: new([]string), + } +} + +// This will be used with the github.com/DATA-DOG/go-sqlmock library to compare values +// that are otherwise not easily compared. These typically would be values generated +// before adding or updating them in the database. +// +// https://github.com/DATA-DOG/go-sqlmock#matching-arguments-like-timetime +type NowTimestamp struct{} + +// Match satisfies sqlmock.Argument interface. +func (t NowTimestamp) Match(v driver.Value) bool { + ts, ok := v.(int64) + if !ok { + return false + } + now := time.Now().Unix() + + return now-ts < 10 +} diff --git a/database/dashboard/delete.go b/database/dashboard/delete.go new file mode 100644 index 000000000..b2b1e4090 --- /dev/null +++ b/database/dashboard/delete.go @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: Apache-2.0 + +package dashboard + +import ( + "context" + + "github.com/sirupsen/logrus" + + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/constants" +) + +// DeleteDashboard deletes an existing dashboard from the database. +func (e *engine) DeleteDashboard(ctx context.Context, d *api.Dashboard) error { + e.logger.WithFields(logrus.Fields{ + "dashboard": d.GetID(), + }).Tracef("deleting dashboard %s from the database", d.GetID()) + + dashboard := FromAPI(d) + + // send query to the database + return e.client. + Table(constants.TableDashboard). + Delete(dashboard). + Error +} diff --git a/database/dashboard/delete_test.go b/database/dashboard/delete_test.go new file mode 100644 index 000000000..3c079efd1 --- /dev/null +++ b/database/dashboard/delete_test.go @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: Apache-2.0 + +package dashboard + +import ( + "context" + "testing" + + "github.com/DATA-DOG/go-sqlmock" + + api "github.com/go-vela/server/api/types" +) + +func TestDashboard_Engine_DeleteDashboard(t *testing.T) { + // setup types + _dashboard := testDashboard() + _dashboard.SetID("c8da1302-07d6-11ea-882f-4893bca275b8") + _dashboard.SetName("vela") + _dashboard.SetCreatedAt(1) + _dashboard.SetCreatedBy("user1") + _dashboard.SetUpdatedAt(1) + _dashboard.SetUpdatedBy("user2") + _dashboard.SetRepos([]*api.DashboardRepo{testDashboardRepo()}) + + _postgres, _mock := testPostgres(t) + defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() + + // ensure the mock expects the query + _mock.ExpectExec(`DELETE FROM "dashboards" WHERE "dashboards"."id" = $1`). + WithArgs("c8da1302-07d6-11ea-882f-4893bca275b8"). + WillReturnResult(sqlmock.NewResult(1, 1)) + + _sqlite := testSqlite(t) + defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() + + _, err := _sqlite.CreateDashboard(context.TODO(), _dashboard) + if err != nil { + t.Errorf("unable to create test dashboard for sqlite: %v", err) + } + + // setup tests + tests := []struct { + failure bool + name string + database *engine + }{ + { + failure: false, + name: "postgres", + database: _postgres, + }, + { + failure: false, + name: "sqlite3", + database: _sqlite, + }, + } + + // run tests + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + err = test.database.DeleteDashboard(context.TODO(), _dashboard) + + if test.failure { + if err == nil { + t.Errorf("DeleteDashboard for %s should have returned err", test.name) + } + + return + } + + if err != nil { + t.Errorf("DeleteDashboard for %s returned err: %v", test.name, err) + } + }) + } +} diff --git a/database/dashboard/get.go b/database/dashboard/get.go new file mode 100644 index 000000000..e4b9694b9 --- /dev/null +++ b/database/dashboard/get.go @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: Apache-2.0 + +package dashboard + +import ( + "context" + + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/constants" +) + +// GetDashboard gets a dashboard by UUID from the database. +func (e *engine) GetDashboard(ctx context.Context, id string) (*api.Dashboard, error) { + e.logger.Tracef("getting dashboard %s from the database", id) + + // variable to store query results + r := new(Dashboard) + + // send query to the database and store result in variable + err := e.client. + Table(constants.TableDashboard). + Where("id = ?", id). + Take(r). + Error + if err != nil { + return nil, err + } + + return r.ToAPI(), nil +} diff --git a/database/dashboard/get_test.go b/database/dashboard/get_test.go new file mode 100644 index 000000000..79664ad91 --- /dev/null +++ b/database/dashboard/get_test.go @@ -0,0 +1,103 @@ +// SPDX-License-Identifier: Apache-2.0 + +package dashboard + +import ( + "context" + "testing" + + "github.com/DATA-DOG/go-sqlmock" + "github.com/google/go-cmp/cmp" + + api "github.com/go-vela/server/api/types" +) + +func TestRepo_Engine_GetDashboard(t *testing.T) { + // setup types + _dashRepo := new(api.DashboardRepo) + _dashRepo.SetID(1) + _dashRepo.SetBranches([]string{"main"}) + _dashRepo.SetEvents([]string{"push"}) + _dashRepos := []*api.DashboardRepo{_dashRepo} + + _admin := new(api.User) + _admin.SetID(1) + _admin.SetName("octocat") + _admin.SetActive(true) + _admins := []*api.User{_admin} + + _dashboard := testDashboard() + _dashboard.SetID("c8da1302-07d6-11ea-882f-4893bca275b8") + _dashboard.SetName("dash") + _dashboard.SetCreatedAt(1) + _dashboard.SetCreatedBy("user1") + _dashboard.SetUpdatedAt(1) + _dashboard.SetUpdatedBy("user2") + _dashboard.SetRepos(_dashRepos) + _dashboard.SetAdmins(_admins) + + // uuid, _ := uuid.Parse("c8da1302-07d6-11ea-882f-4893bca275b8") + + _postgres, _mock := testPostgres(t) + defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() + + // create expected result in mock + _rows := sqlmock.NewRows( + []string{"id", "name", "created_at", "created_by", "updated_at", "updated_by", "admins", "repos"}, + ).AddRow("c8da1302-07d6-11ea-882f-4893bca275b8", "dash", 1, "user1", 1, "user2", []byte(`[{"id":1,"name":"octocat","active":true}]`), []byte(`[{"id":1,"branches":["main"],"events":["push"]}]`)) + + // ensure the mock expects the query + _mock.ExpectQuery(`SELECT * FROM "dashboards" WHERE id = $1 LIMIT $2`).WithArgs("c8da1302-07d6-11ea-882f-4893bca275b8", 1).WillReturnRows(_rows) + + _sqlite := testSqlite(t) + defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() + + _, err := _sqlite.CreateDashboard(context.TODO(), _dashboard) + if err != nil { + t.Errorf("unable to create test repo for sqlite: %v", err) + } + + // setup tests + tests := []struct { + failure bool + name string + database *engine + want *api.Dashboard + }{ + { + failure: false, + name: "postgres", + database: _postgres, + want: _dashboard, + }, + { + failure: false, + name: "sqlite3", + database: _sqlite, + want: _dashboard, + }, + } + + // run tests + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got, err := test.database.GetDashboard(context.TODO(), "c8da1302-07d6-11ea-882f-4893bca275b8") + + if test.failure { + if err == nil { + t.Errorf("GetDashboard for %s should have returned err", test.name) + } + + return + } + + if err != nil { + t.Errorf("GetDashboard for %s returned err: %v", test.name, err) + } + + if diff := cmp.Diff(got, test.want); diff != "" { + t.Errorf("GetDashboard mismatch (-want +got):\n%s", diff) + } + }) + } +} diff --git a/database/dashboard/interface.go b/database/dashboard/interface.go new file mode 100644 index 000000000..027389f00 --- /dev/null +++ b/database/dashboard/interface.go @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: Apache-2.0 + +package dashboard + +import ( + "context" + + api "github.com/go-vela/server/api/types" +) + +// DashboardInterface represents the Vela interface for repo +// functions with the supported Database backends. +// +//nolint:revive // ignore name stutter +type DashboardInterface interface { + // Dashboard Data Definition Language Functions + // + // https://en.wikipedia.org/wiki/Data_definition_language + + // CreateDashboardTable defines a function that creates the dashboards table. + CreateDashboardTable(context.Context, string) error + + // Dashboard Data Manipulation Language Functions + // + // https://en.wikipedia.org/wiki/Data_manipulation_language + + // CreateDashboard defines a function that creates a dashboard. + CreateDashboard(context.Context, *api.Dashboard) (*api.Dashboard, error) + // DeleteDashboard defines a function that deletes a dashboard. + DeleteDashboard(context.Context, *api.Dashboard) error + // GetDashboard defines a function that gets a dashboard by ID. + GetDashboard(context.Context, string) (*api.Dashboard, error) + // UpdateDashboard defines a function that updates a dashboard. + UpdateDashboard(context.Context, *api.Dashboard) (*api.Dashboard, error) +} diff --git a/database/dashboard/opts.go b/database/dashboard/opts.go new file mode 100644 index 000000000..548d26d21 --- /dev/null +++ b/database/dashboard/opts.go @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: Apache-2.0 + +package dashboard + +import ( + "context" + + "github.com/sirupsen/logrus" + "gorm.io/gorm" +) + +// EngineOpt represents a configuration option to initialize the database engine for dashboards. +type EngineOpt func(*engine) error + +// WithClient sets the gorm.io/gorm client in the database engine for dashboards. +func WithClient(client *gorm.DB) EngineOpt { + return func(e *engine) error { + // set the gorm.io/gorm client in the dashboard engine + e.client = client + + return nil + } +} + +// WithDriver sets the driver type in the database engine for dashboards. +func WithDriver(driver string) EngineOpt { + return func(e *engine) error { + // set the driver type in the dashboard engine + e.config.Driver = driver + + return nil + } +} + +// WithLogger sets the github.com/sirupsen/logrus logger in the database engine for dashboards. +func WithLogger(logger *logrus.Entry) EngineOpt { + return func(e *engine) error { + // set the github.com/sirupsen/logrus logger in the dashboard engine + e.logger = logger + + return nil + } +} + +// WithSkipCreation sets the skip creation logic in the database engine for dashboards. +func WithSkipCreation(skipCreation bool) EngineOpt { + return func(e *engine) error { + // set to skip creating tables and indexes in the dashboard engine + e.config.SkipCreation = skipCreation + + return nil + } +} + +// WithContext sets the context in the database engine for dashboards. +func WithContext(ctx context.Context) EngineOpt { + return func(e *engine) error { + e.ctx = ctx + + return nil + } +} diff --git a/database/dashboard/opts_test.go b/database/dashboard/opts_test.go new file mode 100644 index 000000000..0b41b3861 --- /dev/null +++ b/database/dashboard/opts_test.go @@ -0,0 +1,208 @@ +// SPDX-License-Identifier: Apache-2.0 + +package dashboard + +import ( + "context" + "reflect" + "testing" + + "github.com/sirupsen/logrus" + "gorm.io/gorm" +) + +func TestDashboard_EngineOpt_WithClient(t *testing.T) { + // setup types + e := &engine{client: new(gorm.DB)} + + // setup tests + tests := []struct { + failure bool + name string + client *gorm.DB + want *gorm.DB + }{ + { + failure: false, + name: "client set to new database", + client: new(gorm.DB), + want: new(gorm.DB), + }, + { + failure: false, + name: "client set to nil", + client: nil, + want: nil, + }, + } + + // run tests + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + err := WithClient(test.client)(e) + + if test.failure { + if err == nil { + t.Errorf("WithClient for %s should have returned err", test.name) + } + + return + } + + if err != nil { + t.Errorf("WithClient returned err: %v", err) + } + + if !reflect.DeepEqual(e.client, test.want) { + t.Errorf("WithClient is %v, want %v", e.client, test.want) + } + }) + } +} + +func TestDashboard_EngineOpt_WithLogger(t *testing.T) { + // setup types + e := &engine{logger: new(logrus.Entry)} + + // setup tests + tests := []struct { + failure bool + name string + logger *logrus.Entry + want *logrus.Entry + }{ + { + failure: false, + name: "logger set to new entry", + logger: new(logrus.Entry), + want: new(logrus.Entry), + }, + { + failure: false, + name: "logger set to nil", + logger: nil, + want: nil, + }, + } + + // run tests + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + err := WithLogger(test.logger)(e) + + if test.failure { + if err == nil { + t.Errorf("WithLogger for %s should have returned err", test.name) + } + + return + } + + if err != nil { + t.Errorf("WithLogger returned err: %v", err) + } + + if !reflect.DeepEqual(e.logger, test.want) { + t.Errorf("WithLogger is %v, want %v", e.logger, test.want) + } + }) + } +} + +func TestDashboard_EngineOpt_WithSkipCreation(t *testing.T) { + // setup types + e := &engine{config: new(config)} + + // setup tests + tests := []struct { + failure bool + name string + skipCreation bool + want bool + }{ + { + failure: false, + name: "skip creation set to true", + skipCreation: true, + want: true, + }, + { + failure: false, + name: "skip creation set to false", + skipCreation: false, + want: false, + }, + } + + // run tests + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + err := WithSkipCreation(test.skipCreation)(e) + + if test.failure { + if err == nil { + t.Errorf("WithSkipCreation for %s should have returned err", test.name) + } + + return + } + + if err != nil { + t.Errorf("WithSkipCreation returned err: %v", err) + } + + if !reflect.DeepEqual(e.config.SkipCreation, test.want) { + t.Errorf("WithSkipCreation is %v, want %v", e.config.SkipCreation, test.want) + } + }) + } +} + +func TestDashboard_EngineOpt_WithContext(t *testing.T) { + // setup types + e := &engine{config: new(config)} + + // setup tests + tests := []struct { + failure bool + name string + ctx context.Context + want context.Context + }{ + { + failure: false, + name: "context set to TODO", + ctx: context.TODO(), + want: context.TODO(), + }, + { + failure: false, + name: "context set to nil", + ctx: nil, + want: nil, + }, + } + + // run tests + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + err := WithContext(test.ctx)(e) + + if test.failure { + if err == nil { + t.Errorf("WithContext for %s should have returned err", test.name) + } + + return + } + + if err != nil { + t.Errorf("WithContext returned err: %v", err) + } + + if !reflect.DeepEqual(e.ctx, test.want) { + t.Errorf("WithContext is %v, want %v", e.ctx, test.want) + } + }) + } +} diff --git a/database/dashboard/table.go b/database/dashboard/table.go new file mode 100644 index 000000000..51d470a99 --- /dev/null +++ b/database/dashboard/table.go @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: Apache-2.0 + +package dashboard + +import ( + "context" + + "github.com/go-vela/types/constants" +) + +const ( + // CreatePostgresTable represents a query to create the Postgres dashboards table. + CreatePostgresTable = ` +CREATE TABLE +IF NOT EXISTS +dashboards ( + id UUID PRIMARY KEY, + name VARCHAR(250), + created_at INTEGER, + created_by VARCHAR(250), + updated_at INTEGER, + updated_by VARCHAR(250), + admins JSON DEFAULT NULL, + repos JSON DEFAULT NULL +); +` + + // CreateSqliteTable represents a query to create the Sqlite dashboards table. + CreateSqliteTable = ` +CREATE TABLE +IF NOT EXISTS +dashboards ( + id TEXT PRIMARY KEY, + name TEXT, + created_at INTEGER, + created_by TEXT, + updated_at INTEGER, + updated_by TEXT, + admins TEXT, + repos TEXT +); +` +) + +// CreateDashboardTable creates the dashboards table in the database. +func (e *engine) CreateDashboardTable(ctx context.Context, driver string) error { + e.logger.Tracef("creating dashboards table in the database") + + // handle the driver provided to create the table + switch driver { + case constants.DriverPostgres: + // create the dashboards table for Postgres + return e.client.Exec(CreatePostgresTable).Error + case constants.DriverSqlite: + fallthrough + default: + // create the dashboards table for Sqlite + return e.client.Exec(CreateSqliteTable).Error + } +} diff --git a/database/dashboard/table_test.go b/database/dashboard/table_test.go new file mode 100644 index 000000000..2f9c3d953 --- /dev/null +++ b/database/dashboard/table_test.go @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: Apache-2.0 + +package dashboard + +import ( + "context" + "testing" + + "github.com/DATA-DOG/go-sqlmock" +) + +func TestDashboard_Engine_CreateDashboardTable(t *testing.T) { + // setup types + _postgres, _mock := testPostgres(t) + defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() + + _mock.ExpectExec(CreatePostgresTable).WillReturnResult(sqlmock.NewResult(1, 1)) + + _sqlite := testSqlite(t) + defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() + + // setup tests + tests := []struct { + failure bool + name string + database *engine + }{ + { + failure: false, + name: "postgres", + database: _postgres, + }, + { + failure: false, + name: "sqlite3", + database: _sqlite, + }, + } + + // run tests + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + err := test.database.CreateDashboardTable(context.TODO(), test.name) + + if test.failure { + if err == nil { + t.Errorf("CreateDashboardTable for %s should have returned err", test.name) + } + + return + } + + if err != nil { + t.Errorf("CreateDashboardTable for %s returned err: %v", test.name, err) + } + }) + } +} diff --git a/database/dashboard/update.go b/database/dashboard/update.go new file mode 100644 index 000000000..85947f545 --- /dev/null +++ b/database/dashboard/update.go @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: Apache-2.0 + +package dashboard + +import ( + "context" + + "github.com/sirupsen/logrus" + + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/constants" +) + +// UpdateDashboard updates an existing dashboard in the database. +func (e *engine) UpdateDashboard(ctx context.Context, d *api.Dashboard) (*api.Dashboard, error) { + e.logger.WithFields(logrus.Fields{ + "dashboard": d.GetID(), + }).Tracef("creating dashboard %s in the database", d.GetID()) + + dashboard := FromAPI(d) + + err := dashboard.Validate() + if err != nil { + return nil, err + } + + // send query to the database + err = e.client.Table(constants.TableDashboard).Save(dashboard).Error + if err != nil { + return nil, err + } + + return dashboard.ToAPI(), nil +} diff --git a/database/dashboard/update_test.go b/database/dashboard/update_test.go new file mode 100644 index 000000000..adf1627e7 --- /dev/null +++ b/database/dashboard/update_test.go @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: Apache-2.0 + +package dashboard + +import ( + "context" + "testing" + + "github.com/DATA-DOG/go-sqlmock" + "github.com/google/go-cmp/cmp" + + api "github.com/go-vela/server/api/types" +) + +func TestDashboard_Engine_UpdateDashboard(t *testing.T) { + // setup types + _dashRepo := new(api.DashboardRepo) + _dashRepo.SetID(1) + _dashRepo.SetBranches([]string{"main"}) + _dashRepo.SetEvents([]string{"push"}) + _dashRepos := []*api.DashboardRepo{_dashRepo} + + _admin := new(api.User) + _admin.SetID(1) + _admin.SetName("octocat") + _admin.SetActive(true) + _admins := []*api.User{_admin} + + _dashboard := testDashboard() + _dashboard.SetID("c8da1302-07d6-11ea-882f-4893bca275b8") + _dashboard.SetName("dash") + _dashboard.SetCreatedAt(1) + _dashboard.SetCreatedBy("user1") + _dashboard.SetUpdatedAt(1) + _dashboard.SetUpdatedBy("user2") + _dashboard.SetRepos(_dashRepos) + _dashboard.SetAdmins(_admins) + + _postgres, _mock := testPostgres(t) + defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() + + // ensure the mock expects the query + _mock.ExpectExec(`UPDATE "dashboards" +SET "name"=$1,"created_at"=$2,"created_by"=$3,"updated_at"=$4,"updated_by"=$5,"admins"=$6,"repos"=$7 WHERE "id" = $8`). + WithArgs("dash", 1, "user1", NowTimestamp{}, "user2", `[{"id":1,"name":"octocat","active":true}]`, `[{"id":1,"branches":["main"],"events":["push"]}]`, "c8da1302-07d6-11ea-882f-4893bca275b8"). + WillReturnResult(sqlmock.NewResult(1, 1)) + + _sqlite := testSqlite(t) + defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() + + _, err := _sqlite.CreateDashboard(context.TODO(), _dashboard) + if err != nil { + t.Errorf("unable to create test dashboard for sqlite: %v", err) + } + + // setup tests + tests := []struct { + failure bool + name string + database *engine + }{ + { + failure: false, + name: "postgres", + database: _postgres, + }, + { + failure: false, + name: "sqlite3", + database: _sqlite, + }, + } + + // run tests + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got, err := test.database.UpdateDashboard(context.TODO(), _dashboard) + _dashboard.SetUpdatedAt(got.GetUpdatedAt()) + + if test.failure { + if err == nil { + t.Errorf("UpdateDashboard for %s should have returned err", test.name) + } + + return + } + + if err != nil { + t.Errorf("UpdateDashboard for %s returned err: %v", test.name, err) + } + + if diff := cmp.Diff(got, _dashboard); diff != "" { + t.Errorf("GetDashboard mismatch (-want +got):\n%s", diff) + } + }) + } +} diff --git a/database/database.go b/database/database.go index 8f873f776..50d8ae956 100644 --- a/database/database.go +++ b/database/database.go @@ -13,6 +13,7 @@ import ( "gorm.io/gorm" "github.com/go-vela/server/database/build" + "github.com/go-vela/server/database/dashboard" "github.com/go-vela/server/database/deployment" "github.com/go-vela/server/database/executable" "github.com/go-vela/server/database/hook" @@ -61,6 +62,7 @@ type ( logger *logrus.Entry build.BuildInterface + dashboard.DashboardInterface executable.BuildExecutableInterface deployment.DeploymentInterface hook.HookInterface diff --git a/database/integration_test.go b/database/integration_test.go index c1fb14f57..2444795e1 100644 --- a/database/integration_test.go +++ b/database/integration_test.go @@ -14,6 +14,7 @@ import ( api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database/build" + "github.com/go-vela/server/database/dashboard" "github.com/go-vela/server/database/deployment" "github.com/go-vela/server/database/executable" "github.com/go-vela/server/database/hook" @@ -34,6 +35,7 @@ import ( // Resources represents the object containing test resources. type Resources struct { Builds []*library.Build + Dashboards []*api.Dashboard Deployments []*library.Deployment Executables []*library.BuildExecutable Hooks []*library.Hook @@ -121,6 +123,8 @@ func TestDatabase_Integration(t *testing.T) { t.Run("test_builds", func(t *testing.T) { testBuilds(t, db, resources) }) + t.Run("test_dashboards", func(t *testing.T) { testDashboards(t, db, resources) }) + t.Run("test_deployments", func(t *testing.T) { testDeployments(t, db, resources) }) t.Run("test_executables", func(t *testing.T) { testExecutables(t, db, resources) }) @@ -288,6 +292,18 @@ func testBuilds(t *testing.T, db Interface, resources *Resources) { } methods["ListBuildsForRepo"] = true + list, err = db.ListBuildsForDashboardRepo(context.TODO(), resources.Repos[0], []string{"main"}, []string{"push"}) + if err != nil { + t.Errorf("unable to list build for dashboard repo %d: %v", resources.Repos[0].GetID(), err) + } + if len(list) != 1 { + t.Errorf("Number of results for ListBuildsForDashboardRepo() is %v, want %v", len(list), 1) + } + if !cmp.Equal(list, []*library.Build{resources.Builds[0]}) { + t.Errorf("ListBuildsForDashboardRepo() is %v, want %v", list, []*library.Build{resources.Builds[0]}) + } + methods["ListBuildsForDashboardRepo"] = true + // list the pending / running builds for a repo list, err = db.ListPendingAndRunningBuildsForRepo(context.TODO(), resources.Repos[0]) if err != nil { @@ -389,6 +405,90 @@ func testBuilds(t *testing.T, db Interface, resources *Resources) { } } +func testDashboards(t *testing.T, db Interface, resources *Resources) { + // create a variable to track the number of methods called for schedules + methods := make(map[string]bool) + // capture the element type of the schedule interface + element := reflect.TypeOf(new(dashboard.DashboardInterface)).Elem() + // iterate through all methods found in the schedule interface + for i := 0; i < element.NumMethod(); i++ { + // skip tracking the methods to create indexes and tables for schedules + // since those are already called when the database engine starts + if strings.Contains(element.Method(i).Name, "Index") || + strings.Contains(element.Method(i).Name, "Table") { + continue + } + + // add the method name to the list of functions + methods[element.Method(i).Name] = false + } + + ctx := context.TODO() + + // create the dashboard + for _, dashboard := range resources.Dashboards { + _, err := db.CreateDashboard(ctx, dashboard) + if err != nil { + t.Errorf("unable to create dashboard %s: %v", dashboard.GetID(), err) + } + } + methods["CreateDashboard"] = true + + // lookup the dashboards by ID + for _, dashboard := range resources.Dashboards { + got, err := db.GetDashboard(ctx, dashboard.GetID()) + if err != nil { + t.Errorf("unable to get schedule %s: %v", dashboard.GetID(), err) + } + + // JSON tags of `-` prevent unmarshaling of tokens, but they are sanitized anyway + cmpAdmins := []*api.User{} + for _, admin := range got.GetAdmins() { + admin.SetToken(constants.SecretMask) + admin.SetRefreshToken(constants.SecretMask) + + cmpAdmins = append(cmpAdmins, admin) + } + + got.SetAdmins(cmpAdmins) + + if !cmp.Equal(got, dashboard, CmpOptApproxUpdatedAt()) { + t.Errorf("GetDashboard() is %v, want %v", got, dashboard) + } + } + methods["GetDashboard"] = true + + // update the dashboards + for _, dashboard := range resources.Dashboards { + dashboard.SetUpdatedAt(time.Now().UTC().Unix()) + got, err := db.UpdateDashboard(ctx, dashboard) + if err != nil { + t.Errorf("unable to update dashboard %s: %v", dashboard.GetID(), err) + } + + if !cmp.Equal(got, dashboard, CmpOptApproxUpdatedAt()) { + t.Errorf("UpdateDashboard() is %v, want %v", got, dashboard) + } + } + methods["UpdateDashboard"] = true + + // delete the schedules + for _, dashboard := range resources.Dashboards { + err := db.DeleteDashboard(ctx, dashboard) + if err != nil { + t.Errorf("unable to delete schedule %s: %v", dashboard.GetID(), err) + } + } + methods["DeleteDashboard"] = true + + // ensure we called all the methods we expected to + for method, called := range methods { + if !called { + t.Errorf("method %s was not called for dashboards", method) + } + } +} + func testExecutables(t *testing.T, db Interface, resources *Resources) { // create a variable to track the number of methods called for pipelines methods := make(map[string]bool) @@ -1817,6 +1917,7 @@ func testUsers(t *testing.T, db Interface, resources *Resources) { userOne.SetToken("") userOne.SetRefreshToken("") userOne.SetFavorites(nil) + userOne.SetDashboards(nil) userOne.SetActive(false) userOne.SetAdmin(false) @@ -1826,6 +1927,7 @@ func testUsers(t *testing.T, db Interface, resources *Resources) { userTwo.SetToken("") userTwo.SetRefreshToken("") userTwo.SetFavorites(nil) + userTwo.SetDashboards(nil) userTwo.SetActive(false) userTwo.SetAdmin(false) @@ -2009,6 +2111,26 @@ func testWorkers(t *testing.T, db Interface, resources *Resources) { } func newResources() *Resources { + userOne := new(api.User) + userOne.SetID(1) + userOne.SetName("octocat") + userOne.SetToken("superSecretToken") + userOne.SetRefreshToken("superSecretRefreshToken") + userOne.SetFavorites([]string{"github/octocat"}) + userOne.SetActive(true) + userOne.SetAdmin(false) + userOne.SetDashboards([]string{"45bcf19b-c151-4e2d-b8c6-80a62ba2eae7"}) + + userTwo := new(api.User) + userTwo.SetID(2) + userTwo.SetName("octokitty") + userTwo.SetToken("superSecretToken") + userTwo.SetRefreshToken("superSecretRefreshToken") + userTwo.SetFavorites([]string{"github/octocat"}) + userTwo.SetActive(true) + userTwo.SetAdmin(false) + userTwo.SetDashboards([]string{"45bcf19b-c151-4e2d-b8c6-80a62ba2eae7", "ba657dab-bc6e-421f-9188-86272bd0069a"}) + buildOne := new(library.Build) buildOne.SetID(1) buildOne.SetRepoID(1) @@ -2081,6 +2203,32 @@ func newResources() *Resources { buildTwo.SetApprovedAt(1563474078) buildTwo.SetApprovedBy("OctoCat") + dashRepo := new(api.DashboardRepo) + dashRepo.SetID(1) + dashRepo.SetName("go-vela/server") + dashRepo.SetBranches([]string{"main"}) + dashRepo.SetEvents([]string{"push"}) + + dashboardOne := new(api.Dashboard) + dashboardOne.SetID("ba657dab-bc6e-421f-9188-86272bd0069a") + dashboardOne.SetName("vela") + dashboardOne.SetCreatedAt(1) + dashboardOne.SetCreatedBy("octocat") + dashboardOne.SetUpdatedAt(2) + dashboardOne.SetUpdatedBy("octokitty") + dashboardOne.SetAdmins([]*api.User{userOne.Sanitize(), userTwo.Sanitize()}) + dashboardOne.SetRepos([]*api.DashboardRepo{dashRepo}) + + dashboardTwo := new(api.Dashboard) + dashboardTwo.SetID("45bcf19b-c151-4e2d-b8c6-80a62ba2eae7") + dashboardTwo.SetName("vela") + dashboardTwo.SetCreatedAt(1) + dashboardTwo.SetCreatedBy("octocat") + dashboardTwo.SetUpdatedAt(2) + dashboardTwo.SetUpdatedBy("octokitty") + dashboardTwo.SetAdmins([]*api.User{userOne.Sanitize(), userTwo.Sanitize()}) + dashboardTwo.SetRepos([]*api.DashboardRepo{dashRepo}) + executableOne := new(library.BuildExecutable) executableOne.SetID(1) executableOne.SetBuildID(1) @@ -2236,24 +2384,6 @@ func newResources() *Resources { pipelineTwo.SetTemplates(false) pipelineTwo.SetData([]byte("version: 1")) - userOne := new(api.User) - userOne.SetID(1) - userOne.SetName("octocat") - userOne.SetToken("superSecretToken") - userOne.SetRefreshToken("superSecretRefreshToken") - userOne.SetFavorites([]string{"github/octocat"}) - userOne.SetActive(true) - userOne.SetAdmin(false) - - userTwo := new(api.User) - userTwo.SetID(2) - userTwo.SetName("octokitty") - userTwo.SetToken("superSecretToken") - userTwo.SetRefreshToken("superSecretRefreshToken") - userTwo.SetFavorites([]string{"github/octocat"}) - userTwo.SetActive(true) - userTwo.SetAdmin(false) - repoOne := new(api.Repo) repoOne.SetID(1) repoOne.SetOwner(userOne.Sanitize()) @@ -2485,6 +2615,7 @@ func newResources() *Resources { return &Resources{ Builds: []*library.Build{buildOne, buildTwo}, + Dashboards: []*api.Dashboard{dashboardOne, dashboardTwo}, Deployments: []*library.Deployment{deploymentOne, deploymentTwo}, Executables: []*library.BuildExecutable{executableOne, executableTwo}, Hooks: []*library.Hook{hookOne, hookTwo, hookThree}, diff --git a/database/interface.go b/database/interface.go index 4a51019b3..16a0fdf27 100644 --- a/database/interface.go +++ b/database/interface.go @@ -4,6 +4,7 @@ package database import ( "github.com/go-vela/server/database/build" + "github.com/go-vela/server/database/dashboard" "github.com/go-vela/server/database/deployment" "github.com/go-vela/server/database/executable" "github.com/go-vela/server/database/hook" @@ -39,6 +40,9 @@ type Interface interface { // BuildExecutableInterface defines the interface for build executables stored in the database. executable.BuildExecutableInterface + // DashboardInterface defines the interface for builds store in the database. + dashboard.DashboardInterface + // DeploymentInterface defines the interface for deployments stored in the database. deployment.DeploymentInterface diff --git a/database/repo/get_org_test.go b/database/repo/get_org_test.go index 3cf2fd9a3..dc168088c 100644 --- a/database/repo/get_org_test.go +++ b/database/repo/get_org_test.go @@ -12,7 +12,6 @@ import ( api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database/user" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" ) func TestRepo_Engine_GetRepoForOrg(t *testing.T) { @@ -58,7 +57,7 @@ func TestRepo_Engine_GetRepoForOrg(t *testing.T) { t.Errorf("unable to create test repo for sqlite: %v", err) } - err = _sqlite.client.AutoMigrate(&database.User{}) + err = _sqlite.client.AutoMigrate(&user.User{}) if err != nil { t.Errorf("unable to create build table for sqlite: %v", err) } diff --git a/database/repo/get_test.go b/database/repo/get_test.go index 7d7618fd3..9b3ded139 100644 --- a/database/repo/get_test.go +++ b/database/repo/get_test.go @@ -12,7 +12,6 @@ import ( api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database/user" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" ) func TestRepo_Engine_GetRepo(t *testing.T) { @@ -58,7 +57,7 @@ func TestRepo_Engine_GetRepo(t *testing.T) { t.Errorf("unable to create test repo for sqlite: %v", err) } - err = _sqlite.client.AutoMigrate(&database.User{}) + err = _sqlite.client.AutoMigrate(&user.User{}) if err != nil { t.Errorf("unable to create build table for sqlite: %v", err) } diff --git a/database/repo/list_org_test.go b/database/repo/list_org_test.go index 47fa34e1b..54af05969 100644 --- a/database/repo/list_org_test.go +++ b/database/repo/list_org_test.go @@ -131,7 +131,7 @@ func TestRepo_Engine_ListReposForOrg(t *testing.T) { t.Errorf("unable to create test build for sqlite: %v", err) } - err = _sqlite.client.AutoMigrate(&database.User{}) + err = _sqlite.client.AutoMigrate(&user.User{}) if err != nil { t.Errorf("unable to create build table for sqlite: %v", err) } diff --git a/database/repo/list_test.go b/database/repo/list_test.go index 84738be32..5adbc0fa6 100644 --- a/database/repo/list_test.go +++ b/database/repo/list_test.go @@ -12,7 +12,6 @@ import ( api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database/user" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" ) func TestRepo_Engine_ListRepos(t *testing.T) { @@ -82,7 +81,7 @@ func TestRepo_Engine_ListRepos(t *testing.T) { t.Errorf("unable to create test repo for sqlite: %v", err) } - err = _sqlite.client.AutoMigrate(&database.User{}) + err = _sqlite.client.AutoMigrate(&user.User{}) if err != nil { t.Errorf("unable to create build table for sqlite: %v", err) } diff --git a/database/repo/list_user_test.go b/database/repo/list_user_test.go index d4e3152f5..1bdae5d36 100644 --- a/database/repo/list_user_test.go +++ b/database/repo/list_user_test.go @@ -133,7 +133,7 @@ func TestRepo_Engine_ListReposForUser(t *testing.T) { t.Errorf("unable to create test build for sqlite: %v", err) } - err = _sqlite.client.AutoMigrate(&database.User{}) + err = _sqlite.client.AutoMigrate(&user.User{}) if err != nil { t.Errorf("unable to create build table for sqlite: %v", err) } diff --git a/database/resource.go b/database/resource.go index 2e309dedf..d592179c8 100644 --- a/database/resource.go +++ b/database/resource.go @@ -6,6 +6,7 @@ import ( "context" "github.com/go-vela/server/database/build" + "github.com/go-vela/server/database/dashboard" "github.com/go-vela/server/database/deployment" "github.com/go-vela/server/database/executable" "github.com/go-vela/server/database/hook" @@ -35,6 +36,16 @@ func (e *engine) NewResources(ctx context.Context) error { return err } + e.DashboardInterface, err = dashboard.New( + dashboard.WithContext(e.ctx), + dashboard.WithClient(e.client), + dashboard.WithLogger(e.logger), + dashboard.WithSkipCreation(e.config.SkipCreation), + ) + if err != nil { + return err + } + // create the database agnostic engine for build_executables e.BuildExecutableInterface, err = executable.New( executable.WithContext(e.ctx), diff --git a/database/resource_test.go b/database/resource_test.go index 5819739c4..dc99bb63b 100644 --- a/database/resource_test.go +++ b/database/resource_test.go @@ -9,6 +9,7 @@ import ( "github.com/DATA-DOG/go-sqlmock" "github.com/go-vela/server/database/build" + "github.com/go-vela/server/database/dashboard" "github.com/go-vela/server/database/deployment" "github.com/go-vela/server/database/executable" "github.com/go-vela/server/database/hook" @@ -33,6 +34,8 @@ func TestDatabase_Engine_NewResources(t *testing.T) { _mock.ExpectExec(build.CreateRepoIDIndex).WillReturnResult(sqlmock.NewResult(1, 1)) _mock.ExpectExec(build.CreateSourceIndex).WillReturnResult(sqlmock.NewResult(1, 1)) _mock.ExpectExec(build.CreateStatusIndex).WillReturnResult(sqlmock.NewResult(1, 1)) + // ensure the mock expects the dashboard queries + _mock.ExpectExec(dashboard.CreatePostgresTable).WillReturnResult(sqlmock.NewResult(1, 1)) // ensure the mock expects the build executable queries _mock.ExpectExec(executable.CreatePostgresTable).WillReturnResult(sqlmock.NewResult(1, 1)) // ensure the mock expects the deployment queries diff --git a/database/user/create_test.go b/database/user/create_test.go index c9a8acdf0..988cac912 100644 --- a/database/user/create_test.go +++ b/database/user/create_test.go @@ -25,9 +25,9 @@ func TestUser_Engine_CreateUser(t *testing.T) { // ensure the mock expects the query _mock.ExpectQuery(`INSERT INTO "users" -("name","refresh_token","token","favorites","active","admin","id") -VALUES ($1,$2,$3,$4,$5,$6,$7) RETURNING "id"`). - WithArgs("foo", AnyArgument{}, AnyArgument{}, nil, false, false, 1). +("name","refresh_token","token","favorites","active","admin","dashboards","id") +VALUES ($1,$2,$3,$4,$5,$6,$7,$8) RETURNING "id"`). + WithArgs("foo", AnyArgument{}, AnyArgument{}, nil, false, false, AnyArgument{}, 1). WillReturnRows(_rows) _sqlite := testSqlite(t) diff --git a/database/user/get_name_test.go b/database/user/get_name_test.go index 86b812ca0..72a9c1e08 100644 --- a/database/user/get_name_test.go +++ b/database/user/get_name_test.go @@ -20,14 +20,15 @@ func TestUser_Engine_GetUserForName(t *testing.T) { _user.SetToken("bar") _user.SetFavorites([]string{}) + _user.SetDashboards([]string{}) _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() // create expected result in mock _rows := sqlmock.NewRows( - []string{"id", "name", "refresh_token", "token", "hash", "favorites", "active", "admin"}). - AddRow(1, "foo", "", "bar", "baz", "{}", false, false) + []string{"id", "name", "refresh_token", "token", "hash", "favorites", "active", "admin", "dashboards"}). + AddRow(1, "foo", "", "bar", "baz", "{}", false, false, "{}") // ensure the mock expects the query _mock.ExpectQuery(`SELECT * FROM "users" WHERE name = $1 LIMIT $2`).WithArgs("foo", 1).WillReturnRows(_rows) diff --git a/database/user/get_test.go b/database/user/get_test.go index b92f2bee4..213da30f8 100644 --- a/database/user/get_test.go +++ b/database/user/get_test.go @@ -20,14 +20,15 @@ func TestUser_Engine_GetUser(t *testing.T) { _user.SetToken("bar") _user.SetFavorites([]string{}) + _user.SetDashboards([]string{}) _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() // create expected result in mock _rows := sqlmock.NewRows( - []string{"id", "name", "refresh_token", "token", "hash", "favorites", "active", "admin"}). - AddRow(1, "foo", "", "bar", "baz", "{}", false, false) + []string{"id", "name", "refresh_token", "token", "hash", "favorites", "active", "admin", "dashboards"}). + AddRow(1, "foo", "", "bar", "baz", "{}", false, false, "{}") // ensure the mock expects the query _mock.ExpectQuery(`SELECT * FROM "users" WHERE id = $1 LIMIT $2`).WithArgs(1, 1).WillReturnRows(_rows) diff --git a/database/user/list_lite_test.go b/database/user/list_lite_test.go index 780b1e29a..6f2888e50 100644 --- a/database/user/list_lite_test.go +++ b/database/user/list_lite_test.go @@ -19,12 +19,14 @@ func TestUser_Engine_ListLiteUsers(t *testing.T) { _userOne.SetName("foo") _userOne.SetToken("bar") _userOne.SetFavorites([]string{}) + _userOne.SetDashboards([]string{}) _userTwo := testAPIUser() _userTwo.SetID(2) _userTwo.SetName("baz") _userTwo.SetToken("bar") _userTwo.SetFavorites([]string{}) + _userTwo.SetDashboards([]string{}) _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() @@ -61,10 +63,12 @@ func TestUser_Engine_ListLiteUsers(t *testing.T) { _userOne.RefreshToken = new(string) _userOne.Token = new(string) _userOne.Favorites = new([]string) + _userOne.Dashboards = new([]string) _userTwo.RefreshToken = new(string) _userTwo.Token = new(string) _userTwo.Favorites = new([]string) + _userTwo.Dashboards = new([]string) // setup tests tests := []struct { diff --git a/database/user/list_test.go b/database/user/list_test.go index 556e02e57..01a847ea8 100644 --- a/database/user/list_test.go +++ b/database/user/list_test.go @@ -19,12 +19,14 @@ func TestUser_Engine_ListUsers(t *testing.T) { _userOne.SetName("foo") _userOne.SetToken("bar") _userOne.SetFavorites([]string{}) + _userOne.SetDashboards([]string{}) _userTwo := testAPIUser() _userTwo.SetID(2) _userTwo.SetName("baz") _userTwo.SetToken("bar") _userTwo.SetFavorites([]string{}) + _userTwo.SetDashboards([]string{}) _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() @@ -37,9 +39,9 @@ func TestUser_Engine_ListUsers(t *testing.T) { // create expected result in mock _rows = sqlmock.NewRows( - []string{"id", "name", "refresh_token", "token", "hash", "favorites", "active", "admin"}). - AddRow(1, "foo", "", "bar", "baz", "{}", false, false). - AddRow(2, "baz", "", "bar", "foo", "{}", false, false) + []string{"id", "name", "refresh_token", "token", "hash", "favorites", "active", "admin", "dashboards"}). + AddRow(1, "foo", "", "bar", "baz", "{}", false, false, "{}"). + AddRow(2, "baz", "", "bar", "foo", "{}", false, false, "{}") // ensure the mock expects the query _mock.ExpectQuery(`SELECT * FROM "users"`).WillReturnRows(_rows) diff --git a/database/user/table.go b/database/user/table.go index 3ba809872..c5e4d1712 100644 --- a/database/user/table.go +++ b/database/user/table.go @@ -21,6 +21,7 @@ users ( favorites VARCHAR(5000), active BOOLEAN, admin BOOLEAN, + dashboards VARCHAR(5000), UNIQUE(name) ); ` @@ -37,6 +38,7 @@ users ( favorites TEXT, active BOOLEAN, admin BOOLEAN, + dashboards TEXT, UNIQUE(name) ); ` diff --git a/database/user/update_test.go b/database/user/update_test.go index d84022b87..5fbb7ed8b 100644 --- a/database/user/update_test.go +++ b/database/user/update_test.go @@ -22,9 +22,9 @@ func TestUser_Engine_UpdateUser(t *testing.T) { // ensure the mock expects the query _mock.ExpectExec(`UPDATE "users" -SET "name"=$1,"refresh_token"=$2,"token"=$3,"favorites"=$4,"active"=$5,"admin"=$6 -WHERE "id" = $7`). - WithArgs("foo", AnyArgument{}, AnyArgument{}, nil, false, false, 1). +SET "name"=$1,"refresh_token"=$2,"token"=$3,"favorites"=$4,"active"=$5,"admin"=$6,"dashboards"=$7 +WHERE "id" = $8`). + WithArgs("foo", AnyArgument{}, AnyArgument{}, nil, false, false, nil, 1). WillReturnResult(sqlmock.NewResult(1, 1)) _sqlite := testSqlite(t) diff --git a/database/user/user.go b/database/user/user.go index d961f71b0..a29295cbb 100644 --- a/database/user/user.go +++ b/database/user/user.go @@ -43,6 +43,10 @@ var ( // ErrExceededFavoritesLimit defines the error type when a // User type has Favorites field provided that exceeds the database limit. ErrExceededFavoritesLimit = errors.New("exceeded favorites limit") + + // ErrExceededDashboardsLimit defines the error type when a + // User type has Dashboards field provided that exceeds the database limit. + ErrExceededDashboardsLimit = errors.New("exceeded dashboards limit") ) type ( @@ -81,6 +85,7 @@ type ( Favorites pq.StringArray `sql:"favorites" gorm:"type:varchar(5000)"` Active sql.NullBool `sql:"active"` Admin sql.NullBool `sql:"admin"` + Dashboards pq.StringArray `sql:"dashboards" gorm:"type:varchar(5000)"` } ) @@ -249,6 +254,7 @@ func (u *User) ToAPI() *api.User { user.SetActive(u.Active.Bool) user.SetAdmin(u.Admin.Bool) user.SetFavorites(u.Favorites) + user.SetDashboards(u.Dashboards) return user } @@ -271,19 +277,32 @@ func (u *User) Validate() error { return ErrInvalidUserName } - // calculate total size of favorites - total := 0 + // calculate totalFavorites size of favorites + totalFavorites := 0 for _, f := range u.Favorites { - total += len(f) + totalFavorites += len(f) } // verify the Favorites field is within the database constraints // len is to factor in number of comma separators included in the database field, // removing 1 due to the last item not having an appended comma - if (total + len(u.Favorites) - 1) > constants.FavoritesMaxSize { + if (totalFavorites + len(u.Favorites) - 1) > constants.FavoritesMaxSize { return ErrExceededFavoritesLimit } + // calculate totalDashboards size of dashboards + totalDashboards := 0 + for _, d := range u.Dashboards { + totalDashboards += len(d) + } + + // verify the Dashboards field is within the database constraints + // len is to factor in number of comma separators included in the database field, + // removing 1 due to the last item not having an appended comma + if (totalDashboards + len(u.Dashboards) - 1) > constants.FavoritesMaxSize { + return ErrExceededDashboardsLimit + } + // ensure that all User string fields // that can be returned as JSON are sanitized // to avoid unsafe HTML content @@ -309,6 +328,7 @@ func FromAPI(u *api.User) *User { Active: sql.NullBool{Bool: u.GetActive(), Valid: true}, Admin: sql.NullBool{Bool: u.GetAdmin(), Valid: true}, Favorites: pq.StringArray(u.GetFavorites()), + Dashboards: pq.StringArray(u.GetDashboards()), } return user.Nullify() diff --git a/database/user/user_test.go b/database/user/user_test.go index 08db61eef..287ee9508 100644 --- a/database/user/user_test.go +++ b/database/user/user_test.go @@ -183,6 +183,7 @@ func testAPIUser() *api.User { Favorites: new([]string), Active: new(bool), Admin: new(bool), + Dashboards: new([]string), } } @@ -342,6 +343,7 @@ func TestUser_ToAPI(t *testing.T) { want.SetFavorites([]string{"github/octocat"}) want.SetActive(true) want.SetAdmin(false) + want.SetDashboards([]string{"45bcf19b-c151-4e2d-b8c6-80a62ba2eae7"}) // run test got := testUser().ToAPI() @@ -390,7 +392,16 @@ func TestUser_Validate(t *testing.T) { ID: sql.NullInt64{Int64: 1, Valid: true}, Name: sql.NullString{String: "octocat", Valid: true}, Token: sql.NullString{String: "superSecretToken", Valid: true}, - Favorites: exceededFavorites(), + Favorites: exceededField(), + }, + }, + { // invalid dashboards set for user + failure: true, + user: &User{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + Name: sql.NullString{String: "octocat", Valid: true}, + Token: sql.NullString{String: "superSecretToken", Valid: true}, + Dashboards: exceededField(), }, }, } @@ -424,6 +435,7 @@ func TestFromAPI(t *testing.T) { u.SetFavorites([]string{"github/octocat"}) u.SetActive(true) u.SetAdmin(false) + u.SetDashboards([]string{"45bcf19b-c151-4e2d-b8c6-80a62ba2eae7"}) want := testUser() @@ -446,22 +458,23 @@ func testUser() *User { Favorites: []string{"github/octocat"}, Active: sql.NullBool{Bool: true, Valid: true}, Admin: sql.NullBool{Bool: false, Valid: true}, + Dashboards: []string{"45bcf19b-c151-4e2d-b8c6-80a62ba2eae7"}, } } -// exceededFavorites returns a list of valid favorites that exceed the maximum size. -func exceededFavorites() []string { +// exceededField returns a list of strings that exceed the maximum size of a field. +func exceededField() []string { // initialize empty favorites - favorites := []string{} + values := []string{} - // add enough favorites to exceed the character limit + // add enough strings to exceed the character limit for i := 0; i < 500; i++ { - // construct favorite + // construct field // use i to adhere to unique favorites - favorite := "github/octocat-" + strconv.Itoa(i) + field := "github/octocat-" + strconv.Itoa(i) - favorites = append(favorites, favorite) + values = append(values, field) } - return favorites + return values } diff --git a/mock/server/user.go b/mock/server/user.go index e2fb9511c..54fbedd64 100644 --- a/mock/server/user.go +++ b/mock/server/user.go @@ -23,7 +23,8 @@ const ( "token": null, "favorites": ["github/octocat"], "active": true, - "admin": false + "admin": false, + "dashboards": [] }` // UsersResp represents a JSON return for one to many users. @@ -34,7 +35,8 @@ const ( "token": null, "favorites": ["github/octocat"], "active": true, - "admin": false + "admin": false, + "dashboards": [] }, { "id": 1, @@ -42,7 +44,8 @@ const ( "token": null, "favorites": ["github/octocat"], "active": true, - "admin": false + "admin": false, + "dashboards": [] } ]` ) diff --git a/router/dashboard.go b/router/dashboard.go new file mode 100644 index 000000000..57ffafddb --- /dev/null +++ b/router/dashboard.go @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: Apache-2.0 + +package router + +import ( + "github.com/gin-gonic/gin" + + "github.com/go-vela/server/api/dashboard" + dMiddleware "github.com/go-vela/server/router/middleware/dashboard" +) + +// DashboardHandlers is a function that extends the provided base router group +// with the API handlers for resource search functionality. +// +// GET /api/v1/search/builds/:id . +func DashboardHandlers(base *gin.RouterGroup) { + // Search endpoints + dashboards := base.Group("/dashboards") + { + dashboards.POST("", dashboard.CreateDashboard) + + d := dashboards.Group("/:dashboard", dMiddleware.Establish()) + { + d.GET("", dashboard.GetDashboard) + d.PUT("", dashboard.UpdateDashboard) + d.DELETE("", dashboard.DeleteDashboard) + } + } // end of search endpoints +} diff --git a/router/middleware/dashboard/context.go b/router/middleware/dashboard/context.go new file mode 100644 index 000000000..f0f973015 --- /dev/null +++ b/router/middleware/dashboard/context.go @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: Apache-2.0 + +package dashboard + +import ( + "context" + + api "github.com/go-vela/server/api/types" +) + +const key = "dashboard" + +// Setter defines a context that enables setting values. +type Setter interface { + Set(string, interface{}) +} + +// FromContext returns the Dashboard associated with this context. +func FromContext(c context.Context) *api.Dashboard { + value := c.Value(key) + if value == nil { + return nil + } + + b, ok := value.(*api.Dashboard) + if !ok { + return nil + } + + return b +} + +// ToContext adds the Dashboard to this context if it supports +// the Setter interface. +func ToContext(c Setter, b *api.Dashboard) { + c.Set(key, b) +} diff --git a/router/middleware/dashboard/context_test.go b/router/middleware/dashboard/context_test.go new file mode 100644 index 000000000..abda97051 --- /dev/null +++ b/router/middleware/dashboard/context_test.go @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: Apache-2.0 + +package dashboard + +import ( + "testing" + + "github.com/gin-gonic/gin" + + api "github.com/go-vela/server/api/types" +) + +func TestDashboard_FromContext(t *testing.T) { + // setup types + uuid := "c8da1302-07d6-11ea-882f-4893bca275b8" + want := &api.Dashboard{ID: &uuid} + + // setup context + gin.SetMode(gin.TestMode) + context, _ := gin.CreateTestContext(nil) + context.Set(key, want) + + // run test + got := FromContext(context) + + if got != want { + t.Errorf("FromContext is %v, want %v", got, want) + } +} + +func TestDashboard_FromContext_Bad(t *testing.T) { + // setup context + gin.SetMode(gin.TestMode) + context, _ := gin.CreateTestContext(nil) + context.Set(key, nil) + + // run test + got := FromContext(context) + + if got != nil { + t.Errorf("FromContext is %v, want nil", got) + } +} + +func TestDashboard_FromContext_WrongType(t *testing.T) { + // setup context + gin.SetMode(gin.TestMode) + context, _ := gin.CreateTestContext(nil) + context.Set(key, 1) + + // run test + got := FromContext(context) + + if got != nil { + t.Errorf("FromContext is %v, want nil", got) + } +} + +func TestDashboard_FromContext_Empty(t *testing.T) { + // setup context + gin.SetMode(gin.TestMode) + context, _ := gin.CreateTestContext(nil) + + // run test + got := FromContext(context) + + if got != nil { + t.Errorf("FromContext is %v, want nil", got) + } +} + +func TestDashboard_ToContext(t *testing.T) { + // setup types + uuid := "c8da1302-07d6-11ea-882f-4893bca275b8" + want := &api.Dashboard{ID: &uuid} + + // setup context + gin.SetMode(gin.TestMode) + context, _ := gin.CreateTestContext(nil) + ToContext(context, want) + + // run test + got := context.Value(key) + + if got != want { + t.Errorf("ToContext is %v, want %v", got, want) + } +} diff --git a/router/middleware/dashboard/dashboard.go b/router/middleware/dashboard/dashboard.go new file mode 100644 index 000000000..b62db4b90 --- /dev/null +++ b/router/middleware/dashboard/dashboard.go @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: Apache-2.0 + +package dashboard + +import ( + "fmt" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database" + "github.com/go-vela/server/router/middleware/user" + "github.com/go-vela/server/util" +) + +// Retrieve gets the build in the given context. +func Retrieve(c *gin.Context) *api.Dashboard { + return FromContext(c) +} + +// Establish sets the build in the given context. +func Establish() gin.HandlerFunc { + return func(c *gin.Context) { + u := user.Retrieve(c) + ctx := c.Request.Context() + + id := util.PathParameter(c, "dashboard") + if len(id) == 0 { + userBoards := u.GetDashboards() + if len(userBoards) == 0 { + retErr := fmt.Errorf("no available dashboards for user %s", u.GetName()) + util.HandleError(c, http.StatusBadRequest, retErr) + + return + } + + id = userBoards[0] + } + + // update engine logger with API metadata + // + // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields + logrus.WithFields(logrus.Fields{ + "dashboard": id, + "user": u.GetName(), + }).Debugf("reading dashboard %s", id) + + d, err := database.FromContext(c).GetDashboard(ctx, id) + if err != nil { + retErr := fmt.Errorf("unable to read dashboard %s: %w", id, err) + util.HandleError(c, http.StatusNotFound, retErr) + + return + } + + ToContext(c, d) + c.Next() + } +} diff --git a/router/middleware/dashboard/dashboard_test.go b/router/middleware/dashboard/dashboard_test.go new file mode 100644 index 000000000..35509c19e --- /dev/null +++ b/router/middleware/dashboard/dashboard_test.go @@ -0,0 +1,162 @@ +// SPDX-License-Identifier: Apache-2.0 + +package dashboard + +import ( + "context" + "net/http" + "net/http/httptest" + "reflect" + "testing" + + "github.com/gin-gonic/gin" + + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database" +) + +func TestDashboard_Retrieve(t *testing.T) { + // setup types + want := new(api.Dashboard) + want.SetID("c8da1302-07d6-11ea-882f-4893bca275b8") + + // setup context + gin.SetMode(gin.TestMode) + context, _ := gin.CreateTestContext(nil) + ToContext(context, want) + + // run test + got := Retrieve(context) + + if got != want { + t.Errorf("Retrieve is %v, want %v", got, want) + } +} + +func TestDashboard_Establish(t *testing.T) { + // setup types + want := new(api.Dashboard) + want.SetID("c8da1302-07d6-11ea-882f-4893bca275b8") + want.SetName("vela") + want.SetCreatedAt(1) + want.SetCreatedBy("octocat") + want.SetUpdatedAt(1) + want.SetUpdatedBy("octokitty") + + wantRepo := new(api.DashboardRepo) + wantRepo.SetID(1) + wantRepo.SetName("go-vela/server") + wantRepo.SetBranches([]string{"main"}) + wantRepo.SetEvents([]string{"push"}) + + want.SetRepos([]*api.DashboardRepo{wantRepo}) + + wantAdmin := new(api.User) + wantAdmin.SetID(1) + wantAdmin.SetName("octocat") + wantAdmin.SetActive(true) + + want.SetAdmins([]*api.User{wantAdmin}) + + got := new(api.Dashboard) + + // setup database + db, err := database.NewTest() + if err != nil { + t.Errorf("unable to create test database engine: %v", err) + } + + defer func() { + _ = db.DeleteDashboard(context.TODO(), want) + db.Close() + }() + + _, _ = db.CreateDashboard(context.TODO(), want) + + // setup context + gin.SetMode(gin.TestMode) + + resp := httptest.NewRecorder() + context, engine := gin.CreateTestContext(resp) + context.Request, _ = http.NewRequest(http.MethodGet, "/c8da1302-07d6-11ea-882f-4893bca275b8", nil) + + // setup mock server + engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) + engine.Use(Establish()) + engine.GET("/:dashboard", func(c *gin.Context) { + got = Retrieve(c) + + c.Status(http.StatusOK) + }) + + // run test + engine.ServeHTTP(resp, context.Request) + + if resp.Code != http.StatusOK { + t.Errorf("Establish returned %v, want %v", resp.Code, http.StatusOK) + } + + if !reflect.DeepEqual(got, want) { + t.Errorf("Establish is %v, want %v", got, want) + } +} + +func TestDashboard_Establish_NoDashboardParameter(t *testing.T) { + // setup database + db, err := database.NewTest() + if err != nil { + t.Errorf("unable to create test database engine: %v", err) + } + defer db.Close() + + // setup context + gin.SetMode(gin.TestMode) + + resp := httptest.NewRecorder() + context, engine := gin.CreateTestContext(resp) + context.Request, _ = http.NewRequest(http.MethodGet, "//test", nil) + + // setup mock server + engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) + engine.Use(Establish()) + engine.GET("/:dashboard/test", func(c *gin.Context) { + c.Status(http.StatusOK) + }) + + // run test + engine.ServeHTTP(context.Writer, context.Request) + + if resp.Code != http.StatusBadRequest { + t.Errorf("Establish returned %v, want %v", resp.Code, http.StatusBadRequest) + } +} + +func TestDashboard_Establish_NoDashboard(t *testing.T) { + // setup database + db, err := database.NewTest() + if err != nil { + t.Errorf("unable to create test database engine: %v", err) + } + defer db.Close() + + // setup context + gin.SetMode(gin.TestMode) + + resp := httptest.NewRecorder() + context, engine := gin.CreateTestContext(resp) + context.Request, _ = http.NewRequest(http.MethodGet, "/c8da1302-07d6-11ea-882f-4893bca275b8", nil) + + // setup mock server + engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) + engine.Use(Establish()) + engine.GET("/:dashboard", func(c *gin.Context) { + c.Status(http.StatusOK) + }) + + // run test + engine.ServeHTTP(context.Writer, context.Request) + + if resp.Code != http.StatusNotFound { + t.Errorf("Establish returned %v, want %v", resp.Code, http.StatusNotFound) + } +} diff --git a/router/middleware/user/user_test.go b/router/middleware/user/user_test.go index 04e4499b2..a6809c334 100644 --- a/router/middleware/user/user_test.go +++ b/router/middleware/user/user_test.go @@ -61,6 +61,7 @@ func TestUser_Establish(t *testing.T) { want.SetActive(false) want.SetAdmin(false) want.SetFavorites([]string{}) + want.SetDashboards([]string{}) got := new(api.User) diff --git a/router/router.go b/router/router.go index 8f0559ba7..8095da38f 100644 --- a/router/router.go +++ b/router/router.go @@ -125,7 +125,7 @@ func Load(options ...gin.HandlerFunc) *gin.Engine { ScmHandlers(baseAPI) // Search endpoints - SearchHandlers(baseAPI) + DashboardHandlers(baseAPI) // Secret endpoints SecretHandlers(baseAPI) diff --git a/router/user.go b/router/user.go index 64f41b6a5..149fe3146 100644 --- a/router/user.go +++ b/router/user.go @@ -5,6 +5,7 @@ package router import ( "github.com/gin-gonic/gin" + "github.com/go-vela/server/api/dashboard" "github.com/go-vela/server/api/user" "github.com/go-vela/server/router/middleware/perm" ) @@ -21,7 +22,8 @@ import ( // PUT /api/v1/user // GET /api/v1/user/source/repos // POST /api/v1/user/token -// DELETE /api/v1/user/token . +// DELETE /api/v1/user/token +// GET /api/v1/user/dashboards . func UserHandlers(base *gin.RouterGroup) { // Users endpoints _users := base.Group("/users") @@ -41,5 +43,6 @@ func UserHandlers(base *gin.RouterGroup) { _user.GET("/source/repos", user.GetSourceRepos) _user.POST("/token", user.CreateToken) _user.DELETE("/token", user.DeleteToken) + _user.GET("/dashboards", dashboard.ListUserDashboards) } // end of user endpoints } From 0c1751d7640b4ea5622130f4e0e237b342c5d52b Mon Sep 17 00:00:00 2001 From: dave vader <48764154+plyr4@users.noreply.github.com> Date: Mon, 22 Apr 2024 11:24:23 -0500 Subject: [PATCH 36/71] fix: remove sanitize but still crop fields (#1113) --- api/dashboard/create.go | 4 ++-- api/types/user.go | 17 ++++++----------- api/types/user_test.go | 18 +++++++----------- database/integration_test.go | 25 ++++++++++++++----------- database/repo/get_org_test.go | 1 + database/repo/get_test.go | 1 + database/repo/list_org_test.go | 1 + database/repo/list_test.go | 1 + database/repo/list_user_test.go | 1 + database/repo/repo.go | 2 +- database/repo/repo_test.go | 6 ++---- router/router.go | 2 +- 12 files changed, 38 insertions(+), 41 deletions(-) diff --git a/api/dashboard/create.go b/api/dashboard/create.go index c0e8f0029..f14a06fe1 100644 --- a/api/dashboard/create.go +++ b/api/dashboard/create.go @@ -143,7 +143,7 @@ func CreateDashboard(c *gin.Context) { // when a user is inactive or not found in the database. It returns a sanitized slice of admins. func createAdminSet(c context.Context, caller *types.User, users []*types.User) ([]*types.User, error) { // add user creating the dashboard to admin list - admins := []*types.User{caller.Sanitize()} + admins := []*types.User{caller.Crop()} dupMap := make(map[string]bool) @@ -158,7 +158,7 @@ func createAdminSet(c context.Context, caller *types.User, users []*types.User) return nil, fmt.Errorf("unable to create dashboard: %s is not an active user", u.GetName()) } - admins = append(admins, dbUser.Sanitize()) + admins = append(admins, dbUser.Crop()) dupMap[dbUser.GetName()] = true } diff --git a/api/types/user.go b/api/types/user.go index 2bad2f3ea..a7d7691c0 100644 --- a/api/types/user.go +++ b/api/types/user.go @@ -4,8 +4,6 @@ package types import ( "fmt" - - "github.com/go-vela/types/constants" ) // User is the API representation of a user. @@ -22,18 +20,15 @@ type User struct { Dashboards *[]string `json:"dashboards,omitempty"` } -// Sanitize creates a duplicate of the User without the token values. -func (u *User) Sanitize() *User { - // create a variable since constants can not be addressable - // - // https://golang.org/ref/spec#Address_operators - value := constants.SecretMask - +// Crop creates a duplicate of the User with certain fields cropped. +// +// Generally used for cropping large fields that aren't useful for all API calls like favorites and dashboards. +func (u *User) Crop() *User { return &User{ ID: u.ID, Name: u.Name, - RefreshToken: &value, - Token: &value, + RefreshToken: u.RefreshToken, + Token: u.Token, Active: u.Active, } } diff --git a/api/types/user_test.go b/api/types/user_test.go index 1da7acb2f..91134e3e0 100644 --- a/api/types/user_test.go +++ b/api/types/user_test.go @@ -6,26 +6,22 @@ import ( "fmt" "reflect" "testing" - - "github.com/go-vela/types/constants" ) -func TestTypes_User_Sanitize(t *testing.T) { +func TestTypes_User_Crop(t *testing.T) { // setup types u := testUser() - want := new(User) - want.SetID(1) - want.SetName("octocat") - want.SetActive(true) - want.SetToken(constants.SecretMask) - want.SetRefreshToken(constants.SecretMask) + want := testUser() + want.Favorites = nil + want.Dashboards = nil + want.Admin = nil // run test - got := u.Sanitize() + got := u.Crop() if !reflect.DeepEqual(got, want) { - t.Errorf("Sanitize is %v, want %v", got, want) + t.Errorf("Crop is %v, want %v", got, want) } } diff --git a/database/integration_test.go b/database/integration_test.go index 2444795e1..aa00b260c 100644 --- a/database/integration_test.go +++ b/database/integration_test.go @@ -438,18 +438,14 @@ func testDashboards(t *testing.T, db Interface, resources *Resources) { for _, dashboard := range resources.Dashboards { got, err := db.GetDashboard(ctx, dashboard.GetID()) if err != nil { - t.Errorf("unable to get schedule %s: %v", dashboard.GetID(), err) + t.Errorf("unable to get dashboard %s: %v", dashboard.GetID(), err) } // JSON tags of `-` prevent unmarshaling of tokens, but they are sanitized anyway cmpAdmins := []*api.User{} for _, admin := range got.GetAdmins() { - admin.SetToken(constants.SecretMask) - admin.SetRefreshToken(constants.SecretMask) - - cmpAdmins = append(cmpAdmins, admin) + cmpAdmins = append(cmpAdmins, admin.Crop()) } - got.SetAdmins(cmpAdmins) if !cmp.Equal(got, dashboard, CmpOptApproxUpdatedAt()) { @@ -476,7 +472,7 @@ func testDashboards(t *testing.T, db Interface, resources *Resources) { for _, dashboard := range resources.Dashboards { err := db.DeleteDashboard(ctx, dashboard) if err != nil { - t.Errorf("unable to delete schedule %s: %v", dashboard.GetID(), err) + t.Errorf("unable to delete dashboard %s: %v", dashboard.GetID(), err) } } methods["DeleteDashboard"] = true @@ -2131,6 +2127,13 @@ func newResources() *Resources { userTwo.SetAdmin(false) userTwo.SetDashboards([]string{"45bcf19b-c151-4e2d-b8c6-80a62ba2eae7", "ba657dab-bc6e-421f-9188-86272bd0069a"}) + // crop and set "-" JSON tag fields to nil for dashboard admins + dashboardAdmins := []*api.User{userOne.Crop(), userTwo.Crop()} + for _, admin := range dashboardAdmins { + admin.Token = nil + admin.RefreshToken = nil + } + buildOne := new(library.Build) buildOne.SetID(1) buildOne.SetRepoID(1) @@ -2216,7 +2219,7 @@ func newResources() *Resources { dashboardOne.SetCreatedBy("octocat") dashboardOne.SetUpdatedAt(2) dashboardOne.SetUpdatedBy("octokitty") - dashboardOne.SetAdmins([]*api.User{userOne.Sanitize(), userTwo.Sanitize()}) + dashboardOne.SetAdmins(dashboardAdmins) dashboardOne.SetRepos([]*api.DashboardRepo{dashRepo}) dashboardTwo := new(api.Dashboard) @@ -2226,7 +2229,7 @@ func newResources() *Resources { dashboardTwo.SetCreatedBy("octocat") dashboardTwo.SetUpdatedAt(2) dashboardTwo.SetUpdatedBy("octokitty") - dashboardTwo.SetAdmins([]*api.User{userOne.Sanitize(), userTwo.Sanitize()}) + dashboardTwo.SetAdmins(dashboardAdmins) dashboardTwo.SetRepos([]*api.DashboardRepo{dashRepo}) executableOne := new(library.BuildExecutable) @@ -2386,7 +2389,7 @@ func newResources() *Resources { repoOne := new(api.Repo) repoOne.SetID(1) - repoOne.SetOwner(userOne.Sanitize()) + repoOne.SetOwner(userOne.Crop()) repoOne.SetHash("MzM4N2MzMDAtNmY4Mi00OTA5LWFhZDAtNWIzMTlkNTJkODMy") repoOne.SetOrg("github") repoOne.SetName("octocat") @@ -2409,7 +2412,7 @@ func newResources() *Resources { repoTwo := new(api.Repo) repoTwo.SetID(2) - repoTwo.SetOwner(userOne.Sanitize()) + repoTwo.SetOwner(userOne.Crop()) repoTwo.SetHash("MzM4N2MzMDAtNmY4Mi00OTA5LWFhZDAtNWIzMTlkNTJkODMy") repoTwo.SetOrg("github") repoTwo.SetName("octokitty") diff --git a/database/repo/get_org_test.go b/database/repo/get_org_test.go index dc168088c..149b402a9 100644 --- a/database/repo/get_org_test.go +++ b/database/repo/get_org_test.go @@ -30,6 +30,7 @@ func TestRepo_Engine_GetRepoForOrg(t *testing.T) { _owner := testOwner() _owner.SetID(1) _owner.SetName("foo") + _owner.SetToken("bar") _repo.SetOwner(_owner) diff --git a/database/repo/get_test.go b/database/repo/get_test.go index 9b3ded139..651fc8f39 100644 --- a/database/repo/get_test.go +++ b/database/repo/get_test.go @@ -30,6 +30,7 @@ func TestRepo_Engine_GetRepo(t *testing.T) { _owner := testOwner() _owner.SetID(1) _owner.SetName("foo") + _owner.SetToken("bar") _repo.SetOwner(_owner) diff --git a/database/repo/list_org_test.go b/database/repo/list_org_test.go index 54af05969..7f13b540a 100644 --- a/database/repo/list_org_test.go +++ b/database/repo/list_org_test.go @@ -56,6 +56,7 @@ func TestRepo_Engine_ListReposForOrg(t *testing.T) { _owner := testOwner() _owner.SetID(1) _owner.SetName("foo") + _owner.SetToken("bar") _repoOne.SetOwner(_owner) _repoTwo.SetOwner(_owner) diff --git a/database/repo/list_test.go b/database/repo/list_test.go index 5adbc0fa6..01df9981e 100644 --- a/database/repo/list_test.go +++ b/database/repo/list_test.go @@ -41,6 +41,7 @@ func TestRepo_Engine_ListRepos(t *testing.T) { _owner := testOwner() _owner.SetID(1) _owner.SetName("foo") + _owner.SetToken("bar") _repoOne.SetOwner(_owner) _repoTwo.SetOwner(_owner) diff --git a/database/repo/list_user_test.go b/database/repo/list_user_test.go index 1bdae5d36..b89fce07e 100644 --- a/database/repo/list_user_test.go +++ b/database/repo/list_user_test.go @@ -58,6 +58,7 @@ func TestRepo_Engine_ListReposForUser(t *testing.T) { _owner := testOwner() _owner.SetID(1) _owner.SetName("foo") + _owner.SetToken("bar") _repoOne.SetOwner(_owner) _repoTwo.SetOwner(_owner) diff --git a/database/repo/repo.go b/database/repo/repo.go index 33e1cbf36..fc1e7808e 100644 --- a/database/repo/repo.go +++ b/database/repo/repo.go @@ -293,7 +293,7 @@ func (r *Repo) ToAPI() *api.Repo { repo := new(api.Repo) repo.SetID(r.ID.Int64) - repo.SetOwner(r.Owner.ToAPI().Sanitize()) + repo.SetOwner(r.Owner.ToAPI().Crop()) repo.SetHash(r.Hash.String) repo.SetOrg(r.Org.String) repo.SetName(r.Name.String) diff --git a/database/repo/repo_test.go b/database/repo/repo_test.go index 4a179c6d8..8d50ade32 100644 --- a/database/repo/repo_test.go +++ b/database/repo/repo_test.go @@ -232,13 +232,11 @@ func testEvents() *api.Events { // testOwner is a helper function that returns a sanitized user. func testOwner() *api.User { - mask := constants.SecretMask - return &api.User{ ID: new(int64), Name: new(string), - RefreshToken: &mask, - Token: &mask, + RefreshToken: new(string), + Token: new(string), Active: new(bool), } } diff --git a/router/router.go b/router/router.go index 8095da38f..49d8f6012 100644 --- a/router/router.go +++ b/router/router.go @@ -124,7 +124,7 @@ func Load(options ...gin.HandlerFunc) *gin.Engine { // Source code management endpoints ScmHandlers(baseAPI) - // Search endpoints + // Dashboard endpoints DashboardHandlers(baseAPI) // Secret endpoints From 71bfd94c063b02823d773359310422cf4364a427 Mon Sep 17 00:00:00 2001 From: David May <49894298+wass3rw3rk@users.noreply.github.com> Date: Tue, 23 Apr 2024 10:48:58 -0500 Subject: [PATCH 37/71] enhance(log/ecs): log user to user designated field (#1114) --- router/middleware/logger.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/router/middleware/logger.go b/router/middleware/logger.go index f7205ebe2..0f1b14c4c 100644 --- a/router/middleware/logger.go +++ b/router/middleware/logger.go @@ -145,6 +145,7 @@ func (f *ECSFormatter) Format(e *logrus.Entry) ([]byte, error) { for k, v := range e.Data { switch k { + // map fields attached to requests case "ip": data["client.ip"] = v case "latency": @@ -159,6 +160,11 @@ func (f *ECSFormatter) Format(e *logrus.Entry) ([]byte, error) { data["user_agent.name"] = v case "version": data["user_agent.version"] = v + + // map other fields + case "user": + data["user.name"] = v + default: extraData[k] = v } From b55aa2bb36845e95a4766a1f4d7e6abcd9d4a50c Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Wed, 24 Apr 2024 10:44:36 -0400 Subject: [PATCH 38/71] refactor(build)!: move build from types and nest the object (#1111) * init and broken commit * working for now * integration testing fixes * more cleanup and remove repo usage where not needed * address feedback * remove redundant return on a couple extra funcs --------- Co-authored-by: David May <49894298+wass3rw3rk@users.noreply.github.com> --- api/admin/build.go | 4 +- api/build/approve.go | 2 +- api/build/auto_cancel.go | 13 +- api/build/auto_cancel_test.go | 52 +- api/build/cancel.go | 3 +- api/build/clean.go | 3 +- api/build/compile_publish.go | 13 +- api/build/create.go | 7 +- api/build/enqueue.go | 12 +- api/build/executable.go | 3 +- api/build/get_id.go | 24 +- api/build/list_org.go | 4 +- api/build/list_repo.go | 4 +- api/build/plan.go | 5 +- api/build/restart.go | 1 - api/build/update.go | 5 +- api/service/plan.go | 7 +- api/step/plan.go | 14 +- api/types/build.go | 1218 +++++++++++++++++ api/types/build_test.go | 928 +++++++++++++ api/types/executor.go | 38 +- api/types/executor_test.go | 58 - api/types/queue_build.go | 134 ++ api/types/queue_build_test.go | 126 ++ api/types/repo_test.go | 6 +- api/types/worker.go | 32 +- api/types/worker_test.go | 6 +- api/webhook/post.go | 17 +- api/worker/get.go | 4 +- api/worker/list.go | 4 +- cmd/vela-server/schedule.go | 6 +- compiler/engine.go | 2 +- compiler/native/compile.go | 2 +- compiler/native/compile_test.go | 33 +- compiler/native/environment.go | 2 +- compiler/native/environment_test.go | 21 +- compiler/native/expand_test.go | 7 +- compiler/native/native.go | 5 +- compiler/native/native_test.go | 5 +- database/build/build.go | 2 + database/build/build_test.go | 145 +- database/build/clean.go | 8 +- database/build/clean_test.go | 37 +- database/build/count_deployment_test.go | 31 +- database/build/count_org_test.go | 48 +- database/build/count_repo_test.go | 31 +- database/build/count_status_test.go | 24 +- database/build/count_test.go | 24 +- database/build/create.go | 24 +- database/build/create_test.go | 20 +- database/build/delete.go | 11 +- database/build/delete_test.go | 20 +- database/build/get.go | 17 +- database/build/get_repo.go | 16 +- database/build/get_repo_test.go | 67 +- database/build/get_test.go | 58 +- database/build/interface.go | 24 +- database/build/last_repo.go | 16 +- database/build/last_repo_test.go | 61 +- database/build/list.go | 22 +- database/build/list_dashboard.go | 14 +- database/build/list_dashboard_test.go | 37 +- database/build/list_org.go | 22 +- database/build/list_org_test.go | 118 +- database/build/list_pending_running.go | 15 +- database/build/list_pending_running_repo.go | 21 +- .../build/list_pending_running_repo_test.go | 104 +- database/build/list_pending_running_test.go | 50 +- database/build/list_repo.go | 21 +- database/build/list_repo_test.go | 75 +- database/build/list_test.go | 66 +- database/build/opts.go | 10 + database/build/update.go | 24 +- database/build/update_test.go | 22 +- database/dashboard/create.go | 3 +- database/dashboard/create_test.go | 3 +- database/dashboard/dashboard.go | 160 --- database/dashboard/dashboard_test.go | 36 - database/dashboard/delete.go | 3 +- database/dashboard/delete_test.go | 5 +- database/dashboard/get.go | 7 +- database/dashboard/get_test.go | 3 +- database/dashboard/update.go | 3 +- database/dashboard/update_test.go | 3 +- database/deployment/count_repo_test.go | 7 +- database/deployment/count_test.go | 5 +- database/deployment/create_test.go | 3 +- database/deployment/delete_test.go | 3 +- database/deployment/deployment_test.go | 49 - database/deployment/get_repo_test.go | 5 +- database/deployment/get_test.go | 3 +- database/deployment/list_repo_test.go | 7 +- database/deployment/list_test.go | 5 +- database/deployment/update_test.go | 3 +- database/hook/count_repo_test.go | 8 +- database/hook/count_test.go | 6 +- database/hook/create_test.go | 4 +- database/hook/delete_test.go | 4 +- database/hook/get_repo_test.go | 5 +- database/hook/get_test.go | 3 +- database/hook/get_webhook_test.go | 3 +- database/hook/hook_test.go | 48 - database/hook/last_repo_test.go | 5 +- database/hook/list_repo_test.go | 7 +- database/hook/list_test.go | 5 +- database/hook/update_test.go | 4 +- database/integration_test.go | 175 ++- database/log/count_build.go | 4 +- database/log/count_build_test.go | 13 +- database/log/count_test.go | 6 +- database/log/create_test.go | 5 +- database/log/delete_test.go | 4 +- database/log/get_service_test.go | 5 +- database/log/get_step_test.go | 5 +- database/log/get_test.go | 3 +- database/log/interface.go | 5 +- database/log/list_build.go | 3 +- database/log/list_build_test.go | 12 +- database/log/list_test.go | 5 +- database/log/log_test.go | 97 -- database/log/update_test.go | 5 +- database/pipeline/count_repo_test.go | 5 +- database/pipeline/count_test.go | 6 +- database/pipeline/create_test.go | 4 +- database/pipeline/delete_test.go | 4 +- database/pipeline/get_repo_test.go | 3 +- database/pipeline/get_test.go | 3 +- database/pipeline/list_repo_test.go | 5 +- database/pipeline/list_test.go | 5 +- database/pipeline/pipeline_test.go | 24 - database/pipeline/update_test.go | 4 +- database/repo/count_org_test.go | 6 +- database/repo/count_test.go | 6 +- database/repo/count_user_test.go | 18 +- database/repo/create.go | 5 +- database/repo/create_test.go | 4 +- database/repo/delete.go | 3 +- database/repo/delete_test.go | 4 +- database/repo/get.go | 12 +- database/repo/get_org.go | 12 +- database/repo/get_org_test.go | 11 +- database/repo/get_test.go | 11 +- database/repo/list.go | 9 +- database/repo/list_org.go | 9 +- database/repo/list_org_test.go | 60 +- database/repo/list_test.go | 26 +- database/repo/list_user.go | 9 +- database/repo/list_user_test.go | 62 +- database/repo/repo.go | 328 ----- database/repo/repo_test.go | 437 +----- database/repo/update.go | 5 +- database/repo/update_test.go | 3 +- database/resource.go | 1 + database/service/clean_test.go | 10 +- database/service/count_build.go | 4 +- database/service/count_build_test.go | 10 +- database/service/count_test.go | 6 +- database/service/create_test.go | 4 +- database/service/delete_test.go | 4 +- database/service/get_build.go | 3 +- database/service/get_build_test.go | 7 +- database/service/get_test.go | 3 +- database/service/interface.go | 7 +- database/service/list_build.go | 3 +- database/service/list_build_test.go | 9 +- database/service/list_image_test.go | 6 +- database/service/list_status_test.go | 6 +- database/service/list_test.go | 5 +- database/service/service_test.go | 61 - database/service/update_test.go | 4 +- database/step/clean_test.go | 10 +- database/step/count_build.go | 4 +- database/step/count_build_test.go | 10 +- database/step/count_test.go | 6 +- database/step/create_test.go | 4 +- database/step/delete_test.go | 4 +- database/step/get_build.go | 3 +- database/step/get_build_test.go | 7 +- database/step/get_test.go | 4 +- database/step/interface.go | 7 +- database/step/list_build.go | 3 +- database/step/list_build_test.go | 9 +- database/step/list_image_test.go | 6 +- database/step/list_status_test.go | 6 +- database/step/list_test.go | 5 +- database/step/step_test.go | 63 - database/step/update_test.go | 4 +- database/testutils/api_resources.go | 253 ++++ database/types/build.go | 401 ++++++ database/types/build_test.go | 309 +++++ database/types/dashboard.go | 182 +++ database/types/dashboard_test.go | 231 ++++ database/types/queue_build.go | 43 + database/types/queue_build_test.go | 58 + database/types/repo.go | 342 +++++ database/types/repo_test.go | 388 ++++++ database/types/user.go | 261 ++++ database/types/user_test.go | 292 ++++ database/types/worker.go | 192 +++ database/types/worker_test.go | 212 +++ database/user/count_test.go | 6 +- database/user/create.go | 3 +- database/user/create_test.go | 4 +- database/user/delete.go | 3 +- database/user/delete_test.go | 4 +- database/user/get.go | 3 +- database/user/get_name.go | 3 +- database/user/get_name_test.go | 3 +- database/user/get_test.go | 3 +- database/user/list.go | 3 +- database/user/list_lite.go | 3 +- database/user/list_lite_test.go | 5 +- database/user/list_test.go | 5 +- database/user/update.go | 3 +- database/user/update_test.go | 4 +- database/user/user.go | 252 ---- database/user/user_test.go | 299 ---- database/worker/create.go | 3 +- database/worker/delete.go | 3 +- database/worker/get.go | 3 +- database/worker/get_hostname.go | 3 +- database/worker/list.go | 3 +- database/worker/update.go | 3 +- database/worker/worker.go | 188 +-- database/worker/worker_test.go | 15 +- internal/webhook.go | 2 +- internal/webhook_test.go | 6 +- mock/server/build.go | 60 +- mock/server/build_test.go | 4 +- queue/models/item.go | 9 +- queue/models/item_test.go | 101 +- queue/redis/length_test.go | 1 - queue/redis/pop_test.go | 1 - queue/redis/push_test.go | 1 - queue/redis/redis_test.go | 48 +- router/middleware/build/build.go | 4 +- router/middleware/build/build_test.go | 39 +- router/middleware/build/context.go | 8 +- router/middleware/build/context_test.go | 6 +- router/middleware/logger_test.go | 14 +- router/middleware/perm/perm_test.go | 29 +- router/middleware/pipeline/pipeline.go | 7 +- router/middleware/repo/repo_test.go | 7 +- router/middleware/service/service_test.go | 16 +- router/middleware/step/step_test.go | 16 +- router/middleware/worker/worker_test.go | 5 +- scm/github/repo.go | 4 +- scm/github/repo_test.go | 49 +- scm/github/webhook.go | 8 +- scm/github/webhook_test.go | 24 +- scm/service.go | 4 +- 251 files changed, 7410 insertions(+), 3365 deletions(-) create mode 100644 api/types/build.go create mode 100644 api/types/build_test.go create mode 100644 api/types/queue_build.go create mode 100644 api/types/queue_build_test.go create mode 100644 database/testutils/api_resources.go create mode 100644 database/types/build.go create mode 100644 database/types/build_test.go create mode 100644 database/types/dashboard.go create mode 100644 database/types/dashboard_test.go create mode 100644 database/types/queue_build.go create mode 100644 database/types/queue_build_test.go create mode 100644 database/types/repo.go create mode 100644 database/types/repo_test.go create mode 100644 database/types/user.go create mode 100644 database/types/user_test.go create mode 100644 database/types/worker.go create mode 100644 database/types/worker_test.go diff --git a/api/admin/build.go b/api/admin/build.go index d77d3f4b2..5e8d06694 100644 --- a/api/admin/build.go +++ b/api/admin/build.go @@ -12,9 +12,9 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/util" - "github.com/go-vela/types/library" ) // swagger:operation GET /api/v1/admin/builds/queue admin AllBuildsQueue @@ -107,7 +107,7 @@ func UpdateBuild(c *gin.Context) { ctx := c.Request.Context() // capture body from API request - input := new(library.Build) + input := new(types.Build) err := c.Bind(input) if err != nil { diff --git a/api/build/approve.go b/api/build/approve.go index c530a6e41..cd022bd79 100644 --- a/api/build/approve.go +++ b/api/build/approve.go @@ -122,7 +122,7 @@ func ApproveBuild(c *gin.Context) { ctx, queue.FromGinContext(c), database.FromContext(c), - models.ToItem(b, r), + models.ToItem(b), b.GetHost(), ) diff --git a/api/build/auto_cancel.go b/api/build/auto_cancel.go index 3e219d4b4..62b2922a1 100644 --- a/api/build/auto_cancel.go +++ b/api/build/auto_cancel.go @@ -17,13 +17,12 @@ import ( "github.com/go-vela/server/database" "github.com/go-vela/server/internal/token" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" "github.com/go-vela/types/pipeline" ) // AutoCancel is a helper function that checks to see if any pending or running // builds for the repo can be replaced by the current build. -func AutoCancel(c *gin.Context, b *library.Build, rB *library.Build, r *types.Repo, cancelOpts *pipeline.CancelOptions) (bool, error) { +func AutoCancel(c *gin.Context, b *types.Build, rB *types.Build, cancelOpts *pipeline.CancelOptions) (bool, error) { // if build is the current build, continue if rB.GetID() == b.GetID() { return false, nil @@ -52,7 +51,7 @@ func AutoCancel(c *gin.Context, b *library.Build, rB *library.Build, r *types.Re } case strings.EqualFold(status, constants.StatusRunning) && cancelOpts.Running: // call cancelRunning routine for builds already running on worker - err := cancelRunning(c, rB, r) + err := cancelRunning(c, rB) if err != nil { return false, err } @@ -75,7 +74,7 @@ func AutoCancel(c *gin.Context, b *library.Build, rB *library.Build, r *types.Re // cancelRunning is a helper function that determines the executor currently running a build and sends an API call // to that executor's worker to cancel the build. -func cancelRunning(c *gin.Context, b *library.Build, r *types.Repo) error { +func cancelRunning(c *gin.Context, b *types.Build) error { e := new([]types.Executor) // retrieve the worker w, err := database.FromContext(c).GetWorkerForHostname(c, b.GetHost()) @@ -133,7 +132,7 @@ func cancelRunning(c *gin.Context, b *library.Build, r *types.Repo) error { for _, executor := range *e { // check each executor on the worker running the build to see if it's running the build we want to cancel - if strings.EqualFold(executor.Repo.GetFullName(), r.GetFullName()) && *executor.GetBuild().Number == b.GetNumber() { + if executor.Build.GetID() == b.GetID() { // prepare the request to the worker client := http.DefaultClient client.Timeout = 30 * time.Second @@ -189,7 +188,7 @@ func cancelRunning(c *gin.Context, b *library.Build, r *types.Repo) error { // isCancelable is a helper function that determines whether a `target` build should be auto-canceled // given a current build that intends to supersede it. -func isCancelable(target *library.Build, current *library.Build) bool { +func isCancelable(target *types.Build, current *types.Build) bool { switch target.GetEvent() { case constants.EventPush: // target is cancelable if current build is also a push event and the branches are the same @@ -206,7 +205,7 @@ func isCancelable(target *library.Build, current *library.Build) bool { // ShouldAutoCancel is a helper function that determines whether or not a build should be eligible to // auto cancel currently running / pending builds. -func ShouldAutoCancel(opts *pipeline.CancelOptions, b *library.Build, defaultBranch string) bool { +func ShouldAutoCancel(opts *pipeline.CancelOptions, b *types.Build, defaultBranch string) bool { // if the build is pending approval, it should always be eligible to auto cancel if strings.EqualFold(b.GetStatus(), constants.StatusPendingApproval) { return true diff --git a/api/build/auto_cancel_test.go b/api/build/auto_cancel_test.go index 23879b923..15420b04d 100644 --- a/api/build/auto_cancel_test.go +++ b/api/build/auto_cancel_test.go @@ -5,8 +5,8 @@ package build import ( "testing" + "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" "github.com/go-vela/types/pipeline" ) @@ -25,17 +25,17 @@ func Test_isCancelable(t *testing.T) { tests := []struct { name string - target *library.Build - current *library.Build + target *types.Build + current *types.Build want bool }{ { name: "Wrong Event", - target: &library.Build{ + target: &types.Build{ Event: &tagEvent, Branch: &branchDev, }, - current: &library.Build{ + current: &types.Build{ Event: &pushEvent, Branch: &branchDev, }, @@ -43,11 +43,11 @@ func Test_isCancelable(t *testing.T) { }, { name: "Cancelable Push", - target: &library.Build{ + target: &types.Build{ Event: &pushEvent, Branch: &branchDev, }, - current: &library.Build{ + current: &types.Build{ Event: &pushEvent, Branch: &branchDev, }, @@ -55,11 +55,11 @@ func Test_isCancelable(t *testing.T) { }, { name: "Push Branch Mismatch", - target: &library.Build{ + target: &types.Build{ Event: &pushEvent, Branch: &branchDev, }, - current: &library.Build{ + current: &types.Build{ Event: &pushEvent, Branch: &branchPatch, }, @@ -67,11 +67,11 @@ func Test_isCancelable(t *testing.T) { }, { name: "Event Mismatch", - target: &library.Build{ + target: &types.Build{ Event: &pushEvent, Branch: &branchDev, }, - current: &library.Build{ + current: &types.Build{ Event: &pullEvent, Branch: &branchDev, HeadRef: &branchPatch, @@ -80,13 +80,13 @@ func Test_isCancelable(t *testing.T) { }, { name: "Cancelable Pull", - target: &library.Build{ + target: &types.Build{ Event: &pullEvent, Branch: &branchDev, HeadRef: &branchPatch, EventAction: &actionOpened, }, - current: &library.Build{ + current: &types.Build{ Event: &pullEvent, Branch: &branchDev, HeadRef: &branchPatch, @@ -96,13 +96,13 @@ func Test_isCancelable(t *testing.T) { }, { name: "Pull Head Ref Mismatch", - target: &library.Build{ + target: &types.Build{ Event: &pullEvent, Branch: &branchDev, HeadRef: &branchPatch, EventAction: &actionSync, }, - current: &library.Build{ + current: &types.Build{ Event: &pullEvent, Branch: &branchDev, HeadRef: &branchDev, @@ -112,13 +112,13 @@ func Test_isCancelable(t *testing.T) { }, { name: "Pull Ineligible Action", - target: &library.Build{ + target: &types.Build{ Event: &pullEvent, Branch: &branchDev, HeadRef: &branchPatch, EventAction: &actionEdited, }, - current: &library.Build{ + current: &types.Build{ Event: &pullEvent, Branch: &branchDev, HeadRef: &branchDev, @@ -154,7 +154,7 @@ func Test_ShouldAutoCancel(t *testing.T) { tests := []struct { name string opts *pipeline.CancelOptions - build *library.Build + build *types.Build branch string want bool }{ @@ -165,7 +165,7 @@ func Test_ShouldAutoCancel(t *testing.T) { Pending: true, DefaultBranch: true, }, - build: &library.Build{ + build: &types.Build{ Event: &tagEvent, Branch: &branchPatch, }, @@ -179,7 +179,7 @@ func Test_ShouldAutoCancel(t *testing.T) { Pending: false, DefaultBranch: false, }, - build: &library.Build{ + build: &types.Build{ Event: &pushEvent, Branch: &branchPatch, }, @@ -193,7 +193,7 @@ func Test_ShouldAutoCancel(t *testing.T) { Pending: true, DefaultBranch: false, }, - build: &library.Build{ + build: &types.Build{ Event: &pushEvent, Branch: &branchPatch, }, @@ -207,7 +207,7 @@ func Test_ShouldAutoCancel(t *testing.T) { Pending: true, DefaultBranch: true, }, - build: &library.Build{ + build: &types.Build{ Event: &pushEvent, Branch: &branchDev, }, @@ -221,7 +221,7 @@ func Test_ShouldAutoCancel(t *testing.T) { Pending: true, DefaultBranch: false, }, - build: &library.Build{ + build: &types.Build{ Event: &pushEvent, Branch: &branchDev, }, @@ -235,7 +235,7 @@ func Test_ShouldAutoCancel(t *testing.T) { Pending: true, DefaultBranch: false, }, - build: &library.Build{ + build: &types.Build{ Event: &pullEvent, Branch: &branchDev, EventAction: &actionSync, @@ -250,7 +250,7 @@ func Test_ShouldAutoCancel(t *testing.T) { Pending: true, DefaultBranch: false, }, - build: &library.Build{ + build: &types.Build{ Event: &pullEvent, Branch: &branchDev, EventAction: &actionOpened, @@ -265,7 +265,7 @@ func Test_ShouldAutoCancel(t *testing.T) { Pending: false, DefaultBranch: false, }, - build: &library.Build{ + build: &types.Build{ Event: &pullEvent, Branch: &branchDev, EventAction: &actionOpened, diff --git a/api/build/cancel.go b/api/build/cancel.go index ad0ea30e7..afad5d0e0 100644 --- a/api/build/cancel.go +++ b/api/build/cancel.go @@ -8,7 +8,6 @@ import ( "fmt" "io" "net/http" - "strings" "time" "github.com/gin-gonic/gin" @@ -105,7 +104,7 @@ func CancelBuild(c *gin.Context) { for _, executor := range e { // check each executor on the worker running the build to see if it's running the build we want to cancel - if strings.EqualFold(executor.Repo.GetFullName(), r.GetFullName()) && *executor.GetBuild().Number == b.GetNumber() { + if executor.Build.GetID() == b.GetID() { // prepare the request to the worker client := http.DefaultClient client.Timeout = 30 * time.Second diff --git a/api/build/clean.go b/api/build/clean.go index 645b0bef3..235efc989 100644 --- a/api/build/clean.go +++ b/api/build/clean.go @@ -9,6 +9,7 @@ import ( "github.com/sirupsen/logrus" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" @@ -18,7 +19,7 @@ import ( // without execution. This will kill all resources, // like steps and services, for the build in the // configured backend. -func CleanBuild(ctx context.Context, database database.Interface, b *library.Build, services []*library.Service, steps []*library.Step, e error) { +func CleanBuild(ctx context.Context, database database.Interface, b *types.Build, services []*library.Service, steps []*library.Step, e error) { // update fields in build object b.SetError(fmt.Sprintf("unable to publish to queue: %s", e.Error())) b.SetStatus(constants.StatusError) diff --git a/api/build/compile_publish.go b/api/build/compile_publish.go index cc6d121e4..29f2cdac2 100644 --- a/api/build/compile_publish.go +++ b/api/build/compile_publish.go @@ -27,8 +27,7 @@ import ( // CompileAndPublishConfig is a struct that contains information for the CompileAndPublish function. type CompileAndPublishConfig struct { - Build *library.Build - Repo *types.Repo + Build *types.Build Metadata *internal.Metadata BaseErr string Source string @@ -50,11 +49,11 @@ func CompileAndPublish( compiler compiler.Engine, queue queue.Service, ) (*pipeline.Build, *models.Item, int, error) { - logrus.Debugf("generating queue items for build %s/%d", cfg.Repo.GetFullName(), cfg.Build.GetNumber()) + logrus.Debugf("generating queue items for build %s/%d", cfg.Build.GetRepo().GetFullName(), cfg.Build.GetNumber()) // assign variables from form for readibility - r := cfg.Repo - u := cfg.Repo.GetOwner() + r := cfg.Build.GetRepo() + u := cfg.Build.GetRepo().GetOwner() b := cfg.Build baseErr := cfg.BaseErr @@ -410,12 +409,12 @@ func CompileAndPublish( return nil, nil, http.StatusInternalServerError, retErr } - return p, models.ToItem(b, repo), http.StatusCreated, nil + return p, models.ToItem(b), http.StatusCreated, nil } // getPRNumberFromBuild is a helper function to // extract the pull request number from a Build. -func getPRNumberFromBuild(b *library.Build) (int, error) { +func getPRNumberFromBuild(b *types.Build) (int, error) { // parse out pull request number from base ref // // pattern: refs/pull/1/head diff --git a/api/build/create.go b/api/build/create.go index dc8c81149..f5782d331 100644 --- a/api/build/create.go +++ b/api/build/create.go @@ -9,6 +9,7 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/compiler" "github.com/go-vela/server/database" "github.com/go-vela/server/internal" @@ -18,7 +19,6 @@ import ( "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" "github.com/go-vela/server/util" - "github.com/go-vela/types/library" ) // swagger:operation POST /api/v1/repos/{org}/{repo}/builds builds CreateBuild @@ -99,7 +99,7 @@ func CreateBuild(c *gin.Context) { logger.Infof("creating new build for repo %s", r.GetFullName()) // capture body from API request - input := new(library.Build) + input := new(types.Build) err := c.Bind(input) if err != nil { @@ -110,6 +110,8 @@ func CreateBuild(c *gin.Context) { return } + input.SetRepo(r) + // verify the build has a valid event and the repo allows that event type if !r.GetAllowEvents().Allowed(input.GetEvent(), input.GetEventAction()) { retErr := fmt.Errorf("unable to create new build: %s does not have %s events enabled", r.GetFullName(), input.GetEvent()) @@ -122,7 +124,6 @@ func CreateBuild(c *gin.Context) { // create config config := CompileAndPublishConfig{ Build: input, - Repo: r, Metadata: m, BaseErr: "unable to create build", Source: "create", diff --git a/api/build/enqueue.go b/api/build/enqueue.go index cbc2054b5..297a974f5 100644 --- a/api/build/enqueue.go +++ b/api/build/enqueue.go @@ -16,11 +16,11 @@ import ( // Enqueue is a helper function that pushes a queue item (build, repo, user) to the queue. func Enqueue(ctx context.Context, queue queue.Service, db database.Interface, item *models.Item, route string) { - logrus.Infof("Converting queue item to json for build %d for %s", item.Build.GetNumber(), item.Repo.GetFullName()) + logrus.Infof("Converting queue item to json for build %d for %s", item.Build.GetNumber(), item.Build.GetRepo().GetFullName()) byteItem, err := json.Marshal(item) if err != nil { - logrus.Errorf("Failed to convert item to json for build %d for %s: %v", item.Build.GetNumber(), item.Repo.GetFullName(), err) + logrus.Errorf("Failed to convert item to json for build %d for %s: %v", item.Build.GetNumber(), item.Build.GetRepo().GetFullName(), err) // error out the build CleanBuild(ctx, db, item.Build, nil, nil, err) @@ -28,16 +28,16 @@ func Enqueue(ctx context.Context, queue queue.Service, db database.Interface, it return } - logrus.Infof("Pushing item for build %d for %s to queue route %s", item.Build.GetNumber(), item.Repo.GetFullName(), route) + logrus.Infof("Pushing item for build %d for %s to queue route %s", item.Build.GetNumber(), item.Build.GetRepo().GetFullName(), route) // push item on to the queue err = queue.Push(context.Background(), route, byteItem) if err != nil { - logrus.Errorf("Retrying; Failed to publish build %d for %s: %v", item.Build.GetNumber(), item.Repo.GetFullName(), err) + logrus.Errorf("Retrying; Failed to publish build %d for %s: %v", item.Build.GetNumber(), item.Build.GetRepo().GetFullName(), err) err = queue.Push(context.Background(), route, byteItem) if err != nil { - logrus.Errorf("Failed to publish build %d for %s: %v", item.Build.GetNumber(), item.Repo.GetFullName(), err) + logrus.Errorf("Failed to publish build %d for %s: %v", item.Build.GetNumber(), item.Build.GetRepo().GetFullName(), err) // error out the build CleanBuild(ctx, db, item.Build, nil, nil, err) @@ -52,6 +52,6 @@ func Enqueue(ctx context.Context, queue queue.Service, db database.Interface, it // update the build in the db to reflect the time it was enqueued _, err = db.UpdateBuild(ctx, item.Build) if err != nil { - logrus.Errorf("Failed to update build %d during publish to queue for %s: %v", item.Build.GetNumber(), item.Repo.GetFullName(), err) + logrus.Errorf("Failed to update build %d during publish to queue for %s: %v", item.Build.GetNumber(), item.Build.GetRepo().GetFullName(), err) } } diff --git a/api/build/executable.go b/api/build/executable.go index b855ee7bc..324984b10 100644 --- a/api/build/executable.go +++ b/api/build/executable.go @@ -11,6 +11,7 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/claims" @@ -99,7 +100,7 @@ func GetBuildExecutable(c *gin.Context) { // PublishBuildExecutable marshals a pipeline.Build into bytes and pushes that data to the build_executables table to be // requested by a worker whenever the build has been picked up. -func PublishBuildExecutable(ctx context.Context, db database.Interface, p *pipeline.Build, b *library.Build) error { +func PublishBuildExecutable(ctx context.Context, db database.Interface, p *pipeline.Build, b *types.Build) error { // marshal pipeline build into byte data to add to the build executable object byteExecutable, err := json.Marshal(p) if err != nil { diff --git a/api/build/get_id.go b/api/build/get_id.go index b53827c47..d0a72191d 100644 --- a/api/build/get_id.go +++ b/api/build/get_id.go @@ -10,12 +10,10 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" - "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" "github.com/go-vela/server/util" - "github.com/go-vela/types/library" ) // swagger:operation GET /api/v1/search/builds/{id} builds GetBuildByID @@ -50,12 +48,6 @@ import ( // GetBuildByID represents the API handler to capture a // build by its id from the configured backend. func GetBuildByID(c *gin.Context) { - // Variables that will hold the library types of the build and repo - var ( - b *library.Build - r *types.Repo - ) - // Capture user from middleware u := user.Retrieve(c) ctx := c.Request.Context() @@ -80,7 +72,7 @@ func GetBuildByID(c *gin.Context) { }).Infof("reading build %d", id) // Get build from database - b, err = database.FromContext(c).GetBuild(ctx, id) + b, err := database.FromContext(c).GetBuild(ctx, id) if err != nil { retErr := fmt.Errorf("unable to get build: %w", err) @@ -89,21 +81,11 @@ func GetBuildByID(c *gin.Context) { return } - // Get repo from database using repo ID field from build - r, err = database.FromContext(c).GetRepo(ctx, b.GetRepoID()) - if err != nil { - retErr := fmt.Errorf("unable to get repo: %w", err) - - util.HandleError(c, http.StatusInternalServerError, retErr) - - return - } - // Capture user access from SCM. We do this in order to ensure user has access and is not // just retrieving any build using a random id number. - perm, err := scm.FromContext(c).RepoAccess(ctx, u.GetName(), u.GetToken(), r.GetOrg(), r.GetName()) + perm, err := scm.FromContext(c).RepoAccess(ctx, u.GetName(), u.GetToken(), b.GetRepo().GetOrg(), b.GetRepo().GetName()) if err != nil { - logrus.Errorf("unable to get user %s access level for repo %s", u.GetName(), r.GetFullName()) + logrus.Errorf("unable to get user %s access level for repo %s", u.GetName(), b.GetRepo().GetFullName()) } // Ensure that user has at least read access to repo to return the build diff --git a/api/build/list_org.go b/api/build/list_org.go index ed2c4e929..a8e491a47 100644 --- a/api/build/list_org.go +++ b/api/build/list_org.go @@ -11,13 +11,13 @@ import ( "github.com/sirupsen/logrus" "github.com/go-vela/server/api" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" "github.com/go-vela/server/util" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" ) // swagger:operation GET /api/v1/repos/{org}/builds builds ListBuildsForOrg @@ -102,7 +102,7 @@ func ListBuildsForOrg(c *gin.Context) { // variables that will hold the build list, build list filters and total count var ( filters = map[string]interface{}{} - b []*library.Build + b []*types.Build t int64 ) diff --git a/api/build/list_repo.go b/api/build/list_repo.go index e8ed29845..9c3fca345 100644 --- a/api/build/list_repo.go +++ b/api/build/list_repo.go @@ -12,13 +12,13 @@ import ( "github.com/sirupsen/logrus" "github.com/go-vela/server/api" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" ) // swagger:operation GET /api/v1/repos/{org}/{repo}/builds builds ListBuildsForRepo @@ -122,7 +122,7 @@ func ListBuildsForRepo(c *gin.Context) { // variables that will hold the build list, build list filters and total count var ( filters = map[string]interface{}{} - b []*library.Build + b []*types.Build t int64 ) diff --git a/api/build/plan.go b/api/build/plan.go index d34a776ff..49e700d52 100644 --- a/api/build/plan.go +++ b/api/build/plan.go @@ -12,7 +12,6 @@ import ( "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/scm" - "github.com/go-vela/types/library" "github.com/go-vela/types/pipeline" ) @@ -21,7 +20,7 @@ import ( // and services, for the build in the configured backend. // TODO: // - return build and error. -func PlanBuild(ctx context.Context, database database.Interface, scm scm.Service, p *pipeline.Build, b *library.Build, r *types.Repo) error { +func PlanBuild(ctx context.Context, database database.Interface, scm scm.Service, p *pipeline.Build, b *types.Build, r *types.Repo) error { // update fields in build object b.SetCreated(time.Now().UTC().Unix()) @@ -51,7 +50,7 @@ func PlanBuild(ctx context.Context, database database.Interface, scm scm.Service } // plan all steps for the build - steps, err := step.PlanSteps(ctx, database, scm, p, b, r) + steps, err := step.PlanSteps(ctx, database, scm, p, b) if err != nil { // clean up the objects from the pipeline in the database CleanBuild(ctx, database, b, services, steps, err) diff --git a/api/build/restart.go b/api/build/restart.go index 51c1bc0ff..2569a4915 100644 --- a/api/build/restart.go +++ b/api/build/restart.go @@ -121,7 +121,6 @@ func RestartBuild(c *gin.Context) { // restart form config := CompileAndPublishConfig{ Build: b, - Repo: r, Metadata: m, BaseErr: "unable to restart build", Source: "restart", diff --git a/api/build/update.go b/api/build/update.go index be3f0cdec..e1b64b423 100644 --- a/api/build/update.go +++ b/api/build/update.go @@ -9,6 +9,7 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/claims" @@ -88,7 +89,7 @@ func UpdateBuild(c *gin.Context) { }).Infof("updating build %s", entry) // capture body from API request - input := new(library.Build) + input := new(types.Build) err := c.Bind(input) if err != nil { @@ -178,7 +179,7 @@ func UpdateBuild(c *gin.Context) { } // UpdateComponentStatuses updates all components (steps and services) for a build to a given status. -func UpdateComponentStatuses(c *gin.Context, b *library.Build, status string) error { +func UpdateComponentStatuses(c *gin.Context, b *types.Build, status string) error { ctx := c.Request.Context() // retrieve the steps for the build from the step table diff --git a/api/service/plan.go b/api/service/plan.go index 790c9b538..05673f05e 100644 --- a/api/service/plan.go +++ b/api/service/plan.go @@ -7,6 +7,7 @@ import ( "fmt" "time" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" @@ -16,7 +17,7 @@ import ( // PlanServices is a helper function to plan all services // in the build for execution. This creates the services // for the build in the configured backend. -func PlanServices(ctx context.Context, database database.Interface, p *pipeline.Build, b *library.Build) ([]*library.Service, error) { +func PlanServices(ctx context.Context, database database.Interface, p *pipeline.Build, b *types.Build) ([]*library.Service, error) { // variable to store planned services services := []*library.Service{} @@ -25,7 +26,7 @@ func PlanServices(ctx context.Context, database database.Interface, p *pipeline. // create the service object s := new(library.Service) s.SetBuildID(b.GetID()) - s.SetRepoID(b.GetRepoID()) + s.SetRepoID(b.GetRepo().GetID()) s.SetName(service.Name) s.SetImage(service.Image) s.SetNumber(service.Number) @@ -50,7 +51,7 @@ func PlanServices(ctx context.Context, database database.Interface, p *pipeline. l := new(library.Log) l.SetServiceID(s.GetID()) l.SetBuildID(b.GetID()) - l.SetRepoID(b.GetRepoID()) + l.SetRepoID(b.GetRepo().GetID()) l.SetData([]byte{}) // send API call to create the service logs diff --git a/api/step/plan.go b/api/step/plan.go index 7e493aab6..f685170a3 100644 --- a/api/step/plan.go +++ b/api/step/plan.go @@ -20,7 +20,7 @@ import ( // PlanSteps is a helper function to plan all steps // in the build for execution. This creates the steps // for the build in the configured backend. -func PlanSteps(ctx context.Context, database database.Interface, scm scm.Service, p *pipeline.Build, b *library.Build, repo *types.Repo) ([]*library.Step, error) { +func PlanSteps(ctx context.Context, database database.Interface, scm scm.Service, p *pipeline.Build, b *types.Build) ([]*library.Step, error) { // variable to store planned steps steps := []*library.Step{} @@ -29,7 +29,7 @@ func PlanSteps(ctx context.Context, database database.Interface, scm scm.Service // iterate through all steps for each pipeline stage for _, step := range stage.Steps { // create the step object - s, err := planStep(ctx, database, scm, b, step, repo, stage.Name) + s, err := planStep(ctx, database, scm, b, step, stage.Name) if err != nil { return steps, err } @@ -40,7 +40,7 @@ func PlanSteps(ctx context.Context, database database.Interface, scm scm.Service // iterate through all pipeline steps for _, step := range p.Steps { - s, err := planStep(ctx, database, scm, b, step, repo, "") + s, err := planStep(ctx, database, scm, b, step, "") if err != nil { return steps, err } @@ -51,11 +51,11 @@ func PlanSteps(ctx context.Context, database database.Interface, scm scm.Service return steps, nil } -func planStep(ctx context.Context, database database.Interface, scm scm.Service, b *library.Build, c *pipeline.Container, repo *types.Repo, stage string) (*library.Step, error) { +func planStep(ctx context.Context, database database.Interface, scm scm.Service, b *types.Build, c *pipeline.Container, stage string) (*library.Step, error) { // create the step object s := new(library.Step) s.SetBuildID(b.GetID()) - s.SetRepoID(b.GetRepoID()) + s.SetRepoID(b.GetRepo().GetID()) s.SetNumber(c.Number) s.SetName(c.Name) s.SetImage(c.Image) @@ -82,7 +82,7 @@ func planStep(ctx context.Context, database database.Interface, scm scm.Service, l := new(library.Log) l.SetStepID(s.GetID()) l.SetBuildID(b.GetID()) - l.SetRepoID(b.GetRepoID()) + l.SetRepoID(b.GetRepo().GetID()) l.SetData([]byte{}) // send API call to create the step logs @@ -93,7 +93,7 @@ func planStep(ctx context.Context, database database.Interface, scm scm.Service, if len(s.GetReportAs()) > 0 { // send API call to set the status on the commit - err = scm.StepStatus(ctx, repo.GetOwner(), b, s, repo.GetOrg(), repo.GetName()) + err = scm.StepStatus(ctx, b.GetRepo().GetOwner(), b, s, b.GetRepo().GetOrg(), b.GetRepo().GetName()) if err != nil { logrus.Errorf("unable to set commit status for build: %v", err) } diff --git a/api/types/build.go b/api/types/build.go new file mode 100644 index 000000000..231e8b80b --- /dev/null +++ b/api/types/build.go @@ -0,0 +1,1218 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "fmt" + "strings" + "time" + + "github.com/go-vela/types/constants" + "github.com/go-vela/types/library" + "github.com/go-vela/types/raw" +) + +// Build is the API types representation of a build for a pipeline. +// +// swagger:model Build +type Build struct { + ID *int64 `json:"id,omitempty"` + Repo *Repo `json:"repo,omitempty"` + PipelineID *int64 `json:"pipeline_id,omitempty"` + Number *int `json:"number,omitempty"` + Parent *int `json:"parent,omitempty"` + Event *string `json:"event,omitempty"` + EventAction *string `json:"event_action,omitempty"` + Status *string `json:"status,omitempty"` + Error *string `json:"error,omitempty"` + Enqueued *int64 `json:"enqueued,omitempty"` + Created *int64 `json:"created,omitempty"` + 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"` + Title *string `json:"title,omitempty"` + Message *string `json:"message,omitempty"` + Commit *string `json:"commit,omitempty"` + Sender *string `json:"sender,omitempty"` + Author *string `json:"author,omitempty"` + Email *string `json:"email,omitempty"` + Link *string `json:"link,omitempty"` + Branch *string `json:"branch,omitempty"` + Ref *string `json:"ref,omitempty"` + BaseRef *string `json:"base_ref,omitempty"` + HeadRef *string `json:"head_ref,omitempty"` + Host *string `json:"host,omitempty"` + Runtime *string `json:"runtime,omitempty"` + Distribution *string `json:"distribution,omitempty"` + ApprovedAt *int64 `json:"approved_at,omitempty"` + ApprovedBy *string `json:"approved_by,omitempty"` +} + +// Duration calculates and returns the total amount of +// time the build ran for in a human-readable format. +func (b *Build) Duration() string { + // check if the build doesn't have a started timestamp + if b.GetStarted() == 0 { + return "..." + } + + // capture started unix timestamp from the build + started := time.Unix(b.GetStarted(), 0) + + // check if the build doesn't have a finished timestamp + if b.GetFinished() == 0 { + // return the duration in a human-readable form by + // subtracting the build started time from the + // current time rounded to the nearest second + return time.Since(started).Round(time.Second).String() + } + + // capture finished unix timestamp from the build + finished := time.Unix(b.GetFinished(), 0) + + // calculate the duration by subtracting the build + // started time from the build finished time + duration := finished.Sub(started) + + // return the duration in a human-readable form + return duration.String() +} + +// Environment returns a list of environment variables +// provided from the fields of the Build type. +func (b *Build) Environment(workspace, channel string) map[string]string { + envs := map[string]string{ + "VELA_BUILD_APPROVED_AT": ToString(b.GetApprovedAt()), + "VELA_BUILD_APPROVED_BY": ToString(b.GetApprovedBy()), + "VELA_BUILD_AUTHOR": ToString(b.GetAuthor()), + "VELA_BUILD_AUTHOR_EMAIL": ToString(b.GetEmail()), + "VELA_BUILD_BASE_REF": ToString(b.GetBaseRef()), + "VELA_BUILD_BRANCH": ToString(b.GetBranch()), + "VELA_BUILD_CHANNEL": ToString(channel), + "VELA_BUILD_CLONE": ToString(b.GetClone()), + "VELA_BUILD_COMMIT": ToString(b.GetCommit()), + "VELA_BUILD_CREATED": ToString(b.GetCreated()), + "VELA_BUILD_DISTRIBUTION": ToString(b.GetDistribution()), + "VELA_BUILD_ENQUEUED": ToString(b.GetEnqueued()), + "VELA_BUILD_EVENT": ToString(b.GetEvent()), + "VELA_BUILD_EVENT_ACTION": ToString(b.GetEventAction()), + "VELA_BUILD_HOST": ToString(b.GetHost()), + "VELA_BUILD_LINK": ToString(b.GetLink()), + "VELA_BUILD_MESSAGE": ToString(b.GetMessage()), + "VELA_BUILD_NUMBER": ToString(b.GetNumber()), + "VELA_BUILD_PARENT": ToString(b.GetParent()), + "VELA_BUILD_REF": ToString(b.GetRef()), + "VELA_BUILD_RUNTIME": ToString(b.GetRuntime()), + "VELA_BUILD_SENDER": ToString(b.GetSender()), + "VELA_BUILD_STARTED": ToString(b.GetStarted()), + "VELA_BUILD_SOURCE": ToString(b.GetSource()), + "VELA_BUILD_STATUS": ToString(b.GetStatus()), + "VELA_BUILD_TITLE": ToString(b.GetTitle()), + "VELA_BUILD_WORKSPACE": ToString(workspace), + + // deprecated environment variables + "BUILD_AUTHOR": ToString(b.GetAuthor()), + "BUILD_AUTHOR_EMAIL": ToString(b.GetEmail()), + "BUILD_BASE_REF": ToString(b.GetBaseRef()), + "BUILD_BRANCH": ToString(b.GetBranch()), + "BUILD_CHANNEL": ToString(channel), + "BUILD_CLONE": ToString(b.GetClone()), + "BUILD_COMMIT": ToString(b.GetCommit()), + "BUILD_CREATED": ToString(b.GetCreated()), + "BUILD_ENQUEUED": ToString(b.GetEnqueued()), + "BUILD_EVENT": ToString(b.GetEvent()), + "BUILD_HOST": ToString(b.GetHost()), + "BUILD_LINK": ToString(b.GetLink()), + "BUILD_MESSAGE": ToString(b.GetMessage()), + "BUILD_NUMBER": ToString(b.GetNumber()), + "BUILD_PARENT": ToString(b.GetParent()), + "BUILD_REF": ToString(b.GetRef()), + "BUILD_SENDER": ToString(b.GetSender()), + "BUILD_STARTED": ToString(b.GetStarted()), + "BUILD_SOURCE": ToString(b.GetSource()), + "BUILD_STATUS": ToString(b.GetStatus()), + "BUILD_TITLE": ToString(b.GetTitle()), + "BUILD_WORKSPACE": ToString(workspace), + } + + // check if the Build event is comment + if strings.EqualFold(b.GetEvent(), constants.EventComment) { + // capture the pull request number + number := ToString(strings.SplitN(b.GetRef(), "/", 4)[2]) + + // add the pull request number to the list + 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 + if strings.EqualFold(b.GetEvent(), constants.EventDeploy) { + // capture the deployment target + target := ToString(b.GetDeploy()) + + // add the deployment target to the list + 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/") { + // capture the tag reference + tag := ToString(strings.SplitN(b.GetRef(), "refs/tags/", 2)[1]) + + // add the tag reference to the list + envs["BUILD_TAG"] = tag + envs["VELA_BUILD_TAG"] = tag + } + + // add payload data to the list + for key, value := range b.GetDeployPayload() { + envs[fmt.Sprintf("DEPLOYMENT_PARAMETER_%s", strings.ToUpper(key))] = value + } + } + + // check if the Build event is pull_request + if strings.EqualFold(b.GetEvent(), constants.EventPull) { + // capture the pull request number + number := ToString(strings.SplitN(b.GetRef(), "/", 4)[2]) + + // add the pull request number to the list + 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 tag + if strings.EqualFold(b.GetEvent(), constants.EventTag) { + // capture the tag reference + tag := ToString(strings.SplitN(b.GetRef(), "refs/tags/", 2)[1]) + + // add the tag reference to the list + envs["BUILD_TAG"] = tag + 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 +} + +// GetID returns the ID 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) GetID() int64 { + // return zero value if Build type or ID field is nil + if b == nil || b.ID == nil { + return 0 + } + + return *b.ID +} + +// GetRepo returns the Repo 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) GetRepo() *Repo { + // return zero value if Build type or Repo field is nil + if b == nil || b.Repo == nil { + return new(Repo) + } + + return b.Repo +} + +// GetPipelineID returns the PipelineID 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) GetPipelineID() int64 { + // return zero value if Build type or PipelineID field is nil + if b == nil || b.PipelineID == nil { + return 0 + } + + return *b.PipelineID +} + +// GetNumber returns the Number 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) GetNumber() int { + // return zero value if Build type or Number field is nil + if b == nil || b.Number == nil { + return 0 + } + + return *b.Number +} + +// GetParent returns the Parent 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) GetParent() int { + // return zero value if Build type or Parent field is nil + if b == nil || b.Parent == nil { + return 0 + } + + return *b.Parent +} + +// GetEvent returns the Event 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) GetEvent() string { + // return zero value if Build type or Event field is nil + if b == nil || b.Event == nil { + return "" + } + + return *b.Event +} + +// GetEventAction returns the EventAction 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) GetEventAction() string { + // return zero value if Build type or EventAction field is nil + if b == nil || b.EventAction == nil { + return "" + } + + return *b.EventAction +} + +// GetStatus returns the Status 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) GetStatus() string { + // return zero value if Build type or Status field is nil + if b == nil || b.Status == nil { + return "" + } + + return *b.Status +} + +// GetError returns the Error 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) GetError() string { + // return zero value if Build type or Error field is nil + if b == nil || b.Error == nil { + return "" + } + + return *b.Error +} + +// GetEnqueued returns the Enqueued 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) GetEnqueued() int64 { + // return zero value if Build type or Enqueued field is nil + if b == nil || b.Enqueued == nil { + return 0 + } + + return *b.Enqueued +} + +// GetCreated returns the Created 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) GetCreated() int64 { + // return zero value if Build type or Created field is nil + if b == nil || b.Created == nil { + return 0 + } + + return *b.Created +} + +// GetStarted returns the Started 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) GetStarted() int64 { + // return zero value if Build type or Started field is nil + if b == nil || b.Started == nil { + return 0 + } + + return *b.Started +} + +// GetFinished returns the Finished 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) GetFinished() int64 { + // return zero value if Build type or Finished field is nil + if b == nil || b.Finished == nil { + return 0 + } + + return *b.Finished +} + +// GetDeploy returns the Deploy 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) GetDeploy() string { + // return zero value if Build type or Deploy field is nil + if b == nil || b.Deploy == nil { + return "" + } + + 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 +// the type is nil, it returns the zero value for the field. +func (b *Build) GetDeployPayload() raw.StringSliceMap { + // return zero value if Build type or Deploy field is nil + if b == nil || b.DeployPayload == nil { + return raw.StringSliceMap{} + } + + return *b.DeployPayload +} + +// GetClone returns the Clone 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) GetClone() string { + // return zero value if Build type or Clone field is nil + if b == nil || b.Clone == nil { + return "" + } + + return *b.Clone +} + +// GetSource returns the Source 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) GetSource() string { + // return zero value if Build type or Source field is nil + if b == nil || b.Source == nil { + return "" + } + + return *b.Source +} + +// GetTitle returns the Title 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) GetTitle() string { + // return zero value if Build type or Title field is nil + if b == nil || b.Title == nil { + return "" + } + + return *b.Title +} + +// GetMessage returns the Message 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) GetMessage() string { + // return zero value if Build type or Message field is nil + if b == nil || b.Message == nil { + return "" + } + + return *b.Message +} + +// GetCommit returns the Commit 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) GetCommit() string { + // return zero value if Build type or Commit field is nil + if b == nil || b.Commit == nil { + return "" + } + + return *b.Commit +} + +// GetSender returns the Sender 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) GetSender() string { + // return zero value if Build type or Sender field is nil + if b == nil || b.Sender == nil { + return "" + } + + return *b.Sender +} + +// GetAuthor returns the Author 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) GetAuthor() string { + // return zero value if Build type or Author field is nil + if b == nil || b.Author == nil { + return "" + } + + return *b.Author +} + +// GetEmail returns the Email 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) GetEmail() string { + // return zero value if Build type or Email field is nil + if b == nil || b.Email == nil { + return "" + } + + return *b.Email +} + +// GetLink returns the Link 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) GetLink() string { + // return zero value if Build type or Link field is nil + if b == nil || b.Link == nil { + return "" + } + + return *b.Link +} + +// GetBranch returns the Branch 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) GetBranch() string { + // return zero value if Build type or Branch field is nil + if b == nil || b.Branch == nil { + return "" + } + + return *b.Branch +} + +// GetRef returns the Ref 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) GetRef() string { + // return zero value if Build type or Ref field is nil + if b == nil || b.Ref == nil { + return "" + } + + return *b.Ref +} + +// GetBaseRef returns the BaseRef 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) GetBaseRef() string { + // return zero value if Build type or BaseRef field is nil + if b == nil || b.BaseRef == nil { + return "" + } + + return *b.BaseRef +} + +// GetHeadRef returns the HeadRef 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) GetHeadRef() string { + // return zero value if Build type or HeadRef field is nil + if b == nil || b.HeadRef == nil { + return "" + } + + return *b.HeadRef +} + +// GetHost returns the Host 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) GetHost() string { + // return zero value if Build type or Host field is nil + if b == nil || b.Host == nil { + return "" + } + + return *b.Host +} + +// GetRuntime returns the Runtime 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) GetRuntime() string { + // return zero value if Build type or Runtime field is nil + if b == nil || b.Runtime == nil { + return "" + } + + return *b.Runtime +} + +// GetDistribution returns the Distribution 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) GetDistribution() string { + // return zero value if Build type or Distribution field is nil + if b == nil || b.Distribution == nil { + return "" + } + + return *b.Distribution +} + +// GetApprovedAt returns the ApprovedAt 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) GetApprovedAt() int64 { + // return zero value if Build type or ApprovedAt field is nil + if b == nil || b.ApprovedAt == nil { + return 0 + } + + return *b.ApprovedAt +} + +// GetApprovedBy returns the ApprovedBy 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) GetApprovedBy() string { + // return zero value if Build type or ApprovedBy field is nil + if b == nil || b.ApprovedBy == nil { + return "" + } + + return *b.ApprovedBy +} + +// SetID sets the ID field. +// +// When the provided Build type is nil, it +// will set nothing and immediately return. +func (b *Build) SetID(v int64) { + // return if Build type is nil + if b == nil { + return + } + + b.ID = &v +} + +// SetRepo sets the Repo field. +// +// When the provided Build type is nil, it +// will set nothing and immediately return. +func (b *Build) SetRepo(v *Repo) { + // return if Build type is nil + if b == nil { + return + } + + b.Repo = v +} + +// SetPipelineID sets the PipelineID field. +// +// When the provided Build type is nil, it +// will set nothing and immediately return. +func (b *Build) SetPipelineID(v int64) { + // return if Build type is nil + if b == nil { + return + } + + b.PipelineID = &v +} + +// SetNumber sets the Number field. +// +// When the provided Build type is nil, it +// will set nothing and immediately return. +func (b *Build) SetNumber(v int) { + // return if Build type is nil + if b == nil { + return + } + + b.Number = &v +} + +// SetParent sets the Parent field. +// +// When the provided Build type is nil, it +// will set nothing and immediately return. +func (b *Build) SetParent(v int) { + // return if Build type is nil + if b == nil { + return + } + + b.Parent = &v +} + +// SetEvent sets the Event field. +// +// When the provided Build type is nil, it +// will set nothing and immediately return. +func (b *Build) SetEvent(v string) { + // return if Build type is nil + if b == nil { + return + } + + b.Event = &v +} + +// SetEventAction sets the EventAction field. +// +// When the provided Build type is nil, it +// will set nothing and immediately return. +func (b *Build) SetEventAction(v string) { + // return if Build type is nil + if b == nil { + return + } + + b.EventAction = &v +} + +// SetStatus sets the Status field. +// +// When the provided Build type is nil, it +// will set nothing and immediately return. +func (b *Build) SetStatus(v string) { + // return if Build type is nil + if b == nil { + return + } + + b.Status = &v +} + +// SetError sets the Error field. +// +// When the provided Build type is nil, it +// will set nothing and immediately return. +func (b *Build) SetError(v string) { + // return if Build type is nil + if b == nil { + return + } + + b.Error = &v +} + +// SetEnqueued sets the Enqueued field. +// +// When the provided Build type is nil, it +// will set nothing and immediately return. +func (b *Build) SetEnqueued(v int64) { + // return if Build type is nil + if b == nil { + return + } + + b.Enqueued = &v +} + +// SetCreated sets the Created field. +// +// When the provided Build type is nil, it +// will set nothing and immediately return. +func (b *Build) SetCreated(v int64) { + // return if Build type is nil + if b == nil { + return + } + + b.Created = &v +} + +// SetStarted sets the Started field. +// +// When the provided Build type is nil, it +// will set nothing and immediately return. +func (b *Build) SetStarted(v int64) { + // return if Build type is nil + if b == nil { + return + } + + b.Started = &v +} + +// SetFinished sets the Finished field. +// +// When the provided Build type is nil, it +// will set nothing and immediately return. +func (b *Build) SetFinished(v int64) { + // return if Build type is nil + if b == nil { + return + } + + b.Finished = &v +} + +// SetDeploy sets the Deploy field. +// +// When the provided Build type is nil, it +// will set nothing and immediately return. +func (b *Build) SetDeploy(v string) { + // return if Build type is nil + if b == nil { + return + } + + 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 +// will set nothing and immediately return. +func (b *Build) SetDeployPayload(v raw.StringSliceMap) { + // return if Build type is nil + if b == nil { + return + } + + b.DeployPayload = &v +} + +// SetClone sets the Clone field. +// +// When the provided Build type is nil, it +// will set nothing and immediately return. +func (b *Build) SetClone(v string) { + // return if Build type is nil + if b == nil { + return + } + + b.Clone = &v +} + +// SetSource sets the Source field. +// +// When the provided Build type is nil, it +// will set nothing and immediately return. +func (b *Build) SetSource(v string) { + // return if Build type is nil + if b == nil { + return + } + + b.Source = &v +} + +// SetTitle sets the Title field. +// +// When the provided Build type is nil, it +// will set nothing and immediately return. +func (b *Build) SetTitle(v string) { + // return if Build type is nil + if b == nil { + return + } + + b.Title = &v +} + +// SetMessage sets the Message field. +// +// When the provided Build type is nil, it +// will set nothing and immediately return. +func (b *Build) SetMessage(v string) { + // return if Build type is nil + if b == nil { + return + } + + b.Message = &v +} + +// SetCommit sets the Commit field. +// +// When the provided Build type is nil, it +// will set nothing and immediately return. +func (b *Build) SetCommit(v string) { + // return if Build type is nil + if b == nil { + return + } + + b.Commit = &v +} + +// SetSender sets the Sender field. +// +// When the provided Build type is nil, it +// will set nothing and immediately return. +func (b *Build) SetSender(v string) { + // return if Build type is nil + if b == nil { + return + } + + b.Sender = &v +} + +// SetAuthor sets the Author field. +// +// When the provided Build type is nil, it +// will set nothing and immediately return. +func (b *Build) SetAuthor(v string) { + // return if Build type is nil + if b == nil { + return + } + + b.Author = &v +} + +// SetEmail sets the Email field. +// +// When the provided Build type is nil, it +// will set nothing and immediately return. +func (b *Build) SetEmail(v string) { + // return if Build type is nil + if b == nil { + return + } + + b.Email = &v +} + +// SetLink sets the Link field. +// +// When the provided Build type is nil, it +// will set nothing and immediately return. +func (b *Build) SetLink(v string) { + // return if Build type is nil + if b == nil { + return + } + + b.Link = &v +} + +// SetBranch sets the Branch field. +// +// When the provided Build type is nil, it +// will set nothing and immediately return. +func (b *Build) SetBranch(v string) { + // return if Build type is nil + if b == nil { + return + } + + b.Branch = &v +} + +// SetRef sets the Ref field. +// +// When the provided Build type is nil, it +// will set nothing and immediately return. +func (b *Build) SetRef(v string) { + // return if Build type is nil + if b == nil { + return + } + + b.Ref = &v +} + +// SetBaseRef sets the BaseRef field. +// +// When the provided Build type is nil, it +// will set nothing and immediately return. +func (b *Build) SetBaseRef(v string) { + // return if Build type is nil + if b == nil { + return + } + + b.BaseRef = &v +} + +// SetHeadRef sets the HeadRef field. +// +// When the provided Build type is nil, it +// will set nothing and immediately return. +func (b *Build) SetHeadRef(v string) { + // return if Build type is nil + if b == nil { + return + } + + b.HeadRef = &v +} + +// SetHost sets the Host field. +// +// When the provided Build type is nil, it +// will set nothing and immediately return. +func (b *Build) SetHost(v string) { + // return if Build type is nil + if b == nil { + return + } + + b.Host = &v +} + +// SetRuntime sets the Runtime field. +// +// When the provided Build type is nil, it +// will set nothing and immediately return. +func (b *Build) SetRuntime(v string) { + // return if Build type is nil + if b == nil { + return + } + + b.Runtime = &v +} + +// SetDistribution sets the Distribution field. +// +// When the provided Build type is nil, it +// will set nothing and immediately return. +func (b *Build) SetDistribution(v string) { + // return if Build type is nil + if b == nil { + return + } + + b.Distribution = &v +} + +// SetApprovedAt sets the ApprovedAt field. +// +// When the provided Build type is nil, it +// will set nothing and immediately return. +func (b *Build) SetApprovedAt(v int64) { + // return if Build type is nil + if b == nil { + return + } + + b.ApprovedAt = &v +} + +// SetApprovedBy sets the ApprovedBy field. +// +// When the provided Build type is nil, it +// will set nothing and immediately return. +func (b *Build) SetApprovedBy(v string) { + // return if Build type is nil + if b == nil { + return + } + + b.ApprovedBy = &v +} + +// String implements the Stringer interface for the Build type. +// +//nolint:dupl // this is duplicated in the test +func (b *Build) String() string { + return fmt.Sprintf(`{ + ApprovedAt: %d, + ApprovedBy: %s, + Author: %s, + BaseRef: %s, + Branch: %s, + Clone: %s, + Commit: %s, + Created: %d, + Deploy: %s, + DeployNumber: %d, + DeployPayload: %s, + Distribution: %s, + Email: %s, + Enqueued: %d, + Error: %s, + Event: %s, + EventAction: %s, + Finished: %d, + HeadRef: %s, + Host: %s, + ID: %d, + Link: %s, + Message: %s, + Number: %d, + Parent: %d, + PipelineID: %d, + Ref: %s, + Repo: %s, + Runtime: %s, + Sender: %s, + Source: %s, + Started: %d, + Status: %s, + Title: %s, +}`, + b.GetApprovedAt(), + b.GetApprovedBy(), + b.GetAuthor(), + b.GetBaseRef(), + b.GetBranch(), + b.GetClone(), + b.GetCommit(), + b.GetCreated(), + b.GetDeploy(), + b.GetDeployNumber(), + b.GetDeployPayload(), + b.GetDistribution(), + b.GetEmail(), + b.GetEnqueued(), + b.GetError(), + b.GetEvent(), + b.GetEventAction(), + b.GetFinished(), + b.GetHeadRef(), + b.GetHost(), + b.GetID(), + b.GetLink(), + b.GetMessage(), + b.GetNumber(), + b.GetParent(), + b.GetPipelineID(), + b.GetRef(), + b.GetRepo().GetFullName(), + b.GetRuntime(), + b.GetSender(), + b.GetSource(), + b.GetStarted(), + b.GetStatus(), + b.GetTitle(), + ) +} + +// TODO: remove this when Deployment is moved from types and uses Build type instead of library type. +func (b *Build) ToLibrary() *library.Build { + return &library.Build{ + ID: b.ID, + RepoID: b.GetRepo().ID, + PipelineID: b.PipelineID, + Number: b.Number, + Parent: b.Parent, + Event: b.Event, + EventAction: b.EventAction, + Status: b.Status, + Error: b.Error, + Enqueued: b.Enqueued, + Created: b.Created, + Started: b.Started, + Finished: b.Finished, + Deploy: b.Deploy, + DeployNumber: b.DeployNumber, + DeployPayload: b.DeployPayload, + Clone: b.Clone, + Source: b.Source, + Title: b.Title, + Message: b.Message, + Commit: b.Commit, + Sender: b.Sender, + Author: b.Author, + Email: b.Email, + Link: b.Link, + Branch: b.Branch, + Ref: b.Ref, + BaseRef: b.BaseRef, + HeadRef: b.HeadRef, + Host: b.Host, + Runtime: b.Runtime, + Distribution: b.Distribution, + ApprovedAt: b.ApprovedAt, + ApprovedBy: b.ApprovedBy, + } +} diff --git a/api/types/build_test.go b/api/types/build_test.go new file mode 100644 index 000000000..d70853bda --- /dev/null +++ b/api/types/build_test.go @@ -0,0 +1,928 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "fmt" + "reflect" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + + "github.com/go-vela/types/raw" +) + +func TestTypes_Build_Duration(t *testing.T) { + // setup types + unfinished := testBuild() + unfinished.SetFinished(0) + + // setup tests + tests := []struct { + build *Build + want string + }{ + { + build: testBuild(), + want: "1s", + }, + { + build: unfinished, + want: time.Since(time.Unix(unfinished.GetStarted(), 0)).Round(time.Second).String(), + }, + { + build: new(Build), + want: "...", + }, + } + + // run tests + for _, test := range tests { + got := test.build.Duration() + + if got != test.want { + t.Errorf("Duration is %v, want %v", got, test.want) + } + } +} + +func TestTypes_Build_Environment(t *testing.T) { + // setup types + _comment := testBuild() + _comment.SetEvent("comment") + _comment.SetEventAction("created") + _comment.SetRef("refs/pulls/1/head") + _comment.SetHeadRef("dev") + _comment.SetBaseRef("main") + + _deploy := testBuild() + _deploy.SetEvent("deployment") + _deploy.SetDeploy("production") + _deploy.SetDeployNumber(0) + _deploy.SetDeployPayload(map[string]string{ + "foo": "test1", + "bar": "test2", + }) + + _deployTag := testBuild() + _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", + }) + + _pull := testBuild() + _pull.SetEvent("pull_request") + _pull.SetEventAction("opened") + _pull.SetRef("refs/pulls/1/head") + + _tag := testBuild() + _tag.SetEvent("tag") + _tag.SetRef("refs/tags/v0.1.0") + + // setup tests + tests := []struct { + build *Build + want map[string]string + }{ + { + build: testBuild(), + want: map[string]string{ + "VELA_BUILD_APPROVED_AT": "1563474076", + "VELA_BUILD_APPROVED_BY": "OctoCat", + "VELA_BUILD_AUTHOR": "OctoKitty", + "VELA_BUILD_AUTHOR_EMAIL": "OctoKitty@github.com", + "VELA_BUILD_BASE_REF": "", + "VELA_BUILD_BRANCH": "main", + "VELA_BUILD_CHANNEL": "TODO", + "VELA_BUILD_CLONE": "https://github.com/github/octocat.git", + "VELA_BUILD_COMMIT": "48afb5bdc41ad69bf22588491333f7cf71135163", + "VELA_BUILD_CREATED": "1563474076", + "VELA_BUILD_DISTRIBUTION": "linux", + "VELA_BUILD_ENQUEUED": "1563474077", + "VELA_BUILD_EVENT": "push", + "VELA_BUILD_EVENT_ACTION": "", + "VELA_BUILD_HOST": "example.company.com", + "VELA_BUILD_LINK": "https://example.company.com/github/octocat/1", + "VELA_BUILD_MESSAGE": "First commit...", + "VELA_BUILD_NUMBER": "1", + "VELA_BUILD_PARENT": "1", + "VELA_BUILD_REF": "refs/heads/main", + "VELA_BUILD_RUNTIME": "docker", + "VELA_BUILD_SENDER": "OctoKitty", + "VELA_BUILD_STARTED": "1563474078", + "VELA_BUILD_SOURCE": "https://github.com/github/octocat/48afb5bdc41ad69bf22588491333f7cf71135163", + "VELA_BUILD_STATUS": "running", + "VELA_BUILD_TITLE": "push received from https://github.com/github/octocat", + "VELA_BUILD_WORKSPACE": "TODO", + "BUILD_AUTHOR": "OctoKitty", + "BUILD_AUTHOR_EMAIL": "OctoKitty@github.com", + "BUILD_BASE_REF": "", + "BUILD_BRANCH": "main", + "BUILD_CHANNEL": "TODO", + "BUILD_CLONE": "https://github.com/github/octocat.git", + "BUILD_COMMIT": "48afb5bdc41ad69bf22588491333f7cf71135163", + "BUILD_CREATED": "1563474076", + "BUILD_ENQUEUED": "1563474077", + "BUILD_EVENT": "push", + "BUILD_HOST": "example.company.com", + "BUILD_LINK": "https://example.company.com/github/octocat/1", + "BUILD_MESSAGE": "First commit...", + "BUILD_NUMBER": "1", + "BUILD_PARENT": "1", + "BUILD_REF": "refs/heads/main", + "BUILD_SENDER": "OctoKitty", + "BUILD_STARTED": "1563474078", + "BUILD_SOURCE": "https://github.com/github/octocat/48afb5bdc41ad69bf22588491333f7cf71135163", + "BUILD_STATUS": "running", + "BUILD_TITLE": "push received from https://github.com/github/octocat", + "BUILD_WORKSPACE": "TODO", + }, + }, + { + build: _comment, + want: map[string]string{ + "VELA_BUILD_APPROVED_AT": "1563474076", + "VELA_BUILD_APPROVED_BY": "OctoCat", + "VELA_BUILD_AUTHOR": "OctoKitty", + "VELA_BUILD_AUTHOR_EMAIL": "OctoKitty@github.com", + "VELA_BUILD_BASE_REF": "main", + "VELA_BUILD_BRANCH": "main", + "VELA_BUILD_CHANNEL": "TODO", + "VELA_BUILD_CLONE": "https://github.com/github/octocat.git", + "VELA_BUILD_COMMIT": "48afb5bdc41ad69bf22588491333f7cf71135163", + "VELA_BUILD_CREATED": "1563474076", + "VELA_BUILD_DISTRIBUTION": "linux", + "VELA_BUILD_ENQUEUED": "1563474077", + "VELA_BUILD_EVENT": "comment", + "VELA_BUILD_EVENT_ACTION": "created", + "VELA_BUILD_HOST": "example.company.com", + "VELA_BUILD_LINK": "https://example.company.com/github/octocat/1", + "VELA_BUILD_MESSAGE": "First commit...", + "VELA_BUILD_NUMBER": "1", + "VELA_BUILD_PARENT": "1", + "VELA_BUILD_PULL_REQUEST": "1", + "VELA_BUILD_REF": "refs/pulls/1/head", + "VELA_BUILD_RUNTIME": "docker", + "VELA_BUILD_SENDER": "OctoKitty", + "VELA_BUILD_STARTED": "1563474078", + "VELA_BUILD_SOURCE": "https://github.com/github/octocat/48afb5bdc41ad69bf22588491333f7cf71135163", + "VELA_BUILD_STATUS": "running", + "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": "main", + "BUILD_BRANCH": "main", + "BUILD_CHANNEL": "TODO", + "BUILD_CLONE": "https://github.com/github/octocat.git", + "BUILD_COMMIT": "48afb5bdc41ad69bf22588491333f7cf71135163", + "BUILD_CREATED": "1563474076", + "BUILD_ENQUEUED": "1563474077", + "BUILD_EVENT": "comment", + "BUILD_HOST": "example.company.com", + "BUILD_LINK": "https://example.company.com/github/octocat/1", + "BUILD_MESSAGE": "First commit...", + "BUILD_NUMBER": "1", + "BUILD_PARENT": "1", + "BUILD_PULL_REQUEST_NUMBER": "1", + "BUILD_REF": "refs/pulls/1/head", + "BUILD_SENDER": "OctoKitty", + "BUILD_STARTED": "1563474078", + "BUILD_SOURCE": "https://github.com/github/octocat/48afb5bdc41ad69bf22588491333f7cf71135163", + "BUILD_STATUS": "running", + "BUILD_TITLE": "push received from https://github.com/github/octocat", + "BUILD_WORKSPACE": "TODO", + }, + }, + { + build: _deploy, + want: map[string]string{ + "VELA_BUILD_APPROVED_AT": "1563474076", + "VELA_BUILD_APPROVED_BY": "OctoCat", + "VELA_BUILD_AUTHOR": "OctoKitty", + "VELA_BUILD_AUTHOR_EMAIL": "OctoKitty@github.com", + "VELA_BUILD_BASE_REF": "", + "VELA_BUILD_BRANCH": "main", + "VELA_BUILD_CHANNEL": "TODO", + "VELA_BUILD_CLONE": "https://github.com/github/octocat.git", + "VELA_BUILD_COMMIT": "48afb5bdc41ad69bf22588491333f7cf71135163", + "VELA_BUILD_CREATED": "1563474076", + "VELA_BUILD_DISTRIBUTION": "linux", + "VELA_BUILD_ENQUEUED": "1563474077", + "VELA_BUILD_EVENT": "deployment", + "VELA_BUILD_EVENT_ACTION": "", + "VELA_BUILD_HOST": "example.company.com", + "VELA_BUILD_LINK": "https://example.company.com/github/octocat/1", + "VELA_BUILD_MESSAGE": "First commit...", + "VELA_BUILD_NUMBER": "1", + "VELA_BUILD_PARENT": "1", + "VELA_BUILD_REF": "refs/heads/main", + "VELA_BUILD_RUNTIME": "docker", + "VELA_BUILD_SENDER": "OctoKitty", + "VELA_BUILD_STARTED": "1563474078", + "VELA_BUILD_SOURCE": "https://github.com/github/octocat/48afb5bdc41ad69bf22588491333f7cf71135163", + "VELA_BUILD_STATUS": "running", + "VELA_BUILD_TARGET": "production", + "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", + "BUILD_BASE_REF": "", + "BUILD_BRANCH": "main", + "BUILD_CHANNEL": "TODO", + "BUILD_CLONE": "https://github.com/github/octocat.git", + "BUILD_COMMIT": "48afb5bdc41ad69bf22588491333f7cf71135163", + "BUILD_CREATED": "1563474076", + "BUILD_ENQUEUED": "1563474077", + "BUILD_EVENT": "deployment", + "BUILD_HOST": "example.company.com", + "BUILD_LINK": "https://example.company.com/github/octocat/1", + "BUILD_MESSAGE": "First commit...", + "BUILD_NUMBER": "1", + "BUILD_PARENT": "1", + "BUILD_REF": "refs/heads/main", + "BUILD_SENDER": "OctoKitty", + "BUILD_STARTED": "1563474078", + "BUILD_SOURCE": "https://github.com/github/octocat/48afb5bdc41ad69bf22588491333f7cf71135163", + "BUILD_STATUS": "running", + "BUILD_TITLE": "push received from https://github.com/github/octocat", + "BUILD_WORKSPACE": "TODO", + "DEPLOYMENT_PARAMETER_FOO": "test1", + "DEPLOYMENT_PARAMETER_BAR": "test2", + }, + }, + { + build: _deployTag, + want: map[string]string{ + "VELA_BUILD_APPROVED_AT": "1563474076", + "VELA_BUILD_APPROVED_BY": "OctoCat", + "VELA_BUILD_AUTHOR": "OctoKitty", + "VELA_BUILD_AUTHOR_EMAIL": "OctoKitty@github.com", + "VELA_BUILD_BASE_REF": "", + "VELA_BUILD_BRANCH": "main", + "VELA_BUILD_CHANNEL": "TODO", + "VELA_BUILD_CLONE": "https://github.com/github/octocat.git", + "VELA_BUILD_COMMIT": "48afb5bdc41ad69bf22588491333f7cf71135163", + "VELA_BUILD_CREATED": "1563474076", + "VELA_BUILD_DISTRIBUTION": "linux", + "VELA_BUILD_ENQUEUED": "1563474077", + "VELA_BUILD_EVENT": "deployment", + "VELA_BUILD_EVENT_ACTION": "", + "VELA_BUILD_HOST": "example.company.com", + "VELA_BUILD_LINK": "https://example.company.com/github/octocat/1", + "VELA_BUILD_MESSAGE": "First commit...", + "VELA_BUILD_NUMBER": "1", + "VELA_BUILD_PARENT": "1", + "VELA_BUILD_REF": "refs/tags/v0.1.0", + "VELA_BUILD_RUNTIME": "docker", + "VELA_BUILD_SENDER": "OctoKitty", + "VELA_BUILD_STARTED": "1563474078", + "VELA_BUILD_SOURCE": "https://github.com/github/octocat/48afb5bdc41ad69bf22588491333f7cf71135163", + "VELA_BUILD_STATUS": "running", + "VELA_BUILD_TAG": "v0.1.0", + "VELA_BUILD_TARGET": "production", + "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": "", + "BUILD_BRANCH": "main", + "BUILD_CHANNEL": "TODO", + "BUILD_CLONE": "https://github.com/github/octocat.git", + "BUILD_COMMIT": "48afb5bdc41ad69bf22588491333f7cf71135163", + "BUILD_CREATED": "1563474076", + "BUILD_ENQUEUED": "1563474077", + "BUILD_EVENT": "deployment", + "BUILD_HOST": "example.company.com", + "BUILD_LINK": "https://example.company.com/github/octocat/1", + "BUILD_MESSAGE": "First commit...", + "BUILD_NUMBER": "1", + "BUILD_PARENT": "1", + "BUILD_REF": "refs/tags/v0.1.0", + "BUILD_SENDER": "OctoKitty", + "BUILD_STARTED": "1563474078", + "BUILD_SOURCE": "https://github.com/github/octocat/48afb5bdc41ad69bf22588491333f7cf71135163", + "BUILD_STATUS": "running", + "BUILD_TAG": "v0.1.0", + "BUILD_TARGET": "production", + "BUILD_TITLE": "push received from https://github.com/github/octocat", + "BUILD_WORKSPACE": "TODO", + "DEPLOYMENT_PARAMETER_FOO": "test1", + "DEPLOYMENT_PARAMETER_BAR": "test2", + }, + }, + { + build: _pull, + want: map[string]string{ + "VELA_BUILD_APPROVED_AT": "1563474076", + "VELA_BUILD_APPROVED_BY": "OctoCat", + "VELA_BUILD_AUTHOR": "OctoKitty", + "VELA_BUILD_AUTHOR_EMAIL": "OctoKitty@github.com", + "VELA_BUILD_BASE_REF": "", + "VELA_BUILD_BRANCH": "main", + "VELA_BUILD_CHANNEL": "TODO", + "VELA_BUILD_CLONE": "https://github.com/github/octocat.git", + "VELA_BUILD_COMMIT": "48afb5bdc41ad69bf22588491333f7cf71135163", + "VELA_BUILD_CREATED": "1563474076", + "VELA_BUILD_DISTRIBUTION": "linux", + "VELA_BUILD_ENQUEUED": "1563474077", + "VELA_BUILD_EVENT": "pull_request", + "VELA_BUILD_EVENT_ACTION": "opened", + "VELA_BUILD_HOST": "example.company.com", + "VELA_BUILD_LINK": "https://example.company.com/github/octocat/1", + "VELA_BUILD_MESSAGE": "First commit...", + "VELA_BUILD_NUMBER": "1", + "VELA_BUILD_PARENT": "1", + "VELA_BUILD_PULL_REQUEST": "1", + "VELA_BUILD_REF": "refs/pulls/1/head", + "VELA_BUILD_RUNTIME": "docker", + "VELA_BUILD_SENDER": "OctoKitty", + "VELA_BUILD_STARTED": "1563474078", + "VELA_BUILD_SOURCE": "https://github.com/github/octocat/48afb5bdc41ad69bf22588491333f7cf71135163", + "VELA_BUILD_STATUS": "running", + "VELA_BUILD_TITLE": "push received from https://github.com/github/octocat", + "VELA_BUILD_WORKSPACE": "TODO", + "VELA_PULL_REQUEST": "1", + "VELA_PULL_REQUEST_SOURCE": "changes", + "VELA_PULL_REQUEST_TARGET": "", + "BUILD_AUTHOR": "OctoKitty", + "BUILD_AUTHOR_EMAIL": "OctoKitty@github.com", + "BUILD_BASE_REF": "", + "BUILD_BRANCH": "main", + "BUILD_CHANNEL": "TODO", + "BUILD_CLONE": "https://github.com/github/octocat.git", + "BUILD_COMMIT": "48afb5bdc41ad69bf22588491333f7cf71135163", + "BUILD_CREATED": "1563474076", + "BUILD_ENQUEUED": "1563474077", + "BUILD_EVENT": "pull_request", + "BUILD_HOST": "example.company.com", + "BUILD_LINK": "https://example.company.com/github/octocat/1", + "BUILD_MESSAGE": "First commit...", + "BUILD_NUMBER": "1", + "BUILD_PARENT": "1", + "BUILD_PULL_REQUEST_NUMBER": "1", + "BUILD_REF": "refs/pulls/1/head", + "BUILD_SENDER": "OctoKitty", + "BUILD_STARTED": "1563474078", + "BUILD_SOURCE": "https://github.com/github/octocat/48afb5bdc41ad69bf22588491333f7cf71135163", + "BUILD_STATUS": "running", + "BUILD_TITLE": "push received from https://github.com/github/octocat", + "BUILD_WORKSPACE": "TODO", + }, + }, + { + build: _tag, + want: map[string]string{ + "VELA_BUILD_APPROVED_AT": "1563474076", + "VELA_BUILD_APPROVED_BY": "OctoCat", + "VELA_BUILD_AUTHOR": "OctoKitty", + "VELA_BUILD_AUTHOR_EMAIL": "OctoKitty@github.com", + "VELA_BUILD_BASE_REF": "", + "VELA_BUILD_BRANCH": "main", + "VELA_BUILD_CHANNEL": "TODO", + "VELA_BUILD_CLONE": "https://github.com/github/octocat.git", + "VELA_BUILD_COMMIT": "48afb5bdc41ad69bf22588491333f7cf71135163", + "VELA_BUILD_CREATED": "1563474076", + "VELA_BUILD_DISTRIBUTION": "linux", + "VELA_BUILD_ENQUEUED": "1563474077", + "VELA_BUILD_EVENT": "tag", + "VELA_BUILD_EVENT_ACTION": "", + "VELA_BUILD_HOST": "example.company.com", + "VELA_BUILD_LINK": "https://example.company.com/github/octocat/1", + "VELA_BUILD_MESSAGE": "First commit...", + "VELA_BUILD_NUMBER": "1", + "VELA_BUILD_PARENT": "1", + "VELA_BUILD_REF": "refs/tags/v0.1.0", + "VELA_BUILD_RUNTIME": "docker", + "VELA_BUILD_SENDER": "OctoKitty", + "VELA_BUILD_STARTED": "1563474078", + "VELA_BUILD_SOURCE": "https://github.com/github/octocat/48afb5bdc41ad69bf22588491333f7cf71135163", + "VELA_BUILD_STATUS": "running", + "VELA_BUILD_TAG": "v0.1.0", + "VELA_BUILD_TITLE": "push received from https://github.com/github/octocat", + "VELA_BUILD_WORKSPACE": "TODO", + "BUILD_AUTHOR": "OctoKitty", + "BUILD_AUTHOR_EMAIL": "OctoKitty@github.com", + "BUILD_BASE_REF": "", + "BUILD_BRANCH": "main", + "BUILD_CHANNEL": "TODO", + "BUILD_CLONE": "https://github.com/github/octocat.git", + "BUILD_COMMIT": "48afb5bdc41ad69bf22588491333f7cf71135163", + "BUILD_CREATED": "1563474076", + "BUILD_ENQUEUED": "1563474077", + "BUILD_EVENT": "tag", + "BUILD_HOST": "example.company.com", + "BUILD_LINK": "https://example.company.com/github/octocat/1", + "BUILD_MESSAGE": "First commit...", + "BUILD_NUMBER": "1", + "BUILD_PARENT": "1", + "BUILD_REF": "refs/tags/v0.1.0", + "BUILD_SENDER": "OctoKitty", + "BUILD_STARTED": "1563474078", + "BUILD_SOURCE": "https://github.com/github/octocat/48afb5bdc41ad69bf22588491333f7cf71135163", + "BUILD_STATUS": "running", + "BUILD_TAG": "v0.1.0", + "BUILD_TITLE": "push received from https://github.com/github/octocat", + "BUILD_WORKSPACE": "TODO", + }, + }, + } + + // run test + for _, test := range tests { + got := test.build.Environment("TODO", "TODO") + + if diff := cmp.Diff(test.want, got); diff != "" { + t.Errorf("(Environment: -want +got):\n%s", diff) + } + } +} + +func TestTypes_Build_Getters(t *testing.T) { + // setup tests + tests := []struct { + build *Build + want *Build + }{ + { + build: testBuild(), + want: testBuild(), + }, + { + build: new(Build), + want: new(Build), + }, + } + + // run tests + for _, test := range tests { + if test.build.GetID() != test.want.GetID() { + t.Errorf("GetID is %v, want %v", test.build.GetID(), test.want.GetID()) + } + + if !reflect.DeepEqual(test.build.GetRepo(), test.want.GetRepo()) { + t.Errorf("GetRepo is %v, want %v", test.build.GetRepo(), test.want.GetRepo()) + } + + if test.build.GetPipelineID() != test.want.GetPipelineID() { + t.Errorf("GetPipelineID is %v, want %v", test.build.GetPipelineID(), test.want.GetPipelineID()) + } + + if test.build.GetNumber() != test.want.GetNumber() { + t.Errorf("GetNumber is %v, want %v", test.build.GetNumber(), test.want.GetNumber()) + } + + if test.build.GetParent() != test.want.GetParent() { + t.Errorf("GetParent is %v, want %v", test.build.GetParent(), test.want.GetParent()) + } + + if test.build.GetEvent() != test.want.GetEvent() { + t.Errorf("GetEvent is %v, want %v", test.build.GetEvent(), test.want.GetEvent()) + } + + if test.build.GetEventAction() != test.want.GetEventAction() { + t.Errorf("GetEventAction is %v, want %v", test.build.GetEventAction(), test.want.GetEventAction()) + } + + if test.build.GetStatus() != test.want.GetStatus() { + t.Errorf("GetStatus is %v, want %v", test.build.GetStatus(), test.want.GetStatus()) + } + + if test.build.GetError() != test.want.GetError() { + t.Errorf("GetError is %v, want %v", test.build.GetError(), test.want.GetError()) + } + + if test.build.GetEnqueued() != test.want.GetEnqueued() { + t.Errorf("GetEnqueued is %v, want %v", test.build.GetEnqueued(), test.want.GetEnqueued()) + } + + if test.build.GetCreated() != test.want.GetCreated() { + t.Errorf("GetCreated is %v, want %v", test.build.GetCreated(), test.want.GetCreated()) + } + + if test.build.GetStarted() != test.want.GetStarted() { + t.Errorf("GetStarted is %v, want %v", test.build.GetStarted(), test.want.GetStarted()) + } + + if test.build.GetFinished() != test.want.GetFinished() { + t.Errorf("GetFinished is %v, want %v", test.build.GetFinished(), test.want.GetFinished()) + } + + if test.build.GetDeploy() != test.want.GetDeploy() { + 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()) + } + + if test.build.GetClone() != test.want.GetClone() { + t.Errorf("GetClone is %v, want %v", test.build.GetClone(), test.want.GetClone()) + } + + if test.build.GetSource() != test.want.GetSource() { + t.Errorf("GetSource is %v, want %v", test.build.GetSource(), test.want.GetSource()) + } + + if test.build.GetTitle() != test.want.GetTitle() { + t.Errorf("GetTitle is %v, want %v", test.build.GetTitle(), test.want.GetTitle()) + } + + if test.build.GetMessage() != test.want.GetMessage() { + t.Errorf("GetMessage is %v, want %v", test.build.GetMessage(), test.want.GetMessage()) + } + + if test.build.GetCommit() != test.want.GetCommit() { + t.Errorf("GetCommit is %v, want %v", test.build.GetCommit(), test.want.GetCommit()) + } + + if test.build.GetSender() != test.want.GetSender() { + t.Errorf("GetSender is %v, want %v", test.build.GetSender(), test.want.GetSender()) + } + + if test.build.GetAuthor() != test.want.GetAuthor() { + t.Errorf("GetAuthor is %v, want %v", test.build.GetAuthor(), test.want.GetAuthor()) + } + + if test.build.GetEmail() != test.want.GetEmail() { + t.Errorf("GetEmail is %v, want %v", test.build.GetEmail(), test.want.GetEmail()) + } + + if test.build.GetLink() != test.want.GetLink() { + t.Errorf("GetLink is %v, want %v", test.build.GetLink(), test.want.GetLink()) + } + + if test.build.GetBranch() != test.want.GetBranch() { + t.Errorf("GetBranch is %v, want %v", test.build.GetBranch(), test.want.GetBranch()) + } + + if test.build.GetRef() != test.want.GetRef() { + t.Errorf("GetRef is %v, want %v", test.build.GetRef(), test.want.GetRef()) + } + + if test.build.GetBaseRef() != test.want.GetBaseRef() { + t.Errorf("GetBaseRef is %v, want %v", test.build.GetBaseRef(), test.want.GetBaseRef()) + } + + if test.build.GetHeadRef() != test.want.GetHeadRef() { + t.Errorf("GetHeadRef is %v, want %v", test.build.GetHeadRef(), test.want.GetHeadRef()) + } + + if test.build.GetHost() != test.want.GetHost() { + t.Errorf("GetHost is %v, want %v", test.build.GetHost(), test.want.GetHost()) + } + + if test.build.GetRuntime() != test.want.GetRuntime() { + t.Errorf("GetRuntime is %v, want %v", test.build.GetRuntime(), test.want.GetRuntime()) + } + + if test.build.GetDistribution() != test.want.GetDistribution() { + t.Errorf("GetDistribution is %v, want %v", test.build.GetDistribution(), test.want.GetDistribution()) + } + + if test.build.GetApprovedAt() != test.want.GetApprovedAt() { + t.Errorf("GetApprovedAt is %v, want %v", test.build.GetApprovedAt(), test.want.GetApprovedAt()) + } + + if test.build.GetApprovedBy() != test.want.GetApprovedBy() { + t.Errorf("GetApprovedBy is %v, want %v", test.build.GetApprovedBy(), test.want.GetApprovedBy()) + } + } +} + +func TestTypes_Build_Setters(t *testing.T) { + // setup types + var b *Build + + // setup tests + tests := []struct { + build *Build + want *Build + }{ + { + build: testBuild(), + want: testBuild(), + }, + { + build: b, + want: new(Build), + }, + } + + // run tests + for _, test := range tests { + test.build.SetID(test.want.GetID()) + test.build.SetRepo(test.want.GetRepo()) + test.build.SetPipelineID(test.want.GetPipelineID()) + test.build.SetNumber(test.want.GetNumber()) + test.build.SetParent(test.want.GetParent()) + test.build.SetEvent(test.want.GetEvent()) + test.build.SetEventAction(test.want.GetEventAction()) + test.build.SetStatus(test.want.GetStatus()) + test.build.SetError(test.want.GetError()) + test.build.SetEnqueued(test.want.GetEnqueued()) + test.build.SetCreated(test.want.GetCreated()) + 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()) + test.build.SetTitle(test.want.GetTitle()) + test.build.SetMessage(test.want.GetMessage()) + test.build.SetCommit(test.want.GetCommit()) + test.build.SetSender(test.want.GetSender()) + test.build.SetAuthor(test.want.GetAuthor()) + test.build.SetEmail(test.want.GetEmail()) + test.build.SetLink(test.want.GetLink()) + test.build.SetBranch(test.want.GetBranch()) + test.build.SetRef(test.want.GetRef()) + test.build.SetBaseRef(test.want.GetBaseRef()) + test.build.SetHeadRef(test.want.GetHeadRef()) + test.build.SetHost(test.want.GetHost()) + test.build.SetRuntime(test.want.GetRuntime()) + test.build.SetDistribution(test.want.GetDistribution()) + test.build.SetApprovedAt(test.want.GetApprovedAt()) + test.build.SetApprovedBy(test.want.GetApprovedBy()) + + if test.build.GetID() != test.want.GetID() { + t.Errorf("SetID is %v, want %v", test.build.GetID(), test.want.GetID()) + } + + if !reflect.DeepEqual(test.build.GetRepo(), test.want.GetRepo()) { + t.Errorf("SetRepo is %v, want %v", test.build.GetRepo(), test.want.GetRepo()) + } + + if test.build.GetPipelineID() != test.want.GetPipelineID() { + t.Errorf("SetPipelineID is %v, want %v", test.build.GetPipelineID(), test.want.GetPipelineID()) + } + + if test.build.GetNumber() != test.want.GetNumber() { + t.Errorf("SetNumber is %v, want %v", test.build.GetNumber(), test.want.GetNumber()) + } + + if test.build.GetParent() != test.want.GetParent() { + t.Errorf("SetParent is %v, want %v", test.build.GetParent(), test.want.GetParent()) + } + + if test.build.GetEvent() != test.want.GetEvent() { + t.Errorf("SetEvent is %v, want %v", test.build.GetEvent(), test.want.GetEvent()) + } + + if test.build.GetEventAction() != test.want.GetEventAction() { + t.Errorf("SetEventAction is %v, want %v", test.build.GetEventAction(), test.want.GetEventAction()) + } + + if test.build.GetStatus() != test.want.GetStatus() { + t.Errorf("SetStatus is %v, want %v", test.build.GetStatus(), test.want.GetStatus()) + } + + if test.build.GetError() != test.want.GetError() { + t.Errorf("SetError is %v, want %v", test.build.GetError(), test.want.GetError()) + } + + if test.build.GetEnqueued() != test.want.GetEnqueued() { + t.Errorf("SetEnqueued is %v, want %v", test.build.GetEnqueued(), test.want.GetEnqueued()) + } + + if test.build.GetCreated() != test.want.GetCreated() { + t.Errorf("SetCreated is %v, want %v", test.build.GetCreated(), test.want.GetCreated()) + } + + if test.build.GetStarted() != test.want.GetStarted() { + t.Errorf("SetStarted is %v, want %v", test.build.GetStarted(), test.want.GetStarted()) + } + + if test.build.GetFinished() != test.want.GetFinished() { + t.Errorf("SetFinished is %v, want %v", test.build.GetFinished(), test.want.GetFinished()) + } + + if test.build.GetDeploy() != test.want.GetDeploy() { + 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()) + } + + if test.build.GetClone() != test.want.GetClone() { + t.Errorf("SetClone is %v, want %v", test.build.GetClone(), test.want.GetClone()) + } + + if test.build.GetSource() != test.want.GetSource() { + t.Errorf("SetSource is %v, want %v", test.build.GetSource(), test.want.GetSource()) + } + + if test.build.GetTitle() != test.want.GetTitle() { + t.Errorf("SetTitle is %v, want %v", test.build.GetTitle(), test.want.GetTitle()) + } + + if test.build.GetMessage() != test.want.GetMessage() { + t.Errorf("SetMessage is %v, want %v", test.build.GetMessage(), test.want.GetMessage()) + } + + if test.build.GetCommit() != test.want.GetCommit() { + t.Errorf("SetCommit is %v, want %v", test.build.GetCommit(), test.want.GetCommit()) + } + + if test.build.GetSender() != test.want.GetSender() { + t.Errorf("SetSender is %v, want %v", test.build.GetSender(), test.want.GetSender()) + } + + if test.build.GetAuthor() != test.want.GetAuthor() { + t.Errorf("SetAuthor is %v, want %v", test.build.GetAuthor(), test.want.GetAuthor()) + } + + if test.build.GetEmail() != test.want.GetEmail() { + t.Errorf("SetEmail is %v, want %v", test.build.GetEmail(), test.want.GetEmail()) + } + + if test.build.GetLink() != test.want.GetLink() { + t.Errorf("SetLink is %v, want %v", test.build.GetLink(), test.want.GetLink()) + } + + if test.build.GetBranch() != test.want.GetBranch() { + t.Errorf("SetBranch is %v, want %v", test.build.GetBranch(), test.want.GetBranch()) + } + + if test.build.GetRef() != test.want.GetRef() { + t.Errorf("SetRef is %v, want %v", test.build.GetRef(), test.want.GetRef()) + } + + if test.build.GetBaseRef() != test.want.GetBaseRef() { + t.Errorf("SetBaseRef is %v, want %v", test.build.GetBaseRef(), test.want.GetBaseRef()) + } + + if test.build.GetHeadRef() != test.want.GetHeadRef() { + t.Errorf("SetHeadRef is %v, want %v", test.build.GetHeadRef(), test.want.GetHeadRef()) + } + + if test.build.GetHost() != test.want.GetHost() { + t.Errorf("SetHost is %v, want %v", test.build.GetHost(), test.want.GetHost()) + } + + if test.build.GetRuntime() != test.want.GetRuntime() { + t.Errorf("SetRuntime is %v, want %v", test.build.GetRuntime(), test.want.GetRuntime()) + } + + if test.build.GetDistribution() != test.want.GetDistribution() { + t.Errorf("SetDistribution is %v, want %v", test.build.GetDistribution(), test.want.GetDistribution()) + } + + if test.build.GetApprovedAt() != test.want.GetApprovedAt() { + t.Errorf("SetApprovedAt is %v, want %v", test.build.GetApprovedAt(), test.want.GetApprovedAt()) + } + + if test.build.GetApprovedBy() != test.want.GetApprovedBy() { + t.Errorf("SetApprovedBy is %v, want %v", test.build.GetApprovedBy(), test.want.GetApprovedBy()) + } + } +} + +func TestTypes_Build_String(t *testing.T) { + // setup types + b := testBuild() + + want := fmt.Sprintf(`{ + ApprovedAt: %d, + ApprovedBy: %s, + Author: %s, + BaseRef: %s, + Branch: %s, + Clone: %s, + Commit: %s, + Created: %d, + Deploy: %s, + DeployNumber: %d, + DeployPayload: %s, + Distribution: %s, + Email: %s, + Enqueued: %d, + Error: %s, + Event: %s, + EventAction: %s, + Finished: %d, + HeadRef: %s, + Host: %s, + ID: %d, + Link: %s, + Message: %s, + Number: %d, + Parent: %d, + PipelineID: %d, + Ref: %s, + Repo: %s, + Runtime: %s, + Sender: %s, + Source: %s, + Started: %d, + Status: %s, + Title: %s, +}`, + b.GetApprovedAt(), + b.GetApprovedBy(), + b.GetAuthor(), + b.GetBaseRef(), + b.GetBranch(), + b.GetClone(), + b.GetCommit(), + b.GetCreated(), + b.GetDeploy(), + b.GetDeployNumber(), + b.GetDeployPayload(), + b.GetDistribution(), + b.GetEmail(), + b.GetEnqueued(), + b.GetError(), + b.GetEvent(), + b.GetEventAction(), + b.GetFinished(), + b.GetHeadRef(), + b.GetHost(), + b.GetID(), + b.GetLink(), + b.GetMessage(), + b.GetNumber(), + b.GetParent(), + b.GetPipelineID(), + b.GetRef(), + b.GetRepo().GetFullName(), + b.GetRuntime(), + b.GetSender(), + b.GetSource(), + b.GetStarted(), + b.GetStatus(), + b.GetTitle(), + ) + + // run test + got := b.String() + + if !reflect.DeepEqual(got, want) { + t.Errorf("String is %v, want %v", got, want) + } +} + +// testBuild is a test helper function to create a Build +// type with all fields set to a fake value. +func testBuild() *Build { + b := new(Build) + + b.SetID(1) + b.SetRepo(testRepo()) + b.SetPipelineID(1) + b.SetNumber(1) + b.SetParent(1) + b.SetEvent("push") + b.SetStatus("running") + b.SetError("") + b.SetEnqueued(1563474077) + b.SetCreated(1563474076) + 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") + b.SetTitle("push received from https://github.com/github/octocat") + b.SetMessage("First commit...") + b.SetCommit("48afb5bdc41ad69bf22588491333f7cf71135163") + b.SetSender("OctoKitty") + b.SetAuthor("OctoKitty") + b.SetEmail("OctoKitty@github.com") + b.SetLink("https://example.company.com/github/octocat/1") + b.SetBranch("main") + b.SetRef("refs/heads/main") + b.SetBaseRef("") + b.SetHeadRef("changes") + b.SetHost("example.company.com") + b.SetRuntime("docker") + b.SetDistribution("linux") + b.SetApprovedAt(1563474076) + b.SetApprovedBy("OctoCat") + + return b +} diff --git a/api/types/executor.go b/api/types/executor.go index 706862f24..45bbfce2e 100644 --- a/api/types/executor.go +++ b/api/types/executor.go @@ -6,7 +6,6 @@ import ( "fmt" "strings" - "github.com/go-vela/types/library" "github.com/go-vela/types/pipeline" ) @@ -18,8 +17,7 @@ type Executor struct { Host *string `json:"host,omitempty"` Runtime *string `json:"runtime,omitempty"` Distribution *string `json:"distribution,omitempty"` - Build *library.Build `json:"build,omitempty"` - Repo *Repo `json:"repo,omitempty"` + Build *Build `json:"build,omitempty"` Pipeline *pipeline.Build `json:"pipeline,omitempty"` } @@ -79,28 +77,15 @@ func (e *Executor) GetDistribution() string { // // When the provided Executor type is nil, or the field within // the type is nil, it returns the zero value for the field. -func (e *Executor) GetBuild() library.Build { +func (e *Executor) GetBuild() Build { // return zero value if Executor type or Build field is nil if e == nil || e.Build == nil { - return library.Build{} + return Build{} } return *e.Build } -// GetRepo returns the Repo field. -// -// When the provided Executor type is nil, or the field within -// the type is nil, it returns the zero value for the field. -func (e *Executor) GetRepo() Repo { - // return zero value if Executor type or Repo field is nil - if e == nil || e.Repo == nil { - return Repo{} - } - - return *e.Repo -} - // GetPipeline returns the Pipeline field. // // When the provided Executor type is nil, or the field within @@ -170,7 +155,7 @@ func (e *Executor) SetDistribution(v string) { // // When the provided Executor type is nil, it // will set nothing and immediately return. -func (e *Executor) SetBuild(v library.Build) { +func (e *Executor) SetBuild(v Build) { // return if Executor type is nil if e == nil { return @@ -179,19 +164,6 @@ func (e *Executor) SetBuild(v library.Build) { e.Build = &v } -// SetRepo sets the Repo field. -// -// When the provided Executor type is nil, it -// will set nothing and immediately return. -func (e *Executor) SetRepo(v Repo) { - // return if Executor type is nil - if e == nil { - return - } - - e.Repo = &v -} - // SetPipeline sets the pipeline Build field. // // When the provided Executor type is nil, it @@ -212,7 +184,6 @@ func (e *Executor) String() string { Distribution: %s, Host: %s, ID: %d, - Repo: %v, Runtime: %s, Pipeline: %v, }`, @@ -220,7 +191,6 @@ func (e *Executor) String() string { e.GetDistribution(), e.GetHost(), e.GetID(), - strings.ReplaceAll(e.Repo.String(), " ", " "), e.GetRuntime(), e.GetPipeline(), ) diff --git a/api/types/executor_test.go b/api/types/executor_test.go index 72dbac4e4..e47472b8a 100644 --- a/api/types/executor_test.go +++ b/api/types/executor_test.go @@ -8,9 +8,7 @@ import ( "strings" "testing" - "github.com/go-vela/types/library" "github.com/go-vela/types/pipeline" - "github.com/go-vela/types/raw" ) func TestTypes_Executor_Getters(t *testing.T) { @@ -51,10 +49,6 @@ func TestTypes_Executor_Getters(t *testing.T) { t.Errorf("GetBuild is %v, want %v", test.executor.GetBuild(), test.want.GetBuild()) } - if !reflect.DeepEqual(test.executor.GetRepo(), test.want.GetRepo()) { - t.Errorf("GetRepo is %v, want %v", test.executor.GetRepo(), test.want.GetRepo()) - } - if !reflect.DeepEqual(test.executor.GetPipeline(), test.want.GetPipeline()) { t.Errorf("GetPipeline is %v, want %v", test.executor.GetPipeline(), test.want.GetPipeline()) } @@ -87,7 +81,6 @@ func TestTypes_Executor_Setters(t *testing.T) { test.executor.SetRuntime(test.want.GetRuntime()) test.executor.SetDistribution(test.want.GetDistribution()) test.executor.SetBuild(test.want.GetBuild()) - test.executor.SetRepo(test.want.GetRepo()) test.executor.SetPipeline(test.want.GetPipeline()) if test.executor.GetID() != test.want.GetID() { @@ -110,10 +103,6 @@ func TestTypes_Executor_Setters(t *testing.T) { t.Errorf("SetBuild is %v, want %v", test.executor.GetBuild(), test.want.GetBuild()) } - if !reflect.DeepEqual(test.executor.GetRepo(), test.want.GetRepo()) { - t.Errorf("SetRepo is %v, want %v", test.executor.GetRepo(), test.want.GetRepo()) - } - if !reflect.DeepEqual(test.executor.GetPipeline(), test.want.GetPipeline()) { t.Errorf("SetPipeline is %v, want %v", test.executor.GetPipeline(), test.want.GetPipeline()) } @@ -129,7 +118,6 @@ func TestTypes_Executor_String(t *testing.T) { Distribution: %s, Host: %s, ID: %d, - Repo: %v, Runtime: %s, Pipeline: %v, }`, @@ -137,7 +125,6 @@ func TestTypes_Executor_String(t *testing.T) { e.GetDistribution(), e.GetHost(), e.GetID(), - strings.ReplaceAll(e.Repo.String(), " ", " "), e.GetRuntime(), e.GetPipeline(), ) @@ -160,7 +147,6 @@ func testExecutor() *Executor { e.SetRuntime("docker") e.SetDistribution("linux") e.SetBuild(*testBuild()) - e.SetRepo(*testRepo()) e.SetPipeline(pipeline.Build{ Version: "1", ID: "github_octocat_1", @@ -195,47 +181,3 @@ func testExecutor() *Executor { return e } - -// testBuild is a test helper function to create a Build -// type with all fields set to a fake value. -// -// TODO: remove this function once the Build type is moved to server. -func testBuild() *library.Build { - b := new(library.Build) - - b.SetID(1) - b.SetRepoID(1) - b.SetPipelineID(1) - b.SetNumber(1) - b.SetParent(1) - b.SetEvent("push") - b.SetStatus("running") - b.SetError("") - b.SetEnqueued(1563474077) - b.SetCreated(1563474076) - 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") - b.SetTitle("push received from https://github.com/github/octocat") - b.SetMessage("First commit...") - b.SetCommit("48afb5bdc41ad69bf22588491333f7cf71135163") - b.SetSender("OctoKitty") - b.SetAuthor("OctoKitty") - b.SetEmail("OctoKitty@github.com") - b.SetLink("https://example.company.com/github/octocat/1") - b.SetBranch("main") - b.SetRef("refs/heads/main") - b.SetBaseRef("") - b.SetHeadRef("changes") - b.SetHost("example.company.com") - b.SetRuntime("docker") - b.SetDistribution("linux") - b.SetApprovedAt(1563474076) - b.SetApprovedBy("OctoCat") - - return b -} diff --git a/api/types/queue_build.go b/api/types/queue_build.go new file mode 100644 index 000000000..8b39c3bc7 --- /dev/null +++ b/api/types/queue_build.go @@ -0,0 +1,134 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import "fmt" + +// QueueBuild is the API representation of the builds in the queue. +// +// swagger:model QueueBuild +type QueueBuild struct { + Status *string `json:"status,omitempty"` + Number *int32 `json:"number,omitempty"` + Created *int64 `json:"created,omitempty"` + FullName *string `json:"full_name,omitempty"` +} + +// GetStatus returns the Status field. +// +// When the provided QueueBuild type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (b *QueueBuild) GetStatus() string { + // return zero value if QueueBuild type or Status field is nil + if b == nil || b.Status == nil { + return "" + } + + return *b.Status +} + +// GetNumber returns the Number field. +// +// When the provided QueueBuild type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (b *QueueBuild) GetNumber() int32 { + // return zero value if QueueBuild type or Number field is nil + if b == nil || b.Number == nil { + return 0 + } + + return *b.Number +} + +// GetCreated returns the Created field. +// +// When the provided QueueBuild type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (b *QueueBuild) GetCreated() int64 { + // return zero value if QueueBuild type or Created field is nil + if b == nil || b.Created == nil { + return 0 + } + + return *b.Created +} + +// GetFullName returns the FullName field. +// +// When the provided QueueBuild type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (b *QueueBuild) GetFullName() string { + // return zero value if QueueBuild type or FullName field is nil + if b == nil || b.FullName == nil { + return "" + } + + return *b.FullName +} + +// SetStatus sets the Status field. +// +// When the provided QueueBuild type is nil, it +// will set nothing and immediately return. +func (b *QueueBuild) SetStatus(v string) { + // return if QueueBuild type is nil + if b == nil { + return + } + + b.Status = &v +} + +// SetNumber sets the Number field. +// +// When the provided QueueBuild type is nil, it +// will set nothing and immediately return. +func (b *QueueBuild) SetNumber(v int32) { + // return if QueueBuild type is nil + if b == nil { + return + } + + b.Number = &v +} + +// SetCreated sets the Created field. +// +// When the provided QueueBuild type is nil, it +// will set nothing and immediately return. +func (b *QueueBuild) SetCreated(v int64) { + // return if QueueBuild type is nil + if b == nil { + return + } + + b.Created = &v +} + +// SetFullName sets the FullName field. +// +// When the provided QueueBuild type is nil, it +// will set nothing and immediately return. +func (b *QueueBuild) SetFullName(v string) { + // return if QueueBuild type is nil + if b == nil { + return + } + + b.FullName = &v +} + +// String implements the Stringer interface for the QueueBuild type. +func (b *QueueBuild) String() string { + return fmt.Sprintf(`{ + Created: %d, + FullName: %s, + Number: %d, + Status: %s, +}`, + b.GetCreated(), + b.GetFullName(), + b.GetNumber(), + b.GetStatus(), + ) +} diff --git a/api/types/queue_build_test.go b/api/types/queue_build_test.go new file mode 100644 index 000000000..6351b8624 --- /dev/null +++ b/api/types/queue_build_test.go @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "fmt" + "reflect" + "testing" +) + +func TestTypes_QueueBuild_Getters(t *testing.T) { + // setup tests + tests := []struct { + buildQueue *QueueBuild + want *QueueBuild + }{ + { + buildQueue: testQueueBuild(), + want: testQueueBuild(), + }, + { + buildQueue: new(QueueBuild), + want: new(QueueBuild), + }, + } + + // run tests + for _, test := range tests { + if test.buildQueue.GetNumber() != test.want.GetNumber() { + t.Errorf("GetNumber is %v, want %v", test.buildQueue.GetNumber(), test.want.GetNumber()) + } + + if test.buildQueue.GetStatus() != test.want.GetStatus() { + t.Errorf("GetStatus is %v, want %v", test.buildQueue.GetStatus(), test.want.GetStatus()) + } + + if test.buildQueue.GetCreated() != test.want.GetCreated() { + t.Errorf("GetCreated is %v, want %v", test.buildQueue.GetCreated(), test.want.GetCreated()) + } + + if test.buildQueue.GetFullName() != test.want.GetFullName() { + t.Errorf("GetFullName is %v, want %v", test.buildQueue.GetFullName(), test.want.GetFullName()) + } + } +} + +func TestTypes_QueueBuild_Setters(t *testing.T) { + // setup types + var b *QueueBuild + + // setup tests + tests := []struct { + buildQueue *QueueBuild + want *QueueBuild + }{ + { + buildQueue: testQueueBuild(), + want: testQueueBuild(), + }, + { + buildQueue: b, + want: new(QueueBuild), + }, + } + + // run tests + for _, test := range tests { + test.buildQueue.SetNumber(test.want.GetNumber()) + test.buildQueue.SetStatus(test.want.GetStatus()) + test.buildQueue.SetCreated(test.want.GetCreated()) + test.buildQueue.SetFullName(test.want.GetFullName()) + + if test.buildQueue.GetNumber() != test.want.GetNumber() { + t.Errorf("SetNumber is %v, want %v", test.buildQueue.GetNumber(), test.want.GetNumber()) + } + + if test.buildQueue.GetStatus() != test.want.GetStatus() { + t.Errorf("SetStatus is %v, want %v", test.buildQueue.GetStatus(), test.want.GetStatus()) + } + + if test.buildQueue.GetCreated() != test.want.GetCreated() { + t.Errorf("SetCreated is %v, want %v", test.buildQueue.GetCreated(), test.want.GetCreated()) + } + + if test.buildQueue.GetFullName() != test.want.GetFullName() { + t.Errorf("SetFullName is %v, want %v", test.buildQueue.GetFullName(), test.want.GetFullName()) + } + } +} + +func TestTypes_QueueBuild_String(t *testing.T) { + // setup types + b := testQueueBuild() + + want := fmt.Sprintf(`{ + Created: %d, + FullName: %s, + Number: %d, + Status: %s, +}`, + b.GetCreated(), + b.GetFullName(), + b.GetNumber(), + b.GetStatus(), + ) + + // run test + got := b.String() + + if !reflect.DeepEqual(got, want) { + t.Errorf("String is %v, want %v", got, want) + } +} + +// testQueueBuild is a test helper function to create a QueueBuild +// type with all fields set to a fake value. +func testQueueBuild() *QueueBuild { + b := new(QueueBuild) + + b.SetNumber(1) + b.SetStatus("running") + b.SetCreated(1563474076) + b.SetFullName("github/octocat") + + return b +} diff --git a/api/types/repo_test.go b/api/types/repo_test.go index c632b471d..2cbe84639 100644 --- a/api/types/repo_test.go +++ b/api/types/repo_test.go @@ -342,12 +342,8 @@ func testRepo() *Repo { e, _ := testEvents() - owner := new(User) - owner.SetID(1) - owner.SetName("octocat") - r.SetID(1) - r.SetOwner(owner) + r.SetOwner(testUser()) r.SetOrg("github") r.SetName("octocat") r.SetFullName("github/octocat") diff --git a/api/types/worker.go b/api/types/worker.go index 4c06a0e69..af001fa80 100644 --- a/api/types/worker.go +++ b/api/types/worker.go @@ -4,26 +4,24 @@ package types import ( "fmt" - - "github.com/go-vela/types/library" ) // Worker is the API representation of a worker. // // swagger:model Worker type Worker struct { - ID *int64 `json:"id,omitempty"` - Hostname *string `json:"hostname,omitempty"` - Address *string `json:"address,omitempty"` - Routes *[]string `json:"routes,omitempty"` - Active *bool `json:"active,omitempty"` - Status *string `json:"status,omitempty"` - LastStatusUpdateAt *int64 `json:"last_status_update_at,omitempty"` - RunningBuilds *[]*library.Build `json:"running_builds,omitempty"` - LastBuildStartedAt *int64 `json:"last_build_started_at,omitempty"` - LastBuildFinishedAt *int64 `json:"last_build_finished_at,omitempty"` - LastCheckedIn *int64 `json:"last_checked_in,omitempty"` - BuildLimit *int64 `json:"build_limit,omitempty"` + ID *int64 `json:"id,omitempty"` + Hostname *string `json:"hostname,omitempty"` + Address *string `json:"address,omitempty"` + Routes *[]string `json:"routes,omitempty"` + Active *bool `json:"active,omitempty"` + Status *string `json:"status,omitempty"` + LastStatusUpdateAt *int64 `json:"last_status_update_at,omitempty"` + RunningBuilds *[]*Build `json:"running_builds,omitempty"` + LastBuildStartedAt *int64 `json:"last_build_started_at,omitempty"` + LastBuildFinishedAt *int64 `json:"last_build_finished_at,omitempty"` + LastCheckedIn *int64 `json:"last_checked_in,omitempty"` + BuildLimit *int64 `json:"build_limit,omitempty"` } // GetID returns the ID field. @@ -121,10 +119,10 @@ func (w *Worker) GetLastStatusUpdateAt() int64 { // // When the provided Worker type is nil, or the field within // the type is nil, it returns the zero value for the field. -func (w *Worker) GetRunningBuilds() []*library.Build { +func (w *Worker) GetRunningBuilds() []*Build { // return zero value if Worker type or RunningBuilds field is nil if w == nil || w.RunningBuilds == nil { - return []*library.Build{} + return []*Build{} } return *w.RunningBuilds @@ -277,7 +275,7 @@ func (w *Worker) SetLastStatusUpdateAt(v int64) { // // When the provided Worker type is nil, it // will set nothing and immediately return. -func (w *Worker) SetRunningBuilds(builds []*library.Build) { +func (w *Worker) SetRunningBuilds(builds []*Build) { // return if Worker type is nil if w == nil { return diff --git a/api/types/worker_test.go b/api/types/worker_test.go index b1cc06fdb..633b7163d 100644 --- a/api/types/worker_test.go +++ b/api/types/worker_test.go @@ -7,8 +7,6 @@ import ( "reflect" "testing" "time" - - "github.com/go-vela/types/library" ) func TestTypes_Worker_Getters(t *testing.T) { @@ -202,7 +200,7 @@ func TestTypes_Worker_String(t *testing.T) { // testWorker is a test helper function to create a Worker // type with all fields set to a fake value. func testWorker() *Worker { - b := new(library.Build) + b := new(Build) b.SetID(1) w := new(Worker) @@ -214,7 +212,7 @@ func testWorker() *Worker { w.SetActive(true) w.SetStatus("available") w.SetLastStatusUpdateAt(time.Time{}.UTC().Unix()) - w.SetRunningBuilds([]*library.Build{b}) + w.SetRunningBuilds([]*Build{b}) w.SetLastBuildStartedAt(time.Time{}.UTC().Unix()) w.SetLastBuildFinishedAt(time.Time{}.UTC().Unix()) w.SetLastCheckedIn(time.Time{}.UTC().Unix()) diff --git a/api/webhook/post.go b/api/webhook/post.go index 8f6ef750e..20600d525 100644 --- a/api/webhook/post.go +++ b/api/webhook/post.go @@ -208,7 +208,7 @@ func PostWebhook(c *gin.Context) { } // set the RepoID fields - b.SetRepoID(repo.GetID()) + b.SetRepo(repo) h.SetRepoID(repo.GetID()) // send API call to capture the last hook for the repo @@ -299,7 +299,6 @@ func PostWebhook(c *gin.Context) { // construct CompileAndPublishConfig config := build.CompileAndPublishConfig{ Build: b, - Repo: repo, Metadata: m, BaseErr: baseErr, Source: "webhook", @@ -338,7 +337,7 @@ func PostWebhook(c *gin.Context) { } // capture the build and repo from the items - b, repo = item.Build, item.Repo + b = item.Build // set hook build_id to the generated build id h.SetBuildID(b.GetID()) @@ -351,7 +350,7 @@ func PostWebhook(c *gin.Context) { deployment := webhook.Deployment deployment.SetRepoID(repo.GetID()) - deployment.SetBuilds([]*library.Build{b}) + deployment.SetBuilds([]*library.Build{b.ToLibrary()}) _, err := database.FromContext(c).CreateDeployment(c, deployment) if err != nil { @@ -373,8 +372,10 @@ func PostWebhook(c *gin.Context) { return } } else { - build := append(d.GetBuilds(), b) + build := append(d.GetBuilds(), b.ToLibrary()) + d.SetBuilds(build) + _, err := database.FromContext(c).UpdateDeployment(ctx, d) if err != nil { retErr := fmt.Errorf("%s: failed to update deployment %s/%d: %w", baseErr, repo.GetFullName(), d.GetNumber(), err) @@ -401,7 +402,7 @@ func PostWebhook(c *gin.Context) { for _, rB := range rBs { // call auto cancel routine - canceled, err := build.AutoCancel(c, b, rB, repo, p.Metadata.AutoCancel) + canceled, err := build.AutoCancel(c, b, rB, p.Metadata.AutoCancel) if err != nil { // continue cancel loop if error, but log based on type of error if canceled { @@ -650,7 +651,7 @@ func RenameRepository(ctx context.Context, h *library.Hook, r *types.Repo, c *gi return nil, fmt.Errorf("unable to get build count for repo %s: %w", dbR.GetFullName(), err) } - builds := []*library.Build{} + builds := []*types.Build{} page = 1 // capture all builds belonging to repo in database for build := int64(0); build < t; build += 100 { @@ -701,7 +702,7 @@ func RenameRepository(ctx context.Context, h *library.Hook, r *types.Repo, c *gi // gatekeepBuild is a helper function that will set the status of a build to 'pending approval' and // send a status update to the SCM. -func gatekeepBuild(c *gin.Context, b *library.Build, r *types.Repo) error { +func gatekeepBuild(c *gin.Context, b *types.Build, r *types.Repo) error { logrus.Debugf("fork PR build %s/%d waiting for approval", r.GetFullName(), b.GetNumber()) b.SetStatus(constants.StatusPendingApproval) diff --git a/api/worker/get.go b/api/worker/get.go index ab277514f..64ce34173 100644 --- a/api/worker/get.go +++ b/api/worker/get.go @@ -9,11 +9,11 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/router/middleware/worker" "github.com/go-vela/server/util" - "github.com/go-vela/types/library" ) // swagger:operation GET /api/v1/workers/{worker} workers GetWorker @@ -57,7 +57,7 @@ func GetWorker(c *gin.Context) { "worker": w.GetHostname(), }).Infof("reading worker %s", w.GetHostname()) - rBs := []*library.Build{} + rBs := []*types.Build{} for _, b := range w.GetRunningBuilds() { build, err := database.FromContext(c).GetBuild(ctx, b.GetID()) diff --git a/api/worker/list.go b/api/worker/list.go index 656745efa..5141335ba 100644 --- a/api/worker/list.go +++ b/api/worker/list.go @@ -11,10 +11,10 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/go-vela/types/library" ) // swagger:operation GET /api/v1/workers workers ListWorkers @@ -98,7 +98,7 @@ func ListWorkers(c *gin.Context) { } for _, w := range workers { - rBs := []*library.Build{} + rBs := []*types.Build{} for _, b := range w.GetRunningBuilds() { build, err := database.FromContext(c).GetBuild(ctx, b.GetID()) diff --git a/cmd/vela-server/schedule.go b/cmd/vela-server/schedule.go index d069b05a4..ee4a32acd 100644 --- a/cmd/vela-server/schedule.go +++ b/cmd/vela-server/schedule.go @@ -13,6 +13,7 @@ import ( "k8s.io/apimachinery/pkg/util/wait" "github.com/go-vela/server/api/build" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/compiler" "github.com/go-vela/server/database" "github.com/go-vela/server/internal" @@ -155,7 +156,7 @@ func processSchedule(ctx context.Context, s *library.Schedule, compiler compiler url := strings.TrimSuffix(r.GetClone(), ".git") - b := new(library.Build) + b := new(api.Build) b.SetAuthor(s.GetCreatedBy()) b.SetBranch(s.GetBranch()) b.SetClone(r.GetClone()) @@ -163,7 +164,7 @@ func processSchedule(ctx context.Context, s *library.Schedule, compiler compiler b.SetEvent(constants.EventSchedule) b.SetMessage(fmt.Sprintf("triggered for %s schedule with %s entry", s.GetName(), s.GetEntry())) b.SetRef(fmt.Sprintf("refs/heads/%s", b.GetBranch())) - b.SetRepoID(r.GetID()) + b.SetRepo(r) b.SetSender(s.GetUpdatedBy()) b.SetSource(fmt.Sprintf("%s/tree/%s", url, b.GetBranch())) b.SetStatus(constants.StatusPending) @@ -172,7 +173,6 @@ func processSchedule(ctx context.Context, s *library.Schedule, compiler compiler // schedule form config := build.CompileAndPublishConfig{ Build: b, - Repo: r, Metadata: metadata, BaseErr: "unable to schedule build", Source: "schedule", diff --git a/compiler/engine.go b/compiler/engine.go index 137d9000a..3079148d4 100644 --- a/compiler/engine.go +++ b/compiler/engine.go @@ -116,7 +116,7 @@ type Engine interface { // WithBuild defines a function that sets // the library build type in the Engine. - WithBuild(*library.Build) Engine + WithBuild(*api.Build) Engine // WithComment defines a function that sets // the comment in the Engine. WithComment(string) Engine diff --git a/compiler/native/compile.go b/compiler/native/compile.go index d5cb1d49b..c33035149 100644 --- a/compiler/native/compile.go +++ b/compiler/native/compile.go @@ -498,7 +498,7 @@ func errorHandler(resp *http.Response, err error, attempts int) (*http.Response, } // modifyConfig sends the configuration to external http endpoint for modification. -func (c *client) modifyConfig(build *yaml.Build, libraryBuild *library.Build, repo *api.Repo) (*yaml.Build, error) { +func (c *client) modifyConfig(build *yaml.Build, libraryBuild *api.Build, repo *api.Repo) (*yaml.Build, error) { // create request to send to endpoint data, err := yml.Marshal(build) if err != nil { diff --git a/compiler/native/compile_test.go b/compiler/native/compile_test.go index 86db5f595..ed9563045 100644 --- a/compiler/native/compile_test.go +++ b/compiler/native/compile_test.go @@ -21,7 +21,6 @@ import ( api "github.com/go-vela/server/api/types" "github.com/go-vela/server/internal" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" "github.com/go-vela/types/pipeline" "github.com/go-vela/types/raw" "github.com/go-vela/types/yaml" @@ -302,7 +301,7 @@ func TestNative_Compile_StagesPipeline_Modification(t *testing.T) { type args struct { endpoint string - libraryBuild *library.Build + libraryBuild *api.Build repo *api.Repo } @@ -312,12 +311,12 @@ func TestNative_Compile_StagesPipeline_Modification(t *testing.T) { wantErr bool }{ {"bad url", args{ - libraryBuild: &library.Build{Number: &number, Author: &author}, + libraryBuild: &api.Build{Number: &number, Author: &author}, repo: &api.Repo{Name: &name}, endpoint: "bad", }, true}, {"invalid return", args{ - libraryBuild: &library.Build{Number: &number, Author: &author}, + libraryBuild: &api.Build{Number: &number, Author: &author}, repo: &api.Repo{Name: &name}, endpoint: fmt.Sprintf("%s/%s", s.URL, "config/bad"), }, true}, @@ -331,7 +330,7 @@ func TestNative_Compile_StagesPipeline_Modification(t *testing.T) { Endpoint: tt.args.endpoint, }, repo: &api.Repo{Name: &author}, - build: &library.Build{Author: &name, Number: &number}, + build: &api.Build{Author: &name, Number: &number}, } _, _, err := compiler.Compile(yaml) if (err != nil) != tt.wantErr { @@ -370,7 +369,7 @@ func TestNative_Compile_StepsPipeline_Modification(t *testing.T) { type args struct { endpoint string - libraryBuild *library.Build + libraryBuild *api.Build repo *api.Repo } @@ -380,12 +379,12 @@ func TestNative_Compile_StepsPipeline_Modification(t *testing.T) { wantErr bool }{ {"bad url", args{ - libraryBuild: &library.Build{Number: &number, Author: &author}, + libraryBuild: &api.Build{Number: &number, Author: &author}, repo: &api.Repo{Name: &name}, endpoint: "bad", }, true}, {"invalid return", args{ - libraryBuild: &library.Build{Number: &number, Author: &author}, + libraryBuild: &api.Build{Number: &number, Author: &author}, repo: &api.Repo{Name: &name}, endpoint: fmt.Sprintf("%s/%s", s.URL, "config/bad"), }, true}, @@ -1846,7 +1845,7 @@ func TestNative_Compile_NoStepsorStages(t *testing.T) { } compiler.repo = &api.Repo{Name: &author} - compiler.build = &library.Build{Author: &name, Number: &number} + compiler.build = &api.Build{Author: &name, Number: &number} got, _, err := compiler.Compile(yaml) if err == nil { @@ -1878,7 +1877,7 @@ func TestNative_Compile_StepsandStages(t *testing.T) { } compiler.repo = &api.Repo{Name: &author} - compiler.build = &library.Build{Author: &name, Number: &number} + compiler.build = &api.Build{Author: &name, Number: &number} got, _, err := compiler.Compile(yaml) if err == nil { @@ -2079,7 +2078,7 @@ func Test_client_modifyConfig(t *testing.T) { type args struct { endpoint string build *yaml.Build - libraryBuild *library.Build + libraryBuild *api.Build repo *api.Repo } @@ -2091,37 +2090,37 @@ func Test_client_modifyConfig(t *testing.T) { }{ {"unmodified", args{ build: want, - libraryBuild: &library.Build{Number: &number, Author: &author}, + libraryBuild: &api.Build{Number: &number, Author: &author}, repo: &api.Repo{Name: &name}, endpoint: fmt.Sprintf("%s/%s", s.URL, "config/unmodified"), }, want, false}, {"modified", args{ build: want, - libraryBuild: &library.Build{Number: &number, Author: &author}, + libraryBuild: &api.Build{Number: &number, Author: &author}, repo: &api.Repo{Name: &name}, endpoint: fmt.Sprintf("%s/%s", s.URL, "config/modified"), }, want2, false}, {"invalid endpoint", args{ build: want, - libraryBuild: &library.Build{Number: &number, Author: &author}, + libraryBuild: &api.Build{Number: &number, Author: &author}, repo: &api.Repo{Name: &name}, endpoint: "bad", }, nil, true}, {"unauthorized endpoint", args{ build: want, - libraryBuild: &library.Build{Number: &number, Author: &author}, + libraryBuild: &api.Build{Number: &number, Author: &author}, repo: &api.Repo{Name: &name}, endpoint: fmt.Sprintf("%s/%s", s.URL, "config/unauthorized"), }, nil, true}, {"timeout endpoint", args{ build: want, - libraryBuild: &library.Build{Number: &number, Author: &author}, + libraryBuild: &api.Build{Number: &number, Author: &author}, repo: &api.Repo{Name: &name}, endpoint: fmt.Sprintf("%s/%s", s.URL, "config/timeout"), }, nil, true}, {"empty payload", args{ build: want, - libraryBuild: &library.Build{Number: &number, Author: &author}, + libraryBuild: &api.Build{Number: &number, Author: &author}, repo: &api.Repo{Name: &name}, endpoint: fmt.Sprintf("%s/%s", s.URL, "config/empty"), }, nil, true}, diff --git a/compiler/native/environment.go b/compiler/native/environment.go index 8b7972877..1d0666e43 100644 --- a/compiler/native/environment.go +++ b/compiler/native/environment.go @@ -282,7 +282,7 @@ func appendMap(originalMap, otherMap map[string]string) map[string]string { } // helper function that creates the standard set of environment variables for a pipeline. -func environment(b *library.Build, m *internal.Metadata, r *api.Repo, u *api.User) map[string]string { +func environment(b *api.Build, m *internal.Metadata, r *api.Repo, u *api.User) map[string]string { // set default workspace workspace := constants.WorkspaceDefault notImplemented := "TODO" diff --git a/compiler/native/environment_test.go b/compiler/native/environment_test.go index e41e02be4..1e090dad1 100644 --- a/compiler/native/environment_test.go +++ b/compiler/native/environment_test.go @@ -13,7 +13,6 @@ import ( api "github.com/go-vela/server/api/types" "github.com/go-vela/server/internal" - "github.com/go-vela/types/library" "github.com/go-vela/types/raw" "github.com/go-vela/types/yaml" ) @@ -577,7 +576,7 @@ func TestNative_environment(t *testing.T) { tests := []struct { w string - b *library.Build + b *api.Build m *internal.Metadata r *api.Repo u *api.User @@ -586,7 +585,7 @@ func TestNative_environment(t *testing.T) { // push { w: workspace, - b: &library.Build{ID: &num64, RepoID: &num64, Number: &num, Parent: &num, Event: &push, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &str, BaseRef: &str}, + b: &api.Build{ID: &num64, Repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, Number: &num, Parent: &num, Event: &push, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &str, BaseRef: &str}, m: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, r: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, u: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, @@ -595,7 +594,7 @@ func TestNative_environment(t *testing.T) { // tag { w: workspace, - b: &library.Build{ID: &num64, RepoID: &num64, Number: &num, Parent: &num, Event: &tag, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &tagref, BaseRef: &str}, + b: &api.Build{ID: &num64, Repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, Number: &num, Parent: &num, Event: &tag, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &tagref, BaseRef: &str}, m: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, r: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, u: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, @@ -604,7 +603,7 @@ func TestNative_environment(t *testing.T) { // pull_request { w: workspace, - b: &library.Build{ID: &num64, RepoID: &num64, Number: &num, Parent: &num, Event: &pull, EventAction: &pullact, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &pullref, BaseRef: &str}, + b: &api.Build{ID: &num64, Repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, Number: &num, Parent: &num, Event: &pull, EventAction: &pullact, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &pullref, BaseRef: &str}, m: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, r: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, u: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, @@ -613,7 +612,7 @@ func TestNative_environment(t *testing.T) { // deployment { w: workspace, - b: &library.Build{ID: &num64, RepoID: &num64, Number: &num, Parent: &num, Event: &deploy, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &target, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &pullref, BaseRef: &str}, + b: &api.Build{ID: &num64, Repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, Number: &num, Parent: &num, Event: &deploy, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &target, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &pullref, BaseRef: &str}, m: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, r: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, u: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, @@ -690,7 +689,7 @@ func Test_client_EnvironmentBuild(t *testing.T) { target := "production" type fields struct { - build *library.Build + build *api.Build metadata *internal.Metadata repo *api.Repo user *api.User @@ -702,27 +701,27 @@ func Test_client_EnvironmentBuild(t *testing.T) { want map[string]string }{ {"push", fields{ - build: &library.Build{ID: &num64, RepoID: &num64, Number: &num, Parent: &num, Event: &push, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &str, BaseRef: &str}, + build: &api.Build{ID: &num64, Repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, Number: &num, Parent: &num, Event: &push, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &str, BaseRef: &str}, metadata: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, user: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "push", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "foo", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "push", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "foo", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_OWNER": "foo", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}}, {"tag", fields{ - build: &library.Build{ID: &num64, RepoID: &num64, Number: &num, Parent: &num, Event: &tag, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &tagref, BaseRef: &str}, + build: &api.Build{ID: &num64, Repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, Number: &num, Parent: &num, Event: &tag, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &tagref, BaseRef: &str}, metadata: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, user: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "tag", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "refs/tags/1", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TAG": "1", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "tag", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "refs/tags/1", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TAG": "1", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_OWNER": "foo", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, }, {"pull_request", fields{ - build: &library.Build{ID: &num64, RepoID: &num64, Number: &num, Parent: &num, Event: &pull, EventAction: &pullact, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &pullref, BaseRef: &str}, + build: &api.Build{ID: &num64, Repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, Number: &num, Parent: &num, Event: &pull, EventAction: &pullact, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &pullref, BaseRef: &str}, metadata: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, user: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "pull_request", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_PULL_REQUEST_NUMBER": "1", "BUILD_REF": "refs/pull/1/head", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "pull_request", "VELA_BUILD_EVENT_ACTION": "opened", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_PULL_REQUEST": "1", "VELA_BUILD_REF": "refs/pull/1/head", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_PULL_REQUEST": "1", "VELA_PULL_REQUEST_SOURCE": "", "VELA_PULL_REQUEST_TARGET": "foo", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_OWNER": "foo", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, }, {"deployment", fields{ - build: &library.Build{ID: &num64, RepoID: &num64, Number: &num, Parent: &num, Event: &deploy, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &target, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &pullref, BaseRef: &str}, + build: &api.Build{ID: &num64, Repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, Number: &num, Parent: &num, Event: &deploy, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &target, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &pullref, BaseRef: &str}, metadata: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, user: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, diff --git a/compiler/native/expand_test.go b/compiler/native/expand_test.go index c43eb14bd..cf6f3927f 100644 --- a/compiler/native/expand_test.go +++ b/compiler/native/expand_test.go @@ -14,7 +14,6 @@ import ( "github.com/urfave/cli/v2" api "github.com/go-vela/server/api/types" - "github.com/go-vela/types/library" "github.com/go-vela/types/pipeline" "github.com/go-vela/types/raw" "github.com/go-vela/types/yaml" @@ -763,7 +762,7 @@ func TestNative_ExpandSteps_TemplateCallTemplate(t *testing.T) { set.Int("max-template-depth", 5, "doc") c := cli.NewContext(nil, set, nil) - testBuild := new(library.Build) + testBuild := new(api.Build) testBuild.SetID(1) testBuild.SetCommit("123abc456def") @@ -931,7 +930,7 @@ func TestNative_ExpandSteps_TemplateCallTemplate_CircularFail(t *testing.T) { set.Int("max-template-depth", 5, "doc") c := cli.NewContext(nil, set, nil) - testBuild := new(library.Build) + testBuild := new(api.Build) testBuild.SetID(1) testBuild.SetCommit("123abc456def") @@ -1017,7 +1016,7 @@ func TestNative_ExpandSteps_CallTemplateWithRenderInline(t *testing.T) { set.Int("max-template-depth", 5, "doc") c := cli.NewContext(nil, set, nil) - testBuild := new(library.Build) + testBuild := new(api.Build) testBuild.SetID(1) testBuild.SetCommit("123abc456def") diff --git a/compiler/native/native.go b/compiler/native/native.go index b92cfd2ea..026341063 100644 --- a/compiler/native/native.go +++ b/compiler/native/native.go @@ -13,7 +13,6 @@ import ( "github.com/go-vela/server/compiler/registry" "github.com/go-vela/server/compiler/registry/github" "github.com/go-vela/server/internal" - "github.com/go-vela/types/library" ) type ModificationConfig struct { @@ -32,7 +31,7 @@ type client struct { TemplateDepth int StarlarkExecLimit uint64 - build *library.Build + build *api.Build comment string commit string files []string @@ -124,7 +123,7 @@ func (c *client) Duplicate() compiler.Engine { } // WithBuild sets the library build type in the Engine. -func (c *client) WithBuild(b *library.Build) compiler.Engine { +func (c *client) WithBuild(b *api.Build) compiler.Engine { if b != nil { c.build = b } diff --git a/compiler/native/native_test.go b/compiler/native/native_test.go index 5e84a6664..835169e5d 100644 --- a/compiler/native/native_test.go +++ b/compiler/native/native_test.go @@ -12,7 +12,6 @@ import ( api "github.com/go-vela/server/api/types" "github.com/go-vela/server/compiler/registry/github" "github.com/go-vela/server/internal" - "github.com/go-vela/types/library" ) func TestNative_New(t *testing.T) { @@ -100,7 +99,7 @@ func TestNative_DuplicateStripBuild(t *testing.T) { c := cli.NewContext(nil, set, nil) id := int64(1) - b := &library.Build{ID: &id} + b := &api.Build{ID: &id} want, _ := New(c) @@ -123,7 +122,7 @@ func TestNative_WithBuild(t *testing.T) { c := cli.NewContext(nil, set, nil) id := int64(1) - b := &library.Build{ID: &id} + b := &api.Build{ID: &id} want, _ := New(c) want.build = b diff --git a/database/build/build.go b/database/build/build.go index 1d1a42d97..0ff9871bd 100644 --- a/database/build/build.go +++ b/database/build/build.go @@ -15,6 +15,8 @@ import ( type ( // config represents the settings required to create the engine that implements the BuildInterface interface. config struct { + // specifies the encryption key to use for the Build engine + EncryptionKey string // specifies to skip creating tables and indexes for the Build engine SkipCreation bool } diff --git a/database/build/build_test.go b/database/build/build_test.go index 5971b5d48..383c0573c 100644 --- a/database/build/build_test.go +++ b/database/build/build_test.go @@ -14,10 +14,6 @@ import ( "gorm.io/driver/postgres" "gorm.io/driver/sqlite" "gorm.io/gorm" - - api "github.com/go-vela/server/api/types" - "github.com/go-vela/types/library" - "github.com/go-vela/types/raw" ) func TestBuild_New(t *testing.T) { @@ -116,6 +112,34 @@ func TestBuild_New(t *testing.T) { } } +// TEST RESOURCES + +// This will be used with the github.com/DATA-DOG/go-sqlmock library to compare values +// that are otherwise not easily compared. These typically would be values generated +// before adding or updating them in the database. +// +// https://github.com/DATA-DOG/go-sqlmock#matching-arguments-like-timetime +type AnyArgument struct{} + +// Match satisfies sqlmock.Argument interface. +func (a AnyArgument) Match(_ driver.Value) bool { + return true +} + +// NowTimestamp is used to test whether timestamps get updated correctly to the current time with lenience. +type NowTimestamp struct{} + +// Match satisfies sqlmock.Argument interface. +func (t NowTimestamp) Match(v driver.Value) bool { + ts, ok := v.(int64) + if !ok { + return false + } + now := time.Now().Unix() + + return now-ts < 10 +} + // testPostgres is a helper function to create a Postgres engine for testing. func testPostgres(t *testing.T) (*engine, sqlmock.Sqlmock) { // create the new mock sql database @@ -148,6 +172,7 @@ func testPostgres(t *testing.T) (*engine, sqlmock.Sqlmock) { WithClient(_postgres), WithLogger(logrus.NewEntry(logrus.StandardLogger())), WithSkipCreation(false), + WithEncryptionKey("A1B2C3D4E5G6H7I8J9K0LMNOPQRSTUVW"), ) if err != nil { t.Errorf("unable to create new postgres build engine: %v", err) @@ -171,6 +196,7 @@ func testSqlite(t *testing.T) *engine { WithClient(_sqlite), WithLogger(logrus.NewEntry(logrus.StandardLogger())), WithSkipCreation(false), + WithEncryptionKey("A1B2C3D4E5G6H7I8J9K0LMNOPQRSTUVW"), ) if err != nil { t.Errorf("unable to create new sqlite build engine: %v", err) @@ -178,114 +204,3 @@ func testSqlite(t *testing.T) *engine { return _engine } - -// testBuild is a test helper function to create a library -// Build type with all fields set to their zero values. -func testBuild() *library.Build { - return &library.Build{ - ID: new(int64), - RepoID: new(int64), - PipelineID: new(int64), - Number: new(int), - Parent: new(int), - Event: new(string), - EventAction: new(string), - Status: new(string), - Error: new(string), - Enqueued: new(int64), - Created: new(int64), - Started: new(int64), - Finished: new(int64), - Deploy: new(string), - DeployNumber: new(int64), - Clone: new(string), - Source: new(string), - Title: new(string), - Message: new(string), - Commit: new(string), - Sender: new(string), - Author: new(string), - Email: new(string), - Link: new(string), - Branch: new(string), - Ref: new(string), - BaseRef: new(string), - HeadRef: new(string), - Host: new(string), - Runtime: new(string), - Distribution: new(string), - ApprovedAt: new(int64), - ApprovedBy: new(string), - } -} - -// testDeployment is a test helper function to create a library -// Repo type with all fields set to their zero values. -func testDeployment() *library.Deployment { - builds := []*library.Build{} - return &library.Deployment{ - ID: new(int64), - RepoID: new(int64), - Number: new(int64), - URL: new(string), - Commit: new(string), - Ref: new(string), - Task: new(string), - Target: new(string), - Description: new(string), - Payload: new(raw.StringSliceMap), - CreatedAt: new(int64), - CreatedBy: new(string), - Builds: builds, - } -} - -// testRepo is a test helper function to create a library -// Repo type with all fields set to their zero values. -func testRepo() *api.Repo { - return &api.Repo{ - ID: new(int64), - BuildLimit: new(int64), - Timeout: new(int64), - Counter: new(int), - PipelineType: new(string), - Hash: new(string), - Org: new(string), - Name: new(string), - FullName: new(string), - Link: new(string), - Clone: new(string), - Branch: new(string), - Visibility: new(string), - PreviousName: new(string), - Private: new(bool), - Trusted: new(bool), - Active: new(bool), - } -} - -// This will be used with the github.com/DATA-DOG/go-sqlmock library to compare values -// that are otherwise not easily compared. These typically would be values generated -// before adding or updating them in the database. -// -// https://github.com/DATA-DOG/go-sqlmock#matching-arguments-like-timetime -type AnyArgument struct{} - -// Match satisfies sqlmock.Argument interface. -func (a AnyArgument) Match(_ driver.Value) bool { - return true -} - -// NowTimestamp is used to test whether timestamps get updated correctly to the current time with lenience. -type NowTimestamp struct{} - -// Match satisfies sqlmock.Argument interface. -func (t NowTimestamp) Match(v driver.Value) bool { - ts, ok := v.(int64) - if !ok { - return false - } - now := time.Now().Unix() - - return now-ts < 10 -} diff --git a/database/build/clean.go b/database/build/clean.go index 4559bac5f..5c239a57e 100644 --- a/database/build/clean.go +++ b/database/build/clean.go @@ -8,21 +8,21 @@ import ( "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" ) // CleanBuilds updates builds to an error with a provided message with a created timestamp prior to a defined moment. func (e *engine) CleanBuilds(ctx context.Context, msg string, before int64) (int64, error) { logrus.Tracef("cleaning pending or running builds in the database created prior to %d", before) - b := new(library.Build) + b := new(api.Build) b.SetStatus(constants.StatusError) b.SetError(msg) b.SetFinished(time.Now().UTC().Unix()) - build := database.BuildFromLibrary(b) + build := types.BuildFromAPI(b) // send query to the database result := e.client. diff --git a/database/build/clean_test.go b/database/build/clean_test.go index 28eb29195..179dd2fb8 100644 --- a/database/build/clean_test.go +++ b/database/build/clean_test.go @@ -8,35 +8,56 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" ) func TestBuild_Engine_CleanBuilds(t *testing.T) { // setup types - _buildOne := testBuild() + _repo := testutils.APIRepo() + _repo.SetID(1) + _repo.SetHash("baz") + _repo.SetOrg("foo") + _repo.SetName("bar") + _repo.SetFullName("foo/bar") + _repo.SetVisibility("public") + _repo.SetPipelineType("yaml") + _repo.SetTopics([]string{}) + _repo.SetAllowEvents(api.NewEventsFromMask(1)) + + _owner := testutils.APIUser() + _owner.SetID(1) + _owner.SetName("foo") + _owner.SetToken("bar") + + _repo.SetOwner(_owner) + + _buildOne := testutils.APIBuild() _buildOne.SetID(1) - _buildOne.SetRepoID(1) + _buildOne.SetRepo(_repo) _buildOne.SetNumber(1) _buildOne.SetCreated(1) _buildOne.SetStatus("pending") - _buildTwo := testBuild() + _buildTwo := testutils.APIBuild() _buildTwo.SetID(2) - _buildTwo.SetRepoID(1) + _buildTwo.SetRepo(_repo) _buildTwo.SetNumber(2) _buildTwo.SetCreated(2) _buildTwo.SetStatus("running") // setup types - _buildThree := testBuild() + _buildThree := testutils.APIBuild() _buildThree.SetID(3) - _buildThree.SetRepoID(1) + _buildThree.SetRepo(_repo) _buildThree.SetNumber(3) _buildThree.SetCreated(1) _buildThree.SetStatus("success") - _buildFour := testBuild() + _buildFour := testutils.APIBuild() _buildFour.SetID(4) - _buildFour.SetRepoID(1) + _buildFour.SetRepo(_repo) _buildFour.SetNumber(4) _buildFour.SetCreated(5) _buildFour.SetStatus("running") diff --git a/database/build/count_deployment_test.go b/database/build/count_deployment_test.go index 6b4f83823..64fbbbbae 100644 --- a/database/build/count_deployment_test.go +++ b/database/build/count_deployment_test.go @@ -8,25 +8,46 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" ) func TestBuild_Engine_CountBuildsForDeployment(t *testing.T) { // setup types - _buildOne := testBuild() + _repo := testutils.APIRepo() + _repo.SetID(1) + _repo.SetHash("baz") + _repo.SetOrg("foo") + _repo.SetName("bar") + _repo.SetFullName("foo/bar") + _repo.SetVisibility("public") + _repo.SetPipelineType("yaml") + _repo.SetTopics([]string{}) + _repo.SetAllowEvents(api.NewEventsFromMask(1)) + + _owner := testutils.APIUser() + _owner.SetID(1) + _owner.SetName("foo") + _owner.SetToken("bar") + + _repo.SetOwner(_owner) + + _buildOne := testutils.APIBuild() _buildOne.SetID(1) - _buildOne.SetRepoID(1) + _buildOne.SetRepo(_repo) _buildOne.SetNumber(1) _buildOne.SetDeployPayload(nil) _buildOne.SetSource("https://github.com/github/octocat/deployments/1") - _buildTwo := testBuild() + _buildTwo := testutils.APIBuild() _buildTwo.SetID(2) - _buildTwo.SetRepoID(1) + _buildTwo.SetRepo(_repo) _buildTwo.SetNumber(2) _buildTwo.SetDeployPayload(nil) _buildTwo.SetSource("https://github.com/github/octocat/deployments/1") - _deployment := testDeployment() + _deployment := testutils.APIDeployment() _deployment.SetID(1) _deployment.SetRepoID(1) _deployment.SetURL("https://github.com/github/octocat/deployments/1") diff --git a/database/build/count_org_test.go b/database/build/count_org_test.go index 635e7bd66..546e59678 100644 --- a/database/build/count_org_test.go +++ b/database/build/count_org_test.go @@ -9,29 +9,21 @@ import ( "github.com/DATA-DOG/go-sqlmock" - "github.com/go-vela/server/database/repo" + "github.com/go-vela/server/database/testutils" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" ) func TestBuild_Engine_CountBuildsForOrg(t *testing.T) { // setup types - _buildOne := testBuild() - _buildOne.SetID(1) - _buildOne.SetRepoID(1) - _buildOne.SetNumber(1) - _buildOne.SetDeployPayload(nil) - _buildOne.SetEvent("push") - - _buildTwo := testBuild() - _buildTwo.SetID(2) - _buildTwo.SetRepoID(2) - _buildTwo.SetNumber(2) - _buildTwo.SetDeployPayload(nil) - _buildTwo.SetEvent("push") + _owner := testutils.APIUser() + _owner.SetID(1) + _owner.SetName("foo") + _owner.SetToken("bar") - _repoOne := testRepo() + _repoOne := testutils.APIRepo() _repoOne.SetID(1) - _repoOne.GetOwner().SetID(1) + _repoOne.SetOwner(_owner) _repoOne.SetHash("baz") _repoOne.SetOrg("foo") _repoOne.SetName("bar") @@ -40,9 +32,9 @@ func TestBuild_Engine_CountBuildsForOrg(t *testing.T) { _repoOne.SetPipelineType("yaml") _repoOne.SetTopics([]string{}) - _repoTwo := testRepo() + _repoTwo := testutils.APIRepo() _repoTwo.SetID(2) - _repoTwo.GetOwner().SetID(1) + _repoTwo.SetOwner(_owner) _repoTwo.SetHash("bar") _repoTwo.SetOrg("foo") _repoTwo.SetName("baz") @@ -51,6 +43,20 @@ func TestBuild_Engine_CountBuildsForOrg(t *testing.T) { _repoTwo.SetPipelineType("yaml") _repoTwo.SetTopics([]string{}) + _buildOne := testutils.APIBuild() + _buildOne.SetID(1) + _buildOne.SetRepo(_repoOne) + _buildOne.SetNumber(1) + _buildOne.SetDeployPayload(nil) + _buildOne.SetEvent("push") + + _buildTwo := testutils.APIBuild() + _buildTwo.SetID(2) + _buildTwo.SetRepo(_repoTwo) + _buildTwo.SetNumber(2) + _buildTwo.SetDeployPayload(nil) + _buildTwo.SetEvent("push") + _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() @@ -77,17 +83,17 @@ func TestBuild_Engine_CountBuildsForOrg(t *testing.T) { t.Errorf("unable to create test build for sqlite: %v", err) } - err = _sqlite.client.AutoMigrate(&repo.Repo{}) + err = _sqlite.client.AutoMigrate(&types.Repo{}) if err != nil { t.Errorf("unable to create repo table for sqlite: %v", err) } - err = _sqlite.client.Table(constants.TableRepo).Create(repo.FromAPI(_repoOne)).Error + err = _sqlite.client.Table(constants.TableRepo).Create(types.RepoFromAPI(_repoOne)).Error if err != nil { t.Errorf("unable to create test repo for sqlite: %v", err) } - err = _sqlite.client.Table(constants.TableRepo).Create(repo.FromAPI(_repoTwo)).Error + err = _sqlite.client.Table(constants.TableRepo).Create(types.RepoFromAPI(_repoTwo)).Error if err != nil { t.Errorf("unable to create test repo for sqlite: %v", err) } diff --git a/database/build/count_repo_test.go b/database/build/count_repo_test.go index edbb77816..77bbc69d6 100644 --- a/database/build/count_repo_test.go +++ b/database/build/count_repo_test.go @@ -8,23 +8,18 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestBuild_Engine_CountBuildsForRepo(t *testing.T) { // setup types - _buildOne := testBuild() - _buildOne.SetID(1) - _buildOne.SetRepoID(1) - _buildOne.SetNumber(1) - _buildOne.SetDeployPayload(nil) - - _buildTwo := testBuild() - _buildTwo.SetID(2) - _buildTwo.SetRepoID(1) - _buildTwo.SetNumber(2) - _buildTwo.SetDeployPayload(nil) + _owner := testutils.APIUser() + _owner.SetID(1) + _owner.SetName("foo") + _owner.SetToken("bar") - _repo := testRepo() + _repo := testutils.APIRepo() _repo.SetID(1) _repo.GetOwner().SetID(1) _repo.SetHash("baz") @@ -33,6 +28,18 @@ func TestBuild_Engine_CountBuildsForRepo(t *testing.T) { _repo.SetFullName("foo/bar") _repo.SetVisibility("public") + _buildOne := testutils.APIBuild() + _buildOne.SetID(1) + _buildOne.SetRepo(_repo) + _buildOne.SetNumber(1) + _buildOne.SetDeployPayload(nil) + + _buildTwo := testutils.APIBuild() + _buildTwo.SetID(2) + _buildTwo.SetRepo(_repo) + _buildTwo.SetNumber(2) + _buildTwo.SetDeployPayload(nil) + _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() diff --git a/database/build/count_status_test.go b/database/build/count_status_test.go index cea339953..6fe707142 100644 --- a/database/build/count_status_test.go +++ b/database/build/count_status_test.go @@ -8,20 +8,36 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestBuild_Engine_CountBuildsForStatus(t *testing.T) { // setup types - _buildOne := testBuild() + _owner := testutils.APIUser() + _owner.SetID(1) + _owner.SetName("foo") + _owner.SetToken("bar") + + _repo := testutils.APIRepo() + _repo.SetID(1) + _repo.GetOwner().SetID(1) + _repo.SetHash("baz") + _repo.SetOrg("foo") + _repo.SetName("bar") + _repo.SetFullName("foo/bar") + _repo.SetVisibility("public") + + _buildOne := testutils.APIBuild() _buildOne.SetID(1) - _buildOne.SetRepoID(1) + _buildOne.SetRepo(_repo) _buildOne.SetNumber(1) _buildOne.SetDeployPayload(nil) _buildOne.SetStatus("running") - _buildTwo := testBuild() + _buildTwo := testutils.APIBuild() _buildTwo.SetID(2) - _buildTwo.SetRepoID(1) + _buildTwo.SetRepo(_repo) _buildTwo.SetNumber(2) _buildTwo.SetDeployPayload(nil) _buildTwo.SetStatus("running") diff --git a/database/build/count_test.go b/database/build/count_test.go index bdcc57078..a1d7717ce 100644 --- a/database/build/count_test.go +++ b/database/build/count_test.go @@ -8,19 +8,35 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestBuild_Engine_CountBuilds(t *testing.T) { // setup types - _buildOne := testBuild() + _owner := testutils.APIUser() + _owner.SetID(1) + _owner.SetName("foo") + _owner.SetToken("bar") + + _repo := testutils.APIRepo() + _repo.SetID(1) + _repo.GetOwner().SetID(1) + _repo.SetHash("baz") + _repo.SetOrg("foo") + _repo.SetName("bar") + _repo.SetFullName("foo/bar") + _repo.SetVisibility("public") + + _buildOne := testutils.APIBuild() _buildOne.SetID(1) - _buildOne.SetRepoID(1) + _buildOne.SetRepo(_repo) _buildOne.SetNumber(1) _buildOne.SetDeployPayload(nil) - _buildTwo := testBuild() + _buildTwo := testutils.APIBuild() _buildTwo.SetID(2) - _buildTwo.SetRepoID(1) + _buildTwo.SetRepo(_repo) _buildTwo.SetNumber(2) _buildTwo.SetDeployPayload(nil) diff --git a/database/build/create.go b/database/build/create.go index 1c04548b5..0ba65aad5 100644 --- a/database/build/create.go +++ b/database/build/create.go @@ -8,25 +8,19 @@ import ( "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" ) // CreateBuild creates a new build in the database. -func (e *engine) CreateBuild(ctx context.Context, b *library.Build) (*library.Build, error) { +func (e *engine) CreateBuild(ctx context.Context, b *api.Build) (*api.Build, error) { e.logger.WithFields(logrus.Fields{ "build": b.GetNumber(), }).Tracef("creating build %d in the database", b.GetNumber()) - // cast the library type to database type - // - // https://pkg.go.dev/github.com/go-vela/types/database#BuildFromLibrary - build := database.BuildFromLibrary(b) + build := types.BuildFromAPI(b) - // validate the necessary fields are populated - // - // https://pkg.go.dev/github.com/go-vela/types/database#Build.Validate err := build.Validate() if err != nil { return nil, err @@ -36,7 +30,13 @@ func (e *engine) CreateBuild(ctx context.Context, b *library.Build) (*library.Bu build = build.Crop() // send query to the database - result := e.client.Table(constants.TableBuild).Create(build) + err = e.client.Table(constants.TableBuild).Create(build).Error + if err != nil { + return nil, err + } + + result := build.ToAPI() + result.SetRepo(b.GetRepo()) - return build.ToLibrary(), result.Error + return result, nil } diff --git a/database/build/create_test.go b/database/build/create_test.go index 86e9b8751..83b6f5a2c 100644 --- a/database/build/create_test.go +++ b/database/build/create_test.go @@ -8,13 +8,29 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestBuild_Engine_CreateBuild(t *testing.T) { // setup types - _build := testBuild() + _owner := testutils.APIUser() + _owner.SetID(1) + _owner.SetName("foo") + _owner.SetToken("bar") + + _repo := testutils.APIRepo() + _repo.SetID(1) + _repo.GetOwner().SetID(1) + _repo.SetHash("baz") + _repo.SetOrg("foo") + _repo.SetName("bar") + _repo.SetFullName("foo/bar") + _repo.SetVisibility("public") + + _build := testutils.APIBuild() _build.SetID(1) - _build.SetRepoID(1) + _build.SetRepo(_repo) _build.SetNumber(1) _build.SetDeployPayload(nil) diff --git a/database/build/delete.go b/database/build/delete.go index 78bc11f71..b2bff7795 100644 --- a/database/build/delete.go +++ b/database/build/delete.go @@ -7,21 +7,18 @@ import ( "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" ) // DeleteBuild deletes an existing build from the database. -func (e *engine) DeleteBuild(ctx context.Context, b *library.Build) error { +func (e *engine) DeleteBuild(ctx context.Context, b *api.Build) error { e.logger.WithFields(logrus.Fields{ "build": b.GetNumber(), }).Tracef("deleting build %d from the database", b.GetNumber()) - // cast the library type to database type - // - // https://pkg.go.dev/github.com/go-vela/types/database#BuildFromLibrary - build := database.BuildFromLibrary(b) + build := types.BuildFromAPI(b) // send query to the database return e.client. diff --git a/database/build/delete_test.go b/database/build/delete_test.go index 33ca6e3d6..7a7b21ed0 100644 --- a/database/build/delete_test.go +++ b/database/build/delete_test.go @@ -7,13 +7,29 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestBuild_Engine_DeleteBuild(t *testing.T) { // setup types - _build := testBuild() + _owner := testutils.APIUser() + _owner.SetID(1) + _owner.SetName("foo") + _owner.SetToken("bar") + + _repo := testutils.APIRepo() + _repo.SetID(1) + _repo.GetOwner().SetID(1) + _repo.SetHash("baz") + _repo.SetOrg("foo") + _repo.SetName("bar") + _repo.SetFullName("foo/bar") + _repo.SetVisibility("public") + + _build := testutils.APIBuild() _build.SetID(1) - _build.SetRepoID(1) + _build.SetRepo(_repo) _build.SetNumber(1) _build.SetDeployPayload(nil) diff --git a/database/build/get.go b/database/build/get.go index 02df1d42a..a780b1721 100644 --- a/database/build/get.go +++ b/database/build/get.go @@ -5,21 +5,23 @@ package build import ( "context" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" ) // GetBuild gets a build by ID from the database. -func (e *engine) GetBuild(ctx context.Context, id int64) (*library.Build, error) { +func (e *engine) GetBuild(ctx context.Context, id int64) (*api.Build, error) { e.logger.Tracef("getting build %d from the database", id) // variable to store query results - b := new(database.Build) + b := new(types.Build) // send query to the database and store result in variable err := e.client. Table(constants.TableBuild). + Preload("Repo"). + Preload("Repo.Owner"). Where("id = ?", id). Take(b). Error @@ -27,5 +29,10 @@ func (e *engine) GetBuild(ctx context.Context, id int64) (*library.Build, error) return nil, err } - return b.ToLibrary(), nil + err = b.Repo.Decrypt(e.config.EncryptionKey) + if err != nil { + e.logger.Errorf("unable to decrypt repo: %v", err) + } + + return b.ToAPI(), nil } diff --git a/database/build/get_repo.go b/database/build/get_repo.go index 3b3ae9998..8a13009c2 100644 --- a/database/build/get_repo.go +++ b/database/build/get_repo.go @@ -8,13 +8,12 @@ import ( "github.com/sirupsen/logrus" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" ) // GetBuildForRepo gets a build by repo ID and number from the database. -func (e *engine) GetBuildForRepo(ctx context.Context, r *api.Repo, number int) (*library.Build, error) { +func (e *engine) GetBuildForRepo(ctx context.Context, r *api.Repo, number int) (*api.Build, error) { e.logger.WithFields(logrus.Fields{ "build": number, "org": r.GetOrg(), @@ -22,11 +21,13 @@ func (e *engine) GetBuildForRepo(ctx context.Context, r *api.Repo, number int) ( }).Tracef("getting build %s/%d from the database", r.GetFullName(), number) // variable to store query results - b := new(database.Build) + b := new(types.Build) // send query to the database and store result in variable err := e.client. Table(constants.TableBuild). + Preload("Repo"). + Preload("Repo.Owner"). Where("repo_id = ?", r.GetID()). Where("number = ?", number). Take(b). @@ -35,5 +36,10 @@ func (e *engine) GetBuildForRepo(ctx context.Context, r *api.Repo, number int) ( return nil, err } - return b.ToLibrary(), nil + err = b.Repo.Decrypt(e.config.EncryptionKey) + if err != nil { + e.logger.Errorf("unable to decrypt repo %s/%s: %v", r.GetOrg(), r.GetName(), err) + } + + return b.ToAPI(), nil } diff --git a/database/build/get_repo_test.go b/database/build/get_repo_test.go index 906f35aee..e2db55642 100644 --- a/database/build/get_repo_test.go +++ b/database/build/get_repo_test.go @@ -4,31 +4,42 @@ package build import ( "context" - "reflect" "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/google/go-cmp/cmp" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" + "github.com/go-vela/server/database/types" + "github.com/go-vela/types/constants" ) func TestBuild_Engine_GetBuildForRepo(t *testing.T) { // setup types - _build := testBuild() - _build.SetID(1) - _build.SetRepoID(1) - _build.SetNumber(1) - _build.SetDeployNumber(0) - _build.SetDeployPayload(nil) + _owner := testutils.APIUser().Crop() + _owner.SetID(1) + _owner.SetName("foo") + _owner.SetToken("bar") - _repo := testRepo() + _repo := testutils.APIRepo() _repo.SetID(1) - _repo.GetOwner().SetID(1) + _repo.SetOwner(_owner) _repo.SetHash("baz") _repo.SetOrg("foo") _repo.SetName("bar") _repo.SetFullName("foo/bar") _repo.SetVisibility("public") + _repo.SetAllowEvents(api.NewEventsFromMask(1)) + _repo.SetPipelineType(constants.PipelineTypeYAML) + _repo.SetTopics([]string{}) + + _build := testutils.APIBuild() + _build.SetID(1) + _build.SetRepo(_repo) + _build.SetNumber(1) + _build.SetDeployNumber(0) + _build.SetDeployPayload(nil) _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() @@ -38,8 +49,18 @@ func TestBuild_Engine_GetBuildForRepo(t *testing.T) { []string{"id", "repo_id", "pipeline_id", "number", "parent", "event", "event_action", "status", "error", "enqueued", "created", "started", "finished", "deploy", "deploy_number", "deploy_payload", "clone", "source", "title", "message", "commit", "sender", "author", "email", "link", "branch", "ref", "base_ref", "head_ref", "host", "runtime", "distribution", "timestamp"}). AddRow(1, 1, nil, 1, 0, "", "", "", "", 0, 0, 0, 0, "", 0, nil, "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", 0) + _repoRows := sqlmock.NewRows( + []string{"id", "user_id", "hash", "org", "name", "full_name", "link", "clone", "branch", "topics", "build_limit", "timeout", "counter", "visibility", "private", "trusted", "active", "allow_events", "pipeline_type", "previous_name", "approve_build"}). + AddRow(1, 1, "baz", "foo", "bar", "foo/bar", "", "", "", "{}", 0, 0, 0, "public", false, false, false, 1, "yaml", "", "") + + _userRows := sqlmock.NewRows( + []string{"id", "name", "token", "hash", "active", "admin"}). + AddRow(1, "foo", "bar", "baz", false, false) + // ensure the mock expects the query _mock.ExpectQuery(`SELECT * FROM "builds" WHERE repo_id = $1 AND number = $2 LIMIT $3`).WithArgs(1, 1, 1).WillReturnRows(_rows) + _mock.ExpectQuery(`SELECT * FROM "repos" WHERE "repos"."id" = $1`).WithArgs(1).WillReturnRows(_repoRows) + _mock.ExpectQuery(`SELECT * FROM "users" WHERE "users"."id" = $1`).WithArgs(1).WillReturnRows(_userRows) _sqlite := testSqlite(t) defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() @@ -49,12 +70,32 @@ func TestBuild_Engine_GetBuildForRepo(t *testing.T) { t.Errorf("unable to create test build for sqlite: %v", err) } + err = _sqlite.client.AutoMigrate(&types.Repo{}) + if err != nil { + t.Errorf("unable to create build table for sqlite: %v", err) + } + + err = _sqlite.client.Table(constants.TableRepo).Create(types.RepoFromAPI(_repo)).Error + if err != nil { + t.Errorf("unable to create test user for sqlite: %v", err) + } + + err = _sqlite.client.AutoMigrate(&types.User{}) + if err != nil { + t.Errorf("unable to create build table for sqlite: %v", err) + } + + err = _sqlite.client.Table(constants.TableUser).Create(types.UserFromAPI(_owner)).Error + if err != nil { + t.Errorf("unable to create test user for sqlite: %v", err) + } + // setup tests tests := []struct { failure bool name string database *engine - want *library.Build + want *api.Build }{ { failure: false, @@ -87,8 +128,8 @@ func TestBuild_Engine_GetBuildForRepo(t *testing.T) { t.Errorf("GetBuildForRepo for %s returned err: %v", test.name, err) } - if !reflect.DeepEqual(got, test.want) { - t.Errorf("GetBuildForRepo for %s is %v, want %v", test.name, got, test.want) + if diff := cmp.Diff(test.want, got); diff != "" { + t.Errorf("GetBuildForRepo for %s mismatch (-want +got):\n%s", test.name, diff) } }) } diff --git a/database/build/get_test.go b/database/build/get_test.go index 4df407ef7..e4a26d852 100644 --- a/database/build/get_test.go +++ b/database/build/get_test.go @@ -9,14 +9,34 @@ import ( "github.com/DATA-DOG/go-sqlmock" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" + "github.com/go-vela/server/database/types" + "github.com/go-vela/types/constants" ) func TestBuild_Engine_GetBuild(t *testing.T) { // setup types - _build := testBuild() + _owner := testutils.APIUser().Crop() + _owner.SetID(1) + _owner.SetName("foo") + _owner.SetToken("bar") + + _repo := testutils.APIRepo() + _repo.SetID(1) + _repo.SetOwner(_owner) + _repo.SetHash("baz") + _repo.SetOrg("foo") + _repo.SetName("bar") + _repo.SetFullName("foo/bar") + _repo.SetVisibility("public") + _repo.SetAllowEvents(api.NewEventsFromMask(1)) + _repo.SetPipelineType(constants.PipelineTypeYAML) + _repo.SetTopics([]string{}) + + _build := testutils.APIBuild() _build.SetID(1) - _build.SetRepoID(1) + _build.SetRepo(_repo) _build.SetNumber(1) _build.SetDeployPayload(nil) @@ -28,8 +48,18 @@ func TestBuild_Engine_GetBuild(t *testing.T) { []string{"id", "repo_id", "pipeline_id", "number", "parent", "event", "event_action", "status", "error", "enqueued", "created", "started", "finished", "deploy", "deploy_payload", "clone", "source", "title", "message", "commit", "sender", "author", "email", "link", "branch", "ref", "base_ref", "head_ref", "host", "runtime", "distribution", "approved_at", "approved_by", "timestamp"}). AddRow(1, 1, nil, 1, 0, "", "", "", "", 0, 0, 0, 0, "", nil, "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", 0, "", 0) + _repoRows := sqlmock.NewRows( + []string{"id", "user_id", "hash", "org", "name", "full_name", "link", "clone", "branch", "topics", "build_limit", "timeout", "counter", "visibility", "private", "trusted", "active", "allow_events", "pipeline_type", "previous_name", "approve_build"}). + AddRow(1, 1, "baz", "foo", "bar", "foo/bar", "", "", "", "{}", 0, 0, 0, "public", false, false, false, 1, "yaml", "", "") + + _userRows := sqlmock.NewRows( + []string{"id", "name", "token", "hash", "active", "admin"}). + AddRow(1, "foo", "bar", "baz", false, false) + // ensure the mock expects the query _mock.ExpectQuery(`SELECT * FROM "builds" WHERE id = $1 LIMIT $2`).WithArgs(1, 1).WillReturnRows(_rows) + _mock.ExpectQuery(`SELECT * FROM "repos" WHERE "repos"."id" = $1`).WithArgs(1).WillReturnRows(_repoRows) + _mock.ExpectQuery(`SELECT * FROM "users" WHERE "users"."id" = $1`).WithArgs(1).WillReturnRows(_userRows) _sqlite := testSqlite(t) defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() @@ -39,12 +69,32 @@ func TestBuild_Engine_GetBuild(t *testing.T) { t.Errorf("unable to create test build for sqlite: %v", err) } + err = _sqlite.client.AutoMigrate(&types.Repo{}) + if err != nil { + t.Errorf("unable to create build table for sqlite: %v", err) + } + + err = _sqlite.client.Table(constants.TableRepo).Create(types.RepoFromAPI(_repo)).Error + if err != nil { + t.Errorf("unable to create test user for sqlite: %v", err) + } + + err = _sqlite.client.AutoMigrate(&types.User{}) + if err != nil { + t.Errorf("unable to create build table for sqlite: %v", err) + } + + err = _sqlite.client.Table(constants.TableUser).Create(types.UserFromAPI(_owner)).Error + if err != nil { + t.Errorf("unable to create test user for sqlite: %v", err) + } + // setup tests tests := []struct { failure bool name string database *engine - want *library.Build + want *api.Build }{ { failure: false, diff --git a/database/build/interface.go b/database/build/interface.go index 03c6918b7..01fad378a 100644 --- a/database/build/interface.go +++ b/database/build/interface.go @@ -40,27 +40,27 @@ type BuildInterface interface { // CountBuildsForStatus defines a function that gets the count of builds by status. CountBuildsForStatus(context.Context, string, map[string]interface{}) (int64, error) // CreateBuild defines a function that creates a new build. - CreateBuild(context.Context, *library.Build) (*library.Build, error) + CreateBuild(context.Context, *api.Build) (*api.Build, error) // DeleteBuild defines a function that deletes an existing build. - DeleteBuild(context.Context, *library.Build) error + DeleteBuild(context.Context, *api.Build) error // GetBuild defines a function that gets a build by ID. - GetBuild(context.Context, int64) (*library.Build, error) + GetBuild(context.Context, int64) (*api.Build, error) // GetBuildForRepo defines a function that gets a build by repo ID and number. - GetBuildForRepo(context.Context, *api.Repo, int) (*library.Build, error) + GetBuildForRepo(context.Context, *api.Repo, int) (*api.Build, error) // LastBuildForRepo defines a function that gets the last build ran by repo ID and branch. - LastBuildForRepo(context.Context, *api.Repo, string) (*library.Build, error) + LastBuildForRepo(context.Context, *api.Repo, string) (*api.Build, error) // ListBuilds defines a function that gets a list of all builds. - ListBuilds(context.Context) ([]*library.Build, error) + ListBuilds(context.Context) ([]*api.Build, error) // ListBuildsForOrg defines a function that gets a list of builds by org name. - ListBuildsForOrg(context.Context, string, map[string]interface{}, int, int) ([]*library.Build, int64, error) + ListBuildsForOrg(context.Context, string, map[string]interface{}, int, int) ([]*api.Build, int64, error) // ListBuildsForDashboardRepo defines a function that gets a list of builds based on dashboard filters. - ListBuildsForDashboardRepo(context.Context, *api.Repo, []string, []string) ([]*library.Build, error) + ListBuildsForDashboardRepo(context.Context, *api.Repo, []string, []string) ([]*api.Build, error) // ListBuildsForRepo defines a function that gets a list of builds by repo ID. - ListBuildsForRepo(context.Context, *api.Repo, map[string]interface{}, int64, int64, int, int) ([]*library.Build, int64, error) + ListBuildsForRepo(context.Context, *api.Repo, map[string]interface{}, int64, int64, int, int) ([]*api.Build, int64, error) // ListPendingAndRunningBuilds defines a function that gets a list of pending and running builds. - ListPendingAndRunningBuilds(context.Context, string) ([]*library.BuildQueue, error) + ListPendingAndRunningBuilds(context.Context, string) ([]*api.QueueBuild, error) // ListPendingAndRunningBuildsForRepo defines a function that gets a list of pending and running builds for a repo. - ListPendingAndRunningBuildsForRepo(context.Context, *api.Repo) ([]*library.Build, error) + ListPendingAndRunningBuildsForRepo(context.Context, *api.Repo) ([]*api.Build, error) // UpdateBuild defines a function that updates an existing build. - UpdateBuild(context.Context, *library.Build) (*library.Build, error) + UpdateBuild(context.Context, *api.Build) (*api.Build, error) } diff --git a/database/build/last_repo.go b/database/build/last_repo.go index 3900e62d0..2795d2f47 100644 --- a/database/build/last_repo.go +++ b/database/build/last_repo.go @@ -10,24 +10,25 @@ import ( "gorm.io/gorm" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" ) // LastBuildForRepo gets the last build by repo ID and branch from the database. -func (e *engine) LastBuildForRepo(ctx context.Context, r *api.Repo, branch string) (*library.Build, error) { +func (e *engine) LastBuildForRepo(ctx context.Context, r *api.Repo, branch string) (*api.Build, error) { e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), }).Tracef("getting last build for repo %s from the database", r.GetFullName()) // variable to store query results - b := new(database.Build) + b := new(types.Build) // send query to the database and store result in variable err := e.client. Table(constants.TableBuild). + Preload("Repo"). + Preload("Repo.Owner"). Where("repo_id = ?", r.GetID()). Where("branch = ?", branch). Order("number DESC"). @@ -43,5 +44,10 @@ func (e *engine) LastBuildForRepo(ctx context.Context, r *api.Repo, branch strin return nil, err } - return b.ToLibrary(), nil + err = b.Repo.Decrypt(e.config.EncryptionKey) + if err != nil { + e.logger.Errorf("unable to decrypt repo %s/%s: %v", r.GetOrg(), r.GetName(), err) + } + + return b.ToAPI(), nil } diff --git a/database/build/last_repo_test.go b/database/build/last_repo_test.go index 5755d1318..140b79651 100644 --- a/database/build/last_repo_test.go +++ b/database/build/last_repo_test.go @@ -9,26 +9,37 @@ import ( "github.com/DATA-DOG/go-sqlmock" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" + "github.com/go-vela/server/database/types" + "github.com/go-vela/types/constants" ) func TestBuild_Engine_LastBuildForRepo(t *testing.T) { // setup types - _build := testBuild() - _build.SetID(1) - _build.SetRepoID(1) - _build.SetNumber(1) - _build.SetDeployPayload(nil) - _build.SetBranch("main") + _owner := testutils.APIUser().Crop() + _owner.SetID(1) + _owner.SetName("foo") + _owner.SetToken("bar") - _repo := testRepo() + _repo := testutils.APIRepo() _repo.SetID(1) - _repo.GetOwner().SetID(1) + _repo.SetOwner(_owner) _repo.SetHash("baz") _repo.SetOrg("foo") _repo.SetName("bar") _repo.SetFullName("foo/bar") _repo.SetVisibility("public") + _repo.SetAllowEvents(api.NewEventsFromMask(1)) + _repo.SetPipelineType(constants.PipelineTypeYAML) + _repo.SetTopics([]string{}) + + _build := testutils.APIBuild() + _build.SetID(1) + _build.SetRepo(_repo) + _build.SetNumber(1) + _build.SetDeployPayload(nil) + _build.SetBranch("main") _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() @@ -38,8 +49,18 @@ func TestBuild_Engine_LastBuildForRepo(t *testing.T) { []string{"id", "repo_id", "pipeline_id", "number", "parent", "event", "event_action", "status", "error", "enqueued", "created", "started", "finished", "deploy", "deploy_payload", "clone", "source", "title", "message", "commit", "sender", "author", "email", "link", "branch", "ref", "base_ref", "head_ref", "host", "runtime", "distribution", "approved_at", "approved_by", "timestamp"}). AddRow(1, 1, nil, 1, 0, "", "", "", "", 0, 0, 0, 0, "", nil, "", "", "", "", "", "", "", "", "", "main", "", "", "", "", "", "", 0, "", 0) + _repoRows := sqlmock.NewRows( + []string{"id", "user_id", "hash", "org", "name", "full_name", "link", "clone", "branch", "topics", "build_limit", "timeout", "counter", "visibility", "private", "trusted", "active", "allow_events", "pipeline_type", "previous_name", "approve_build"}). + AddRow(1, 1, "baz", "foo", "bar", "foo/bar", "", "", "", "{}", 0, 0, 0, "public", false, false, false, 1, "yaml", "", "") + + _userRows := sqlmock.NewRows( + []string{"id", "name", "token", "hash", "active", "admin"}). + AddRow(1, "foo", "bar", "baz", false, false) + // ensure the mock expects the query _mock.ExpectQuery(`SELECT * FROM "builds" WHERE repo_id = $1 AND branch = $2 ORDER BY number DESC LIMIT $3`).WithArgs(1, "main", 1).WillReturnRows(_rows) + _mock.ExpectQuery(`SELECT * FROM "repos" WHERE "repos"."id" = $1`).WithArgs(1).WillReturnRows(_repoRows) + _mock.ExpectQuery(`SELECT * FROM "users" WHERE "users"."id" = $1`).WithArgs(1).WillReturnRows(_userRows) _sqlite := testSqlite(t) defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() @@ -49,12 +70,32 @@ func TestBuild_Engine_LastBuildForRepo(t *testing.T) { t.Errorf("unable to create test build for sqlite: %v", err) } + err = _sqlite.client.AutoMigrate(&types.Repo{}) + if err != nil { + t.Errorf("unable to create build table for sqlite: %v", err) + } + + err = _sqlite.client.Table(constants.TableRepo).Create(types.RepoFromAPI(_repo)).Error + if err != nil { + t.Errorf("unable to create test user for sqlite: %v", err) + } + + err = _sqlite.client.AutoMigrate(&types.User{}) + if err != nil { + t.Errorf("unable to create build table for sqlite: %v", err) + } + + err = _sqlite.client.Table(constants.TableUser).Create(types.UserFromAPI(_owner)).Error + if err != nil { + t.Errorf("unable to create test user for sqlite: %v", err) + } + // setup tests tests := []struct { failure bool name string database *engine - want *library.Build + want *api.Build }{ { failure: false, diff --git a/database/build/list.go b/database/build/list.go index 109d2ae5f..2b5176d30 100644 --- a/database/build/list.go +++ b/database/build/list.go @@ -5,19 +5,19 @@ package build import ( "context" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" ) // ListBuilds gets a list of all builds from the database. -func (e *engine) ListBuilds(ctx context.Context) ([]*library.Build, error) { +func (e *engine) ListBuilds(ctx context.Context) ([]*api.Build, error) { e.logger.Trace("listing all builds from the database") // variables to store query results and return value count := int64(0) - b := new([]database.Build) - builds := []*library.Build{} + b := new([]types.Build) + builds := []*api.Build{} // count the results count, err := e.CountBuilds(ctx) @@ -32,6 +32,8 @@ func (e *engine) ListBuilds(ctx context.Context) ([]*library.Build, error) { // send query to the database and store result in variable err = e.client. + Preload("Repo"). + Preload("Repo.Owner"). Table(constants.TableBuild). Find(&b). Error @@ -44,10 +46,12 @@ func (e *engine) ListBuilds(ctx context.Context) ([]*library.Build, error) { // https://golang.org/doc/faq#closures_and_goroutines tmp := build - // convert query result to library type - // - // https://pkg.go.dev/github.com/go-vela/types/database#Build.ToLibrary - builds = append(builds, tmp.ToLibrary()) + err = tmp.Repo.Decrypt(e.config.EncryptionKey) + if err != nil { + e.logger.Errorf("unable to decrypt repo: %v", err) + } + + builds = append(builds, tmp.ToAPI()) } return builds, nil diff --git a/database/build/list_dashboard.go b/database/build/list_dashboard.go index d9f772873..10d2c378d 100644 --- a/database/build/list_dashboard.go +++ b/database/build/list_dashboard.go @@ -8,21 +8,20 @@ import ( "github.com/sirupsen/logrus" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" ) // ListBuildsForDashboardRepo gets a list of builds by repo ID from the database. -func (e *engine) ListBuildsForDashboardRepo(ctx context.Context, r *api.Repo, branches, events []string) ([]*library.Build, error) { +func (e *engine) ListBuildsForDashboardRepo(ctx context.Context, r *api.Repo, branches, events []string) ([]*api.Build, error) { e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), }).Tracef("listing builds for repo %s from the database", r.GetFullName()) // variables to store query results and return values - b := new([]database.Build) - builds := []*library.Build{} + b := new([]types.Build) + builds := []*api.Build{} query := e.client.Table(constants.TableBuild).Where("repo_id = ?", r.GetID()) @@ -48,10 +47,7 @@ func (e *engine) ListBuildsForDashboardRepo(ctx context.Context, r *api.Repo, br // https://golang.org/doc/faq#closures_and_goroutines tmp := build - // convert query result to library type - // - // https://pkg.go.dev/github.com/go-vela/types/database#Build.ToLibrary - builds = append(builds, tmp.ToLibrary()) + builds = append(builds, tmp.ToAPI()) } return builds, nil diff --git a/database/build/list_dashboard_test.go b/database/build/list_dashboard_test.go index e73242efb..81a042296 100644 --- a/database/build/list_dashboard_test.go +++ b/database/build/list_dashboard_test.go @@ -9,36 +9,41 @@ import ( "github.com/DATA-DOG/go-sqlmock" "github.com/google/go-cmp/cmp" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" ) func TestBuild_Engine_ListBuildsForDashboardRepo(t *testing.T) { // setup types - _buildOne := testBuild() + _repo := testutils.APIRepo() + _repo.SetID(1) + + _buildOne := testutils.APIBuild() _buildOne.SetID(1) - _buildOne.SetRepoID(1) + _buildOne.SetRepo(_repo) _buildOne.SetNumber(1) _buildOne.SetDeployPayload(nil) _buildOne.SetCreated(1) _buildOne.SetEvent("push") _buildOne.SetBranch("main") - _buildTwo := testBuild() + _buildTwo := testutils.APIBuild() _buildTwo.SetID(2) - _buildTwo.SetRepoID(1) + _buildTwo.SetRepo(_repo) _buildTwo.SetNumber(2) _buildTwo.SetDeployPayload(nil) _buildTwo.SetCreated(2) _buildTwo.SetEvent("pull_request") _buildTwo.SetBranch("main") - _repo := testRepo() - _repo.SetID(1) - _repo.SetHash("baz") - _repo.SetOrg("foo") - _repo.SetName("bar") - _repo.SetFullName("foo/bar") - _repo.SetVisibility("public") + // ListBuildsForDashboardRepo does not return the repo object but the repo ID is needed to create builds + _wantBuildOne := *_buildOne + _wantBuildOne.Repo = testutils.APIRepo() + _wantBuildOne.Repo.Owner = testutils.APIUser().Crop() + + _wantBuildTwo := *_buildTwo + _wantBuildTwo.Repo = testutils.APIRepo() + _wantBuildTwo.Repo.Owner = testutils.APIUser().Crop() _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() @@ -70,19 +75,19 @@ func TestBuild_Engine_ListBuildsForDashboardRepo(t *testing.T) { failure bool name string database *engine - want []*library.Build + want []*api.Build }{ { failure: false, name: "postgres", database: _postgres, - want: []*library.Build{_buildTwo, _buildOne}, + want: []*api.Build{&_wantBuildTwo, &_wantBuildOne}, }, { failure: false, name: "sqlite3", database: _sqlite, - want: []*library.Build{_buildTwo, _buildOne}, + want: []*api.Build{&_wantBuildTwo, &_wantBuildOne}, }, } @@ -103,7 +108,7 @@ func TestBuild_Engine_ListBuildsForDashboardRepo(t *testing.T) { t.Errorf("ListBuildsForRepo for %s returned err: %v", test.name, err) } - if diff := cmp.Diff(got, test.want); diff != "" { + if diff := cmp.Diff(test.want, got); diff != "" { t.Errorf("GetDashboard mismatch (-want +got):\n%s", diff) } }) diff --git a/database/build/list_org.go b/database/build/list_org.go index ef7ef140a..0799635b4 100644 --- a/database/build/list_org.go +++ b/database/build/list_org.go @@ -7,23 +7,23 @@ import ( "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" ) // ListBuildsForOrg gets a list of builds by org name from the database. // //nolint:lll // ignore long line length due to variable names -func (e *engine) ListBuildsForOrg(ctx context.Context, org string, filters map[string]interface{}, page, perPage int) ([]*library.Build, int64, error) { +func (e *engine) ListBuildsForOrg(ctx context.Context, org string, filters map[string]interface{}, page, perPage int) ([]*api.Build, int64, error) { e.logger.WithFields(logrus.Fields{ "org": org, }).Tracef("listing builds for org %s from the database", org) // variables to store query results and return values count := int64(0) - b := new([]database.Build) - builds := []*library.Build{} + b := new([]types.Build) + builds := []*api.Build{} // count the results count, err := e.CountBuildsForOrg(ctx, org, filters) @@ -41,6 +41,8 @@ func (e *engine) ListBuildsForOrg(ctx context.Context, org string, filters map[s err = e.client. Table(constants.TableBuild). + Preload("Repo"). + Preload("Repo.Owner"). Select("builds.*"). Joins("JOIN repos ON builds.repo_id = repos.id"). Where("repos.org = ?", org). @@ -60,10 +62,12 @@ func (e *engine) ListBuildsForOrg(ctx context.Context, org string, filters map[s // https://golang.org/doc/faq#closures_and_goroutines tmp := build - // convert query result to library type - // - // https://pkg.go.dev/github.com/go-vela/types/database#Build.ToLibrary - builds = append(builds, tmp.ToLibrary()) + err = tmp.Repo.Decrypt(e.config.EncryptionKey) + if err != nil { + e.logger.Errorf("unable to decrypt repo: %v", err) + } + + builds = append(builds, tmp.ToAPI()) } return builds, count, nil diff --git a/database/build/list_org_test.go b/database/build/list_org_test.go index 488cf1e33..4d25d6062 100644 --- a/database/build/list_org_test.go +++ b/database/build/list_org_test.go @@ -4,54 +4,62 @@ package build import ( "context" - "reflect" "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/google/go-cmp/cmp" - "github.com/go-vela/server/database/repo" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" ) func TestBuild_Engine_ListBuildsForOrg(t *testing.T) { // setup types - _buildOne := testBuild() - _buildOne.SetID(1) - _buildOne.SetRepoID(1) - _buildOne.SetNumber(1) - _buildOne.SetDeployPayload(nil) - _buildOne.SetEvent("push") - - _buildTwo := testBuild() - _buildTwo.SetID(2) - _buildTwo.SetRepoID(2) - _buildTwo.SetNumber(2) - _buildTwo.SetDeployPayload(nil) - _buildTwo.SetEvent("push") + _owner := testutils.APIUser().Crop() + _owner.SetID(1) + _owner.SetName("foo") + _owner.SetToken("bar") - _repoOne := testRepo() + _repoOne := testutils.APIRepo() _repoOne.SetID(1) - _repoOne.GetOwner().SetID(1) + _repoOne.SetOwner(_owner) _repoOne.SetHash("baz") _repoOne.SetOrg("foo") _repoOne.SetName("bar") _repoOne.SetFullName("foo/bar") _repoOne.SetVisibility("public") _repoOne.SetPipelineType("yaml") + _repoOne.SetAllowEvents(api.NewEventsFromMask(1)) _repoOne.SetTopics([]string{}) - _repoTwo := testRepo() + _repoTwo := testutils.APIRepo() _repoTwo.SetID(2) - _repoTwo.GetOwner().SetID(1) + _repoTwo.SetOwner(_owner) _repoTwo.SetHash("bar") _repoTwo.SetOrg("foo") _repoTwo.SetName("baz") _repoTwo.SetFullName("foo/baz") _repoTwo.SetVisibility("public") _repoTwo.SetPipelineType("yaml") + _repoTwo.SetAllowEvents(api.NewEventsFromMask(1)) _repoTwo.SetTopics([]string{}) + _buildOne := testutils.APIBuild() + _buildOne.SetID(1) + _buildOne.SetRepo(_repoOne) + _buildOne.SetNumber(1) + _buildOne.SetDeployPayload(nil) + _buildOne.SetEvent("push") + + _buildTwo := testutils.APIBuild() + _buildTwo.SetID(2) + _buildTwo.SetRepo(_repoTwo) + _buildTwo.SetNumber(2) + _buildTwo.SetDeployPayload(nil) + _buildTwo.SetEvent("push") + _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() @@ -64,8 +72,20 @@ func TestBuild_Engine_ListBuildsForOrg(t *testing.T) { []string{"id", "repo_id", "pipeline_id", "number", "parent", "event", "event_action", "status", "error", "enqueued", "created", "started", "finished", "deploy", "deploy_payload", "clone", "source", "title", "message", "commit", "sender", "author", "email", "link", "branch", "ref", "base_ref", "head_ref", "host", "runtime", "distribution", "approved_at", "approved_by", "timestamp"}). AddRow(1, 1, nil, 1, 0, "push", "", "", "", 0, 0, 0, 0, "", nil, "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", 0, "", 0). AddRow(2, 2, nil, 2, 0, "push", "", "", "", 0, 0, 0, 0, "", nil, "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", 0, "", 0) + + _repoRows := sqlmock.NewRows( + []string{"id", "user_id", "hash", "org", "name", "full_name", "link", "clone", "branch", "topics", "build_limit", "timeout", "counter", "visibility", "private", "trusted", "active", "allow_events", "pipeline_type", "previous_name", "approve_build"}). + AddRow(1, 1, "baz", "foo", "bar", "foo/bar", "", "", "", "{}", 0, 0, 0, "public", false, false, false, 1, "yaml", "", ""). + AddRow(2, 1, "bar", "foo", "baz", "foo/baz", "", "", "", "{}", 0, 0, 0, "public", false, false, false, 1, "yaml", "", "") + + _userRows := sqlmock.NewRows( + []string{"id", "name", "token", "hash", "active", "admin"}). + AddRow(1, "foo", "bar", "baz", false, false) + // ensure the mock expects the query without filters _mock.ExpectQuery(`SELECT builds.* FROM "builds" JOIN repos ON builds.repo_id = repos.id WHERE repos.org = $1 ORDER BY created DESC,id LIMIT $2`).WithArgs("foo", 10).WillReturnRows(_rows) + _mock.ExpectQuery(`SELECT * FROM "repos" WHERE "repos"."id" IN ($1,$2)`).WithArgs(1, 2).WillReturnRows(_repoRows) + _mock.ExpectQuery(`SELECT * FROM "users" WHERE "users"."id" = $1`).WithArgs(1).WillReturnRows(_userRows) // create expected count query with event filter result in mock _rows = sqlmock.NewRows([]string{"count"}).AddRow(2) @@ -76,8 +96,20 @@ func TestBuild_Engine_ListBuildsForOrg(t *testing.T) { []string{"id", "repo_id", "pipeline_id", "number", "parent", "event", "event_action", "status", "error", "enqueued", "created", "started", "finished", "deploy", "deploy_payload", "clone", "source", "title", "message", "commit", "sender", "author", "email", "link", "branch", "ref", "base_ref", "head_ref", "host", "runtime", "distribution", "approved_at", "approved_by", "timestamp"}). AddRow(1, 1, nil, 1, 0, "push", "", "", "", 0, 0, 0, 0, "", nil, "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", 0, "", 0). AddRow(2, 2, nil, 2, 0, "push", "", "", "", 0, 0, 0, 0, "", nil, "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", 0, "", 0) + + _repoRows = sqlmock.NewRows( + []string{"id", "user_id", "hash", "org", "name", "full_name", "link", "clone", "branch", "topics", "build_limit", "timeout", "counter", "visibility", "private", "trusted", "active", "allow_events", "pipeline_type", "previous_name", "approve_build"}). + AddRow(1, 1, "baz", "foo", "bar", "foo/bar", "", "", "", "{}", 0, 0, 0, "public", false, false, false, 1, "yaml", "", ""). + AddRow(2, 1, "bar", "foo", "baz", "foo/baz", "", "", "", "{}", 0, 0, 0, "public", false, false, false, 1, "yaml", "", "") + + _userRows = sqlmock.NewRows( + []string{"id", "name", "token", "hash", "active", "admin"}). + AddRow(1, "foo", "bar", "baz", false, false) + // ensure the mock expects the query with event filter _mock.ExpectQuery(`SELECT builds.* FROM "builds" JOIN repos ON builds.repo_id = repos.id WHERE repos.org = $1 AND "event" = $2 ORDER BY created DESC,id LIMIT $3`).WithArgs("foo", "push", 10).WillReturnRows(_rows) + _mock.ExpectQuery(`SELECT * FROM "repos" WHERE "repos"."id" IN ($1,$2)`).WithArgs(1, 2).WillReturnRows(_repoRows) + _mock.ExpectQuery(`SELECT * FROM "users" WHERE "users"."id" = $1`).WithArgs(1).WillReturnRows(_userRows) // create expected count query with visibility filter result in mock _rows = sqlmock.NewRows([]string{"count"}).AddRow(2) @@ -88,8 +120,20 @@ func TestBuild_Engine_ListBuildsForOrg(t *testing.T) { []string{"id", "repo_id", "pipeline_id", "number", "parent", "event", "event_action", "status", "error", "enqueued", "created", "started", "finished", "deploy", "deploy_payload", "clone", "source", "title", "message", "commit", "sender", "author", "email", "link", "branch", "ref", "base_ref", "head_ref", "host", "runtime", "distribution", "approved_at", "approved_by", "timestamp"}). AddRow(1, 1, nil, 1, 0, "push", "", "", "", 0, 0, 0, 0, "", nil, "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", 0, "", 0). AddRow(2, 2, nil, 2, 0, "push", "", "", "", 0, 0, 0, 0, "", nil, "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", 0, "", 0) + + _repoRows = sqlmock.NewRows( + []string{"id", "user_id", "hash", "org", "name", "full_name", "link", "clone", "branch", "topics", "build_limit", "timeout", "counter", "visibility", "private", "trusted", "active", "allow_events", "pipeline_type", "previous_name", "approve_build"}). + AddRow(1, 1, "baz", "foo", "bar", "foo/bar", "", "", "", "{}", 0, 0, 0, "public", false, false, false, 1, "yaml", "", ""). + AddRow(2, 1, "bar", "foo", "baz", "foo/baz", "", "", "", "{}", 0, 0, 0, "public", false, false, false, 1, "yaml", "", "") + + _userRows = sqlmock.NewRows( + []string{"id", "name", "token", "hash", "active", "admin"}). + AddRow(1, "foo", "bar", "baz", false, false) + // ensure the mock expects the query with visibility filter _mock.ExpectQuery(`SELECT builds.* FROM "builds" JOIN repos ON builds.repo_id = repos.id WHERE repos.org = $1 AND "visibility" = $2 ORDER BY created DESC,id LIMIT $3`).WithArgs("foo", "public", 10).WillReturnRows(_rows) + _mock.ExpectQuery(`SELECT * FROM "repos" WHERE "repos"."id" IN ($1,$2)`).WithArgs(1, 2).WillReturnRows(_repoRows) + _mock.ExpectQuery(`SELECT * FROM "users" WHERE "users"."id" = $1`).WithArgs(1).WillReturnRows(_userRows) _sqlite := testSqlite(t) defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() @@ -104,35 +148,45 @@ func TestBuild_Engine_ListBuildsForOrg(t *testing.T) { t.Errorf("unable to create test build for sqlite: %v", err) } - err = _sqlite.client.AutoMigrate(&repo.Repo{}) + err = _sqlite.client.AutoMigrate(&types.Repo{}) if err != nil { t.Errorf("unable to create repo table for sqlite: %v", err) } - err = _sqlite.client.Table(constants.TableRepo).Create(repo.FromAPI(_repoOne)).Error + err = _sqlite.client.Table(constants.TableRepo).Create(types.RepoFromAPI(_repoOne)).Error if err != nil { t.Errorf("unable to create test repo for sqlite: %v", err) } - err = _sqlite.client.Table(constants.TableRepo).Create(repo.FromAPI(_repoTwo)).Error + err = _sqlite.client.Table(constants.TableRepo).Create(types.RepoFromAPI(_repoTwo)).Error if err != nil { t.Errorf("unable to create test repo for sqlite: %v", err) } + err = _sqlite.client.AutoMigrate(&types.User{}) + if err != nil { + t.Errorf("unable to create build table for sqlite: %v", err) + } + + err = _sqlite.client.Table(constants.TableUser).Create(types.UserFromAPI(_owner)).Error + if err != nil { + t.Errorf("unable to create test user for sqlite: %v", err) + } + // setup tests tests := []struct { failure bool name string database *engine filters map[string]interface{} - want []*library.Build + want []*api.Build }{ { failure: false, name: "postgres without filters", database: _postgres, filters: map[string]interface{}{}, - want: []*library.Build{_buildOne, _buildTwo}, + want: []*api.Build{_buildOne, _buildTwo}, }, { failure: false, @@ -141,7 +195,7 @@ func TestBuild_Engine_ListBuildsForOrg(t *testing.T) { filters: map[string]interface{}{ "event": "push", }, - want: []*library.Build{_buildOne, _buildTwo}, + want: []*api.Build{_buildOne, _buildTwo}, }, { failure: false, @@ -150,14 +204,14 @@ func TestBuild_Engine_ListBuildsForOrg(t *testing.T) { filters: map[string]interface{}{ "visibility": "public", }, - want: []*library.Build{_buildOne, _buildTwo}, + want: []*api.Build{_buildOne, _buildTwo}, }, { failure: false, name: "sqlite3 without filters", database: _sqlite, filters: map[string]interface{}{}, - want: []*library.Build{_buildOne, _buildTwo}, + want: []*api.Build{_buildOne, _buildTwo}, }, { failure: false, @@ -166,7 +220,7 @@ func TestBuild_Engine_ListBuildsForOrg(t *testing.T) { filters: map[string]interface{}{ "event": "push", }, - want: []*library.Build{_buildOne, _buildTwo}, + want: []*api.Build{_buildOne, _buildTwo}, }, { failure: false, @@ -175,7 +229,7 @@ func TestBuild_Engine_ListBuildsForOrg(t *testing.T) { filters: map[string]interface{}{ "visibility": "public", }, - want: []*library.Build{_buildOne, _buildTwo}, + want: []*api.Build{_buildOne, _buildTwo}, }, } @@ -196,8 +250,8 @@ func TestBuild_Engine_ListBuildsForOrg(t *testing.T) { t.Errorf("ListBuildsForOrg for %s returned err: %v", test.name, err) } - if !reflect.DeepEqual(got, test.want) { - t.Errorf("ListBuildsForOrg for %s is %v, want %v", test.name, got, test.want) + if diff := cmp.Diff(test.want, got); diff != "" { + t.Errorf("ListBuildsForOrg for %s mismatch (-want +got):\n%s", test.name, diff) } }) } diff --git a/database/build/list_pending_running.go b/database/build/list_pending_running.go index de4b4ac68..ae40ece51 100644 --- a/database/build/list_pending_running.go +++ b/database/build/list_pending_running.go @@ -5,18 +5,18 @@ package build import ( "context" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" ) // ListPendingAndRunningBuilds gets a list of all pending and running builds in the provided timeframe from the database. -func (e *engine) ListPendingAndRunningBuilds(ctx context.Context, after string) ([]*library.BuildQueue, error) { +func (e *engine) ListPendingAndRunningBuilds(ctx context.Context, after string) ([]*api.QueueBuild, error) { e.logger.Trace("listing all pending and running builds from the database") // variables to store query results and return value - b := new([]database.BuildQueue) - builds := []*library.BuildQueue{} + b := new([]types.QueueBuild) + builds := []*api.QueueBuild{} // send query to the database and store result in variable err := e.client. @@ -36,10 +36,7 @@ func (e *engine) ListPendingAndRunningBuilds(ctx context.Context, after string) // https://golang.org/doc/faq#closures_and_goroutines tmp := build - // convert query result to library type - // - // https://pkg.go.dev/github.com/go-vela/types/database#Build.ToLibrary - builds = append(builds, tmp.ToLibrary()) + builds = append(builds, tmp.ToAPI()) } return builds, nil diff --git a/database/build/list_pending_running_repo.go b/database/build/list_pending_running_repo.go index 119b78625..6213bab29 100644 --- a/database/build/list_pending_running_repo.go +++ b/database/build/list_pending_running_repo.go @@ -6,22 +6,23 @@ import ( "context" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" ) // ListPendingAndRunningBuilds gets a list of all pending and running builds in the provided timeframe from the database. -func (e *engine) ListPendingAndRunningBuildsForRepo(ctx context.Context, repo *api.Repo) ([]*library.Build, error) { +func (e *engine) ListPendingAndRunningBuildsForRepo(ctx context.Context, repo *api.Repo) ([]*api.Build, error) { e.logger.Trace("listing all pending and running builds from the database") // variables to store query results and return value - b := new([]database.Build) - builds := []*library.Build{} + b := new([]types.Build) + builds := []*api.Build{} // send query to the database and store result in variable err := e.client. Table(constants.TableBuild). + Preload("Repo"). + Preload("Repo.Owner"). Select("*"). Where("repo_id = ?", repo.GetID()). Where("status = 'running' OR status = 'pending' OR status = 'pending approval'"). @@ -36,10 +37,12 @@ func (e *engine) ListPendingAndRunningBuildsForRepo(ctx context.Context, repo *a // https://golang.org/doc/faq#closures_and_goroutines tmp := build - // convert query result to library type - // - // https://pkg.go.dev/github.com/go-vela/types/database#Build.ToLibrary - builds = append(builds, tmp.ToLibrary()) + err = tmp.Repo.Decrypt(e.config.EncryptionKey) + if err != nil { + e.logger.Errorf("unable to decrypt repo %s/%s: %v", repo.GetOrg(), repo.GetName(), err) + } + + builds = append(builds, tmp.ToAPI()) } return builds, nil diff --git a/database/build/list_pending_running_repo_test.go b/database/build/list_pending_running_repo_test.go index 8ea610fb6..286b68141 100644 --- a/database/build/list_pending_running_repo_test.go +++ b/database/build/list_pending_running_repo_test.go @@ -4,60 +4,72 @@ package build import ( "context" - "reflect" "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/google/go-cmp/cmp" - "github.com/go-vela/server/database/repo" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" ) func TestBuild_Engine_ListPendingAndRunningBuildsForRepo(t *testing.T) { // setup types - _buildOne := testBuild() + _owner := testutils.APIUser().Crop() + _owner.SetID(1) + _owner.SetName("foo") + _owner.SetToken("bar") + + _repoOne := testutils.APIRepo() + _repoOne.SetID(1) + _repoOne.SetOwner(_owner) + _repoOne.SetHash("baz") + _repoOne.SetOrg("foo") + _repoOne.SetName("bar") + _repoOne.SetFullName("foo/bar") + _repoOne.SetVisibility("public") + _repoOne.SetPipelineType("yaml") + _repoOne.SetAllowEvents(api.NewEventsFromMask(1)) + _repoOne.SetTopics([]string{}) + + _repoTwo := testutils.APIRepo() + _repoTwo.SetID(2) + _repoTwo.SetOwner(_owner) + _repoTwo.SetHash("bar") + _repoTwo.SetOrg("foo") + _repoTwo.SetName("baz") + _repoTwo.SetFullName("foo/baz") + _repoTwo.SetVisibility("public") + _repoTwo.SetPipelineType("yaml") + _repoTwo.SetAllowEvents(api.NewEventsFromMask(1)) + _repoTwo.SetTopics([]string{}) + + _buildOne := testutils.APIBuild() _buildOne.SetID(1) - _buildOne.SetRepoID(1) + _buildOne.SetRepo(_repoOne) _buildOne.SetNumber(1) _buildOne.SetStatus("running") _buildOne.SetCreated(1) _buildOne.SetDeployPayload(nil) - _buildTwo := testBuild() + _buildTwo := testutils.APIBuild() _buildTwo.SetID(2) - _buildTwo.SetRepoID(1) + _buildTwo.SetRepo(_repoOne) _buildTwo.SetNumber(2) _buildTwo.SetStatus("pending") _buildTwo.SetCreated(1) _buildTwo.SetDeployPayload(nil) - _buildThree := testBuild() + _buildThree := testutils.APIBuild() _buildThree.SetID(3) - _buildThree.SetRepoID(2) + _buildThree.SetRepo(_repoTwo) _buildThree.SetNumber(1) _buildThree.SetStatus("pending") _buildThree.SetCreated(1) _buildThree.SetDeployPayload(nil) - _repo := testRepo() - _repo.SetID(1) - _repo.GetOwner().SetID(1) - _repo.SetHash("baz") - _repo.SetOrg("foo") - _repo.SetName("bar") - _repo.SetFullName("foo/bar") - _repo.SetVisibility("public") - - _repoTwo := testRepo() - _repoTwo.SetID(2) - _repoTwo.GetOwner().SetID(1) - _repoTwo.SetHash("bazzy") - _repoTwo.SetOrg("foo") - _repoTwo.SetName("baz") - _repoTwo.SetFullName("foo/baz") - _repoTwo.SetVisibility("public") - _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() @@ -67,8 +79,18 @@ func TestBuild_Engine_ListPendingAndRunningBuildsForRepo(t *testing.T) { AddRow(2, 1, nil, 2, 0, "", "", "pending", "", 0, 1, 0, 0, "", nil, "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", 0, "", 0). AddRow(1, 1, nil, 1, 0, "", "", "running", "", 0, 1, 0, 0, "", nil, "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", 0, "", 0) + _repoRows := sqlmock.NewRows( + []string{"id", "user_id", "hash", "org", "name", "full_name", "link", "clone", "branch", "topics", "build_limit", "timeout", "counter", "visibility", "private", "trusted", "active", "allow_events", "pipeline_type", "previous_name", "approve_build"}). + AddRow(1, 1, "baz", "foo", "bar", "foo/bar", "", "", "", "{}", 0, 0, 0, "public", false, false, false, 1, "yaml", "", "") + + _userRows := sqlmock.NewRows( + []string{"id", "name", "token", "hash", "active", "admin"}). + AddRow(1, "foo", "bar", "baz", false, false) + // ensure the mock expects the name query _mock.ExpectQuery(`SELECT * FROM "builds" WHERE repo_id = $1 AND (status = 'running' OR status = 'pending' OR status = 'pending approval')`).WithArgs(1).WillReturnRows(_rows) + _mock.ExpectQuery(`SELECT * FROM "repos" WHERE "repos"."id" = $1`).WithArgs(1).WillReturnRows(_repoRows) + _mock.ExpectQuery(`SELECT * FROM "users" WHERE "users"."id" = $1`).WithArgs(1).WillReturnRows(_userRows) _sqlite := testSqlite(t) defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() @@ -88,46 +110,56 @@ func TestBuild_Engine_ListPendingAndRunningBuildsForRepo(t *testing.T) { t.Errorf("unable to create test build for sqlite: %v", err) } - err = _sqlite.client.AutoMigrate(&repo.Repo{}) + err = _sqlite.client.AutoMigrate(&types.Repo{}) if err != nil { t.Errorf("unable to create repo table for sqlite: %v", err) } - err = _sqlite.client.Table(constants.TableRepo).Create(repo.FromAPI(_repo)).Error + err = _sqlite.client.Table(constants.TableRepo).Create(types.RepoFromAPI(_repoOne)).Error if err != nil { t.Errorf("unable to create test repo for sqlite: %v", err) } - err = _sqlite.client.Table(constants.TableRepo).Create(repo.FromAPI(_repoTwo)).Error + err = _sqlite.client.Table(constants.TableRepo).Create(types.RepoFromAPI(_repoTwo)).Error if err != nil { t.Errorf("unable to create test repo for sqlite: %v", err) } + err = _sqlite.client.AutoMigrate(&types.User{}) + if err != nil { + t.Errorf("unable to create build table for sqlite: %v", err) + } + + err = _sqlite.client.Table(constants.TableUser).Create(types.UserFromAPI(_owner)).Error + if err != nil { + t.Errorf("unable to create test user for sqlite: %v", err) + } + // setup tests tests := []struct { failure bool name string database *engine - want []*library.Build + want []*api.Build }{ { failure: false, name: "postgres", database: _postgres, - want: []*library.Build{_buildTwo, _buildOne}, + want: []*api.Build{_buildTwo, _buildOne}, }, { failure: false, name: "sqlite3", database: _sqlite, - want: []*library.Build{_buildOne, _buildTwo}, + want: []*api.Build{_buildOne, _buildTwo}, }, } // run tests for _, test := range tests { t.Run(test.name, func(t *testing.T) { - got, err := test.database.ListPendingAndRunningBuildsForRepo(context.TODO(), _repo) + got, err := test.database.ListPendingAndRunningBuildsForRepo(context.TODO(), _repoOne) if test.failure { if err == nil { @@ -141,8 +173,8 @@ func TestBuild_Engine_ListPendingAndRunningBuildsForRepo(t *testing.T) { t.Errorf("ListPendingAndRunningBuildsForRepo for %s returned err: %v", test.name, err) } - if !reflect.DeepEqual(got, test.want) { - t.Errorf("ListPendingAndRunningBuildsForRepo for %s is %v, want %v", test.name, got, test.want) + if diff := cmp.Diff(test.want, got); diff != "" { + t.Errorf("ListPendingAndRunningBuildsForRepo for %s mismatch (-want +got):\n%s", test.name, diff) } }) } diff --git a/database/build/list_pending_running_test.go b/database/build/list_pending_running_test.go index 5b427702f..c164827d8 100644 --- a/database/build/list_pending_running_test.go +++ b/database/build/list_pending_running_test.go @@ -9,50 +9,56 @@ import ( "github.com/DATA-DOG/go-sqlmock" - "github.com/go-vela/server/database/repo" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" ) func TestBuild_Engine_ListPendingAndRunningBuilds(t *testing.T) { // setup types - _buildOne := testBuild() + _owner := testutils.APIUser().Crop() + _owner.SetID(1) + _owner.SetName("foo") + _owner.SetToken("bar") + + _repo := testutils.APIRepo() + _repo.SetID(1) + _repo.SetOwner(_owner) + _repo.SetHash("baz") + _repo.SetOrg("foo") + _repo.SetName("bar") + _repo.SetFullName("foo/bar") + _repo.SetVisibility("public") + + _buildOne := testutils.APIBuild() _buildOne.SetID(1) - _buildOne.SetRepoID(1) + _buildOne.SetRepo(_repo) _buildOne.SetNumber(1) _buildOne.SetStatus("running") _buildOne.SetCreated(1) _buildOne.SetDeployPayload(nil) - _buildTwo := testBuild() + _buildTwo := testutils.APIBuild() _buildTwo.SetID(2) - _buildTwo.SetRepoID(1) + _buildTwo.SetRepo(_repo) _buildTwo.SetNumber(2) _buildTwo.SetStatus("pending") _buildTwo.SetCreated(1) _buildTwo.SetDeployPayload(nil) - _queueOne := new(library.BuildQueue) + _queueOne := new(api.QueueBuild) _queueOne.SetCreated(1) _queueOne.SetFullName("foo/bar") _queueOne.SetNumber(1) _queueOne.SetStatus("running") - _queueTwo := new(library.BuildQueue) + _queueTwo := new(api.QueueBuild) _queueTwo.SetCreated(1) _queueTwo.SetFullName("foo/bar") _queueTwo.SetNumber(2) _queueTwo.SetStatus("pending") - _repo := testRepo() - _repo.SetID(1) - _repo.GetOwner().SetID(1) - _repo.SetHash("baz") - _repo.SetOrg("foo") - _repo.SetName("bar") - _repo.SetFullName("foo/bar") - _repo.SetVisibility("public") - _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() @@ -75,12 +81,12 @@ func TestBuild_Engine_ListPendingAndRunningBuilds(t *testing.T) { t.Errorf("unable to create test build for sqlite: %v", err) } - err = _sqlite.client.AutoMigrate(&repo.Repo{}) + err = _sqlite.client.AutoMigrate(&types.Repo{}) if err != nil { t.Errorf("unable to create repo table for sqlite: %v", err) } - err = _sqlite.client.Table(constants.TableRepo).Create(repo.FromAPI(_repo)).Error + err = _sqlite.client.Table(constants.TableRepo).Create(types.RepoFromAPI(_repo)).Error if err != nil { t.Errorf("unable to create test repo for sqlite: %v", err) } @@ -90,19 +96,19 @@ func TestBuild_Engine_ListPendingAndRunningBuilds(t *testing.T) { failure bool name string database *engine - want []*library.BuildQueue + want []*api.QueueBuild }{ { failure: false, name: "postgres", database: _postgres, - want: []*library.BuildQueue{_queueTwo, _queueOne}, + want: []*api.QueueBuild{_queueTwo, _queueOne}, }, { failure: false, name: "sqlite3", database: _sqlite, - want: []*library.BuildQueue{_queueTwo, _queueOne}, + want: []*api.QueueBuild{_queueTwo, _queueOne}, }, } diff --git a/database/build/list_repo.go b/database/build/list_repo.go index 87f8c3389..753c941c2 100644 --- a/database/build/list_repo.go +++ b/database/build/list_repo.go @@ -8,15 +8,14 @@ import ( "github.com/sirupsen/logrus" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" ) // ListBuildsForRepo gets a list of builds by repo ID from the database. // //nolint:lll // ignore long line length due to variable names -func (e *engine) ListBuildsForRepo(ctx context.Context, r *api.Repo, filters map[string]interface{}, before, after int64, page, perPage int) ([]*library.Build, int64, error) { +func (e *engine) ListBuildsForRepo(ctx context.Context, r *api.Repo, filters map[string]interface{}, before, after int64, page, perPage int) ([]*api.Build, int64, error) { e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), @@ -24,8 +23,8 @@ func (e *engine) ListBuildsForRepo(ctx context.Context, r *api.Repo, filters map // variables to store query results and return values count := int64(0) - b := new([]database.Build) - builds := []*library.Build{} + b := new([]types.Build) + builds := []*api.Build{} // count the results count, err := e.CountBuildsForRepo(ctx, r, filters) @@ -43,6 +42,8 @@ func (e *engine) ListBuildsForRepo(ctx context.Context, r *api.Repo, filters map err = e.client. Table(constants.TableBuild). + Preload("Repo"). + Preload("Repo.Owner"). Where("repo_id = ?", r.GetID()). Where("created < ?", before). Where("created > ?", after). @@ -61,10 +62,12 @@ func (e *engine) ListBuildsForRepo(ctx context.Context, r *api.Repo, filters map // https://golang.org/doc/faq#closures_and_goroutines tmp := build - // convert query result to library type - // - // https://pkg.go.dev/github.com/go-vela/types/database#Build.ToLibrary - builds = append(builds, tmp.ToLibrary()) + err = tmp.Repo.Decrypt(e.config.EncryptionKey) + if err != nil { + e.logger.Errorf("unable to decrypt repo %s/%s: %v", r.GetOrg(), r.GetName(), err) + } + + builds = append(builds, tmp.ToAPI()) } return builds, count, nil diff --git a/database/build/list_repo_test.go b/database/build/list_repo_test.go index 1f0e0fb9d..96368faec 100644 --- a/database/build/list_repo_test.go +++ b/database/build/list_repo_test.go @@ -10,34 +10,45 @@ import ( "github.com/DATA-DOG/go-sqlmock" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" + "github.com/go-vela/server/database/types" + "github.com/go-vela/types/constants" ) func TestBuild_Engine_ListBuildsForRepo(t *testing.T) { // setup types - _buildOne := testBuild() + _owner := testutils.APIUser().Crop() + _owner.SetID(1) + _owner.SetName("foo") + _owner.SetToken("bar") + + _repo := testutils.APIRepo() + _repo.SetID(1) + _repo.SetOwner(_owner) + _repo.SetHash("baz") + _repo.SetOrg("foo") + _repo.SetName("bar") + _repo.SetFullName("foo/bar") + _repo.SetVisibility("public") + _repo.SetAllowEvents(api.NewEventsFromMask(1)) + _repo.SetPipelineType(constants.PipelineTypeYAML) + _repo.SetTopics([]string{}) + + _buildOne := testutils.APIBuild() _buildOne.SetID(1) - _buildOne.SetRepoID(1) + _buildOne.SetRepo(_repo) _buildOne.SetNumber(1) _buildOne.SetDeployPayload(nil) _buildOne.SetCreated(1) - _buildTwo := testBuild() + _buildTwo := testutils.APIBuild() _buildTwo.SetID(2) - _buildTwo.SetRepoID(1) + _buildTwo.SetRepo(_repo) _buildTwo.SetNumber(2) _buildTwo.SetDeployPayload(nil) _buildTwo.SetCreated(2) - _repo := testRepo() - _repo.SetID(1) - _repo.GetOwner().SetID(1) - _repo.SetHash("baz") - _repo.SetOrg("foo") - _repo.SetName("bar") - _repo.SetFullName("foo/bar") - _repo.SetVisibility("public") - _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() @@ -53,8 +64,18 @@ func TestBuild_Engine_ListBuildsForRepo(t *testing.T) { AddRow(2, 1, nil, 2, 0, "", "", "", "", 0, 2, 0, 0, "", nil, "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", 0, "", 0). AddRow(1, 1, nil, 1, 0, "", "", "", "", 0, 1, 0, 0, "", nil, "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", 0, "", 0) + _repoRows := sqlmock.NewRows( + []string{"id", "user_id", "hash", "org", "name", "full_name", "link", "clone", "branch", "topics", "build_limit", "timeout", "counter", "visibility", "private", "trusted", "active", "allow_events", "pipeline_type", "previous_name", "approve_build"}). + AddRow(1, 1, "baz", "foo", "bar", "foo/bar", "", "", "", "{}", 0, 0, 0, "public", false, false, false, 1, "yaml", "", "") + + _userRows := sqlmock.NewRows( + []string{"id", "name", "token", "hash", "active", "admin"}). + AddRow(1, "foo", "bar", "baz", false, false) + // ensure the mock expects the query _mock.ExpectQuery(`SELECT * FROM "builds" WHERE repo_id = $1 AND created < $2 AND created > $3 ORDER BY number DESC LIMIT $4`).WithArgs(1, AnyArgument{}, 0, 10).WillReturnRows(_rows) + _mock.ExpectQuery(`SELECT * FROM "repos" WHERE "repos"."id" = $1`).WithArgs(1).WillReturnRows(_repoRows) + _mock.ExpectQuery(`SELECT * FROM "users" WHERE "users"."id" = $1`).WithArgs(1).WillReturnRows(_userRows) _sqlite := testSqlite(t) defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() @@ -69,24 +90,44 @@ func TestBuild_Engine_ListBuildsForRepo(t *testing.T) { t.Errorf("unable to create test build for sqlite: %v", err) } + err = _sqlite.client.AutoMigrate(&types.Repo{}) + if err != nil { + t.Errorf("unable to create build table for sqlite: %v", err) + } + + err = _sqlite.client.Table(constants.TableRepo).Create(types.RepoFromAPI(_repo)).Error + if err != nil { + t.Errorf("unable to create test user for sqlite: %v", err) + } + + err = _sqlite.client.AutoMigrate(&types.User{}) + if err != nil { + t.Errorf("unable to create build table for sqlite: %v", err) + } + + err = _sqlite.client.Table(constants.TableUser).Create(types.UserFromAPI(_owner)).Error + if err != nil { + t.Errorf("unable to create test user for sqlite: %v", err) + } + // setup tests tests := []struct { failure bool name string database *engine - want []*library.Build + want []*api.Build }{ { failure: false, name: "postgres", database: _postgres, - want: []*library.Build{_buildTwo, _buildOne}, + want: []*api.Build{_buildTwo, _buildOne}, }, { failure: false, name: "sqlite3", database: _sqlite, - want: []*library.Build{_buildTwo, _buildOne}, + want: []*api.Build{_buildTwo, _buildOne}, }, } diff --git a/database/build/list_test.go b/database/build/list_test.go index ec645ace1..15688d252 100644 --- a/database/build/list_test.go +++ b/database/build/list_test.go @@ -9,21 +9,41 @@ import ( "github.com/DATA-DOG/go-sqlmock" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" + "github.com/go-vela/server/database/types" + "github.com/go-vela/types/constants" ) func TestBuild_Engine_ListBuilds(t *testing.T) { // setup types - _buildOne := testBuild() + _owner := testutils.APIUser().Crop() + _owner.SetID(1) + _owner.SetName("foo") + _owner.SetToken("bar") + + _repo := testutils.APIRepo() + _repo.SetID(1) + _repo.SetOwner(_owner) + _repo.SetHash("baz") + _repo.SetOrg("foo") + _repo.SetName("bar") + _repo.SetFullName("foo/bar") + _repo.SetVisibility("public") + _repo.SetAllowEvents(api.NewEventsFromMask(1)) + _repo.SetPipelineType(constants.PipelineTypeYAML) + _repo.SetTopics([]string{}) + + _buildOne := testutils.APIBuild() _buildOne.SetID(1) - _buildOne.SetRepoID(1) + _buildOne.SetRepo(_repo) _buildOne.SetNumber(1) _buildOne.SetDeployNumber(0) _buildOne.SetDeployPayload(nil) - _buildTwo := testBuild() + _buildTwo := testutils.APIBuild() _buildTwo.SetID(2) - _buildTwo.SetRepoID(1) + _buildTwo.SetRepo(_repo) _buildTwo.SetNumber(2) _buildTwo.SetDeployNumber(0) _buildTwo.SetDeployPayload(nil) @@ -43,8 +63,18 @@ func TestBuild_Engine_ListBuilds(t *testing.T) { AddRow(1, 1, nil, 1, 0, "", "", "", "", 0, 0, 0, 0, "", 0, nil, "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", 0). AddRow(2, 1, nil, 2, 0, "", "", "", "", 0, 0, 0, 0, "", 0, nil, "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", 0) + _repoRows := sqlmock.NewRows( + []string{"id", "user_id", "hash", "org", "name", "full_name", "link", "clone", "branch", "topics", "build_limit", "timeout", "counter", "visibility", "private", "trusted", "active", "allow_events", "pipeline_type", "previous_name", "approve_build"}). + AddRow(1, 1, "baz", "foo", "bar", "foo/bar", "", "", "", "{}", 0, 0, 0, "public", false, false, false, 1, "yaml", "", "") + + _userRows := sqlmock.NewRows( + []string{"id", "name", "token", "hash", "active", "admin"}). + AddRow(1, "foo", "bar", "baz", false, false) + // ensure the mock expects the query _mock.ExpectQuery(`SELECT * FROM "builds"`).WillReturnRows(_rows) + _mock.ExpectQuery(`SELECT * FROM "repos" WHERE "repos"."id" = $1`).WithArgs(1).WillReturnRows(_repoRows) + _mock.ExpectQuery(`SELECT * FROM "users" WHERE "users"."id" = $1`).WithArgs(1).WillReturnRows(_userRows) _sqlite := testSqlite(t) defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() @@ -59,24 +89,44 @@ func TestBuild_Engine_ListBuilds(t *testing.T) { t.Errorf("unable to create test build for sqlite: %v", err) } + err = _sqlite.client.AutoMigrate(&types.Repo{}) + if err != nil { + t.Errorf("unable to create build table for sqlite: %v", err) + } + + err = _sqlite.client.Table(constants.TableRepo).Create(types.RepoFromAPI(_repo)).Error + if err != nil { + t.Errorf("unable to create test user for sqlite: %v", err) + } + + err = _sqlite.client.AutoMigrate(&types.User{}) + if err != nil { + t.Errorf("unable to create build table for sqlite: %v", err) + } + + err = _sqlite.client.Table(constants.TableUser).Create(types.UserFromAPI(_owner)).Error + if err != nil { + t.Errorf("unable to create test user for sqlite: %v", err) + } + // setup tests tests := []struct { failure bool name string database *engine - want []*library.Build + want []*api.Build }{ { failure: false, name: "postgres", database: _postgres, - want: []*library.Build{_buildOne, _buildTwo}, + want: []*api.Build{_buildOne, _buildTwo}, }, { failure: false, name: "sqlite3", database: _sqlite, - want: []*library.Build{_buildOne, _buildTwo}, + want: []*api.Build{_buildOne, _buildTwo}, }, } diff --git a/database/build/opts.go b/database/build/opts.go index b3a68e3c7..0c3a661be 100644 --- a/database/build/opts.go +++ b/database/build/opts.go @@ -22,6 +22,16 @@ func WithClient(client *gorm.DB) EngineOpt { } } +// WithEncryptionKey sets the encryption key in the database engine for Repos. +func WithEncryptionKey(key string) EngineOpt { + return func(e *engine) error { + // set the encryption key in the repo engine + e.config.EncryptionKey = key + + return nil + } +} + // WithLogger sets the github.com/sirupsen/logrus logger in the database engine for Builds. func WithLogger(logger *logrus.Entry) EngineOpt { return func(e *engine) error { diff --git a/database/build/update.go b/database/build/update.go index ff5519fc9..0657470aa 100644 --- a/database/build/update.go +++ b/database/build/update.go @@ -8,25 +8,19 @@ import ( "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" ) // UpdateBuild updates an existing build in the database. -func (e *engine) UpdateBuild(ctx context.Context, b *library.Build) (*library.Build, error) { +func (e *engine) UpdateBuild(ctx context.Context, b *api.Build) (*api.Build, error) { e.logger.WithFields(logrus.Fields{ "build": b.GetNumber(), }).Tracef("updating build %d in the database", b.GetNumber()) - // cast the library type to database type - // - // https://pkg.go.dev/github.com/go-vela/types/database#BuildFromLibrary - build := database.BuildFromLibrary(b) + build := types.BuildFromAPI(b) - // validate the necessary fields are populated - // - // https://pkg.go.dev/github.com/go-vela/types/database#Build.Validate err := build.Validate() if err != nil { return nil, err @@ -36,7 +30,13 @@ func (e *engine) UpdateBuild(ctx context.Context, b *library.Build) (*library.Bu build = build.Crop() // send query to the database - result := e.client.Table(constants.TableBuild).Save(build) + err = e.client.Table(constants.TableBuild).Save(build).Error + if err != nil { + return nil, err + } + + result := build.ToAPI() + result.SetRepo(b.GetRepo()) - return build.ToLibrary(), result.Error + return result, nil } diff --git a/database/build/update_test.go b/database/build/update_test.go index 4d75183df..149779780 100644 --- a/database/build/update_test.go +++ b/database/build/update_test.go @@ -8,13 +8,31 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" ) func TestBuild_Engine_UpdateBuild(t *testing.T) { // setup types - _build := testBuild() + _owner := testutils.APIUser() + _owner.SetID(1) + _owner.SetName("foo") + _owner.SetToken("bar") + + _repo := testutils.APIRepo() + _repo.SetID(1) + _repo.SetOwner(_owner) + _repo.SetHash("baz") + _repo.SetOrg("foo") + _repo.SetName("bar") + _repo.SetFullName("foo/bar") + _repo.SetVisibility("public") + _repo.SetAllowEvents(api.NewEventsFromMask(1)) + + _build := testutils.APIBuild() _build.SetID(1) - _build.SetRepoID(1) + _build.SetRepo(_repo) _build.SetNumber(1) _build.SetDeployPayload(nil) diff --git a/database/dashboard/create.go b/database/dashboard/create.go index 5e7ec7887..5d179e11e 100644 --- a/database/dashboard/create.go +++ b/database/dashboard/create.go @@ -9,6 +9,7 @@ import ( api "github.com/go-vela/server/api/types" "github.com/go-vela/server/constants" + "github.com/go-vela/server/database/types" ) // CreateDashboard creates a new dashboard in the database. @@ -17,7 +18,7 @@ func (e *engine) CreateDashboard(ctx context.Context, d *api.Dashboard) (*api.Da "dashboard": d.GetName(), }).Tracef("creating dashboard %s in the database", d.GetName()) - dashboard := FromAPI(d) + dashboard := types.DashboardFromAPI(d) err := dashboard.Validate() if err != nil { diff --git a/database/dashboard/create_test.go b/database/dashboard/create_test.go index 041a39149..dba9fffc3 100644 --- a/database/dashboard/create_test.go +++ b/database/dashboard/create_test.go @@ -10,6 +10,7 @@ import ( "github.com/DATA-DOG/go-sqlmock" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" ) func TestDashboard_Engine_CreateDashboard(t *testing.T) { @@ -26,7 +27,7 @@ func TestDashboard_Engine_CreateDashboard(t *testing.T) { _admin.SetActive(true) _admins := []*api.User{_admin} - _dashboard := testDashboard() + _dashboard := testutils.APIDashboard() _dashboard.SetID("c8da1302-07d6-11ea-882f-4893bca275b8") _dashboard.SetName("dash") _dashboard.SetCreatedAt(1) diff --git a/database/dashboard/dashboard.go b/database/dashboard/dashboard.go index 321cfe609..8cd70c080 100644 --- a/database/dashboard/dashboard.go +++ b/database/dashboard/dashboard.go @@ -4,19 +4,13 @@ package dashboard import ( "context" - "database/sql" - "database/sql/driver" - "encoding/json" "errors" "fmt" - "github.com/google/uuid" "github.com/sirupsen/logrus" "gorm.io/gorm" - api "github.com/go-vela/server/api/types" "github.com/go-vela/server/constants" - "github.com/go-vela/server/util" ) var ( @@ -55,21 +49,6 @@ type ( // https://pkg.go.dev/github.com/sirupsen/logrus#Entry logger *logrus.Entry } - - // Dashboard is the database representation of a dashboard. - Dashboard struct { - ID uuid.UUID `gorm:"type:uuid;default:uuid_generate_v4()"` - Name sql.NullString `sql:"name"` - CreatedAt sql.NullInt64 `sql:"created_at"` - CreatedBy sql.NullString `sql:"created_by"` - UpdatedAt sql.NullInt64 `sql:"updated_at"` - UpdatedBy sql.NullString `sql:"updated_by"` - Admins AdminsJSON - Repos DashReposJSON - } - - DashReposJSON []*api.DashboardRepo - AdminsJSON []*api.User ) // New creates and returns a Vela service for integrating with dashboards in the database. @@ -107,142 +86,3 @@ func New(opts ...EngineOpt) (*engine, error) { return e, nil } - -// Value - Implementation of valuer for database/sql for DashReposJSON. -func (r DashReposJSON) Value() (driver.Value, error) { - valueString, err := json.Marshal(r) - return string(valueString), err -} - -// Scan - Implement the database/sql scanner interface for DashReposJSON. -func (r *DashReposJSON) Scan(value interface{}) error { - switch v := value.(type) { - case []byte: - return json.Unmarshal(v, &r) - case string: - return json.Unmarshal([]byte(v), &r) - default: - return fmt.Errorf("wrong type for repos: %T", v) - } -} - -// Value - Implementation of valuer for database/sql for AdminsJSON. -func (a AdminsJSON) Value() (driver.Value, error) { - valueString, err := json.Marshal(a) - return string(valueString), err -} - -// Scan - Implement the database/sql scanner interface for AdminsJSON. -func (a *AdminsJSON) Scan(value interface{}) error { - switch v := value.(type) { - case []byte: - return json.Unmarshal(v, &a) - case string: - return json.Unmarshal([]byte(v), &a) - default: - return fmt.Errorf("wrong type for admins: %T", v) - } -} - -// Nullify ensures the valid flag for -// the sql.Null types are properly set. -// -// When a field within the Dashboard 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 *Dashboard) Nullify() *Dashboard { - if d == nil { - return nil - } - - // check if the Name field should be false - if len(d.Name.String) == 0 { - d.Name.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 - } - - // check if the UpdatedAt field should be false - if d.UpdatedAt.Int64 == 0 { - d.UpdatedAt.Valid = false - } - - // check if the UpdatedBy field should be false - if len(d.UpdatedBy.String) == 0 { - d.UpdatedBy.Valid = false - } - - return d -} - -// ToAPI converts the Dashboard type -// to an API Dashboard type. -func (d *Dashboard) ToAPI() *api.Dashboard { - dashboard := new(api.Dashboard) - - dashboard.SetID(d.ID.String()) - dashboard.SetName(d.Name.String) - dashboard.SetAdmins(d.Admins) - dashboard.SetCreatedAt(d.CreatedAt.Int64) - dashboard.SetCreatedBy(d.CreatedBy.String) - dashboard.SetUpdatedAt(d.UpdatedAt.Int64) - dashboard.SetUpdatedBy(d.UpdatedBy.String) - dashboard.SetRepos(d.Repos) - - return dashboard -} - -// Validate verifies the necessary fields for -// the Dashboard type are populated correctly. -func (d *Dashboard) Validate() error { - // verify the Name field is populated - if len(d.Name.String) == 0 { - return ErrEmptyDashName - } - - // ensure that all Dashboard string fields - // that can be returned as JSON are sanitized - // to avoid unsafe HTML content - d.Name = sql.NullString{String: util.Sanitize(d.Name.String), Valid: d.Name.Valid} - - return nil -} - -// FromAPI converts the API Dashboard type -// to a database Dashboard type. -func FromAPI(d *api.Dashboard) *Dashboard { - var ( - id uuid.UUID - err error - ) - - if d.GetID() == "" { - id = uuid.New() - } else { - id, err = uuid.Parse(d.GetID()) - if err != nil { - return nil - } - } - - dashboard := &Dashboard{ - ID: id, - Name: sql.NullString{String: d.GetName(), Valid: true}, - CreatedAt: sql.NullInt64{Int64: d.GetCreatedAt(), Valid: true}, - CreatedBy: sql.NullString{String: d.GetCreatedBy(), Valid: true}, - UpdatedAt: sql.NullInt64{Int64: d.GetUpdatedAt(), Valid: true}, - UpdatedBy: sql.NullString{String: d.GetUpdatedBy(), Valid: true}, - Admins: d.GetAdmins(), - Repos: d.GetRepos(), - } - - return dashboard.Nullify() -} diff --git a/database/dashboard/dashboard_test.go b/database/dashboard/dashboard_test.go index 3073fe299..77d5069a9 100644 --- a/database/dashboard/dashboard_test.go +++ b/database/dashboard/dashboard_test.go @@ -13,8 +13,6 @@ import ( "gorm.io/driver/postgres" "gorm.io/driver/sqlite" "gorm.io/gorm" - - api "github.com/go-vela/server/api/types" ) func TestDashboard_New(t *testing.T) { @@ -166,40 +164,6 @@ func testSqlite(t *testing.T) *engine { return _engine } -// testAdmin is a test helper function to create an API -// User type wil all fields set to their zero values. -func testAdmins() *[]*api.User { - return &[]*api.User{ - { - ID: new(int64), - Name: new(string), - Active: new(bool), - }, - } -} - -// testDashboard is a test helper function to create a library -// Dashboard type with all fields set to their zero values. -func testDashboard() *api.Dashboard { - return &api.Dashboard{ - ID: new(string), - Name: new(string), - CreatedAt: new(int64), - CreatedBy: new(string), - UpdatedAt: new(int64), - UpdatedBy: new(string), - Admins: testAdmins(), - } -} - -func testDashboardRepo() *api.DashboardRepo { - return &api.DashboardRepo{ - ID: new(int64), - Branches: new([]string), - Events: new([]string), - } -} - // This will be used with the github.com/DATA-DOG/go-sqlmock library to compare values // that are otherwise not easily compared. These typically would be values generated // before adding or updating them in the database. diff --git a/database/dashboard/delete.go b/database/dashboard/delete.go index b2b1e4090..c0bf658ee 100644 --- a/database/dashboard/delete.go +++ b/database/dashboard/delete.go @@ -9,6 +9,7 @@ import ( api "github.com/go-vela/server/api/types" "github.com/go-vela/server/constants" + "github.com/go-vela/server/database/types" ) // DeleteDashboard deletes an existing dashboard from the database. @@ -17,7 +18,7 @@ func (e *engine) DeleteDashboard(ctx context.Context, d *api.Dashboard) error { "dashboard": d.GetID(), }).Tracef("deleting dashboard %s from the database", d.GetID()) - dashboard := FromAPI(d) + dashboard := types.DashboardFromAPI(d) // send query to the database return e.client. diff --git a/database/dashboard/delete_test.go b/database/dashboard/delete_test.go index 3c079efd1..1987d51a4 100644 --- a/database/dashboard/delete_test.go +++ b/database/dashboard/delete_test.go @@ -9,18 +9,19 @@ import ( "github.com/DATA-DOG/go-sqlmock" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" ) func TestDashboard_Engine_DeleteDashboard(t *testing.T) { // setup types - _dashboard := testDashboard() + _dashboard := testutils.APIDashboard() _dashboard.SetID("c8da1302-07d6-11ea-882f-4893bca275b8") _dashboard.SetName("vela") _dashboard.SetCreatedAt(1) _dashboard.SetCreatedBy("user1") _dashboard.SetUpdatedAt(1) _dashboard.SetUpdatedBy("user2") - _dashboard.SetRepos([]*api.DashboardRepo{testDashboardRepo()}) + _dashboard.SetRepos([]*api.DashboardRepo{testutils.APIDashboardRepo()}) _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() diff --git a/database/dashboard/get.go b/database/dashboard/get.go index e4b9694b9..1e08391f9 100644 --- a/database/dashboard/get.go +++ b/database/dashboard/get.go @@ -7,6 +7,7 @@ import ( api "github.com/go-vela/server/api/types" "github.com/go-vela/server/constants" + "github.com/go-vela/server/database/types" ) // GetDashboard gets a dashboard by UUID from the database. @@ -14,17 +15,17 @@ func (e *engine) GetDashboard(ctx context.Context, id string) (*api.Dashboard, e e.logger.Tracef("getting dashboard %s from the database", id) // variable to store query results - r := new(Dashboard) + d := new(types.Dashboard) // send query to the database and store result in variable err := e.client. Table(constants.TableDashboard). Where("id = ?", id). - Take(r). + Take(d). Error if err != nil { return nil, err } - return r.ToAPI(), nil + return d.ToAPI(), nil } diff --git a/database/dashboard/get_test.go b/database/dashboard/get_test.go index 79664ad91..3727328a6 100644 --- a/database/dashboard/get_test.go +++ b/database/dashboard/get_test.go @@ -10,6 +10,7 @@ import ( "github.com/google/go-cmp/cmp" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" ) func TestRepo_Engine_GetDashboard(t *testing.T) { @@ -26,7 +27,7 @@ func TestRepo_Engine_GetDashboard(t *testing.T) { _admin.SetActive(true) _admins := []*api.User{_admin} - _dashboard := testDashboard() + _dashboard := testutils.APIDashboard() _dashboard.SetID("c8da1302-07d6-11ea-882f-4893bca275b8") _dashboard.SetName("dash") _dashboard.SetCreatedAt(1) diff --git a/database/dashboard/update.go b/database/dashboard/update.go index 85947f545..f05fe3e28 100644 --- a/database/dashboard/update.go +++ b/database/dashboard/update.go @@ -9,6 +9,7 @@ import ( api "github.com/go-vela/server/api/types" "github.com/go-vela/server/constants" + "github.com/go-vela/server/database/types" ) // UpdateDashboard updates an existing dashboard in the database. @@ -17,7 +18,7 @@ func (e *engine) UpdateDashboard(ctx context.Context, d *api.Dashboard) (*api.Da "dashboard": d.GetID(), }).Tracef("creating dashboard %s in the database", d.GetID()) - dashboard := FromAPI(d) + dashboard := types.DashboardFromAPI(d) err := dashboard.Validate() if err != nil { diff --git a/database/dashboard/update_test.go b/database/dashboard/update_test.go index adf1627e7..95437613e 100644 --- a/database/dashboard/update_test.go +++ b/database/dashboard/update_test.go @@ -10,6 +10,7 @@ import ( "github.com/google/go-cmp/cmp" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" ) func TestDashboard_Engine_UpdateDashboard(t *testing.T) { @@ -26,7 +27,7 @@ func TestDashboard_Engine_UpdateDashboard(t *testing.T) { _admin.SetActive(true) _admins := []*api.User{_admin} - _dashboard := testDashboard() + _dashboard := testutils.APIDashboard() _dashboard.SetID("c8da1302-07d6-11ea-882f-4893bca275b8") _dashboard.SetName("dash") _dashboard.SetCreatedAt(1) diff --git a/database/deployment/count_repo_test.go b/database/deployment/count_repo_test.go index d358aad3f..775361570 100644 --- a/database/deployment/count_repo_test.go +++ b/database/deployment/count_repo_test.go @@ -9,6 +9,7 @@ import ( "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/types/library" ) @@ -16,7 +17,7 @@ func TestDeployment_Engine_CountDeploymentsForRepo(t *testing.T) { builds := []*library.Build{} // setup types - _deploymentOne := testDeployment() + _deploymentOne := testutils.APIDeployment() _deploymentOne.SetID(1) _deploymentOne.SetRepoID(1) _deploymentOne.SetNumber(1) @@ -31,7 +32,7 @@ func TestDeployment_Engine_CountDeploymentsForRepo(t *testing.T) { _deploymentOne.SetCreatedBy("octocat") _deploymentOne.SetBuilds(builds) - _deploymentTwo := testDeployment() + _deploymentTwo := testutils.APIDeployment() _deploymentTwo.SetID(2) _deploymentTwo.SetRepoID(2) _deploymentTwo.SetNumber(2) @@ -46,7 +47,7 @@ func TestDeployment_Engine_CountDeploymentsForRepo(t *testing.T) { _deploymentTwo.SetCreatedBy("octocat") _deploymentTwo.SetBuilds(builds) - _repo := testRepo() + _repo := testutils.APIRepo() _repo.SetID(1) _repo.GetOwner().SetID(1) _repo.SetOrg("foo") diff --git a/database/deployment/count_test.go b/database/deployment/count_test.go index 78a07afeb..914bb22a5 100644 --- a/database/deployment/count_test.go +++ b/database/deployment/count_test.go @@ -9,6 +9,7 @@ import ( "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/types/library" "github.com/go-vela/types/raw" ) @@ -51,7 +52,7 @@ func TestDeployment_Engine_CountDeployments(t *testing.T) { builds = append(builds, buildOne) // setup types - _deploymentOne := testDeployment() + _deploymentOne := testutils.APIDeployment() _deploymentOne.SetID(1) _deploymentOne.SetRepoID(1) _deploymentOne.SetNumber(1) @@ -66,7 +67,7 @@ func TestDeployment_Engine_CountDeployments(t *testing.T) { _deploymentOne.SetCreatedBy("octocat") _deploymentOne.SetBuilds(builds) - _deploymentTwo := testDeployment() + _deploymentTwo := testutils.APIDeployment() _deploymentTwo.SetID(2) _deploymentTwo.SetRepoID(2) _deploymentTwo.SetNumber(2) diff --git a/database/deployment/create_test.go b/database/deployment/create_test.go index f915eea0b..92a2e3448 100644 --- a/database/deployment/create_test.go +++ b/database/deployment/create_test.go @@ -8,6 +8,7 @@ import ( "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/types/library" ) @@ -15,7 +16,7 @@ func TestDeployment_Engine_CreateDeployment(t *testing.T) { builds := []*library.Build{} // setup types - _deploymentOne := testDeployment() + _deploymentOne := testutils.APIDeployment() _deploymentOne.SetID(1) _deploymentOne.SetRepoID(1) _deploymentOne.SetNumber(1) diff --git a/database/deployment/delete_test.go b/database/deployment/delete_test.go index 5b984bbd7..e037c684c 100644 --- a/database/deployment/delete_test.go +++ b/database/deployment/delete_test.go @@ -8,6 +8,7 @@ import ( "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/types/library" ) @@ -15,7 +16,7 @@ func TestDeployment_Engine_DeleteDeployment(t *testing.T) { builds := []*library.Build{} // setup types - _deploymentOne := testDeployment() + _deploymentOne := testutils.APIDeployment() _deploymentOne.SetID(1) _deploymentOne.SetRepoID(1) _deploymentOne.SetNumber(1) diff --git a/database/deployment/deployment_test.go b/database/deployment/deployment_test.go index 1aabcb6c3..6ab73474f 100644 --- a/database/deployment/deployment_test.go +++ b/database/deployment/deployment_test.go @@ -11,10 +11,6 @@ import ( "gorm.io/driver/postgres" "gorm.io/driver/sqlite" "gorm.io/gorm" - - api "github.com/go-vela/server/api/types" - "github.com/go-vela/types/library" - "github.com/go-vela/types/raw" ) func TestDeployment_New(t *testing.T) { @@ -165,48 +161,3 @@ func testSqlite(t *testing.T) *engine { return _engine } - -// testDeployment is a test helper function to create a library -// Deployment type with all fields set to their zero values. -func testDeployment() *library.Deployment { - builds := []*library.Build{} - return &library.Deployment{ - ID: new(int64), - RepoID: new(int64), - Number: new(int64), - URL: new(string), - Commit: new(string), - Ref: new(string), - Task: new(string), - Target: new(string), - Description: new(string), - Payload: new(raw.StringSliceMap), - CreatedAt: new(int64), - CreatedBy: new(string), - Builds: builds, - } -} - -// testRepo is a test helper function to create a library -// Repo type with all fields set to their zero values. -func testRepo() *api.Repo { - return &api.Repo{ - ID: new(int64), - BuildLimit: new(int64), - Timeout: new(int64), - Counter: new(int), - PipelineType: new(string), - Hash: new(string), - Org: new(string), - Name: new(string), - FullName: new(string), - Link: new(string), - Clone: new(string), - Branch: new(string), - Visibility: new(string), - PreviousName: new(string), - Private: new(bool), - Trusted: new(bool), - Active: new(bool), - } -} diff --git a/database/deployment/get_repo_test.go b/database/deployment/get_repo_test.go index 72f258182..78070f8c3 100644 --- a/database/deployment/get_repo_test.go +++ b/database/deployment/get_repo_test.go @@ -9,6 +9,7 @@ import ( "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/types/library" ) @@ -16,7 +17,7 @@ func TestDeployment_Engine_GetDeploymentForRepo(t *testing.T) { builds := []*library.Build{} // setup types - _deploymentOne := testDeployment() + _deploymentOne := testutils.APIDeployment() _deploymentOne.SetID(1) _deploymentOne.SetRepoID(1) _deploymentOne.SetNumber(1) @@ -31,7 +32,7 @@ func TestDeployment_Engine_GetDeploymentForRepo(t *testing.T) { _deploymentOne.SetCreatedBy("octocat") _deploymentOne.SetBuilds(builds) - _repo := testRepo() + _repo := testutils.APIRepo() _repo.SetID(1) _repo.GetOwner().SetID(1) _repo.SetOrg("foo") diff --git a/database/deployment/get_test.go b/database/deployment/get_test.go index 0fdb289c9..b579aeecd 100644 --- a/database/deployment/get_test.go +++ b/database/deployment/get_test.go @@ -9,6 +9,7 @@ import ( "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/types/library" ) @@ -16,7 +17,7 @@ func TestDeployment_Engine_GetDeployment(t *testing.T) { builds := []*library.Build{} // setup types - _deploymentOne := testDeployment() + _deploymentOne := testutils.APIDeployment() _deploymentOne.SetID(1) _deploymentOne.SetRepoID(1) _deploymentOne.SetNumber(1) diff --git a/database/deployment/list_repo_test.go b/database/deployment/list_repo_test.go index 377ee8af3..c93de0939 100644 --- a/database/deployment/list_repo_test.go +++ b/database/deployment/list_repo_test.go @@ -9,11 +9,12 @@ import ( "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/types/library" ) func TestDeployment_Engine_ListDeploymentsForRepo(t *testing.T) { - _repo := testRepo() + _repo := testutils.APIRepo() _repo.SetID(1) _repo.SetOrg("foo") _repo.SetName("bar") @@ -22,7 +23,7 @@ func TestDeployment_Engine_ListDeploymentsForRepo(t *testing.T) { builds := []*library.Build{} // setup types - _deploymentOne := testDeployment() + _deploymentOne := testutils.APIDeployment() _deploymentOne.SetID(1) _deploymentOne.SetRepoID(1) _deploymentOne.SetNumber(1) @@ -37,7 +38,7 @@ func TestDeployment_Engine_ListDeploymentsForRepo(t *testing.T) { _deploymentOne.SetCreatedBy("octocat") _deploymentOne.SetBuilds(builds) - _deploymentTwo := testDeployment() + _deploymentTwo := testutils.APIDeployment() _deploymentTwo.SetID(2) _deploymentTwo.SetRepoID(2) _deploymentTwo.SetNumber(2) diff --git a/database/deployment/list_test.go b/database/deployment/list_test.go index 8b620eda4..8edefe64e 100644 --- a/database/deployment/list_test.go +++ b/database/deployment/list_test.go @@ -9,6 +9,7 @@ import ( "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/types/library" ) @@ -16,7 +17,7 @@ func TestDeployment_Engine_ListDeployments(t *testing.T) { builds := []*library.Build{} // setup types - _deploymentOne := testDeployment() + _deploymentOne := testutils.APIDeployment() _deploymentOne.SetID(1) _deploymentOne.SetRepoID(1) _deploymentOne.SetNumber(1) @@ -31,7 +32,7 @@ func TestDeployment_Engine_ListDeployments(t *testing.T) { _deploymentOne.SetCreatedBy("octocat") _deploymentOne.SetBuilds(builds) - _deploymentTwo := testDeployment() + _deploymentTwo := testutils.APIDeployment() _deploymentTwo.SetID(2) _deploymentTwo.SetRepoID(2) _deploymentTwo.SetNumber(2) diff --git a/database/deployment/update_test.go b/database/deployment/update_test.go index d8aaa574d..d70b3ea85 100644 --- a/database/deployment/update_test.go +++ b/database/deployment/update_test.go @@ -8,6 +8,7 @@ import ( "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/types/library" ) @@ -15,7 +16,7 @@ func TestDeployment_Engine_UpdateDeployment(t *testing.T) { builds := []*library.Build{} // setup types - _deploymentOne := testDeployment() + _deploymentOne := testutils.APIDeployment() _deploymentOne.SetID(1) _deploymentOne.SetRepoID(1) _deploymentOne.SetNumber(1) diff --git a/database/hook/count_repo_test.go b/database/hook/count_repo_test.go index cd1592f4e..e6b8c8d43 100644 --- a/database/hook/count_repo_test.go +++ b/database/hook/count_repo_test.go @@ -8,11 +8,13 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestHook_Engine_CountHooksForRepo(t *testing.T) { // setup types - _hookOne := testHook() + _hookOne := testutils.APIHook() _hookOne.SetID(1) _hookOne.SetRepoID(1) _hookOne.SetBuildID(1) @@ -20,7 +22,7 @@ func TestHook_Engine_CountHooksForRepo(t *testing.T) { _hookOne.SetSourceID("c8da1302-07d6-11ea-882f-4893bca275b8") _hookOne.SetWebhookID(1) - _hookTwo := testHook() + _hookTwo := testutils.APIHook() _hookTwo.SetID(2) _hookTwo.SetRepoID(2) _hookTwo.SetBuildID(2) @@ -28,7 +30,7 @@ func TestHook_Engine_CountHooksForRepo(t *testing.T) { _hookTwo.SetSourceID("c8da1302-07d6-11ea-882f-4893bca275b8") _hookTwo.SetWebhookID(1) - _repo := testRepo() + _repo := testutils.APIRepo() _repo.SetID(1) _repo.GetOwner().SetID(1) _repo.SetOrg("foo") diff --git a/database/hook/count_test.go b/database/hook/count_test.go index 96cc5560e..20c022217 100644 --- a/database/hook/count_test.go +++ b/database/hook/count_test.go @@ -8,11 +8,13 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestHook_Engine_CountHooks(t *testing.T) { // setup types - _hookOne := testHook() + _hookOne := testutils.APIHook() _hookOne.SetID(1) _hookOne.SetRepoID(1) _hookOne.SetBuildID(1) @@ -20,7 +22,7 @@ func TestHook_Engine_CountHooks(t *testing.T) { _hookOne.SetSourceID("c8da1302-07d6-11ea-882f-4893bca275b8") _hookOne.SetWebhookID(1) - _hookTwo := testHook() + _hookTwo := testutils.APIHook() _hookTwo.SetID(2) _hookTwo.SetRepoID(1) _hookTwo.SetBuildID(2) diff --git a/database/hook/create_test.go b/database/hook/create_test.go index cd5b6e62e..2dd34cb10 100644 --- a/database/hook/create_test.go +++ b/database/hook/create_test.go @@ -7,11 +7,13 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestHook_Engine_CreateHook(t *testing.T) { // setup types - _hook := testHook() + _hook := testutils.APIHook() _hook.SetID(1) _hook.SetRepoID(1) _hook.SetBuildID(1) diff --git a/database/hook/delete_test.go b/database/hook/delete_test.go index cbdef043e..f89e44116 100644 --- a/database/hook/delete_test.go +++ b/database/hook/delete_test.go @@ -7,11 +7,13 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestHook_Engine_DeleteHook(t *testing.T) { // setup types - _hook := testHook() + _hook := testutils.APIHook() _hook.SetID(1) _hook.SetRepoID(1) _hook.SetBuildID(1) diff --git a/database/hook/get_repo_test.go b/database/hook/get_repo_test.go index 2ee8de362..df2dc6d7f 100644 --- a/database/hook/get_repo_test.go +++ b/database/hook/get_repo_test.go @@ -9,12 +9,13 @@ import ( "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/types/library" ) func TestHook_Engine_GetHookForRepo(t *testing.T) { // setup types - _hook := testHook() + _hook := testutils.APIHook() _hook.SetID(1) _hook.SetRepoID(1) _hook.SetBuildID(1) @@ -22,7 +23,7 @@ func TestHook_Engine_GetHookForRepo(t *testing.T) { _hook.SetSourceID("c8da1302-07d6-11ea-882f-4893bca275b8") _hook.SetWebhookID(1) - _repo := testRepo() + _repo := testutils.APIRepo() _repo.SetID(1) _repo.GetOwner().SetID(1) _repo.SetOrg("foo") diff --git a/database/hook/get_test.go b/database/hook/get_test.go index 004baa3fe..a33f144c2 100644 --- a/database/hook/get_test.go +++ b/database/hook/get_test.go @@ -9,12 +9,13 @@ import ( "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/types/library" ) func TestHook_Engine_GetHook(t *testing.T) { // setup types - _hook := testHook() + _hook := testutils.APIHook() _hook.SetID(1) _hook.SetRepoID(1) _hook.SetBuildID(1) diff --git a/database/hook/get_webhook_test.go b/database/hook/get_webhook_test.go index 57bd3628f..975c568af 100644 --- a/database/hook/get_webhook_test.go +++ b/database/hook/get_webhook_test.go @@ -9,12 +9,13 @@ import ( "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/types/library" ) func TestHook_Engine_GetHookByWebhookID(t *testing.T) { // setup types - _hook := testHook() + _hook := testutils.APIHook() _hook.SetID(1) _hook.SetRepoID(1) _hook.SetBuildID(1) diff --git a/database/hook/hook_test.go b/database/hook/hook_test.go index cb66db823..615572398 100644 --- a/database/hook/hook_test.go +++ b/database/hook/hook_test.go @@ -11,9 +11,6 @@ import ( "gorm.io/driver/postgres" "gorm.io/driver/sqlite" "gorm.io/gorm" - - api "github.com/go-vela/server/api/types" - "github.com/go-vela/types/library" ) func TestHook_New(t *testing.T) { @@ -164,48 +161,3 @@ func testSqlite(t *testing.T) *engine { return _engine } - -// testHook is a test helper function to create a library -// Hook type with all fields set to their zero values. -func testHook() *library.Hook { - return &library.Hook{ - ID: new(int64), - RepoID: new(int64), - BuildID: new(int64), - Number: new(int), - SourceID: new(string), - Created: new(int64), - Host: new(string), - Event: new(string), - EventAction: new(string), - Branch: new(string), - Error: new(string), - Status: new(string), - Link: new(string), - WebhookID: new(int64), - } -} - -// testRepo is a test helper function to create a library -// Repo type with all fields set to their zero values. -func testRepo() *api.Repo { - return &api.Repo{ - ID: new(int64), - BuildLimit: new(int64), - Timeout: new(int64), - Counter: new(int), - PipelineType: new(string), - Hash: new(string), - Org: new(string), - Name: new(string), - FullName: new(string), - Link: new(string), - Clone: new(string), - Branch: new(string), - Visibility: new(string), - PreviousName: new(string), - Private: new(bool), - Trusted: new(bool), - Active: new(bool), - } -} diff --git a/database/hook/last_repo_test.go b/database/hook/last_repo_test.go index a9366d259..277932f2d 100644 --- a/database/hook/last_repo_test.go +++ b/database/hook/last_repo_test.go @@ -9,12 +9,13 @@ import ( "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/types/library" ) func TestHook_Engine_LastHookForRepo(t *testing.T) { // setup types - _hook := testHook() + _hook := testutils.APIHook() _hook.SetID(1) _hook.SetRepoID(1) _hook.SetBuildID(1) @@ -22,7 +23,7 @@ func TestHook_Engine_LastHookForRepo(t *testing.T) { _hook.SetSourceID("c8da1302-07d6-11ea-882f-4893bca275b8") _hook.SetWebhookID(1) - _repo := testRepo() + _repo := testutils.APIRepo() _repo.SetID(1) _repo.GetOwner().SetID(1) _repo.SetOrg("foo") diff --git a/database/hook/list_repo_test.go b/database/hook/list_repo_test.go index c9698c0eb..b68a41747 100644 --- a/database/hook/list_repo_test.go +++ b/database/hook/list_repo_test.go @@ -9,12 +9,13 @@ import ( "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/types/library" ) func TestHook_Engine_ListHooksForRepo(t *testing.T) { // setup types - _hookOne := testHook() + _hookOne := testutils.APIHook() _hookOne.SetID(1) _hookOne.SetRepoID(1) _hookOne.SetBuildID(1) @@ -22,7 +23,7 @@ func TestHook_Engine_ListHooksForRepo(t *testing.T) { _hookOne.SetSourceID("c8da1302-07d6-11ea-882f-4893bca275b8") _hookOne.SetWebhookID(1) - _hookTwo := testHook() + _hookTwo := testutils.APIHook() _hookTwo.SetID(2) _hookTwo.SetRepoID(1) _hookTwo.SetBuildID(2) @@ -30,7 +31,7 @@ func TestHook_Engine_ListHooksForRepo(t *testing.T) { _hookTwo.SetSourceID("c8da1302-07d6-11ea-882f-4893bca275b8") _hookTwo.SetWebhookID(1) - _repo := testRepo() + _repo := testutils.APIRepo() _repo.SetID(1) _repo.GetOwner().SetID(1) _repo.SetOrg("foo") diff --git a/database/hook/list_test.go b/database/hook/list_test.go index 79c788e0a..89098751d 100644 --- a/database/hook/list_test.go +++ b/database/hook/list_test.go @@ -9,12 +9,13 @@ import ( "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/types/library" ) func TestHook_Engine_ListHooks(t *testing.T) { // setup types - _hookOne := testHook() + _hookOne := testutils.APIHook() _hookOne.SetID(1) _hookOne.SetRepoID(1) _hookOne.SetBuildID(1) @@ -22,7 +23,7 @@ func TestHook_Engine_ListHooks(t *testing.T) { _hookOne.SetSourceID("c8da1302-07d6-11ea-882f-4893bca275b8") _hookOne.SetWebhookID(1) - _hookTwo := testHook() + _hookTwo := testutils.APIHook() _hookTwo.SetID(2) _hookTwo.SetRepoID(1) _hookTwo.SetBuildID(2) diff --git a/database/hook/update_test.go b/database/hook/update_test.go index 44828b5db..72982b6c0 100644 --- a/database/hook/update_test.go +++ b/database/hook/update_test.go @@ -7,11 +7,13 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestHook_Engine_UpdateHook(t *testing.T) { // setup types - _hook := testHook() + _hook := testutils.APIHook() _hook.SetID(1) _hook.SetRepoID(1) _hook.SetBuildID(1) diff --git a/database/integration_test.go b/database/integration_test.go index aa00b260c..36e2cb5a6 100644 --- a/database/integration_test.go +++ b/database/integration_test.go @@ -25,6 +25,7 @@ import ( "github.com/go-vela/server/database/secret" "github.com/go-vela/server/database/service" "github.com/go-vela/server/database/step" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/server/database/user" "github.com/go-vela/server/database/worker" "github.com/go-vela/types/constants" @@ -34,7 +35,7 @@ import ( // Resources represents the object containing test resources. type Resources struct { - Builds []*library.Build + Builds []*api.Build Dashboards []*api.Dashboard Deployments []*library.Deployment Executables []*library.BuildExecutable @@ -175,6 +176,14 @@ func testBuilds(t *testing.T, db Interface, resources *Resources) { methods[element.Method(i).Name] = false } + // create the users for build related functions (owners of repos) + for _, user := range resources.Users { + _, err := db.CreateUser(context.TODO(), user) + if err != nil { + t.Errorf("unable to create user %d: %v", user.GetID(), err) + } + } + // create the repos for build related functions for _, repo := range resources.Repos { _, err := db.CreateRepo(context.TODO(), repo) @@ -183,19 +192,19 @@ func testBuilds(t *testing.T, db Interface, resources *Resources) { } } - buildOne := new(library.BuildQueue) + buildOne := new(api.QueueBuild) buildOne.SetCreated(1563474076) buildOne.SetFullName("github/octocat") buildOne.SetNumber(1) buildOne.SetStatus("running") - buildTwo := new(library.BuildQueue) + buildTwo := new(api.QueueBuild) buildTwo.SetCreated(1563474076) buildTwo.SetFullName("github/octocat") buildTwo.SetNumber(2) buildTwo.SetStatus("running") - queueBuilds := []*library.BuildQueue{buildOne, buildTwo} + queueBuilds := []*api.QueueBuild{buildOne, buildTwo} // create the builds for _, build := range resources.Builds { @@ -287,7 +296,7 @@ func testBuilds(t *testing.T, db Interface, resources *Resources) { if int(count) != len(resources.Builds) { t.Errorf("ListBuildsForRepo() is %v, want %v", count, len(resources.Builds)) } - if diff := cmp.Diff([]*library.Build{resources.Builds[1], resources.Builds[0]}, list); diff != "" { + if diff := cmp.Diff([]*api.Build{resources.Builds[1], resources.Builds[0]}, list); diff != "" { t.Errorf("ListBuildsForRepo() mismatch (-want +got):\n%s", diff) } methods["ListBuildsForRepo"] = true @@ -299,8 +308,14 @@ func testBuilds(t *testing.T, db Interface, resources *Resources) { if len(list) != 1 { t.Errorf("Number of results for ListBuildsForDashboardRepo() is %v, want %v", len(list), 1) } - if !cmp.Equal(list, []*library.Build{resources.Builds[0]}) { - t.Errorf("ListBuildsForDashboardRepo() is %v, want %v", list, []*library.Build{resources.Builds[0]}) + + // ListBuildsForDashboardRepo does not contain nested repo + wantBuild := *resources.Builds[0] + wantBuild.Repo = testutils.APIRepo() + wantBuild.Repo.Owner = testutils.APIUser().Crop() + + if diff := cmp.Diff([]*api.Build{&wantBuild}, list); diff != "" { + t.Errorf("ListBuildsForDashboardRepo() mismatch (-want +got):\n%s", diff) } methods["ListBuildsForDashboardRepo"] = true @@ -312,7 +327,7 @@ func testBuilds(t *testing.T, db Interface, resources *Resources) { if int(count) != len(resources.Builds) { t.Errorf("ListPendingAndRunningBuildsForRepo() is %v, want %v", count, len(resources.Builds)) } - if diff := cmp.Diff([]*library.Build{resources.Builds[0], resources.Builds[1]}, list); diff != "" { + if diff := cmp.Diff([]*api.Build{resources.Builds[0], resources.Builds[1]}, list); diff != "" { t.Errorf("ListPendingAndRunningBuildsForRepo() mismatch (-want +got):\n%s", diff) } methods["ListPendingAndRunningBuildsForRepo"] = true @@ -339,7 +354,7 @@ func testBuilds(t *testing.T, db Interface, resources *Resources) { // lookup the builds by repo and number for _, build := range resources.Builds { - repo := resources.Repos[build.GetRepoID()-1] + repo := resources.Repos[build.GetRepo().GetID()-1] got, err = db.GetBuildForRepo(context.TODO(), repo, build.GetNumber()) if err != nil { t.Errorf("unable to get build %d for repo %d: %v", build.GetID(), repo.GetID(), err) @@ -397,6 +412,14 @@ func testBuilds(t *testing.T, db Interface, resources *Resources) { } } + // delete the users for the build related functions + for _, user := range resources.Users { + err = db.DeleteUser(context.TODO(), user) + if err != nil { + t.Errorf("unable to delete user %d: %v", user.GetID(), err) + } + } + // ensure we called all the methods we expected to for method, called := range methods { if !called { @@ -462,8 +485,14 @@ func testDashboards(t *testing.T, db Interface, resources *Resources) { t.Errorf("unable to update dashboard %s: %v", dashboard.GetID(), err) } - if !cmp.Equal(got, dashboard, CmpOptApproxUpdatedAt()) { - t.Errorf("UpdateDashboard() is %v, want %v", got, dashboard) + // JSON marshaling does not include comparing token due to `-` struct tag + cmpAdmins := got.GetAdmins() + for i, admin := range cmpAdmins { + admin.SetToken(resources.Users[i].GetToken()) + } + + if diff := cmp.Diff(dashboard, got, CmpOptApproxUpdatedAt()); diff != "" { + t.Errorf("UpdateDashboard() mismatch (-want +got):\n%s", diff) } } methods["UpdateDashboard"] = true @@ -2123,20 +2152,59 @@ func newResources() *Resources { userTwo.SetToken("superSecretToken") userTwo.SetRefreshToken("superSecretRefreshToken") userTwo.SetFavorites([]string{"github/octocat"}) + userTwo.SetDashboards([]string{"45bcf19b-c151-4e2d-b8c6-80a62ba2eae7"}) userTwo.SetActive(true) userTwo.SetAdmin(false) - userTwo.SetDashboards([]string{"45bcf19b-c151-4e2d-b8c6-80a62ba2eae7", "ba657dab-bc6e-421f-9188-86272bd0069a"}) - // crop and set "-" JSON tag fields to nil for dashboard admins - dashboardAdmins := []*api.User{userOne.Crop(), userTwo.Crop()} - for _, admin := range dashboardAdmins { - admin.Token = nil - admin.RefreshToken = nil - } + repoOne := new(api.Repo) + repoOne.SetID(1) + repoOne.SetOwner(userOne.Crop()) + repoOne.SetHash("MzM4N2MzMDAtNmY4Mi00OTA5LWFhZDAtNWIzMTlkNTJkODMy") + repoOne.SetOrg("github") + repoOne.SetName("octocat") + repoOne.SetFullName("github/octocat") + repoOne.SetLink("https://github.com/github/octocat") + repoOne.SetClone("https://github.com/github/octocat.git") + repoOne.SetBranch("main") + repoOne.SetTopics([]string{"cloud", "security"}) + repoOne.SetBuildLimit(10) + repoOne.SetTimeout(30) + repoOne.SetCounter(0) + repoOne.SetVisibility("public") + repoOne.SetPrivate(false) + repoOne.SetTrusted(false) + repoOne.SetActive(true) + repoOne.SetPipelineType("") + repoOne.SetPreviousName("") + repoOne.SetApproveBuild(constants.ApproveNever) + repoOne.SetAllowEvents(api.NewEventsFromMask(1)) - buildOne := new(library.Build) + repoTwo := new(api.Repo) + repoTwo.SetID(2) + repoTwo.SetOwner(userOne.Crop()) + repoTwo.SetHash("MzM4N2MzMDAtNmY4Mi00OTA5LWFhZDAtNWIzMTlkNTJkODMy") + repoTwo.SetOrg("github") + repoTwo.SetName("octokitty") + repoTwo.SetFullName("github/octokitty") + repoTwo.SetLink("https://github.com/github/octokitty") + repoTwo.SetClone("https://github.com/github/octokitty.git") + repoTwo.SetBranch("main") + repoTwo.SetTopics([]string{"cloud", "security"}) + repoTwo.SetBuildLimit(10) + repoTwo.SetTimeout(30) + repoTwo.SetCounter(0) + repoTwo.SetVisibility("public") + repoTwo.SetPrivate(false) + repoTwo.SetTrusted(false) + repoTwo.SetActive(true) + repoTwo.SetPipelineType("") + repoTwo.SetPreviousName("") + repoTwo.SetApproveBuild(constants.ApproveForkAlways) + repoTwo.SetAllowEvents(api.NewEventsFromMask(1)) + + buildOne := new(api.Build) buildOne.SetID(1) - buildOne.SetRepoID(1) + buildOne.SetRepo(repoOne) buildOne.SetPipelineID(1) buildOne.SetNumber(1) buildOne.SetParent(1) @@ -2170,9 +2238,9 @@ func newResources() *Resources { buildOne.SetApprovedAt(1563474078) buildOne.SetApprovedBy("OctoCat") - buildTwo := new(library.Build) + buildTwo := new(api.Build) buildTwo.SetID(2) - buildTwo.SetRepoID(1) + buildTwo.SetRepo(repoOne) buildTwo.SetPipelineID(1) buildTwo.SetNumber(2) buildTwo.SetParent(1) @@ -2212,6 +2280,13 @@ func newResources() *Resources { dashRepo.SetBranches([]string{"main"}) dashRepo.SetEvents([]string{"push"}) + // crop and set "-" JSON tag fields to nil for dashboard admins + dashboardAdmins := []*api.User{userOne.Crop(), userTwo.Crop()} + for _, admin := range dashboardAdmins { + admin.Token = nil + admin.RefreshToken = nil + } + dashboardOne := new(api.Dashboard) dashboardOne.SetID("ba657dab-bc6e-421f-9188-86272bd0069a") dashboardOne.SetName("vela") @@ -2387,52 +2462,6 @@ func newResources() *Resources { pipelineTwo.SetTemplates(false) pipelineTwo.SetData([]byte("version: 1")) - repoOne := new(api.Repo) - repoOne.SetID(1) - repoOne.SetOwner(userOne.Crop()) - repoOne.SetHash("MzM4N2MzMDAtNmY4Mi00OTA5LWFhZDAtNWIzMTlkNTJkODMy") - repoOne.SetOrg("github") - repoOne.SetName("octocat") - repoOne.SetFullName("github/octocat") - repoOne.SetLink("https://github.com/github/octocat") - repoOne.SetClone("https://github.com/github/octocat.git") - repoOne.SetBranch("main") - repoOne.SetTopics([]string{"cloud", "security"}) - repoOne.SetBuildLimit(10) - repoOne.SetTimeout(30) - repoOne.SetCounter(0) - repoOne.SetVisibility("public") - repoOne.SetPrivate(false) - repoOne.SetTrusted(false) - repoOne.SetActive(true) - repoOne.SetPipelineType("") - repoOne.SetPreviousName("") - repoOne.SetApproveBuild(constants.ApproveNever) - repoOne.SetAllowEvents(api.NewEventsFromMask(1)) - - repoTwo := new(api.Repo) - repoTwo.SetID(2) - repoTwo.SetOwner(userOne.Crop()) - repoTwo.SetHash("MzM4N2MzMDAtNmY4Mi00OTA5LWFhZDAtNWIzMTlkNTJkODMy") - repoTwo.SetOrg("github") - repoTwo.SetName("octokitty") - repoTwo.SetFullName("github/octokitty") - repoTwo.SetLink("https://github.com/github/octokitty") - repoTwo.SetClone("https://github.com/github/octokitty.git") - repoTwo.SetBranch("main") - repoTwo.SetTopics([]string{"cloud", "security"}) - repoTwo.SetBuildLimit(10) - repoTwo.SetTimeout(30) - repoTwo.SetCounter(0) - repoTwo.SetVisibility("public") - repoTwo.SetPrivate(false) - repoTwo.SetTrusted(false) - repoTwo.SetActive(true) - repoTwo.SetPipelineType("") - repoTwo.SetPreviousName("") - repoTwo.SetApproveBuild(constants.ApproveForkAlways) - repoTwo.SetAllowEvents(api.NewEventsFromMask(1)) - scheduleOne := new(library.Schedule) scheduleOne.SetID(1) scheduleOne.SetRepoID(1) @@ -2582,10 +2611,10 @@ func newResources() *Resources { stepTwo.SetDistribution("linux") stepTwo.SetReportAs("test") - _bPartialOne := new(library.Build) + _bPartialOne := new(api.Build) _bPartialOne.SetID(1) - _bPartialTwo := new(library.Build) + _bPartialTwo := new(api.Build) _bPartialTwo.SetID(2) workerOne := new(api.Worker) @@ -2596,7 +2625,7 @@ func newResources() *Resources { workerOne.SetActive(true) workerOne.SetStatus("available") workerOne.SetLastStatusUpdateAt(time.Now().UTC().Unix()) - workerOne.SetRunningBuilds([]*library.Build{_bPartialOne}) + workerOne.SetRunningBuilds([]*api.Build{_bPartialOne}) workerOne.SetLastBuildStartedAt(time.Now().UTC().Unix()) workerOne.SetLastBuildFinishedAt(time.Now().UTC().Unix()) workerOne.SetLastCheckedIn(time.Now().UTC().Unix() - 60) @@ -2610,14 +2639,14 @@ func newResources() *Resources { workerTwo.SetActive(true) workerTwo.SetStatus("available") workerTwo.SetLastStatusUpdateAt(time.Now().UTC().Unix()) - workerTwo.SetRunningBuilds([]*library.Build{_bPartialTwo}) + workerTwo.SetRunningBuilds([]*api.Build{_bPartialTwo}) workerTwo.SetLastBuildStartedAt(time.Now().UTC().Unix()) workerTwo.SetLastBuildFinishedAt(time.Now().UTC().Unix()) workerTwo.SetLastCheckedIn(time.Now().UTC().Unix() - 60) workerTwo.SetBuildLimit(1) return &Resources{ - Builds: []*library.Build{buildOne, buildTwo}, + Builds: []*api.Build{buildOne, buildTwo}, Dashboards: []*api.Dashboard{dashboardOne, dashboardTwo}, Deployments: []*library.Deployment{deploymentOne, deploymentTwo}, Executables: []*library.BuildExecutable{executableOne, executableTwo}, diff --git a/database/log/count_build.go b/database/log/count_build.go index 168d9e1c1..75145d5e3 100644 --- a/database/log/count_build.go +++ b/database/log/count_build.go @@ -5,12 +5,12 @@ package log import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" ) // CountLogsForBuild gets the count of logs by build ID from the database. -func (e *engine) CountLogsForBuild(ctx context.Context, b *library.Build) (int64, error) { +func (e *engine) CountLogsForBuild(ctx context.Context, b *api.Build) (int64, error) { e.logger.Tracef("getting count of logs for build %d from the database", b.GetID()) // variable to store query results diff --git a/database/log/count_build_test.go b/database/log/count_build_test.go index c66422134..ca05016fb 100644 --- a/database/log/count_build_test.go +++ b/database/log/count_build_test.go @@ -8,26 +8,31 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestLog_Engine_CountLogsForBuild(t *testing.T) { // setup types - _service := testLog() + _service := testutils.APILog() _service.SetID(1) _service.SetRepoID(1) _service.SetBuildID(1) _service.SetServiceID(1) - _step := testLog() + _step := testutils.APILog() _step.SetID(2) _step.SetRepoID(1) _step.SetBuildID(1) _step.SetStepID(1) - _build := testBuild() + _repo := testutils.APIRepo() + _repo.SetID(1) + + _build := testutils.APIBuild() _build.SetID(1) _build.SetID(1) - _build.SetRepoID(1) + _build.SetRepo(_repo) _build.SetNumber(1) _postgres, _mock := testPostgres(t) diff --git a/database/log/count_test.go b/database/log/count_test.go index cb7f516dc..49ee80de5 100644 --- a/database/log/count_test.go +++ b/database/log/count_test.go @@ -8,17 +8,19 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestLog_Engine_CountLogs(t *testing.T) { // setup types - _service := testLog() + _service := testutils.APILog() _service.SetID(1) _service.SetRepoID(1) _service.SetBuildID(1) _service.SetServiceID(1) - _step := testLog() + _step := testutils.APILog() _step.SetID(2) _step.SetRepoID(1) _step.SetBuildID(1) diff --git a/database/log/create_test.go b/database/log/create_test.go index 9f6852ab9..3b86fbe44 100644 --- a/database/log/create_test.go +++ b/database/log/create_test.go @@ -8,18 +8,19 @@ import ( "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/types/library" ) func TestLog_Engine_CreateLog(t *testing.T) { // setup types - _service := testLog() + _service := testutils.APILog() _service.SetID(1) _service.SetRepoID(1) _service.SetBuildID(1) _service.SetServiceID(1) - _step := testLog() + _step := testutils.APILog() _step.SetID(2) _step.SetRepoID(1) _step.SetBuildID(1) diff --git a/database/log/delete_test.go b/database/log/delete_test.go index 3b3000fc6..610f0c2cd 100644 --- a/database/log/delete_test.go +++ b/database/log/delete_test.go @@ -7,11 +7,13 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestLog_Engine_DeleteLog(t *testing.T) { // setup types - _log := testLog() + _log := testutils.APILog() _log.SetID(1) _log.SetRepoID(1) _log.SetBuildID(1) diff --git a/database/log/get_service_test.go b/database/log/get_service_test.go index 6b7c89529..b4ae5efe5 100644 --- a/database/log/get_service_test.go +++ b/database/log/get_service_test.go @@ -9,19 +9,20 @@ import ( "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/types/library" ) func TestLog_Engine_GetLogForService(t *testing.T) { // setup types - _log := testLog() + _log := testutils.APILog() _log.SetID(1) _log.SetRepoID(1) _log.SetBuildID(1) _log.SetServiceID(1) _log.SetData([]byte{}) - _service := testService() + _service := testutils.APIService() _service.SetID(1) _service.SetID(1) _service.SetRepoID(1) diff --git a/database/log/get_step_test.go b/database/log/get_step_test.go index 5606ef79b..68073bf85 100644 --- a/database/log/get_step_test.go +++ b/database/log/get_step_test.go @@ -9,19 +9,20 @@ import ( "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/types/library" ) func TestLog_Engine_GetLogForStep(t *testing.T) { // setup types - _log := testLog() + _log := testutils.APILog() _log.SetID(1) _log.SetRepoID(1) _log.SetBuildID(1) _log.SetStepID(1) _log.SetData([]byte{}) - _step := testStep() + _step := testutils.APIStep() _step.SetID(1) _step.SetID(1) _step.SetRepoID(1) diff --git a/database/log/get_test.go b/database/log/get_test.go index 33028ad7d..d2263704f 100644 --- a/database/log/get_test.go +++ b/database/log/get_test.go @@ -9,12 +9,13 @@ import ( "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/types/library" ) func TestLog_Engine_GetLog(t *testing.T) { // setup types - _log := testLog() + _log := testutils.APILog() _log.SetID(1) _log.SetRepoID(1) _log.SetBuildID(1) diff --git a/database/log/interface.go b/database/log/interface.go index 92f5d6cdd..97ace05c6 100644 --- a/database/log/interface.go +++ b/database/log/interface.go @@ -5,6 +5,7 @@ package log import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/library" ) @@ -29,7 +30,7 @@ type LogInterface interface { // CountLogs defines a function that gets the count of all logs. CountLogs(context.Context) (int64, error) // CountLogsForBuild defines a function that gets the count of logs by build ID. - CountLogsForBuild(context.Context, *library.Build) (int64, error) + CountLogsForBuild(context.Context, *api.Build) (int64, error) // CreateLog defines a function that creates a new log. CreateLog(context.Context, *library.Log) error // DeleteLog defines a function that deletes an existing log. @@ -43,7 +44,7 @@ type LogInterface interface { // ListLogs defines a function that gets a list of all logs. ListLogs(context.Context) ([]*library.Log, error) // ListLogsForBuild defines a function that gets a list of logs by build ID. - ListLogsForBuild(context.Context, *library.Build, int, int) ([]*library.Log, int64, error) + ListLogsForBuild(context.Context, *api.Build, int, int) ([]*library.Log, int64, error) // UpdateLog defines a function that updates an existing log. UpdateLog(context.Context, *library.Log) error } diff --git a/database/log/list_build.go b/database/log/list_build.go index 183b1f167..f5619d40b 100644 --- a/database/log/list_build.go +++ b/database/log/list_build.go @@ -5,13 +5,14 @@ package log import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" ) // ListLogsForBuild gets a list of logs by build ID from the database. -func (e *engine) ListLogsForBuild(ctx context.Context, b *library.Build, page, perPage int) ([]*library.Log, int64, error) { +func (e *engine) ListLogsForBuild(ctx context.Context, b *api.Build, page, perPage int) ([]*library.Log, int64, error) { e.logger.Tracef("listing logs for build %d from the database", b.GetID()) // variables to store query results and return value diff --git a/database/log/list_build_test.go b/database/log/list_build_test.go index 04f4f6efc..e4b9038cd 100644 --- a/database/log/list_build_test.go +++ b/database/log/list_build_test.go @@ -9,29 +9,33 @@ import ( "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/types/library" ) func TestLog_Engine_ListLogsForBuild(t *testing.T) { // setup types - _service := testLog() + _service := testutils.APILog() _service.SetID(1) _service.SetRepoID(1) _service.SetBuildID(1) _service.SetServiceID(1) _service.SetData([]byte{}) - _step := testLog() + _step := testutils.APILog() _step.SetID(2) _step.SetRepoID(1) _step.SetBuildID(1) _step.SetStepID(1) _step.SetData([]byte{}) - _build := testBuild() + _repo := testutils.APIRepo() + _repo.SetID(1) + + _build := testutils.APIBuild() _build.SetID(1) _build.SetID(1) - _build.SetRepoID(1) + _build.SetRepo(_repo) _build.SetNumber(1) _postgres, _mock := testPostgres(t) diff --git a/database/log/list_test.go b/database/log/list_test.go index 605ed26df..6371c9fd2 100644 --- a/database/log/list_test.go +++ b/database/log/list_test.go @@ -9,19 +9,20 @@ import ( "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/types/library" ) func TestLog_Engine_ListLogs(t *testing.T) { // setup types - _service := testLog() + _service := testutils.APILog() _service.SetID(1) _service.SetRepoID(1) _service.SetBuildID(1) _service.SetServiceID(1) _service.SetData([]byte{}) - _step := testLog() + _step := testutils.APILog() _step.SetID(2) _step.SetRepoID(1) _step.SetBuildID(1) diff --git a/database/log/log_test.go b/database/log/log_test.go index 86862bbc2..528dba1e2 100644 --- a/database/log/log_test.go +++ b/database/log/log_test.go @@ -12,8 +12,6 @@ import ( "gorm.io/driver/postgres" "gorm.io/driver/sqlite" "gorm.io/gorm" - - "github.com/go-vela/types/library" ) func TestLog_New(t *testing.T) { @@ -177,98 +175,3 @@ type AnyArgument struct{} func (a AnyArgument) Match(_ driver.Value) bool { return true } - -// testBuild is a test helper function to create a library -// Build type with all fields set to their zero values. -func testBuild() *library.Build { - return &library.Build{ - ID: new(int64), - RepoID: new(int64), - PipelineID: new(int64), - Number: new(int), - Parent: new(int), - Event: new(string), - EventAction: new(string), - Status: new(string), - Error: new(string), - Enqueued: new(int64), - Created: new(int64), - Started: new(int64), - Finished: new(int64), - Deploy: new(string), - Clone: new(string), - Source: new(string), - Title: new(string), - Message: new(string), - Commit: new(string), - Sender: new(string), - Author: new(string), - Email: new(string), - Link: new(string), - Branch: new(string), - Ref: new(string), - BaseRef: new(string), - HeadRef: new(string), - Host: new(string), - Runtime: new(string), - Distribution: new(string), - } -} - -// testLog is a test helper function to create a library -// Log type with all fields set to their zero values. -func testLog() *library.Log { - return &library.Log{ - ID: new(int64), - RepoID: new(int64), - BuildID: new(int64), - ServiceID: new(int64), - StepID: new(int64), - Data: new([]byte), - } -} - -// testService is a test helper function to create a library -// Service type with all fields set to their zero values. -func testService() *library.Service { - return &library.Service{ - ID: new(int64), - BuildID: new(int64), - RepoID: new(int64), - Number: new(int), - Name: new(string), - Image: new(string), - Status: new(string), - Error: new(string), - ExitCode: new(int), - Created: new(int64), - Started: new(int64), - Finished: new(int64), - Host: new(string), - Runtime: new(string), - Distribution: new(string), - } -} - -// testStep is a test helper function to create a library -// Step type with all fields set to their zero values. -func testStep() *library.Step { - return &library.Step{ - ID: new(int64), - BuildID: new(int64), - RepoID: new(int64), - Number: new(int), - Name: new(string), - Image: new(string), - Stage: new(string), - Status: new(string), - Error: new(string), - ExitCode: new(int), - Created: new(int64), - Started: new(int64), - Finished: new(int64), - Host: new(string), - Runtime: new(string), - Distribution: new(string), - } -} diff --git a/database/log/update_test.go b/database/log/update_test.go index 67f3313bc..ae2ca53f0 100644 --- a/database/log/update_test.go +++ b/database/log/update_test.go @@ -8,19 +8,20 @@ import ( "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/types/library" ) func TestLog_Engine_UpdateLog(t *testing.T) { // setup types - _service := testLog() + _service := testutils.APILog() _service.SetID(1) _service.SetRepoID(1) _service.SetBuildID(1) _service.SetServiceID(1) _service.SetData([]byte{}) - _step := testLog() + _step := testutils.APILog() _step.SetID(2) _step.SetRepoID(1) _step.SetBuildID(1) diff --git a/database/pipeline/count_repo_test.go b/database/pipeline/count_repo_test.go index 729b25955..ae306e9e5 100644 --- a/database/pipeline/count_repo_test.go +++ b/database/pipeline/count_repo_test.go @@ -10,11 +10,12 @@ import ( "github.com/DATA-DOG/go-sqlmock" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" ) func TestPipeline_Engine_CountPipelinesForRepo(t *testing.T) { // setup types - _pipelineOne := testPipeline() + _pipelineOne := testutils.APIPipeline() _pipelineOne.SetID(1) _pipelineOne.SetRepoID(1) _pipelineOne.SetCommit("48afb5bdc41ad69bf22588491333f7cf71135163") @@ -22,7 +23,7 @@ func TestPipeline_Engine_CountPipelinesForRepo(t *testing.T) { _pipelineOne.SetType("yaml") _pipelineOne.SetVersion("1") - _pipelineTwo := testPipeline() + _pipelineTwo := testutils.APIPipeline() _pipelineTwo.SetID(2) _pipelineTwo.SetRepoID(1) _pipelineTwo.SetCommit("a49aaf4afae6431a79239c95247a2b169fd9f067") diff --git a/database/pipeline/count_test.go b/database/pipeline/count_test.go index 829acfd58..351e84050 100644 --- a/database/pipeline/count_test.go +++ b/database/pipeline/count_test.go @@ -8,11 +8,13 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestPipeline_Engine_CountPipelines(t *testing.T) { // setup types - _pipelineOne := testPipeline() + _pipelineOne := testutils.APIPipeline() _pipelineOne.SetID(1) _pipelineOne.SetRepoID(1) _pipelineOne.SetCommit("48afb5bdc41ad69bf22588491333f7cf71135163") @@ -20,7 +22,7 @@ func TestPipeline_Engine_CountPipelines(t *testing.T) { _pipelineOne.SetType("yaml") _pipelineOne.SetVersion("1") - _pipelineTwo := testPipeline() + _pipelineTwo := testutils.APIPipeline() _pipelineTwo.SetID(2) _pipelineTwo.SetRepoID(2) _pipelineTwo.SetCommit("a49aaf4afae6431a79239c95247a2b169fd9f067") diff --git a/database/pipeline/create_test.go b/database/pipeline/create_test.go index f6a0b7af1..58f52ffcc 100644 --- a/database/pipeline/create_test.go +++ b/database/pipeline/create_test.go @@ -8,11 +8,13 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestPipeline_Engine_CreatePipeline(t *testing.T) { // setup types - _pipeline := testPipeline() + _pipeline := testutils.APIPipeline() _pipeline.SetID(1) _pipeline.SetRepoID(1) _pipeline.SetCommit("48afb5bdc41ad69bf22588491333f7cf71135163") diff --git a/database/pipeline/delete_test.go b/database/pipeline/delete_test.go index 2b141b702..35a03d463 100644 --- a/database/pipeline/delete_test.go +++ b/database/pipeline/delete_test.go @@ -7,11 +7,13 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestPipeline_Engine_DeletePipeline(t *testing.T) { // setup types - _pipeline := testPipeline() + _pipeline := testutils.APIPipeline() _pipeline.SetID(1) _pipeline.SetRepoID(1) _pipeline.SetCommit("48afb5bdc41ad69bf22588491333f7cf71135163") diff --git a/database/pipeline/get_repo_test.go b/database/pipeline/get_repo_test.go index 69ffe7751..d62612cd2 100644 --- a/database/pipeline/get_repo_test.go +++ b/database/pipeline/get_repo_test.go @@ -10,12 +10,13 @@ import ( "github.com/DATA-DOG/go-sqlmock" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/types/library" ) func TestPipeline_Engine_GetPipelineForRepo(t *testing.T) { // setup types - _pipeline := testPipeline() + _pipeline := testutils.APIPipeline() _pipeline.SetID(1) _pipeline.SetRepoID(1) _pipeline.SetCommit("48afb5bdc41ad69bf22588491333f7cf71135163") diff --git a/database/pipeline/get_test.go b/database/pipeline/get_test.go index 614b6a7c9..c24f97da0 100644 --- a/database/pipeline/get_test.go +++ b/database/pipeline/get_test.go @@ -9,12 +9,13 @@ import ( "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/types/library" ) func TestPipeline_Engine_GetPipeline(t *testing.T) { // setup types - _pipeline := testPipeline() + _pipeline := testutils.APIPipeline() _pipeline.SetID(1) _pipeline.SetRepoID(1) _pipeline.SetCommit("48afb5bdc41ad69bf22588491333f7cf71135163") diff --git a/database/pipeline/list_repo_test.go b/database/pipeline/list_repo_test.go index 7daa96547..4acc87e20 100644 --- a/database/pipeline/list_repo_test.go +++ b/database/pipeline/list_repo_test.go @@ -10,12 +10,13 @@ import ( "github.com/DATA-DOG/go-sqlmock" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/types/library" ) func TestPipeline_Engine_ListPipelinesForRepo(t *testing.T) { // setup types - _pipelineOne := testPipeline() + _pipelineOne := testutils.APIPipeline() _pipelineOne.SetID(1) _pipelineOne.SetRepoID(1) _pipelineOne.SetCommit("48afb5bdc41ad69bf22588491333f7cf71135163") @@ -24,7 +25,7 @@ func TestPipeline_Engine_ListPipelinesForRepo(t *testing.T) { _pipelineOne.SetVersion("1") _pipelineOne.SetData([]byte("foo")) - _pipelineTwo := testPipeline() + _pipelineTwo := testutils.APIPipeline() _pipelineTwo.SetID(2) _pipelineTwo.SetRepoID(1) _pipelineTwo.SetCommit("a49aaf4afae6431a79239c95247a2b169fd9f067") diff --git a/database/pipeline/list_test.go b/database/pipeline/list_test.go index f356afe82..b485bab6f 100644 --- a/database/pipeline/list_test.go +++ b/database/pipeline/list_test.go @@ -9,12 +9,13 @@ import ( "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/types/library" ) func TestPipeline_Engine_ListPipelines(t *testing.T) { // setup types - _pipelineOne := testPipeline() + _pipelineOne := testutils.APIPipeline() _pipelineOne.SetID(1) _pipelineOne.SetRepoID(1) _pipelineOne.SetCommit("48afb5bdc41ad69bf22588491333f7cf71135163") @@ -23,7 +24,7 @@ func TestPipeline_Engine_ListPipelines(t *testing.T) { _pipelineOne.SetVersion("1") _pipelineOne.SetData([]byte("foo")) - _pipelineTwo := testPipeline() + _pipelineTwo := testutils.APIPipeline() _pipelineTwo.SetID(2) _pipelineTwo.SetRepoID(2) _pipelineTwo.SetCommit("a49aaf4afae6431a79239c95247a2b169fd9f067") diff --git a/database/pipeline/pipeline_test.go b/database/pipeline/pipeline_test.go index 76abee9ed..e748b21f1 100644 --- a/database/pipeline/pipeline_test.go +++ b/database/pipeline/pipeline_test.go @@ -13,8 +13,6 @@ import ( "gorm.io/driver/postgres" "gorm.io/driver/sqlite" "gorm.io/gorm" - - "github.com/go-vela/types/library" ) func TestPipeline_New(t *testing.T) { @@ -174,28 +172,6 @@ func testSqlite(t *testing.T) *engine { return _engine } -// testPipeline is a test helper function to create a library -// Pipeline type with all fields set to their zero values. -func testPipeline() *library.Pipeline { - return &library.Pipeline{ - ID: new(int64), - RepoID: new(int64), - Commit: new(string), - Flavor: new(string), - Platform: new(string), - Ref: new(string), - Type: new(string), - Version: new(string), - ExternalSecrets: new(bool), - InternalSecrets: new(bool), - Services: new(bool), - Stages: new(bool), - Steps: new(bool), - Templates: new(bool), - Data: new([]byte), - } -} - // This will be used with the github.com/DATA-DOG/go-sqlmock library to compare values // that are otherwise not easily compared. These typically would be values generated // before adding or updating them in the database. diff --git a/database/pipeline/update_test.go b/database/pipeline/update_test.go index a489913ab..bb0464550 100644 --- a/database/pipeline/update_test.go +++ b/database/pipeline/update_test.go @@ -8,11 +8,13 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestPipeline_Engine_UpdatePipeline(t *testing.T) { // setup types - _pipeline := testPipeline() + _pipeline := testutils.APIPipeline() _pipeline.SetID(1) _pipeline.SetRepoID(1) _pipeline.SetCommit("48afb5bdc41ad69bf22588491333f7cf71135163") diff --git a/database/repo/count_org_test.go b/database/repo/count_org_test.go index 650770e4a..1521e3025 100644 --- a/database/repo/count_org_test.go +++ b/database/repo/count_org_test.go @@ -8,11 +8,13 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestRepo_Engine_CountReposForOrg(t *testing.T) { // setup types - _repoOne := testAPIRepo() + _repoOne := testutils.APIRepo() _repoOne.SetID(1) _repoOne.GetOwner().SetID(1) _repoOne.SetHash("baz") @@ -21,7 +23,7 @@ func TestRepo_Engine_CountReposForOrg(t *testing.T) { _repoOne.SetFullName("foo/bar") _repoOne.SetVisibility("public") - _repoTwo := testAPIRepo() + _repoTwo := testutils.APIRepo() _repoTwo.SetID(2) _repoTwo.GetOwner().SetID(1) _repoTwo.SetHash("baz") diff --git a/database/repo/count_test.go b/database/repo/count_test.go index f295d885e..4803e7ea9 100644 --- a/database/repo/count_test.go +++ b/database/repo/count_test.go @@ -8,11 +8,13 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestRepo_Engine_CountRepos(t *testing.T) { // setup types - _repoOne := testAPIRepo() + _repoOne := testutils.APIRepo() _repoOne.SetID(1) _repoOne.GetOwner().SetID(1) _repoOne.SetHash("baz") @@ -21,7 +23,7 @@ func TestRepo_Engine_CountRepos(t *testing.T) { _repoOne.SetFullName("foo/bar") _repoOne.SetVisibility("public") - _repoTwo := testAPIRepo() + _repoTwo := testutils.APIRepo() _repoTwo.SetID(2) _repoTwo.GetOwner().SetID(1) _repoTwo.SetHash("baz") diff --git a/database/repo/count_user_test.go b/database/repo/count_user_test.go index 8b420ea56..543f13a1c 100644 --- a/database/repo/count_user_test.go +++ b/database/repo/count_user_test.go @@ -8,32 +8,34 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestRepo_Engine_CountReposForUser(t *testing.T) { // setup types - _repoOne := testAPIRepo() + _user := testutils.APIUser() + _user.SetID(1) + _user.SetName("foo") + + _repoOne := testutils.APIRepo() _repoOne.SetID(1) - _repoOne.GetOwner().SetID(1) + _repoOne.SetOwner(_user) _repoOne.SetHash("baz") _repoOne.SetOrg("foo") _repoOne.SetName("bar") _repoOne.SetFullName("foo/bar") _repoOne.SetVisibility("public") - _repoTwo := testAPIRepo() + _repoTwo := testutils.APIRepo() _repoTwo.SetID(2) - _repoTwo.GetOwner().SetID(1) + _repoTwo.SetOwner(_user) _repoTwo.SetHash("baz") _repoTwo.SetOrg("bar") _repoTwo.SetName("foo") _repoTwo.SetFullName("bar/foo") _repoTwo.SetVisibility("public") - _user := testOwner() - _user.SetID(1) - _user.SetName("foo") - _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() diff --git a/database/repo/create.go b/database/repo/create.go index fcfd837c6..3a604348e 100644 --- a/database/repo/create.go +++ b/database/repo/create.go @@ -10,6 +10,7 @@ import ( "github.com/sirupsen/logrus" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" ) @@ -21,7 +22,7 @@ func (e *engine) CreateRepo(ctx context.Context, r *api.Repo) (*api.Repo, error) }).Tracef("creating repo %s in the database", r.GetFullName()) // cast the library type to database type - repo := FromAPI(r) + repo := types.RepoFromAPI(r) // validate the necessary fields are populated err := repo.Validate() @@ -46,8 +47,6 @@ func (e *engine) CreateRepo(ctx context.Context, r *api.Repo) (*api.Repo, error) if err != nil { // only log to preserve backwards compatibility e.logger.Errorf("unable to decrypt repo %d: %v", r.GetID(), err) - - return repo.ToAPI(), nil } // set owner to provided owner if creation successful diff --git a/database/repo/create_test.go b/database/repo/create_test.go index 67371ec5b..07b8204ab 100644 --- a/database/repo/create_test.go +++ b/database/repo/create_test.go @@ -8,11 +8,13 @@ import ( "github.com/DATA-DOG/go-sqlmock" "github.com/google/go-cmp/cmp" + + "github.com/go-vela/server/database/testutils" ) func TestRepo_Engine_CreateRepo(t *testing.T) { // setup types - _repo := testAPIRepo() + _repo := testutils.APIRepo() _repo.SetID(1) _repo.GetOwner().SetID(1) _repo.SetHash("baz") diff --git a/database/repo/delete.go b/database/repo/delete.go index 357404048..115e131c8 100644 --- a/database/repo/delete.go +++ b/database/repo/delete.go @@ -8,6 +8,7 @@ import ( "github.com/sirupsen/logrus" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" ) @@ -19,7 +20,7 @@ func (e *engine) DeleteRepo(ctx context.Context, r *api.Repo) error { }).Tracef("deleting repo %s from the database", r.GetFullName()) // cast the library type to database type - repo := FromAPI(r) + repo := types.RepoFromAPI(r) // send query to the database return e.client. diff --git a/database/repo/delete_test.go b/database/repo/delete_test.go index 8829da36e..9326c62b6 100644 --- a/database/repo/delete_test.go +++ b/database/repo/delete_test.go @@ -7,11 +7,13 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestRepo_Engine_DeleteRepo(t *testing.T) { // setup types - _repo := testAPIRepo() + _repo := testutils.APIRepo() _repo.SetID(1) _repo.GetOwner().SetID(1) _repo.SetHash("baz") diff --git a/database/repo/get.go b/database/repo/get.go index ee603b09d..9d3fb7412 100644 --- a/database/repo/get.go +++ b/database/repo/get.go @@ -6,6 +6,7 @@ import ( "context" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" ) @@ -14,7 +15,7 @@ func (e *engine) GetRepo(ctx context.Context, id int64) (*api.Repo, error) { e.logger.Tracef("getting repo %d from the database", id) // variable to store query results - r := new(Repo) + r := new(types.Repo) // send query to the database and store result in variable err := e.client. @@ -45,15 +46,6 @@ func (e *engine) GetRepo(ctx context.Context, id int64) (*api.Repo, error) { return r.ToAPI(), nil } - // decrypt owner fields - err = r.Owner.Decrypt(e.config.EncryptionKey) - if err != nil { - e.logger.Errorf("unable to decrypt repo owner %d: %v", id, err) - - // return the unencrypted repo - return r.ToAPI(), nil - } - // return the decrypted repo // // https://pkg.go.dev/github.com/go-vela/types/database#Repo.ToLibrary diff --git a/database/repo/get_org.go b/database/repo/get_org.go index 889b5b812..ecca4530f 100644 --- a/database/repo/get_org.go +++ b/database/repo/get_org.go @@ -8,6 +8,7 @@ import ( "github.com/sirupsen/logrus" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" ) @@ -19,7 +20,7 @@ func (e *engine) GetRepoForOrg(ctx context.Context, org, name string) (*api.Repo }).Tracef("getting repo %s/%s from the database", org, name) // variable to store query results - r := new(Repo) + r := new(types.Repo) // send query to the database and store result in variable err := e.client. @@ -47,15 +48,6 @@ func (e *engine) GetRepoForOrg(ctx context.Context, org, name string) (*api.Repo return r.ToAPI(), nil } - // decrypt owner fields - err = r.Owner.Decrypt(e.config.EncryptionKey) - if err != nil { - e.logger.Errorf("unable to decrypt repo owner %s/%s: %v", org, name, err) - - // return the unencrypted repo - return r.ToAPI(), nil - } - // return the decrypted repo return r.ToAPI(), nil } diff --git a/database/repo/get_org_test.go b/database/repo/get_org_test.go index 149b402a9..1570398c0 100644 --- a/database/repo/get_org_test.go +++ b/database/repo/get_org_test.go @@ -10,13 +10,14 @@ import ( "github.com/google/go-cmp/cmp" api "github.com/go-vela/server/api/types" - "github.com/go-vela/server/database/user" + "github.com/go-vela/server/database/testutils" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" ) func TestRepo_Engine_GetRepoForOrg(t *testing.T) { // setup types - _repo := testAPIRepo() + _repo := testutils.APIRepo() _repo.SetID(1) _repo.SetHash("baz") _repo.SetOrg("foo") @@ -27,7 +28,7 @@ func TestRepo_Engine_GetRepoForOrg(t *testing.T) { _repo.SetTopics([]string{}) _repo.SetAllowEvents(api.NewEventsFromMask(1)) - _owner := testOwner() + _owner := testutils.APIUser().Crop() _owner.SetID(1) _owner.SetName("foo") _owner.SetToken("bar") @@ -58,12 +59,12 @@ func TestRepo_Engine_GetRepoForOrg(t *testing.T) { t.Errorf("unable to create test repo for sqlite: %v", err) } - err = _sqlite.client.AutoMigrate(&user.User{}) + err = _sqlite.client.AutoMigrate(&types.User{}) if err != nil { t.Errorf("unable to create build table for sqlite: %v", err) } - err = _sqlite.client.Table(constants.TableUser).Create(user.FromAPI(_owner)).Error + err = _sqlite.client.Table(constants.TableUser).Create(types.UserFromAPI(_owner)).Error if err != nil { t.Errorf("unable to create test user for sqlite: %v", err) } diff --git a/database/repo/get_test.go b/database/repo/get_test.go index 651fc8f39..bab82c6f3 100644 --- a/database/repo/get_test.go +++ b/database/repo/get_test.go @@ -10,13 +10,14 @@ import ( "github.com/DATA-DOG/go-sqlmock" api "github.com/go-vela/server/api/types" - "github.com/go-vela/server/database/user" + "github.com/go-vela/server/database/testutils" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" ) func TestRepo_Engine_GetRepo(t *testing.T) { // setup types - _repo := testAPIRepo() + _repo := testutils.APIRepo() _repo.SetID(1) _repo.SetHash("baz") _repo.SetOrg("foo") @@ -27,7 +28,7 @@ func TestRepo_Engine_GetRepo(t *testing.T) { _repo.SetTopics([]string{}) _repo.SetAllowEvents(api.NewEventsFromMask(1)) - _owner := testOwner() + _owner := testutils.APIUser().Crop() _owner.SetID(1) _owner.SetName("foo") _owner.SetToken("bar") @@ -58,12 +59,12 @@ func TestRepo_Engine_GetRepo(t *testing.T) { t.Errorf("unable to create test repo for sqlite: %v", err) } - err = _sqlite.client.AutoMigrate(&user.User{}) + err = _sqlite.client.AutoMigrate(&types.User{}) if err != nil { t.Errorf("unable to create build table for sqlite: %v", err) } - err = _sqlite.client.Table(constants.TableUser).Create(user.FromAPI(_owner)).Error + err = _sqlite.client.Table(constants.TableUser).Create(types.UserFromAPI(_owner)).Error if err != nil { t.Errorf("unable to create test user for sqlite: %v", err) } diff --git a/database/repo/list.go b/database/repo/list.go index 2197acbb1..e50de9a21 100644 --- a/database/repo/list.go +++ b/database/repo/list.go @@ -6,6 +6,7 @@ import ( "context" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" ) @@ -15,7 +16,7 @@ func (e *engine) ListRepos(ctx context.Context) ([]*api.Repo, error) { // variables to store query results and return value count := int64(0) - r := new([]Repo) + r := new([]types.Repo) repos := []*api.Repo{} // count the results @@ -55,12 +56,6 @@ func (e *engine) ListRepos(ctx context.Context) ([]*api.Repo, error) { e.logger.Errorf("unable to decrypt repo %d: %v", tmp.ID.Int64, err) } - // decrypt owner fields - err = tmp.Owner.Decrypt(e.config.EncryptionKey) - if err != nil { - e.logger.Errorf("unable to decrypt repo owner %d: %v", tmp.ID.Int64, err) - } - // convert query result to library type repos = append(repos, tmp.ToAPI()) } diff --git a/database/repo/list_org.go b/database/repo/list_org.go index 32529268e..bc1ee5597 100644 --- a/database/repo/list_org.go +++ b/database/repo/list_org.go @@ -8,6 +8,7 @@ import ( "github.com/sirupsen/logrus" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" ) @@ -21,7 +22,7 @@ func (e *engine) ListReposForOrg(ctx context.Context, org, sortBy string, filter // variables to store query results and return values count := int64(0) - r := new([]Repo) + r := new([]types.Repo) repos := []*api.Repo{} // count the results @@ -94,12 +95,6 @@ func (e *engine) ListReposForOrg(ctx context.Context, org, sortBy string, filter e.logger.Errorf("unable to decrypt repo %d: %v", tmp.ID.Int64, err) } - // decrypt owner fields - err = tmp.Owner.Decrypt(e.config.EncryptionKey) - if err != nil { - e.logger.Errorf("unable to decrypt repo owner %d: %v", tmp.ID.Int64, err) - } - // convert query result to API type repos = append(repos, tmp.ToAPI()) } diff --git a/database/repo/list_org_test.go b/database/repo/list_org_test.go index 7f13b540a..9a7bb5aa6 100644 --- a/database/repo/list_org_test.go +++ b/database/repo/list_org_test.go @@ -11,28 +11,21 @@ import ( "github.com/google/go-cmp/cmp" api "github.com/go-vela/server/api/types" - "github.com/go-vela/server/database/user" + "github.com/go-vela/server/database/testutils" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" ) func TestRepo_Engine_ListReposForOrg(t *testing.T) { // setup types - _buildOne := new(library.Build) - _buildOne.SetID(1) - _buildOne.SetRepoID(1) - _buildOne.SetNumber(1) - _buildOne.SetCreated(time.Now().UTC().Unix()) - - _buildTwo := new(library.Build) - _buildTwo.SetID(2) - _buildTwo.SetRepoID(2) - _buildTwo.SetNumber(1) - _buildTwo.SetCreated(time.Now().UTC().Unix()) + _owner := testutils.APIUser().Crop() + _owner.SetID(1) + _owner.SetName("foo") + _owner.SetToken("bar") - _repoOne := testAPIRepo() + _repoOne := testutils.APIRepo() _repoOne.SetID(1) + _repoOne.SetOwner(_owner) _repoOne.SetHash("baz") _repoOne.SetOrg("foo") _repoOne.SetName("bar") @@ -42,8 +35,9 @@ func TestRepo_Engine_ListReposForOrg(t *testing.T) { _repoOne.SetTopics([]string{}) _repoOne.SetAllowEvents(api.NewEventsFromMask(1)) - _repoTwo := testAPIRepo() + _repoTwo := testutils.APIRepo() _repoTwo.SetID(2) + _repoTwo.SetOwner(_owner) _repoTwo.SetHash("bar") _repoTwo.SetOrg("foo") _repoTwo.SetName("baz") @@ -53,13 +47,17 @@ func TestRepo_Engine_ListReposForOrg(t *testing.T) { _repoTwo.SetTopics([]string{}) _repoTwo.SetAllowEvents(api.NewEventsFromMask(1)) - _owner := testOwner() - _owner.SetID(1) - _owner.SetName("foo") - _owner.SetToken("bar") + _buildOne := new(api.Build) + _buildOne.SetID(1) + _buildOne.SetRepo(_repoOne) + _buildOne.SetNumber(1) + _buildOne.SetCreated(time.Now().UTC().Unix()) - _repoOne.SetOwner(_owner) - _repoTwo.SetOwner(_owner) + _buildTwo := new(api.Build) + _buildTwo.SetID(2) + _buildTwo.SetRepo(_repoTwo) + _buildTwo.SetNumber(1) + _buildTwo.SetCreated(time.Now().UTC().Unix()) _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() @@ -117,29 +115,29 @@ func TestRepo_Engine_ListReposForOrg(t *testing.T) { t.Errorf("unable to create test repo for sqlite: %v", err) } - err = _sqlite.client.AutoMigrate(&database.Build{}) + err = _sqlite.client.Migrator().CreateTable(&types.User{}) if err != nil { t.Errorf("unable to create build table for sqlite: %v", err) } - err = _sqlite.client.Table(constants.TableBuild).Create(database.BuildFromLibrary(_buildOne).Crop()).Error + err = _sqlite.client.Table(constants.TableUser).Create(types.UserFromAPI(_owner)).Error if err != nil { - t.Errorf("unable to create test build for sqlite: %v", err) + t.Errorf("unable to create test user for sqlite: %v", err) } - err = _sqlite.client.Table(constants.TableBuild).Create(database.BuildFromLibrary(_buildTwo).Crop()).Error + err = _sqlite.client.Migrator().CreateTable(&types.Build{}) if err != nil { - t.Errorf("unable to create test build for sqlite: %v", err) + t.Errorf("unable to create build table for sqlite: %v", err) } - err = _sqlite.client.AutoMigrate(&user.User{}) + err = _sqlite.client.Table(constants.TableBuild).Create(types.BuildFromAPI(_buildOne)).Error if err != nil { - t.Errorf("unable to create build table for sqlite: %v", err) + t.Errorf("unable to create test build for sqlite: %v", err) } - err = _sqlite.client.Table(constants.TableUser).Create(user.FromAPI(_owner)).Error + err = _sqlite.client.Table(constants.TableBuild).Create(types.BuildFromAPI(_buildTwo)).Error if err != nil { - t.Errorf("unable to create test user for sqlite: %v", err) + t.Errorf("unable to create test build for sqlite: %v", err) } // setup tests diff --git a/database/repo/list_test.go b/database/repo/list_test.go index 01df9981e..a4f40dcbe 100644 --- a/database/repo/list_test.go +++ b/database/repo/list_test.go @@ -10,14 +10,21 @@ import ( "github.com/DATA-DOG/go-sqlmock" api "github.com/go-vela/server/api/types" - "github.com/go-vela/server/database/user" + "github.com/go-vela/server/database/testutils" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" ) func TestRepo_Engine_ListRepos(t *testing.T) { // setup types - _repoOne := testAPIRepo() + _owner := testutils.APIUser().Crop() + _owner.SetID(1) + _owner.SetName("foo") + _owner.SetToken("bar") + + _repoOne := testutils.APIRepo() _repoOne.SetID(1) + _repoOne.SetOwner(_owner) _repoOne.SetHash("baz") _repoOne.SetOrg("foo") _repoOne.SetName("bar") @@ -27,8 +34,9 @@ func TestRepo_Engine_ListRepos(t *testing.T) { _repoOne.SetTopics([]string{}) _repoOne.SetAllowEvents(api.NewEventsFromMask(1)) - _repoTwo := testAPIRepo() + _repoTwo := testutils.APIRepo() _repoTwo.SetID(2) + _repoTwo.SetOwner(_owner) _repoTwo.SetHash("baz") _repoTwo.SetOrg("bar") _repoTwo.SetName("foo") @@ -38,14 +46,6 @@ func TestRepo_Engine_ListRepos(t *testing.T) { _repoTwo.SetTopics([]string{}) _repoTwo.SetAllowEvents(api.NewEventsFromMask(1)) - _owner := testOwner() - _owner.SetID(1) - _owner.SetName("foo") - _owner.SetToken("bar") - - _repoOne.SetOwner(_owner) - _repoTwo.SetOwner(_owner) - _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() @@ -82,12 +82,12 @@ func TestRepo_Engine_ListRepos(t *testing.T) { t.Errorf("unable to create test repo for sqlite: %v", err) } - err = _sqlite.client.AutoMigrate(&user.User{}) + err = _sqlite.client.AutoMigrate(&types.User{}) if err != nil { t.Errorf("unable to create build table for sqlite: %v", err) } - err = _sqlite.client.Table(constants.TableUser).Create(user.FromAPI(_owner)).Error + err = _sqlite.client.Table(constants.TableUser).Create(types.UserFromAPI(_owner)).Error if err != nil { t.Errorf("unable to create test user for sqlite: %v", err) } diff --git a/database/repo/list_user.go b/database/repo/list_user.go index 1f1c709a1..37665769a 100644 --- a/database/repo/list_user.go +++ b/database/repo/list_user.go @@ -8,6 +8,7 @@ import ( "github.com/sirupsen/logrus" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" ) @@ -21,7 +22,7 @@ func (e *engine) ListReposForUser(ctx context.Context, u *api.User, sortBy strin // variables to store query results and return values count := int64(0) - r := new([]Repo) + r := new([]types.Repo) repos := []*api.Repo{} // count the results @@ -94,12 +95,6 @@ func (e *engine) ListReposForUser(ctx context.Context, u *api.User, sortBy strin e.logger.Errorf("unable to decrypt repo %d: %v", tmp.ID.Int64, err) } - // decrypt owner fields - err = tmp.Owner.Decrypt(e.config.EncryptionKey) - if err != nil { - e.logger.Errorf("unable to decrypt repo owner %d: %v", tmp.ID.Int64, err) - } - // convert query result to library type repos = append(repos, tmp.ToAPI()) } diff --git a/database/repo/list_user_test.go b/database/repo/list_user_test.go index b89fce07e..49261c95e 100644 --- a/database/repo/list_user_test.go +++ b/database/repo/list_user_test.go @@ -11,29 +11,21 @@ import ( "github.com/DATA-DOG/go-sqlmock" api "github.com/go-vela/server/api/types" - "github.com/go-vela/server/database/user" + "github.com/go-vela/server/database/testutils" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" ) func TestRepo_Engine_ListReposForUser(t *testing.T) { // setup types - _buildOne := new(library.Build) - _buildOne.SetID(1) - _buildOne.SetRepoID(1) - _buildOne.SetNumber(1) - _buildOne.SetCreated(time.Now().UTC().Unix()) - - _buildTwo := new(library.Build) - _buildTwo.SetID(2) - _buildTwo.SetRepoID(2) - _buildTwo.SetNumber(1) - _buildTwo.SetCreated(time.Now().UTC().Unix()) + _owner := testutils.APIUser().Crop() + _owner.SetID(1) + _owner.SetName("foo") + _owner.SetToken("bar") - _repoOne := testAPIRepo() + _repoOne := testutils.APIRepo() _repoOne.SetID(1) - _repoOne.GetOwner().SetID(1) + _repoOne.SetOwner(_owner) _repoOne.SetHash("baz") _repoOne.SetOrg("foo") _repoOne.SetName("bar") @@ -43,9 +35,9 @@ func TestRepo_Engine_ListReposForUser(t *testing.T) { _repoOne.SetTopics([]string{}) _repoOne.SetAllowEvents(api.NewEventsFromMask(1)) - _repoTwo := testAPIRepo() + _repoTwo := testutils.APIRepo() _repoTwo.SetID(2) - _repoTwo.GetOwner().SetID(1) + _repoTwo.SetOwner(_owner) _repoTwo.SetHash("baz") _repoTwo.SetOrg("bar") _repoTwo.SetName("foo") @@ -55,13 +47,17 @@ func TestRepo_Engine_ListReposForUser(t *testing.T) { _repoTwo.SetTopics([]string{}) _repoTwo.SetAllowEvents(api.NewEventsFromMask(1)) - _owner := testOwner() - _owner.SetID(1) - _owner.SetName("foo") - _owner.SetToken("bar") + _buildOne := new(api.Build) + _buildOne.SetID(1) + _buildOne.SetRepo(_repoOne) + _buildOne.SetNumber(1) + _buildOne.SetCreated(time.Now().UTC().Unix()) - _repoOne.SetOwner(_owner) - _repoTwo.SetOwner(_owner) + _buildTwo := new(api.Build) + _buildTwo.SetID(2) + _buildTwo.SetRepo(_repoTwo) + _buildTwo.SetNumber(1) + _buildTwo.SetCreated(time.Now().UTC().Unix()) _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() @@ -119,29 +115,29 @@ func TestRepo_Engine_ListReposForUser(t *testing.T) { t.Errorf("unable to create test repo for sqlite: %v", err) } - err = _sqlite.client.AutoMigrate(&database.Build{}) + err = _sqlite.client.Migrator().CreateTable(&types.User{}) if err != nil { t.Errorf("unable to create build table for sqlite: %v", err) } - err = _sqlite.client.Table(constants.TableBuild).Create(database.BuildFromLibrary(_buildOne).Crop()).Error + err = _sqlite.client.Table(constants.TableUser).Create(types.UserFromAPI(_owner)).Error if err != nil { - t.Errorf("unable to create test build for sqlite: %v", err) + t.Errorf("unable to create test user for sqlite: %v", err) } - err = _sqlite.client.Table(constants.TableBuild).Create(database.BuildFromLibrary(_buildTwo).Crop()).Error + err = _sqlite.client.Migrator().CreateTable(&types.Build{}) if err != nil { - t.Errorf("unable to create test build for sqlite: %v", err) + t.Errorf("unable to create build table for sqlite: %v", err) } - err = _sqlite.client.AutoMigrate(&user.User{}) + err = _sqlite.client.Table(constants.TableBuild).Create(types.BuildFromAPI(_buildOne)).Error if err != nil { - t.Errorf("unable to create build table for sqlite: %v", err) + t.Errorf("unable to create test build for sqlite: %v", err) } - err = _sqlite.client.Table(constants.TableUser).Create(user.FromAPI(_owner)).Error + err = _sqlite.client.Table(constants.TableBuild).Create(types.BuildFromAPI(_buildTwo)).Error if err != nil { - t.Errorf("unable to create test user for sqlite: %v", err) + t.Errorf("unable to create test build for sqlite: %v", err) } // setup tests diff --git a/database/repo/repo.go b/database/repo/repo.go index fc1e7808e..6f9edeb19 100644 --- a/database/repo/repo.go +++ b/database/repo/repo.go @@ -4,51 +4,14 @@ package repo import ( "context" - "database/sql" - "encoding/base64" - "errors" "fmt" - "github.com/lib/pq" "github.com/sirupsen/logrus" "gorm.io/gorm" - api "github.com/go-vela/server/api/types" - "github.com/go-vela/server/database/user" - "github.com/go-vela/server/util" "github.com/go-vela/types/constants" ) -var ( - // ErrEmptyRepoFullName defines the error type when a - // Repo type has an empty FullName field provided. - ErrEmptyRepoFullName = errors.New("empty repo full_name provided") - - // ErrEmptyRepoHash defines the error type when a - // Repo type has an empty Hash field provided. - ErrEmptyRepoHash = errors.New("empty repo hash provided") - - // ErrEmptyRepoName defines the error type when a - // Repo type has an empty Name field provided. - ErrEmptyRepoName = errors.New("empty repo name provided") - - // ErrEmptyRepoOrg defines the error type when a - // Repo type has an empty Org field provided. - ErrEmptyRepoOrg = errors.New("empty repo org provided") - - // ErrEmptyRepoUserID defines the error type when a - // Repo type has an empty UserID field provided. - ErrEmptyRepoUserID = errors.New("empty repo user_id provided") - - // ErrEmptyRepoVisibility defines the error type when a - // Repo type has an empty Visibility field provided. - ErrEmptyRepoVisibility = errors.New("empty repo visibility provided") - - // ErrExceededTopicsLimit defines the error type when a - // Repo type has Topics field provided that exceeds the database limit. - ErrExceededTopicsLimit = errors.New("exceeded topics limit") -) - type ( // config represents the settings required to create the engine that implements the RepoInterface interface. config struct { @@ -75,33 +38,6 @@ type ( // https://pkg.go.dev/github.com/sirupsen/logrus#Entry logger *logrus.Entry } - - // Repo is the database representation of a repo. - Repo struct { - ID sql.NullInt64 `sql:"id"` - UserID sql.NullInt64 `sql:"user_id"` - Hash sql.NullString `sql:"hash"` - Org sql.NullString `sql:"org"` - Name sql.NullString `sql:"name"` - FullName sql.NullString `sql:"full_name"` - Link sql.NullString `sql:"link"` - Clone sql.NullString `sql:"clone"` - Branch sql.NullString `sql:"branch"` - Topics pq.StringArray `sql:"topics" gorm:"type:varchar(1020)"` - BuildLimit sql.NullInt64 `sql:"build_limit"` - Timeout sql.NullInt64 `sql:"timeout"` - Counter sql.NullInt32 `sql:"counter"` - Visibility sql.NullString `sql:"visibility"` - Private sql.NullBool `sql:"private"` - Trusted sql.NullBool `sql:"trusted"` - Active sql.NullBool `sql:"active"` - AllowEvents sql.NullInt64 `sql:"allow_events"` - PipelineType sql.NullString `sql:"pipeline_type"` - PreviousName sql.NullString `sql:"previous_name"` - ApproveBuild sql.NullString `sql:"approve_build"` - - Owner user.User `gorm:"foreignKey:UserID"` - } ) // New creates and returns a Vela service for integrating with repos in the database. @@ -145,267 +81,3 @@ func New(opts ...EngineOpt) (*engine, error) { return e, nil } - -// Decrypt will manipulate the existing repo hash by -// base64 decoding that value. Then, a AES-256 cipher -// block is created from the encryption key in order to -// decrypt the base64 decoded secret value. -func (r *Repo) Decrypt(key string) error { - // base64 decode the encrypted repo hash - decoded, err := base64.StdEncoding.DecodeString(r.Hash.String) - if err != nil { - return err - } - - // decrypt the base64 decoded repo hash - decrypted, err := util.Decrypt(key, decoded) - if err != nil { - return err - } - - // set the decrypted repo hash - r.Hash = sql.NullString{ - String: string(decrypted), - Valid: true, - } - - return nil -} - -// Encrypt will manipulate the existing repo hash by -// creating a AES-256 cipher block from the encryption -// key in order to encrypt the repo hash. Then, the -// repo hash is base64 encoded for transport across -// network boundaries. -func (r *Repo) Encrypt(key string) error { - // encrypt the repo hash - encrypted, err := util.Encrypt(key, []byte(r.Hash.String)) - if err != nil { - return err - } - - // base64 encode the encrypted repo hash to make it network safe - r.Hash = sql.NullString{ - String: base64.StdEncoding.EncodeToString(encrypted), - Valid: true, - } - - return nil -} - -// Nullify ensures the valid flag for -// the sql.Null types are properly set. -// -// When a field within the Repo type is the zero -// value for the field, the valid flag is set to -// false causing it to be NULL in the database. -func (r *Repo) Nullify() *Repo { - if r == nil { - return nil - } - - // check if the ID field should be false - if r.ID.Int64 == 0 { - r.ID.Valid = false - } - - // check if the UserID field should be false - if r.UserID.Int64 == 0 { - r.UserID.Valid = false - } - - // check if the Hash field should be false - if len(r.Hash.String) == 0 { - r.Hash.Valid = false - } - - // check if the Org field should be false - if len(r.Org.String) == 0 { - r.Org.Valid = false - } - - // check if the Name field should be false - if len(r.Name.String) == 0 { - r.Name.Valid = false - } - - // check if the FullName field should be false - if len(r.FullName.String) == 0 { - r.FullName.Valid = false - } - - // check if the Link field should be false - if len(r.Link.String) == 0 { - r.Link.Valid = false - } - - // check if the Clone field should be false - if len(r.Clone.String) == 0 { - r.Clone.Valid = false - } - - // check if the Branch field should be false - if len(r.Branch.String) == 0 { - r.Branch.Valid = false - } - - // check if the BuildLimit field should be false - if r.BuildLimit.Int64 == 0 { - r.BuildLimit.Valid = false - } - - // check if the Timeout field should be false - if r.Timeout.Int64 == 0 { - r.Timeout.Valid = false - } - - // check if the AllowEvents field should be false - if r.AllowEvents.Int64 == 0 { - r.AllowEvents.Valid = false - } - - // check if the Visibility field should be false - if len(r.Visibility.String) == 0 { - r.Visibility.Valid = false - } - - // check if the PipelineType field should be false - if len(r.PipelineType.String) == 0 { - r.PipelineType.Valid = false - } - - // check if the PreviousName field should be false - if len(r.PreviousName.String) == 0 { - r.PreviousName.Valid = false - } - - // check if the ApproveForkBuild field should be false - if len(r.ApproveBuild.String) == 0 { - r.ApproveBuild.Valid = false - } - - return r -} - -// ToAPI converts the Repo type -// to an API Repo type. -func (r *Repo) ToAPI() *api.Repo { - repo := new(api.Repo) - - repo.SetID(r.ID.Int64) - repo.SetOwner(r.Owner.ToAPI().Crop()) - repo.SetHash(r.Hash.String) - repo.SetOrg(r.Org.String) - repo.SetName(r.Name.String) - repo.SetFullName(r.FullName.String) - repo.SetLink(r.Link.String) - repo.SetClone(r.Clone.String) - repo.SetBranch(r.Branch.String) - repo.SetTopics(r.Topics) - repo.SetBuildLimit(r.BuildLimit.Int64) - repo.SetTimeout(r.Timeout.Int64) - repo.SetCounter(int(r.Counter.Int32)) - repo.SetVisibility(r.Visibility.String) - repo.SetPrivate(r.Private.Bool) - repo.SetTrusted(r.Trusted.Bool) - repo.SetActive(r.Active.Bool) - repo.SetAllowEvents(api.NewEventsFromMask(r.AllowEvents.Int64)) - repo.SetPipelineType(r.PipelineType.String) - repo.SetPreviousName(r.PreviousName.String) - repo.SetApproveBuild(r.ApproveBuild.String) - - return repo -} - -// Validate verifies the necessary fields for -// the Repo type are populated correctly. -func (r *Repo) Validate() error { - // verify the UserID field is populated - if r.UserID.Int64 <= 0 { - return ErrEmptyRepoUserID - } - - // verify the Hash field is populated - if len(r.Hash.String) == 0 { - return ErrEmptyRepoHash - } - - // verify the Org field is populated - if len(r.Org.String) == 0 { - return ErrEmptyRepoOrg - } - - // verify the Name field is populated - if len(r.Name.String) == 0 { - return ErrEmptyRepoName - } - - // verify the FullName field is populated - if len(r.FullName.String) == 0 { - return ErrEmptyRepoFullName - } - - // verify the Visibility field is populated - if len(r.Visibility.String) == 0 { - return ErrEmptyRepoVisibility - } - - // calculate total size of favorites while sanitizing entries - total := 0 - - for i, t := range r.Topics { - r.Topics[i] = util.Sanitize(t) - total += len(t) - } - - // verify the Favorites field is within the database constraints - // len is to factor in number of comma separators included in the database field, - // removing 1 due to the last item not having an appended comma - if (total + len(r.Topics) - 1) > constants.TopicsMaxSize { - return ErrExceededTopicsLimit - } - - // ensure that all Repo string fields - // that can be returned as JSON are sanitized - // to avoid unsafe HTML content - r.Org = sql.NullString{String: util.Sanitize(r.Org.String), Valid: r.Org.Valid} - r.Name = sql.NullString{String: util.Sanitize(r.Name.String), Valid: r.Name.Valid} - r.FullName = sql.NullString{String: util.Sanitize(r.FullName.String), Valid: r.FullName.Valid} - r.Link = sql.NullString{String: util.Sanitize(r.Link.String), Valid: r.Link.Valid} - r.Clone = sql.NullString{String: util.Sanitize(r.Clone.String), Valid: r.Clone.Valid} - r.Branch = sql.NullString{String: util.Sanitize(r.Branch.String), Valid: r.Branch.Valid} - r.Visibility = sql.NullString{String: util.Sanitize(r.Visibility.String), Valid: r.Visibility.Valid} - r.PipelineType = sql.NullString{String: util.Sanitize(r.PipelineType.String), Valid: r.PipelineType.Valid} - - return nil -} - -// FromAPI converts the API Repo type -// to a database repo type. -func FromAPI(r *api.Repo) *Repo { - repo := &Repo{ - ID: sql.NullInt64{Int64: r.GetID(), Valid: true}, - UserID: sql.NullInt64{Int64: r.GetOwner().GetID(), Valid: true}, - Hash: sql.NullString{String: r.GetHash(), Valid: true}, - Org: sql.NullString{String: r.GetOrg(), Valid: true}, - Name: sql.NullString{String: r.GetName(), Valid: true}, - FullName: sql.NullString{String: r.GetFullName(), Valid: true}, - Link: sql.NullString{String: r.GetLink(), Valid: true}, - Clone: sql.NullString{String: r.GetClone(), Valid: true}, - Branch: sql.NullString{String: r.GetBranch(), Valid: true}, - Topics: pq.StringArray(r.GetTopics()), - BuildLimit: sql.NullInt64{Int64: r.GetBuildLimit(), Valid: true}, - Timeout: sql.NullInt64{Int64: r.GetTimeout(), Valid: true}, - Counter: sql.NullInt32{Int32: int32(r.GetCounter()), Valid: true}, - Visibility: sql.NullString{String: r.GetVisibility(), Valid: true}, - Private: sql.NullBool{Bool: r.GetPrivate(), Valid: true}, - Trusted: sql.NullBool{Bool: r.GetTrusted(), Valid: true}, - Active: sql.NullBool{Bool: r.GetActive(), Valid: true}, - AllowEvents: sql.NullInt64{Int64: r.GetAllowEvents().ToDatabase(), Valid: true}, - PipelineType: sql.NullString{String: r.GetPipelineType(), Valid: true}, - PreviousName: sql.NullString{String: r.GetPreviousName(), Valid: true}, - ApproveBuild: sql.NullString{String: r.GetApproveBuild(), Valid: true}, - } - - return repo.Nullify() -} diff --git a/database/repo/repo_test.go b/database/repo/repo_test.go index 8d50ade32..498940ebb 100644 --- a/database/repo/repo_test.go +++ b/database/repo/repo_test.go @@ -3,21 +3,15 @@ package repo import ( - "database/sql" "database/sql/driver" "reflect" "testing" "github.com/DATA-DOG/go-sqlmock" - "github.com/google/go-cmp/cmp" "github.com/sirupsen/logrus" "gorm.io/driver/postgres" "gorm.io/driver/sqlite" "gorm.io/gorm" - - api "github.com/go-vela/server/api/types" - "github.com/go-vela/server/api/types/actions" - "github.com/go-vela/types/constants" ) func TestRepo_New(t *testing.T) { @@ -155,7 +149,10 @@ func testPostgres(t *testing.T) (*engine, sqlmock.Sqlmock) { func testSqlite(t *testing.T) *engine { _sqlite, err := gorm.Open( sqlite.Open("file::memory:?cache=shared"), - &gorm.Config{SkipDefaultTransaction: true}, + &gorm.Config{ + SkipDefaultTransaction: true, + DisableForeignKeyConstraintWhenMigrating: true, + }, ) if err != nil { t.Errorf("unable to create new sqlite database: %v", err) @@ -174,73 +171,6 @@ func testSqlite(t *testing.T) *engine { return _engine } -// testAPIRepo is a test helper function to create an API -// Repo type with all fields set to their zero values. -func testAPIRepo() *api.Repo { - return &api.Repo{ - ID: new(int64), - Owner: testOwner(), - BuildLimit: new(int64), - Timeout: new(int64), - Counter: new(int), - PipelineType: new(string), - Hash: new(string), - Org: new(string), - Name: new(string), - FullName: new(string), - Link: new(string), - Clone: new(string), - Branch: new(string), - Visibility: new(string), - PreviousName: new(string), - ApproveBuild: new(string), - Private: new(bool), - Trusted: new(bool), - Active: new(bool), - AllowEvents: testEvents(), - } -} - -func testEvents() *api.Events { - return &api.Events{ - Push: &actions.Push{ - Branch: new(bool), - Tag: new(bool), - DeleteBranch: new(bool), - DeleteTag: new(bool), - }, - PullRequest: &actions.Pull{ - Opened: new(bool), - Edited: new(bool), - Synchronize: new(bool), - Reopened: new(bool), - Labeled: new(bool), - Unlabeled: new(bool), - }, - Deployment: &actions.Deploy{ - Created: new(bool), - }, - Comment: &actions.Comment{ - Created: new(bool), - Edited: new(bool), - }, - Schedule: &actions.Schedule{ - Run: new(bool), - }, - } -} - -// testOwner is a helper function that returns a sanitized user. -func testOwner() *api.User { - return &api.User{ - ID: new(int64), - Name: new(string), - RefreshToken: new(string), - Token: new(string), - Active: new(bool), - } -} - // This will be used with the github.com/DATA-DOG/go-sqlmock library to compare values // that are otherwise not easily compared. These typically would be values generated // before adding or updating them in the database. @@ -252,362 +182,3 @@ type AnyArgument struct{} func (a AnyArgument) Match(_ driver.Value) bool { return true } - -func TestRepo_Decrypt(t *testing.T) { - // setup types - key := "C639A572E14D5075C526FDDD43E4ECF6" - encrypted := testRepo() - - err := encrypted.Encrypt(key) - if err != nil { - t.Errorf("unable to encrypt repo: %v", err) - } - - // setup tests - tests := []struct { - failure bool - key string - repo Repo - }{ - { - failure: false, - key: key, - repo: *encrypted, - }, - { - failure: true, - key: "", - repo: *encrypted, - }, - { - failure: true, - key: key, - repo: *testRepo(), - }, - } - - // run tests - for _, test := range tests { - err := test.repo.Decrypt(test.key) - - if test.failure { - if err == nil { - t.Errorf("Decrypt should have returned err") - } - - continue - } - - if err != nil { - t.Errorf("Decrypt returned err: %v", err) - } - } -} - -func TestRepo_Encrypt(t *testing.T) { - // setup types - key := "C639A572E14D5075C526FDDD43E4ECF6" - - // setup tests - tests := []struct { - failure bool - key string - repo *Repo - }{ - { - failure: false, - key: key, - repo: testRepo(), - }, - { - failure: true, - key: "", - repo: testRepo(), - }, - } - - // run tests - for _, test := range tests { - err := test.repo.Encrypt(test.key) - - if test.failure { - if err == nil { - t.Errorf("Encrypt should have returned err") - } - - continue - } - - if err != nil { - t.Errorf("Encrypt returned err: %v", err) - } - } -} - -func TestRepo_Nullify(t *testing.T) { - // setup types - var r *Repo - - want := &Repo{ - ID: sql.NullInt64{Int64: 0, Valid: false}, - UserID: sql.NullInt64{Int64: 0, Valid: false}, - Hash: sql.NullString{String: "", Valid: false}, - Org: sql.NullString{String: "", Valid: false}, - Name: sql.NullString{String: "", Valid: false}, - FullName: sql.NullString{String: "", Valid: false}, - Link: sql.NullString{String: "", Valid: false}, - Clone: sql.NullString{String: "", Valid: false}, - Branch: sql.NullString{String: "", Valid: false}, - Timeout: sql.NullInt64{Int64: 0, Valid: false}, - AllowEvents: sql.NullInt64{Int64: 0, Valid: false}, - Visibility: sql.NullString{String: "", Valid: false}, - PipelineType: sql.NullString{String: "", Valid: false}, - ApproveBuild: sql.NullString{String: "", Valid: false}, - } - - // setup tests - tests := []struct { - repo *Repo - want *Repo - }{ - { - repo: testRepo(), - want: testRepo(), - }, - { - repo: r, - want: nil, - }, - { - repo: new(Repo), - want: want, - }, - } - - // run tests - for _, test := range tests { - got := test.repo.Nullify() - - if !reflect.DeepEqual(got, test.want) { - t.Errorf("Nullify is %v, want %v", got, test.want) - } - } -} - -func TestRepo_ToAPI(t *testing.T) { - // setup types - want := new(api.Repo) - e := api.NewEventsFromMask(1) - owner := testOwner() - - want.SetID(1) - want.SetOwner(owner) - want.SetHash("superSecretHash") - want.SetOrg("github") - want.SetName("octocat") - want.SetFullName("github/octocat") - want.SetLink("https://github.com/github/octocat") - want.SetClone("https://github.com/github/octocat.git") - want.SetBranch("main") - want.SetTopics([]string{"cloud", "security"}) - want.SetBuildLimit(10) - want.SetTimeout(30) - want.SetCounter(0) - want.SetVisibility("public") - want.SetPrivate(false) - want.SetTrusted(false) - want.SetActive(true) - want.SetAllowEvents(e) - want.SetPipelineType("yaml") - want.SetPreviousName("oldName") - want.SetApproveBuild(constants.ApproveNever) - - // run test - got := testRepo().ToAPI() - - if diff := cmp.Diff(want, got); diff != "" { - t.Errorf("ToAPI() mismatch (-want +got):\n%s", diff) - } -} - -func TestRepo_Validate(t *testing.T) { - // setup types - topics := []string{} - longTopic := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" - - for len(topics) < 21 { - topics = append(topics, longTopic) - } - - // setup tests - tests := []struct { - failure bool - repo *Repo - }{ - { - failure: false, - repo: testRepo(), - }, - { // no user_id set for repo - failure: true, - repo: &Repo{ - ID: sql.NullInt64{Int64: 1, Valid: true}, - Hash: sql.NullString{String: "superSecretHash", Valid: true}, - Org: sql.NullString{String: "github", Valid: true}, - Name: sql.NullString{String: "octocat", Valid: true}, - FullName: sql.NullString{String: "github/octocat", Valid: true}, - Visibility: sql.NullString{String: "public", Valid: true}, - }, - }, - { // no hash set for repo - failure: true, - repo: &Repo{ - ID: sql.NullInt64{Int64: 1, Valid: true}, - UserID: sql.NullInt64{Int64: 1, Valid: true}, - Org: sql.NullString{String: "github", Valid: true}, - Name: sql.NullString{String: "octocat", Valid: true}, - FullName: sql.NullString{String: "github/octocat", Valid: true}, - Visibility: sql.NullString{String: "public", Valid: true}, - }, - }, - { // no org set for repo - failure: true, - repo: &Repo{ - ID: sql.NullInt64{Int64: 1, Valid: true}, - UserID: sql.NullInt64{Int64: 1, Valid: true}, - Hash: sql.NullString{String: "superSecretHash", Valid: true}, - Name: sql.NullString{String: "octocat", Valid: true}, - FullName: sql.NullString{String: "github/octocat", Valid: true}, - Visibility: sql.NullString{String: "public", Valid: true}, - }, - }, - { // no name set for repo - failure: true, - repo: &Repo{ - ID: sql.NullInt64{Int64: 1, Valid: true}, - UserID: sql.NullInt64{Int64: 1, Valid: true}, - Hash: sql.NullString{String: "superSecretHash", Valid: true}, - Org: sql.NullString{String: "github", Valid: true}, - FullName: sql.NullString{String: "github/octocat", Valid: true}, - Visibility: sql.NullString{String: "public", Valid: true}, - }, - }, - { // no full_name set for repo - failure: true, - repo: &Repo{ - ID: sql.NullInt64{Int64: 1, Valid: true}, - UserID: sql.NullInt64{Int64: 1, Valid: true}, - Hash: sql.NullString{String: "superSecretHash", Valid: true}, - Org: sql.NullString{String: "github", Valid: true}, - Name: sql.NullString{String: "octocat", Valid: true}, - Visibility: sql.NullString{String: "public", Valid: true}, - }, - }, - { // no visibility set for repo - failure: true, - repo: &Repo{ - ID: sql.NullInt64{Int64: 1, Valid: true}, - UserID: sql.NullInt64{Int64: 1, Valid: true}, - Hash: sql.NullString{String: "superSecretHash", Valid: true}, - Org: sql.NullString{String: "github", Valid: true}, - Name: sql.NullString{String: "octocat", Valid: true}, - FullName: sql.NullString{String: "github/octocat", Valid: true}, - }, - }, - { // topics exceed max size - failure: true, - repo: &Repo{ - ID: sql.NullInt64{Int64: 1, Valid: true}, - UserID: sql.NullInt64{Int64: 1, Valid: true}, - Hash: sql.NullString{String: "superSecretHash", Valid: true}, - Org: sql.NullString{String: "github", Valid: true}, - Name: sql.NullString{String: "octocat", Valid: true}, - FullName: sql.NullString{String: "github/octocat", Valid: true}, - Topics: topics, - }, - }, - } - - // run tests - for _, test := range tests { - err := test.repo.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 TestRepo_FromAPI(t *testing.T) { - // setup types - r := new(api.Repo) - owner := testOwner() - owner.SetID(1) - - r.SetID(1) - r.SetOwner(owner) - r.SetHash("superSecretHash") - r.SetOrg("github") - r.SetName("octocat") - r.SetFullName("github/octocat") - r.SetLink("https://github.com/github/octocat") - r.SetClone("https://github.com/github/octocat.git") - r.SetBranch("main") - r.SetTopics([]string{"cloud", "security"}) - r.SetBuildLimit(10) - r.SetTimeout(30) - r.SetCounter(0) - r.SetVisibility("public") - r.SetPrivate(false) - r.SetTrusted(false) - r.SetActive(true) - r.SetAllowEvents(api.NewEventsFromMask(1)) - r.SetPipelineType("yaml") - r.SetPreviousName("oldName") - r.SetApproveBuild(constants.ApproveNever) - - want := testRepo() - - // run test - got := FromAPI(r) - - if diff := cmp.Diff(want, got); diff != "" { - t.Errorf("FromAPI() mismatch (-want +got):\n%s", diff) - } -} - -// testRepo is a test helper function to create a Repo -// type with all fields set to a fake value. -func testRepo() *Repo { - return &Repo{ - ID: sql.NullInt64{Int64: 1, Valid: true}, - UserID: sql.NullInt64{Int64: 1, Valid: true}, - Hash: sql.NullString{String: "superSecretHash", Valid: true}, - Org: sql.NullString{String: "github", Valid: true}, - Name: sql.NullString{String: "octocat", Valid: true}, - FullName: sql.NullString{String: "github/octocat", Valid: true}, - Link: sql.NullString{String: "https://github.com/github/octocat", Valid: true}, - Clone: sql.NullString{String: "https://github.com/github/octocat.git", Valid: true}, - Branch: sql.NullString{String: "main", Valid: true}, - Topics: []string{"cloud", "security"}, - BuildLimit: sql.NullInt64{Int64: 10, Valid: true}, - Timeout: sql.NullInt64{Int64: 30, Valid: true}, - Counter: sql.NullInt32{Int32: 0, Valid: true}, - Visibility: sql.NullString{String: "public", Valid: true}, - Private: sql.NullBool{Bool: false, Valid: true}, - Trusted: sql.NullBool{Bool: false, Valid: true}, - Active: sql.NullBool{Bool: true, Valid: true}, - AllowEvents: sql.NullInt64{Int64: 1, Valid: true}, - PipelineType: sql.NullString{String: "yaml", Valid: true}, - PreviousName: sql.NullString{String: "oldName", Valid: true}, - ApproveBuild: sql.NullString{String: constants.ApproveNever, Valid: true}, - } -} diff --git a/database/repo/update.go b/database/repo/update.go index 8bbcefbc9..31922068f 100644 --- a/database/repo/update.go +++ b/database/repo/update.go @@ -10,6 +10,7 @@ import ( "github.com/sirupsen/logrus" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" ) @@ -21,7 +22,7 @@ func (e *engine) UpdateRepo(ctx context.Context, r *api.Repo) (*api.Repo, error) }).Tracef("creating repo %s in the database", r.GetFullName()) // cast the library type to database type - repo := FromAPI(r) + repo := types.RepoFromAPI(r) // validate the necessary fields are populated err := repo.Validate() @@ -46,8 +47,6 @@ func (e *engine) UpdateRepo(ctx context.Context, r *api.Repo) (*api.Repo, error) if err != nil { // only log to preserve backwards compatibility e.logger.Errorf("unable to decrypt repo %d: %v", r.GetID(), err) - - return repo.ToAPI(), nil } // set owner to provided owner if creation successful diff --git a/database/repo/update_test.go b/database/repo/update_test.go index 92e714567..e175a349a 100644 --- a/database/repo/update_test.go +++ b/database/repo/update_test.go @@ -10,12 +10,13 @@ import ( "github.com/DATA-DOG/go-sqlmock" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/types/constants" ) func TestRepo_Engine_UpdateRepo(t *testing.T) { // setup types - _repo := testAPIRepo() + _repo := testutils.APIRepo() _repo.SetID(1) _repo.GetOwner().SetID(1) _repo.SetHash("baz") diff --git a/database/resource.go b/database/resource.go index d592179c8..cbdad190c 100644 --- a/database/resource.go +++ b/database/resource.go @@ -31,6 +31,7 @@ func (e *engine) NewResources(ctx context.Context) error { build.WithClient(e.client), build.WithLogger(e.logger), build.WithSkipCreation(e.config.SkipCreation), + build.WithEncryptionKey(e.config.EncryptionKey), ) if err != nil { return err diff --git a/database/service/clean_test.go b/database/service/clean_test.go index a3edada5b..b72d14dad 100644 --- a/database/service/clean_test.go +++ b/database/service/clean_test.go @@ -8,11 +8,13 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestService_Engine_CleanService(t *testing.T) { // setup types - _serviceOne := testService() + _serviceOne := testutils.APIService() _serviceOne.SetID(1) _serviceOne.SetRepoID(1) _serviceOne.SetBuildID(1) @@ -22,7 +24,7 @@ func TestService_Engine_CleanService(t *testing.T) { _serviceOne.SetCreated(1) _serviceOne.SetStatus("running") - _serviceTwo := testService() + _serviceTwo := testutils.APIService() _serviceTwo.SetID(2) _serviceTwo.SetRepoID(1) _serviceTwo.SetBuildID(1) @@ -32,7 +34,7 @@ func TestService_Engine_CleanService(t *testing.T) { _serviceTwo.SetCreated(1) _serviceTwo.SetStatus("pending") - _serviceThree := testService() + _serviceThree := testutils.APIService() _serviceThree.SetID(3) _serviceThree.SetRepoID(1) _serviceThree.SetBuildID(1) @@ -42,7 +44,7 @@ func TestService_Engine_CleanService(t *testing.T) { _serviceThree.SetCreated(1) _serviceThree.SetStatus("success") - _serviceFour := testService() + _serviceFour := testutils.APIService() _serviceFour.SetID(4) _serviceFour.SetRepoID(1) _serviceFour.SetBuildID(1) diff --git a/database/service/count_build.go b/database/service/count_build.go index f1d9f1e36..a15c061ff 100644 --- a/database/service/count_build.go +++ b/database/service/count_build.go @@ -7,12 +7,12 @@ import ( "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" ) // CountServicesForBuild gets the count of services by build ID from the database. -func (e *engine) CountServicesForBuild(ctx context.Context, b *library.Build, filters map[string]interface{}) (int64, error) { +func (e *engine) CountServicesForBuild(ctx context.Context, b *api.Build, filters map[string]interface{}) (int64, error) { e.logger.WithFields(logrus.Fields{ "build": b.GetNumber(), }).Tracef("getting count of services for build %d from the database", b.GetNumber()) diff --git a/database/service/count_build_test.go b/database/service/count_build_test.go index 09b013c0c..e0c1cefcf 100644 --- a/database/service/count_build_test.go +++ b/database/service/count_build_test.go @@ -8,16 +8,18 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestService_Engine_CountServicesForBuild(t *testing.T) { // setup types - _build := testBuild() + _build := testutils.APIBuild() _build.SetID(1) - _build.SetRepoID(1) + _build.SetRepo(testutils.APIRepo()) _build.SetNumber(1) - _serviceOne := testService() + _serviceOne := testutils.APIService() _serviceOne.SetID(1) _serviceOne.SetRepoID(1) _serviceOne.SetBuildID(1) @@ -25,7 +27,7 @@ func TestService_Engine_CountServicesForBuild(t *testing.T) { _serviceOne.SetName("foo") _serviceOne.SetImage("bar") - _serviceTwo := testService() + _serviceTwo := testutils.APIService() _serviceTwo.SetID(2) _serviceTwo.SetRepoID(1) _serviceTwo.SetBuildID(2) diff --git a/database/service/count_test.go b/database/service/count_test.go index bbd0b6faf..c25a0d5b0 100644 --- a/database/service/count_test.go +++ b/database/service/count_test.go @@ -8,11 +8,13 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestService_Engine_CountServices(t *testing.T) { // setup types - _serviceOne := testService() + _serviceOne := testutils.APIService() _serviceOne.SetID(1) _serviceOne.SetRepoID(1) _serviceOne.SetBuildID(1) @@ -20,7 +22,7 @@ func TestService_Engine_CountServices(t *testing.T) { _serviceOne.SetName("foo") _serviceOne.SetImage("bar") - _serviceTwo := testService() + _serviceTwo := testutils.APIService() _serviceTwo.SetID(2) _serviceTwo.SetRepoID(1) _serviceTwo.SetBuildID(2) diff --git a/database/service/create_test.go b/database/service/create_test.go index b284bd4f8..6893daabc 100644 --- a/database/service/create_test.go +++ b/database/service/create_test.go @@ -8,11 +8,13 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestService_Engine_CreateService(t *testing.T) { // setup types - _service := testService() + _service := testutils.APIService() _service.SetID(1) _service.SetRepoID(1) _service.SetBuildID(1) diff --git a/database/service/delete_test.go b/database/service/delete_test.go index 3600242d9..5481e9258 100644 --- a/database/service/delete_test.go +++ b/database/service/delete_test.go @@ -7,11 +7,13 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestService_Engine_DeleteService(t *testing.T) { // setup types - _service := testService() + _service := testutils.APIService() _service.SetID(1) _service.SetRepoID(1) _service.SetBuildID(1) diff --git a/database/service/get_build.go b/database/service/get_build.go index cc4109762..26b5632c8 100644 --- a/database/service/get_build.go +++ b/database/service/get_build.go @@ -7,13 +7,14 @@ import ( "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" ) // GetServiceForBuild gets a service by number and build ID from the database. -func (e *engine) GetServiceForBuild(ctx context.Context, b *library.Build, number int) (*library.Service, error) { +func (e *engine) GetServiceForBuild(ctx context.Context, b *api.Build, number int) (*library.Service, error) { e.logger.WithFields(logrus.Fields{ "build": b.GetNumber(), "service": number, diff --git a/database/service/get_build_test.go b/database/service/get_build_test.go index af26ee7d0..da26e4ce9 100644 --- a/database/service/get_build_test.go +++ b/database/service/get_build_test.go @@ -9,17 +9,18 @@ import ( "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/types/library" ) func TestService_Engine_GetServiceForBuild(t *testing.T) { // setup types - _build := testBuild() + _build := testutils.APIBuild() _build.SetID(1) - _build.SetRepoID(1) + _build.SetRepo(testutils.APIRepo()) _build.SetNumber(1) - _service := testService() + _service := testutils.APIService() _service.SetID(1) _service.SetRepoID(1) _service.SetBuildID(1) diff --git a/database/service/get_test.go b/database/service/get_test.go index edeb82b9e..612811eed 100644 --- a/database/service/get_test.go +++ b/database/service/get_test.go @@ -9,12 +9,13 @@ import ( "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/types/library" ) func TestService_Engine_GetService(t *testing.T) { // setup types - _service := testService() + _service := testutils.APIService() _service.SetID(1) _service.SetRepoID(1) _service.SetBuildID(1) diff --git a/database/service/interface.go b/database/service/interface.go index 90982afa0..40fc30293 100644 --- a/database/service/interface.go +++ b/database/service/interface.go @@ -5,6 +5,7 @@ package service import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/library" ) @@ -29,7 +30,7 @@ type ServiceInterface interface { // CountServices defines a function that gets the count of all services. CountServices(context.Context) (int64, error) // CountServicesForBuild defines a function that gets the count of services by build ID. - CountServicesForBuild(context.Context, *library.Build, map[string]interface{}) (int64, error) + CountServicesForBuild(context.Context, *api.Build, map[string]interface{}) (int64, error) // CreateService defines a function that creates a new service. CreateService(context.Context, *library.Service) (*library.Service, error) // DeleteService defines a function that deletes an existing service. @@ -37,11 +38,11 @@ type ServiceInterface interface { // GetService defines a function that gets a service by ID. GetService(context.Context, int64) (*library.Service, error) // GetServiceForBuild defines a function that gets a service by number and build ID. - GetServiceForBuild(context.Context, *library.Build, int) (*library.Service, error) + GetServiceForBuild(context.Context, *api.Build, int) (*library.Service, error) // ListServices defines a function that gets a list of all services. ListServices(context.Context) ([]*library.Service, error) // ListServicesForBuild defines a function that gets a list of services by build ID. - ListServicesForBuild(context.Context, *library.Build, map[string]interface{}, int, int) ([]*library.Service, int64, error) + ListServicesForBuild(context.Context, *api.Build, map[string]interface{}, int, int) ([]*library.Service, int64, error) // ListServiceImageCount defines a function that gets a list of all service images and the count of their occurrence. ListServiceImageCount(context.Context) (map[string]float64, error) // ListServiceStatusCount defines a function that gets a list of all service statuses and the count of their occurrence. diff --git a/database/service/list_build.go b/database/service/list_build.go index 020f53fa0..98cb70294 100644 --- a/database/service/list_build.go +++ b/database/service/list_build.go @@ -7,13 +7,14 @@ import ( "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" ) // ListServicesForBuild gets a list of all services from the database. -func (e *engine) ListServicesForBuild(ctx context.Context, b *library.Build, filters map[string]interface{}, page int, perPage int) ([]*library.Service, int64, error) { +func (e *engine) ListServicesForBuild(ctx context.Context, b *api.Build, filters map[string]interface{}, page int, perPage int) ([]*library.Service, int64, error) { e.logger.WithFields(logrus.Fields{ "build": b.GetNumber(), }).Tracef("listing services for build %d from the database", b.GetNumber()) diff --git a/database/service/list_build_test.go b/database/service/list_build_test.go index 283f7fe5b..cd09061ee 100644 --- a/database/service/list_build_test.go +++ b/database/service/list_build_test.go @@ -9,17 +9,18 @@ import ( "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/types/library" ) func TestService_Engine_ListServicesForBuild(t *testing.T) { // setup types - _build := testBuild() + _build := testutils.APIBuild() _build.SetID(1) - _build.SetRepoID(1) + _build.SetRepo(testutils.APIRepo()) _build.SetNumber(1) - _serviceOne := testService() + _serviceOne := testutils.APIService() _serviceOne.SetID(1) _serviceOne.SetRepoID(1) _serviceOne.SetBuildID(1) @@ -27,7 +28,7 @@ func TestService_Engine_ListServicesForBuild(t *testing.T) { _serviceOne.SetName("foo") _serviceOne.SetImage("bar") - _serviceTwo := testService() + _serviceTwo := testutils.APIService() _serviceTwo.SetID(2) _serviceTwo.SetRepoID(1) _serviceTwo.SetBuildID(1) diff --git a/database/service/list_image_test.go b/database/service/list_image_test.go index fdf8a35fa..1bf4578b6 100644 --- a/database/service/list_image_test.go +++ b/database/service/list_image_test.go @@ -8,11 +8,13 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestService_Engine_ListServiceImageCount(t *testing.T) { // setup types - _serviceOne := testService() + _serviceOne := testutils.APIService() _serviceOne.SetID(1) _serviceOne.SetRepoID(1) _serviceOne.SetBuildID(1) @@ -20,7 +22,7 @@ func TestService_Engine_ListServiceImageCount(t *testing.T) { _serviceOne.SetName("foo") _serviceOne.SetImage("bar") - _serviceTwo := testService() + _serviceTwo := testutils.APIService() _serviceTwo.SetID(2) _serviceTwo.SetRepoID(1) _serviceTwo.SetBuildID(1) diff --git a/database/service/list_status_test.go b/database/service/list_status_test.go index 0b6e7ea1a..56b6f9203 100644 --- a/database/service/list_status_test.go +++ b/database/service/list_status_test.go @@ -8,11 +8,13 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestService_Engine_ListServiceStatusCount(t *testing.T) { // setup types - _serviceOne := testService() + _serviceOne := testutils.APIService() _serviceOne.SetID(1) _serviceOne.SetRepoID(1) _serviceOne.SetBuildID(1) @@ -20,7 +22,7 @@ func TestService_Engine_ListServiceStatusCount(t *testing.T) { _serviceOne.SetName("foo") _serviceOne.SetImage("bar") - _serviceTwo := testService() + _serviceTwo := testutils.APIService() _serviceTwo.SetID(2) _serviceTwo.SetRepoID(1) _serviceTwo.SetBuildID(1) diff --git a/database/service/list_test.go b/database/service/list_test.go index 6fcecdfd4..462dae56c 100644 --- a/database/service/list_test.go +++ b/database/service/list_test.go @@ -9,12 +9,13 @@ import ( "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/types/library" ) func TestService_Engine_ListServices(t *testing.T) { // setup types - _serviceOne := testService() + _serviceOne := testutils.APIService() _serviceOne.SetID(1) _serviceOne.SetRepoID(1) _serviceOne.SetBuildID(1) @@ -22,7 +23,7 @@ func TestService_Engine_ListServices(t *testing.T) { _serviceOne.SetName("foo") _serviceOne.SetImage("bar") - _serviceTwo := testService() + _serviceTwo := testutils.APIService() _serviceTwo.SetID(2) _serviceTwo.SetRepoID(1) _serviceTwo.SetBuildID(2) diff --git a/database/service/service_test.go b/database/service/service_test.go index 73a113568..9dcec640b 100644 --- a/database/service/service_test.go +++ b/database/service/service_test.go @@ -13,8 +13,6 @@ import ( "gorm.io/driver/postgres" "gorm.io/driver/sqlite" "gorm.io/gorm" - - "github.com/go-vela/types/library" ) func TestService_New(t *testing.T) { @@ -164,65 +162,6 @@ func testSqlite(t *testing.T) *engine { return _engine } -// testBuild is a test helper function to create a library -// Build type with all fields set to their zero values. -func testBuild() *library.Build { - return &library.Build{ - ID: new(int64), - RepoID: new(int64), - PipelineID: new(int64), - Number: new(int), - Parent: new(int), - Event: new(string), - EventAction: new(string), - Status: new(string), - Error: new(string), - Enqueued: new(int64), - Created: new(int64), - Started: new(int64), - Finished: new(int64), - Deploy: new(string), - Clone: new(string), - Source: new(string), - Title: new(string), - Message: new(string), - Commit: new(string), - Sender: new(string), - Author: new(string), - Email: new(string), - Link: new(string), - Branch: new(string), - Ref: new(string), - BaseRef: new(string), - HeadRef: new(string), - Host: new(string), - Runtime: new(string), - Distribution: new(string), - } -} - -// testService is a test helper function to create a library -// Service type with all fields set to their zero values. -func testService() *library.Service { - return &library.Service{ - ID: new(int64), - BuildID: new(int64), - RepoID: new(int64), - Number: new(int), - Name: new(string), - Image: new(string), - Status: new(string), - Error: new(string), - ExitCode: new(int), - Created: new(int64), - Started: new(int64), - Finished: new(int64), - Host: new(string), - Runtime: new(string), - Distribution: new(string), - } -} - // This will be used with the github.com/DATA-DOG/go-sqlmock library to compare values // that are otherwise not easily compared. These typically would be values generated // before adding or updating them in the database. diff --git a/database/service/update_test.go b/database/service/update_test.go index 6e8001deb..82dccac9c 100644 --- a/database/service/update_test.go +++ b/database/service/update_test.go @@ -8,11 +8,13 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestService_Engine_UpdateService(t *testing.T) { // setup types - _service := testService() + _service := testutils.APIService() _service.SetID(1) _service.SetRepoID(1) _service.SetBuildID(1) diff --git a/database/step/clean_test.go b/database/step/clean_test.go index a7cadded5..132d3a00d 100644 --- a/database/step/clean_test.go +++ b/database/step/clean_test.go @@ -8,11 +8,13 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestStep_Engine_CleanStep(t *testing.T) { // setup types - _stepOne := testStep() + _stepOne := testutils.APIStep() _stepOne.SetID(1) _stepOne.SetRepoID(1) _stepOne.SetBuildID(1) @@ -22,7 +24,7 @@ func TestStep_Engine_CleanStep(t *testing.T) { _stepOne.SetCreated(1) _stepOne.SetStatus("running") - _stepTwo := testStep() + _stepTwo := testutils.APIStep() _stepTwo.SetID(2) _stepTwo.SetRepoID(1) _stepTwo.SetBuildID(1) @@ -32,7 +34,7 @@ func TestStep_Engine_CleanStep(t *testing.T) { _stepTwo.SetCreated(1) _stepTwo.SetStatus("pending") - _stepThree := testStep() + _stepThree := testutils.APIStep() _stepThree.SetID(3) _stepThree.SetRepoID(1) _stepThree.SetBuildID(1) @@ -42,7 +44,7 @@ func TestStep_Engine_CleanStep(t *testing.T) { _stepThree.SetCreated(1) _stepThree.SetStatus("success") - _stepFour := testStep() + _stepFour := testutils.APIStep() _stepFour.SetID(4) _stepFour.SetRepoID(1) _stepFour.SetBuildID(1) diff --git a/database/step/count_build.go b/database/step/count_build.go index 595811112..35109fa06 100644 --- a/database/step/count_build.go +++ b/database/step/count_build.go @@ -7,12 +7,12 @@ import ( "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" ) // CountStepsForBuild gets the count of steps by build ID from the database. -func (e *engine) CountStepsForBuild(ctx context.Context, b *library.Build, filters map[string]interface{}) (int64, error) { +func (e *engine) CountStepsForBuild(ctx context.Context, b *api.Build, filters map[string]interface{}) (int64, error) { e.logger.WithFields(logrus.Fields{ "build": b.GetNumber(), }).Tracef("getting count of steps for build %d from the database", b.GetNumber()) diff --git a/database/step/count_build_test.go b/database/step/count_build_test.go index e17b666f3..dad4c0a59 100644 --- a/database/step/count_build_test.go +++ b/database/step/count_build_test.go @@ -8,16 +8,18 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestStep_Engine_CountStepsForBuild(t *testing.T) { // setup types - _build := testBuild() + _build := testutils.APIBuild() _build.SetID(1) - _build.SetRepoID(1) + _build.SetRepo(testutils.APIRepo()) _build.SetNumber(1) - _stepOne := testStep() + _stepOne := testutils.APIStep() _stepOne.SetID(1) _stepOne.SetRepoID(1) _stepOne.SetBuildID(1) @@ -25,7 +27,7 @@ func TestStep_Engine_CountStepsForBuild(t *testing.T) { _stepOne.SetName("foo") _stepOne.SetImage("bar") - _stepTwo := testStep() + _stepTwo := testutils.APIStep() _stepTwo.SetID(2) _stepTwo.SetRepoID(1) _stepTwo.SetBuildID(2) diff --git a/database/step/count_test.go b/database/step/count_test.go index 621f0a7cd..bdc358a21 100644 --- a/database/step/count_test.go +++ b/database/step/count_test.go @@ -8,11 +8,13 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestStep_Engine_CountSteps(t *testing.T) { // setup types - _stepOne := testStep() + _stepOne := testutils.APIStep() _stepOne.SetID(1) _stepOne.SetRepoID(1) _stepOne.SetBuildID(1) @@ -20,7 +22,7 @@ func TestStep_Engine_CountSteps(t *testing.T) { _stepOne.SetName("foo") _stepOne.SetImage("bar") - _stepTwo := testStep() + _stepTwo := testutils.APIStep() _stepTwo.SetID(2) _stepTwo.SetRepoID(1) _stepTwo.SetBuildID(2) diff --git a/database/step/create_test.go b/database/step/create_test.go index 987ffb5b1..07824dc5a 100644 --- a/database/step/create_test.go +++ b/database/step/create_test.go @@ -8,11 +8,13 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestStep_Engine_CreateStep(t *testing.T) { // setup types - _step := testStep() + _step := testutils.APIStep() _step.SetID(1) _step.SetRepoID(1) _step.SetBuildID(1) diff --git a/database/step/delete_test.go b/database/step/delete_test.go index 476ee969f..25eae5a69 100644 --- a/database/step/delete_test.go +++ b/database/step/delete_test.go @@ -7,11 +7,13 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestStep_Engine_DeleteStep(t *testing.T) { // setup types - _step := testStep() + _step := testutils.APIStep() _step.SetID(1) _step.SetRepoID(1) _step.SetBuildID(1) diff --git a/database/step/get_build.go b/database/step/get_build.go index 99ed00026..9fd8a937e 100644 --- a/database/step/get_build.go +++ b/database/step/get_build.go @@ -7,13 +7,14 @@ import ( "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" ) // GetStepForBuild gets a step by number and build ID from the database. -func (e *engine) GetStepForBuild(ctx context.Context, b *library.Build, number int) (*library.Step, error) { +func (e *engine) GetStepForBuild(ctx context.Context, b *api.Build, number int) (*library.Step, error) { e.logger.WithFields(logrus.Fields{ "build": b.GetNumber(), "step": number, diff --git a/database/step/get_build_test.go b/database/step/get_build_test.go index 1906dc3f1..c5490aa58 100644 --- a/database/step/get_build_test.go +++ b/database/step/get_build_test.go @@ -9,17 +9,18 @@ import ( "github.com/DATA-DOG/go-sqlmock" "github.com/google/go-cmp/cmp" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/types/library" ) func TestStep_Engine_GetStepForBuild(t *testing.T) { // setup types - _build := testBuild() + _build := testutils.APIBuild() _build.SetID(1) - _build.SetRepoID(1) + _build.SetRepo(testutils.APIRepo()) _build.SetNumber(1) - _step := testStep() + _step := testutils.APIStep() _step.SetID(1) _step.SetRepoID(1) _step.SetBuildID(1) diff --git a/database/step/get_test.go b/database/step/get_test.go index a9e5106a1..4c05103ea 100644 --- a/database/step/get_test.go +++ b/database/step/get_test.go @@ -9,18 +9,20 @@ import ( "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/types/library" ) func TestStep_Engine_GetStep(t *testing.T) { // setup types - _step := testStep() + _step := testutils.APIStep() _step.SetID(1) _step.SetRepoID(1) _step.SetBuildID(1) _step.SetNumber(1) _step.SetName("foo") _step.SetImage("bar") + ctx := context.TODO() _postgres, _mock := testPostgres(t) diff --git a/database/step/interface.go b/database/step/interface.go index 3c41017a9..6de0cc168 100644 --- a/database/step/interface.go +++ b/database/step/interface.go @@ -5,6 +5,7 @@ package step import ( "context" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/library" ) @@ -29,7 +30,7 @@ type StepInterface interface { // CountSteps defines a function that gets the count of all steps. CountSteps(context.Context) (int64, error) // CountStepsForBuild defines a function that gets the count of steps by build ID. - CountStepsForBuild(context.Context, *library.Build, map[string]interface{}) (int64, error) + CountStepsForBuild(context.Context, *api.Build, map[string]interface{}) (int64, error) // CreateStep defines a function that creates a new step. CreateStep(context.Context, *library.Step) (*library.Step, error) // DeleteStep defines a function that deletes an existing step. @@ -37,11 +38,11 @@ type StepInterface interface { // GetStep defines a function that gets a step by ID. GetStep(context.Context, int64) (*library.Step, error) // GetStepForBuild defines a function that gets a step by number and build ID. - GetStepForBuild(context.Context, *library.Build, int) (*library.Step, error) + GetStepForBuild(context.Context, *api.Build, int) (*library.Step, error) // ListSteps defines a function that gets a list of all steps. ListSteps(ctx context.Context) ([]*library.Step, error) // ListStepsForBuild defines a function that gets a list of steps by build ID. - ListStepsForBuild(context.Context, *library.Build, map[string]interface{}, int, int) ([]*library.Step, int64, error) + ListStepsForBuild(context.Context, *api.Build, map[string]interface{}, int, int) ([]*library.Step, int64, error) // ListStepImageCount defines a function that gets a list of all step images and the count of their occurrence. ListStepImageCount(context.Context) (map[string]float64, error) // ListStepStatusCount defines a function that gets a list of all step statuses and the count of their occurrence. diff --git a/database/step/list_build.go b/database/step/list_build.go index dbf8a717a..fce2619e8 100644 --- a/database/step/list_build.go +++ b/database/step/list_build.go @@ -7,13 +7,14 @@ import ( "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/database" "github.com/go-vela/types/library" ) // ListStepsForBuild gets a list of all steps from the database. -func (e *engine) ListStepsForBuild(ctx context.Context, b *library.Build, filters map[string]interface{}, page int, perPage int) ([]*library.Step, int64, error) { +func (e *engine) ListStepsForBuild(ctx context.Context, b *api.Build, filters map[string]interface{}, page int, perPage int) ([]*library.Step, int64, error) { e.logger.WithFields(logrus.Fields{ "build": b.GetNumber(), }).Tracef("listing steps for build %d from the database", b.GetNumber()) diff --git a/database/step/list_build_test.go b/database/step/list_build_test.go index 46fda88a4..327076fec 100644 --- a/database/step/list_build_test.go +++ b/database/step/list_build_test.go @@ -9,17 +9,18 @@ import ( "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/types/library" ) func TestStep_Engine_ListStepsForBuild(t *testing.T) { // setup types - _build := testBuild() + _build := testutils.APIBuild() _build.SetID(1) - _build.SetRepoID(1) + _build.SetRepo(testutils.APIRepo()) _build.SetNumber(1) - _stepOne := testStep() + _stepOne := testutils.APIStep() _stepOne.SetID(1) _stepOne.SetRepoID(1) _stepOne.SetBuildID(1) @@ -27,7 +28,7 @@ func TestStep_Engine_ListStepsForBuild(t *testing.T) { _stepOne.SetName("foo") _stepOne.SetImage("bar") - _stepTwo := testStep() + _stepTwo := testutils.APIStep() _stepTwo.SetID(2) _stepTwo.SetRepoID(1) _stepTwo.SetBuildID(1) diff --git a/database/step/list_image_test.go b/database/step/list_image_test.go index ea0b78585..0447f9fc4 100644 --- a/database/step/list_image_test.go +++ b/database/step/list_image_test.go @@ -8,11 +8,13 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestStep_Engine_ListStepImageCount(t *testing.T) { // setup types - _stepOne := testStep() + _stepOne := testutils.APIStep() _stepOne.SetID(1) _stepOne.SetRepoID(1) _stepOne.SetBuildID(1) @@ -20,7 +22,7 @@ func TestStep_Engine_ListStepImageCount(t *testing.T) { _stepOne.SetName("foo") _stepOne.SetImage("bar") - _stepTwo := testStep() + _stepTwo := testutils.APIStep() _stepTwo.SetID(2) _stepTwo.SetRepoID(1) _stepTwo.SetBuildID(1) diff --git a/database/step/list_status_test.go b/database/step/list_status_test.go index 22f9d51c1..e6fa36ab4 100644 --- a/database/step/list_status_test.go +++ b/database/step/list_status_test.go @@ -8,11 +8,13 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestStep_Engine_ListStepStatusCount(t *testing.T) { // setup types - _stepOne := testStep() + _stepOne := testutils.APIStep() _stepOne.SetID(1) _stepOne.SetRepoID(1) _stepOne.SetBuildID(1) @@ -20,7 +22,7 @@ func TestStep_Engine_ListStepStatusCount(t *testing.T) { _stepOne.SetName("foo") _stepOne.SetImage("bar") - _stepTwo := testStep() + _stepTwo := testutils.APIStep() _stepTwo.SetID(2) _stepTwo.SetRepoID(1) _stepTwo.SetBuildID(1) diff --git a/database/step/list_test.go b/database/step/list_test.go index bed53585c..921a3f2f7 100644 --- a/database/step/list_test.go +++ b/database/step/list_test.go @@ -9,12 +9,13 @@ import ( "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/types/library" ) func TestStep_Engine_ListSteps(t *testing.T) { // setup types - _stepOne := testStep() + _stepOne := testutils.APIStep() _stepOne.SetID(1) _stepOne.SetRepoID(1) _stepOne.SetBuildID(1) @@ -22,7 +23,7 @@ func TestStep_Engine_ListSteps(t *testing.T) { _stepOne.SetName("foo") _stepOne.SetImage("bar") - _stepTwo := testStep() + _stepTwo := testutils.APIStep() _stepTwo.SetID(2) _stepTwo.SetRepoID(1) _stepTwo.SetBuildID(2) diff --git a/database/step/step_test.go b/database/step/step_test.go index 861937831..6643e5139 100644 --- a/database/step/step_test.go +++ b/database/step/step_test.go @@ -13,8 +13,6 @@ import ( "gorm.io/driver/postgres" "gorm.io/driver/sqlite" "gorm.io/gorm" - - "github.com/go-vela/types/library" ) func TestStep_New(t *testing.T) { @@ -164,67 +162,6 @@ func testSqlite(t *testing.T) *engine { return _engine } -// testBuild is a test helper function to create a library -// Build type with all fields set to their zero values. -func testBuild() *library.Build { - return &library.Build{ - ID: new(int64), - RepoID: new(int64), - PipelineID: new(int64), - Number: new(int), - Parent: new(int), - Event: new(string), - EventAction: new(string), - Status: new(string), - Error: new(string), - Enqueued: new(int64), - Created: new(int64), - Started: new(int64), - Finished: new(int64), - Deploy: new(string), - Clone: new(string), - Source: new(string), - Title: new(string), - Message: new(string), - Commit: new(string), - Sender: new(string), - Author: new(string), - Email: new(string), - Link: new(string), - Branch: new(string), - Ref: new(string), - BaseRef: new(string), - HeadRef: new(string), - Host: new(string), - Runtime: new(string), - Distribution: new(string), - } -} - -// testStep is a test helper function to create a library -// Step type with all fields set to their zero values. -func testStep() *library.Step { - return &library.Step{ - ID: new(int64), - BuildID: new(int64), - RepoID: new(int64), - Number: new(int), - Name: new(string), - Image: new(string), - Stage: new(string), - Status: new(string), - Error: new(string), - ExitCode: new(int), - Created: new(int64), - Started: new(int64), - Finished: new(int64), - Host: new(string), - Runtime: new(string), - Distribution: new(string), - ReportAs: new(string), - } -} - // This will be used with the github.com/DATA-DOG/go-sqlmock library to compare values // that are otherwise not easily compared. These typically would be values generated // before adding or updating them in the database. diff --git a/database/step/update_test.go b/database/step/update_test.go index d1b14dd2b..06a589307 100644 --- a/database/step/update_test.go +++ b/database/step/update_test.go @@ -8,11 +8,13 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestStep_Engine_UpdateStep(t *testing.T) { // setup types - _step := testStep() + _step := testutils.APIStep() _step.SetID(1) _step.SetRepoID(1) _step.SetBuildID(1) diff --git a/database/testutils/api_resources.go b/database/testutils/api_resources.go new file mode 100644 index 000000000..78aec3aa6 --- /dev/null +++ b/database/testutils/api_resources.go @@ -0,0 +1,253 @@ +// SPDX-License-Identifier: Apache-2.0 + +package testutils + +import ( + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/api/types/actions" + "github.com/go-vela/types/library" + "github.com/go-vela/types/raw" +) + +// API TEST RESOURCES +// +// These are API resources initialized to their zero values for testing. + +func APIBuild() *api.Build { + return &api.Build{ + ID: new(int64), + Repo: APIRepo(), + PipelineID: new(int64), + Number: new(int), + Parent: new(int), + Event: new(string), + EventAction: new(string), + Status: new(string), + Error: new(string), + Enqueued: new(int64), + Created: new(int64), + Started: new(int64), + Finished: new(int64), + Deploy: new(string), + DeployNumber: new(int64), + Clone: new(string), + Source: new(string), + Title: new(string), + Message: new(string), + Commit: new(string), + Sender: new(string), + Author: new(string), + Email: new(string), + Link: new(string), + Branch: new(string), + Ref: new(string), + BaseRef: new(string), + HeadRef: new(string), + Host: new(string), + Runtime: new(string), + Distribution: new(string), + ApprovedAt: new(int64), + ApprovedBy: new(string), + } +} + +func APIDeployment() *library.Deployment { + builds := []*library.Build{} + + return &library.Deployment{ + ID: new(int64), + RepoID: new(int64), + Number: new(int64), + URL: new(string), + Commit: new(string), + Ref: new(string), + Task: new(string), + Target: new(string), + Description: new(string), + Payload: new(raw.StringSliceMap), + CreatedAt: new(int64), + CreatedBy: new(string), + Builds: builds, + } +} + +func APIEvents() *api.Events { + return &api.Events{ + Push: &actions.Push{ + Branch: new(bool), + Tag: new(bool), + DeleteBranch: new(bool), + DeleteTag: new(bool), + }, + PullRequest: &actions.Pull{ + Opened: new(bool), + Edited: new(bool), + Synchronize: new(bool), + Reopened: new(bool), + Labeled: new(bool), + Unlabeled: new(bool), + }, + Deployment: &actions.Deploy{ + Created: new(bool), + }, + Comment: &actions.Comment{ + Created: new(bool), + Edited: new(bool), + }, + Schedule: &actions.Schedule{ + Run: new(bool), + }, + } +} + +func APIRepo() *api.Repo { + return &api.Repo{ + ID: new(int64), + Owner: APIUser(), + BuildLimit: new(int64), + Timeout: new(int64), + Counter: new(int), + PipelineType: new(string), + Hash: new(string), + Org: new(string), + Name: new(string), + FullName: new(string), + Link: new(string), + Clone: new(string), + Branch: new(string), + Visibility: new(string), + PreviousName: new(string), + Private: new(bool), + Trusted: new(bool), + Active: new(bool), + AllowEvents: APIEvents(), + Topics: new([]string), + ApproveBuild: new(string), + } +} + +func APIUser() *api.User { + return &api.User{ + ID: new(int64), + Name: new(string), + RefreshToken: new(string), + Token: new(string), + Favorites: new([]string), + Dashboards: new([]string), + Active: new(bool), + Admin: new(bool), + } +} + +func APIHook() *library.Hook { + return &library.Hook{ + ID: new(int64), + RepoID: new(int64), + BuildID: new(int64), + Number: new(int), + SourceID: new(string), + Created: new(int64), + Host: new(string), + Event: new(string), + EventAction: new(string), + Branch: new(string), + Error: new(string), + Status: new(string), + Link: new(string), + WebhookID: new(int64), + } +} + +func APILog() *library.Log { + return &library.Log{ + ID: new(int64), + RepoID: new(int64), + BuildID: new(int64), + ServiceID: new(int64), + StepID: new(int64), + Data: new([]byte), + } +} + +func APIService() *library.Service { + return &library.Service{ + ID: new(int64), + BuildID: new(int64), + RepoID: new(int64), + Number: new(int), + Name: new(string), + Image: new(string), + Status: new(string), + Error: new(string), + ExitCode: new(int), + Created: new(int64), + Started: new(int64), + Finished: new(int64), + Host: new(string), + Runtime: new(string), + Distribution: new(string), + } +} + +func APIStep() *library.Step { + return &library.Step{ + ID: new(int64), + BuildID: new(int64), + RepoID: new(int64), + Number: new(int), + Name: new(string), + Image: new(string), + Stage: new(string), + Status: new(string), + Error: new(string), + ExitCode: new(int), + Created: new(int64), + Started: new(int64), + Finished: new(int64), + Host: new(string), + Runtime: new(string), + Distribution: new(string), + ReportAs: new(string), + } +} + +func APIPipeline() *library.Pipeline { + return &library.Pipeline{ + ID: new(int64), + RepoID: new(int64), + Commit: new(string), + Flavor: new(string), + Platform: new(string), + Ref: new(string), + Type: new(string), + Version: new(string), + ExternalSecrets: new(bool), + InternalSecrets: new(bool), + Services: new(bool), + Stages: new(bool), + Steps: new(bool), + Templates: new(bool), + Data: new([]byte), + } +} + +func APIDashboard() *api.Dashboard { + return &api.Dashboard{ + ID: new(string), + Name: new(string), + CreatedAt: new(int64), + CreatedBy: new(string), + UpdatedAt: new(int64), + UpdatedBy: new(string), + Admins: &[]*api.User{APIUser()}, + Repos: &[]*api.DashboardRepo{APIDashboardRepo()}, + } +} + +func APIDashboardRepo() *api.DashboardRepo { + return &api.DashboardRepo{ + ID: new(int64), + Branches: new([]string), + Events: new([]string), + } +} diff --git a/database/types/build.go b/database/types/build.go new file mode 100644 index 000000000..4023836e6 --- /dev/null +++ b/database/types/build.go @@ -0,0 +1,401 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "database/sql" + "errors" + + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/util" + "github.com/go-vela/types/raw" +) + +var ( + // ErrEmptyBuildNumber defines the error type when a + // Build type has an empty Number field provided. + ErrEmptyBuildNumber = errors.New("empty build number provided") + + // ErrEmptyBuildRepoID defines the error type when a + // Build type has an empty `RepoID` field provided. + ErrEmptyBuildRepoID = errors.New("empty build repo_id provided") +) + +const ( + // Maximum title field length. + maxTitleLength = 1000 + // Maximum message field length. + maxMessageLength = 2000 + // Maximum error field length. + maxErrorLength = 1000 +) + +// Build is the database representation of a build for a pipeline. +type Build struct { + ID sql.NullInt64 `sql:"id"` + RepoID sql.NullInt64 `sql:"repo_id"` + PipelineID sql.NullInt64 `sql:"pipeline_id"` + Number sql.NullInt32 `sql:"number"` + Parent sql.NullInt32 `sql:"parent"` + Event sql.NullString `sql:"event"` + EventAction sql.NullString `sql:"event_action"` + Status sql.NullString `sql:"status"` + Error sql.NullString `sql:"error"` + Enqueued sql.NullInt64 `sql:"enqueued"` + Created sql.NullInt64 `sql:"created"` + 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"` + Title sql.NullString `sql:"title"` + Message sql.NullString `sql:"message"` + Commit sql.NullString `sql:"commit"` + Sender sql.NullString `sql:"sender"` + Author sql.NullString `sql:"author"` + Email sql.NullString `sql:"email"` + Link sql.NullString `sql:"link"` + Branch sql.NullString `sql:"branch"` + Ref sql.NullString `sql:"ref"` + BaseRef sql.NullString `sql:"base_ref"` + HeadRef sql.NullString `sql:"head_ref"` + Host sql.NullString `sql:"host"` + Runtime sql.NullString `sql:"runtime"` + Distribution sql.NullString `sql:"distribution"` + ApprovedAt sql.NullInt64 `sql:"approved_at"` + ApprovedBy sql.NullString `sql:"approved_by"` + + Repo Repo `gorm:"foreignKey:RepoID"` +} + +// Crop prepares the Build type for inserting into the database by +// trimming values that may exceed the database column limit. +func (b *Build) Crop() *Build { + // trim the Title field to 1000 characters + if len(b.Title.String) > maxTitleLength { + b.Title = sql.NullString{String: b.Title.String[:maxTitleLength], Valid: true} + } + + // trim the Message field to 2000 characters + if len(b.Message.String) > maxMessageLength { + b.Message = sql.NullString{String: b.Message.String[:maxMessageLength], Valid: true} + } + + // trim the Error field to 1000 characters + if len(b.Error.String) > maxErrorLength { + b.Error = sql.NullString{String: b.Error.String[:maxErrorLength], Valid: true} + } + + return b +} + +// Nullify ensures the valid flag for +// the sql.Null types are properly set. +// +// When a field within the Build type is the zero +// value for the field, the valid flag is set to +// false causing it to be NULL in the database. +// +//nolint:gocyclo,funlen // ignore cyclomatic complexity due to number of fields +func (b *Build) Nullify() *Build { + if b == nil { + return nil + } + + // check if the ID field should be false + if b.ID.Int64 == 0 { + b.ID.Valid = false + } + + // check if the RepoID field should be false + if b.RepoID.Int64 == 0 { + b.RepoID.Valid = false + } + + // check if the PipelineID field should be false + if b.PipelineID.Int64 == 0 { + b.PipelineID.Valid = false + } + + // check if the Number field should be false + if b.Number.Int32 == 0 { + b.Number.Valid = false + } + + // check if the Parent field should be false + if b.Parent.Int32 == 0 { + b.Parent.Valid = false + } + + // check if the Event field should be false + if len(b.Event.String) == 0 { + b.Event.Valid = false + } + + // check if the EventAction field should be false + if len(b.EventAction.String) == 0 { + b.EventAction.Valid = false + } + + // check if the Status field should be false + if len(b.Status.String) == 0 { + b.Status.Valid = false + } + + // check if the Error field should be false + if len(b.Error.String) == 0 { + b.Error.Valid = false + } + + // check if the Enqueued field should be false + if b.Enqueued.Int64 == 0 { + b.Enqueued.Valid = false + } + + // check if the Created field should be false + if b.Created.Int64 == 0 { + b.Created.Valid = false + } + + // check if the Started field should be false + if b.Started.Int64 == 0 { + b.Started.Valid = false + } + + // check if the Finished field should be false + if b.Finished.Int64 == 0 { + b.Finished.Valid = false + } + + // check if the Deploy field should be false + if len(b.Deploy.String) == 0 { + b.Deploy.Valid = false + } + + // check if the DeployNumber field should be false + if b.DeployNumber.Int64 == 0 { + b.DeployNumber.Valid = false + } + + // check if the Clone field should be false + if len(b.Clone.String) == 0 { + b.Clone.Valid = false + } + + // check if the Source field should be false + if len(b.Source.String) == 0 { + b.Source.Valid = false + } + + // check if the Title field should be false + if len(b.Title.String) == 0 { + b.Title.Valid = false + } + + // check if the Message field should be false + if len(b.Message.String) == 0 { + b.Message.Valid = false + } + + // check if the Commit field should be false + if len(b.Commit.String) == 0 { + b.Commit.Valid = false + } + + // check if the Sender field should be false + if len(b.Sender.String) == 0 { + b.Sender.Valid = false + } + + // check if the Author field should be false + if len(b.Author.String) == 0 { + b.Author.Valid = false + } + + // check if the Email field should be false + if len(b.Email.String) == 0 { + b.Email.Valid = false + } + + // check if the Link field should be false + if len(b.Link.String) == 0 { + b.Link.Valid = false + } + + // check if the Branch field should be false + if len(b.Branch.String) == 0 { + b.Branch.Valid = false + } + + // check if the Ref field should be false + if len(b.Ref.String) == 0 { + b.Ref.Valid = false + } + + // check if the BaseRef field should be false + if len(b.BaseRef.String) == 0 { + b.BaseRef.Valid = false + } + + // check if the HeadRef field should be false + if len(b.HeadRef.String) == 0 { + b.HeadRef.Valid = false + } + + // check if the Host field should be false + if len(b.Host.String) == 0 { + b.Host.Valid = false + } + + // check if the Runtime field should be false + if len(b.Runtime.String) == 0 { + b.Runtime.Valid = false + } + + // check if the Distribution field should be false + if len(b.Distribution.String) == 0 { + b.Distribution.Valid = false + } + + // check if the ApprovedAt field should be false + if b.ApprovedAt.Int64 == 0 { + b.ApprovedAt.Valid = false + } + + // check if the ApprovedBy field should be false + if len(b.ApprovedBy.String) == 0 { + b.ApprovedBy.Valid = false + } + + return b +} + +// ToAPI converts the Build type +// to an API Build type. +func (b *Build) ToAPI() *api.Build { + build := new(api.Build) + + build.SetID(b.ID.Int64) + build.SetRepo(b.Repo.ToAPI()) + build.SetPipelineID(b.PipelineID.Int64) + build.SetNumber(int(b.Number.Int32)) + build.SetParent(int(b.Parent.Int32)) + build.SetEvent(b.Event.String) + build.SetEventAction(b.EventAction.String) + build.SetStatus(b.Status.String) + build.SetError(b.Error.String) + build.SetEnqueued(b.Enqueued.Int64) + build.SetCreated(b.Created.Int64) + 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) + build.SetTitle(b.Title.String) + build.SetMessage(b.Message.String) + build.SetCommit(b.Commit.String) + build.SetSender(b.Sender.String) + build.SetAuthor(b.Author.String) + build.SetEmail(b.Email.String) + build.SetLink(b.Link.String) + build.SetBranch(b.Branch.String) + build.SetRef(b.Ref.String) + build.SetBaseRef(b.BaseRef.String) + build.SetHeadRef(b.HeadRef.String) + build.SetHost(b.Host.String) + build.SetRuntime(b.Runtime.String) + build.SetDistribution(b.Distribution.String) + build.SetApprovedAt(b.ApprovedAt.Int64) + build.SetApprovedBy(b.ApprovedBy.String) + + return build +} + +// Validate verifies the necessary fields for +// the Build type are populated correctly. +func (b *Build) Validate() error { + // verify the RepoID field is populated + if b.RepoID.Int64 <= 0 { + return ErrEmptyBuildRepoID + } + + // verify the Number field is populated + if b.Number.Int32 <= 0 { + return ErrEmptyBuildNumber + } + + // ensure that all Build string fields + // that can be returned as JSON are sanitized + // to avoid unsafe HTML content + b.Event = sql.NullString{String: util.Sanitize(b.Event.String), Valid: b.Event.Valid} + b.EventAction = sql.NullString{String: util.Sanitize(b.EventAction.String), Valid: b.EventAction.Valid} + b.Status = sql.NullString{String: util.Sanitize(b.Status.String), Valid: b.Status.Valid} + b.Error = sql.NullString{String: util.Sanitize(b.Error.String), Valid: b.Error.Valid} + b.Deploy = sql.NullString{String: util.Sanitize(b.Deploy.String), Valid: b.Deploy.Valid} + b.Clone = sql.NullString{String: util.Sanitize(b.Clone.String), Valid: b.Clone.Valid} + b.Source = sql.NullString{String: util.Sanitize(b.Source.String), Valid: b.Source.Valid} + b.Title = sql.NullString{String: util.Sanitize(b.Title.String), Valid: b.Title.Valid} + b.Message = sql.NullString{String: util.Sanitize(b.Message.String), Valid: b.Message.Valid} + b.Commit = sql.NullString{String: util.Sanitize(b.Commit.String), Valid: b.Commit.Valid} + b.Sender = sql.NullString{String: util.Sanitize(b.Sender.String), Valid: b.Sender.Valid} + b.Author = sql.NullString{String: util.Sanitize(b.Author.String), Valid: b.Author.Valid} + b.Email = sql.NullString{String: util.Sanitize(b.Email.String), Valid: b.Email.Valid} + b.Link = sql.NullString{String: util.Sanitize(b.Link.String), Valid: b.Link.Valid} + b.Branch = sql.NullString{String: util.Sanitize(b.Branch.String), Valid: b.Branch.Valid} + b.Ref = sql.NullString{String: util.Sanitize(b.Ref.String), Valid: b.Ref.Valid} + b.BaseRef = sql.NullString{String: util.Sanitize(b.BaseRef.String), Valid: b.BaseRef.Valid} + b.HeadRef = sql.NullString{String: util.Sanitize(b.HeadRef.String), Valid: b.HeadRef.Valid} + b.Host = sql.NullString{String: util.Sanitize(b.Host.String), Valid: b.Host.Valid} + b.Runtime = sql.NullString{String: util.Sanitize(b.Runtime.String), Valid: b.Runtime.Valid} + b.Distribution = sql.NullString{String: util.Sanitize(b.Distribution.String), Valid: b.Distribution.Valid} + b.ApprovedBy = sql.NullString{String: util.Sanitize(b.ApprovedBy.String), Valid: b.ApprovedBy.Valid} + + return nil +} + +// BuildFromAPI converts the API Build type +// to a database build type. +func BuildFromAPI(b *api.Build) *Build { + build := &Build{ + ID: sql.NullInt64{Int64: b.GetID(), Valid: true}, + RepoID: sql.NullInt64{Int64: b.GetRepo().GetID(), Valid: true}, + PipelineID: sql.NullInt64{Int64: b.GetPipelineID(), Valid: true}, + Number: sql.NullInt32{Int32: int32(b.GetNumber()), Valid: true}, + Parent: sql.NullInt32{Int32: int32(b.GetParent()), Valid: true}, + Event: sql.NullString{String: b.GetEvent(), Valid: true}, + EventAction: sql.NullString{String: b.GetEventAction(), Valid: true}, + Status: sql.NullString{String: b.GetStatus(), Valid: true}, + Error: sql.NullString{String: b.GetError(), Valid: true}, + Enqueued: sql.NullInt64{Int64: b.GetEnqueued(), Valid: true}, + Created: sql.NullInt64{Int64: b.GetCreated(), Valid: true}, + 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}, + Title: sql.NullString{String: b.GetTitle(), Valid: true}, + Message: sql.NullString{String: b.GetMessage(), Valid: true}, + Commit: sql.NullString{String: b.GetCommit(), Valid: true}, + Sender: sql.NullString{String: b.GetSender(), Valid: true}, + Author: sql.NullString{String: b.GetAuthor(), Valid: true}, + Email: sql.NullString{String: b.GetEmail(), Valid: true}, + Link: sql.NullString{String: b.GetLink(), Valid: true}, + Branch: sql.NullString{String: b.GetBranch(), Valid: true}, + Ref: sql.NullString{String: b.GetRef(), Valid: true}, + BaseRef: sql.NullString{String: b.GetBaseRef(), Valid: true}, + HeadRef: sql.NullString{String: b.GetHeadRef(), Valid: true}, + Host: sql.NullString{String: b.GetHost(), Valid: true}, + Runtime: sql.NullString{String: b.GetRuntime(), Valid: true}, + Distribution: sql.NullString{String: b.GetDistribution(), Valid: true}, + ApprovedAt: sql.NullInt64{Int64: b.GetApprovedAt(), Valid: true}, + ApprovedBy: sql.NullString{String: b.GetApprovedBy(), Valid: true}, + } + + return build.Nullify() +} diff --git a/database/types/build_test.go b/database/types/build_test.go new file mode 100644 index 000000000..04a88d923 --- /dev/null +++ b/database/types/build_test.go @@ -0,0 +1,309 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "database/sql" + "math/rand" + "reflect" + "testing" + + "github.com/google/go-cmp/cmp" + + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" + "github.com/go-vela/types/raw" +) + +func TestTypes_Build_Crop(t *testing.T) { + // setup types + title := randomString(1001) + message := randomString(2001) + err := randomString(1001) + + b := testBuild() + b.Title = sql.NullString{String: title, Valid: true} + b.Message = sql.NullString{String: message, Valid: true} + b.Error = sql.NullString{String: err, Valid: true} + + want := testBuild() + want.Title = sql.NullString{String: title[:1000], Valid: true} + want.Message = sql.NullString{String: message[:2000], Valid: true} + want.Error = sql.NullString{String: err[:1000], Valid: true} + + // run test + got := b.Crop() + + if !reflect.DeepEqual(got, want) { + t.Errorf("Crop is %v, want %v", got, want) + } +} + +func TestTypes_Build_Nullify(t *testing.T) { + // setup types + var b *Build + + want := &Build{ + ID: sql.NullInt64{Int64: 0, Valid: false}, + RepoID: sql.NullInt64{Int64: 0, Valid: false}, + PipelineID: sql.NullInt64{Int64: 0, Valid: false}, + Number: sql.NullInt32{Int32: 0, Valid: false}, + Parent: sql.NullInt32{Int32: 0, Valid: false}, + Event: sql.NullString{String: "", Valid: false}, + EventAction: sql.NullString{String: "", Valid: false}, + Status: sql.NullString{String: "", Valid: false}, + Error: sql.NullString{String: "", Valid: false}, + Enqueued: sql.NullInt64{Int64: 0, Valid: false}, + Created: sql.NullInt64{Int64: 0, Valid: false}, + 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}, + Title: sql.NullString{String: "", Valid: false}, + Message: sql.NullString{String: "", Valid: false}, + Commit: sql.NullString{String: "", Valid: false}, + Sender: sql.NullString{String: "", Valid: false}, + Author: sql.NullString{String: "", Valid: false}, + Email: sql.NullString{String: "", Valid: false}, + Link: sql.NullString{String: "", Valid: false}, + Branch: sql.NullString{String: "", Valid: false}, + Ref: sql.NullString{String: "", Valid: false}, + BaseRef: sql.NullString{String: "", Valid: false}, + HeadRef: sql.NullString{String: "", Valid: false}, + Host: sql.NullString{String: "", Valid: false}, + Runtime: sql.NullString{String: "", Valid: false}, + Distribution: sql.NullString{String: "", Valid: false}, + } + + // setup tests + tests := []struct { + build *Build + want *Build + }{ + { + build: testBuild(), + want: testBuild(), + }, + { + build: b, + want: nil, + }, + { + build: new(Build), + want: want, + }, + } + + // run tests + for _, test := range tests { + got := test.build.Nullify() + + if !reflect.DeepEqual(got, test.want) { + t.Errorf("Nullify is %v, want %v", got, test.want) + } + } +} + +func TestTypes_Build_ToAPI(t *testing.T) { + // setup types + want := new(api.Build) + + want.SetID(1) + want.SetRepo(testRepo().ToAPI()) + want.SetPipelineID(1) + want.SetNumber(1) + want.SetParent(1) + want.SetEvent("push") + want.SetEventAction("") + want.SetStatus("running") + want.SetError("") + want.SetEnqueued(1563474077) + want.SetCreated(1563474076) + 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") + want.SetTitle("push received from https://github.com/github/octocat") + want.SetMessage("First commit...") + want.SetCommit("48afb5bdc41ad69bf22588491333f7cf71135163") + want.SetSender("OctoKitty") + want.SetAuthor("OctoKitty") + want.SetEmail("OctoKitty@github.com") + want.SetLink("https://example.company.com/github/octocat/1") + want.SetBranch("main") + want.SetRef("refs/heads/main") + want.SetBaseRef("") + want.SetHeadRef("") + want.SetHost("example.company.com") + want.SetRuntime("docker") + want.SetDistribution("linux") + want.SetDeployPayload(raw.StringSliceMap{"foo": "test1", "bar": "test2"}) + want.SetApprovedAt(1563474076) + want.SetApprovedBy("OctoCat") + + // run test + got := testBuild().ToAPI() + + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("ToAPI() mismatch (-want +got):\n%s", diff) + } +} + +func TestTypes_Build_Validate(t *testing.T) { + // setup tests + tests := []struct { + failure bool + build *Build + }{ + { + failure: false, + build: testBuild(), + }, + { // no repo_id set for build + failure: true, + build: &Build{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + Number: sql.NullInt32{Int32: 1, Valid: true}, + }, + }, + { // no number set for build + failure: true, + build: &Build{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + RepoID: sql.NullInt64{Int64: 1, Valid: true}, + }, + }, + } + + // run tests + for _, test := range tests { + err := test.build.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 TestTypes_Build_BuildFromAPI(t *testing.T) { + // setup types + b := new(api.Build) + + r := testutils.APIRepo() + r.SetID(1) + + b.SetID(1) + b.SetRepo(r) + b.SetPipelineID(1) + b.SetNumber(1) + b.SetParent(1) + b.SetEvent("push") + b.SetEventAction("") + b.SetStatus("running") + b.SetError("") + b.SetEnqueued(1563474077) + b.SetCreated(1563474076) + 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") + b.SetTitle("push received from https://github.com/github/octocat") + b.SetMessage("First commit...") + b.SetCommit("48afb5bdc41ad69bf22588491333f7cf71135163") + b.SetSender("OctoKitty") + b.SetAuthor("OctoKitty") + b.SetEmail("OctoKitty@github.com") + b.SetLink("https://example.company.com/github/octocat/1") + b.SetBranch("main") + b.SetRef("refs/heads/main") + b.SetBaseRef("") + b.SetHeadRef("") + b.SetHost("example.company.com") + b.SetRuntime("docker") + b.SetDistribution("linux") + b.SetDeployPayload(raw.StringSliceMap{"foo": "test1", "bar": "test2"}) + b.SetApprovedAt(1563474076) + b.SetApprovedBy("OctoCat") + + want := testBuild() + want.Repo = Repo{} + + // run test + got := BuildFromAPI(b) + + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("FromAPI() mismatch (-want +got):\n%s", diff) + } +} + +func randomString(n int) string { + var letter = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") + + b := make([]rune, n) + for i := range b { + //nolint:gosec // accepting weak RNG for test + b[i] = letter[rand.Intn(len(letter))] + } + + return string(b) +} + +// testBuild is a test helper function to create a Build +// type with all fields set to a fake value. +func testBuild() *Build { + return &Build{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + RepoID: sql.NullInt64{Int64: 1, Valid: true}, + PipelineID: sql.NullInt64{Int64: 1, Valid: true}, + Number: sql.NullInt32{Int32: 1, Valid: true}, + Parent: sql.NullInt32{Int32: 1, Valid: true}, + Event: sql.NullString{String: "push", Valid: true}, + EventAction: sql.NullString{String: "", Valid: false}, + Status: sql.NullString{String: "running", Valid: true}, + Error: sql.NullString{String: "", Valid: false}, + Enqueued: sql.NullInt64{Int64: 1563474077, Valid: true}, + Created: sql.NullInt64{Int64: 1563474076, Valid: true}, + 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: false}, + 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}, + Title: sql.NullString{String: "push received from https://github.com/github/octocat", Valid: true}, + Message: sql.NullString{String: "First commit...", Valid: true}, + Commit: sql.NullString{String: "48afb5bdc41ad69bf22588491333f7cf71135163", Valid: true}, + Sender: sql.NullString{String: "OctoKitty", Valid: true}, + Author: sql.NullString{String: "OctoKitty", Valid: true}, + Email: sql.NullString{String: "OctoKitty@github.com", Valid: true}, + Link: sql.NullString{String: "https://example.company.com/github/octocat/1", Valid: true}, + Branch: sql.NullString{String: "main", Valid: true}, + Ref: sql.NullString{String: "refs/heads/main", Valid: true}, + BaseRef: sql.NullString{String: "", Valid: false}, + HeadRef: sql.NullString{String: "", Valid: false}, + Host: sql.NullString{String: "example.company.com", Valid: true}, + Runtime: sql.NullString{String: "docker", Valid: true}, + Distribution: sql.NullString{String: "linux", Valid: true}, + ApprovedAt: sql.NullInt64{Int64: 1563474076, Valid: true}, + ApprovedBy: sql.NullString{String: "OctoCat", Valid: true}, + + Repo: *testRepo(), + } +} diff --git a/database/types/dashboard.go b/database/types/dashboard.go new file mode 100644 index 000000000..181824b7e --- /dev/null +++ b/database/types/dashboard.go @@ -0,0 +1,182 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "database/sql" + "database/sql/driver" + "encoding/json" + "errors" + "fmt" + + "github.com/google/uuid" + + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/util" +) + +var ( + // ErrEmptyDashName defines the error type when a + // User type has an empty Name field provided. + ErrEmptyDashName = errors.New("empty dashboard name provided") + + // ErrExceededAdminLimit defines the error type when a + // User type has Admins field provided that exceeds the database limit. + ErrExceededAdminLimit = errors.New("exceeded admins limit") +) + +type ( + // Dashboard is the database representation of a dashboard. + Dashboard struct { + ID uuid.UUID `gorm:"type:uuid;default:uuid_generate_v4()"` + Name sql.NullString `sql:"name"` + CreatedAt sql.NullInt64 `sql:"created_at"` + CreatedBy sql.NullString `sql:"created_by"` + UpdatedAt sql.NullInt64 `sql:"updated_at"` + UpdatedBy sql.NullString `sql:"updated_by"` + Admins AdminsJSON + Repos DashReposJSON + } + + DashReposJSON []*api.DashboardRepo + AdminsJSON []*api.User +) + +// Value - Implementation of valuer for database/sql for DashReposJSON. +func (r DashReposJSON) Value() (driver.Value, error) { + valueString, err := json.Marshal(r) + return string(valueString), err +} + +// Scan - Implement the database/sql scanner interface for DashReposJSON. +func (r *DashReposJSON) Scan(value interface{}) error { + switch v := value.(type) { + case []byte: + return json.Unmarshal(v, &r) + case string: + return json.Unmarshal([]byte(v), &r) + default: + return fmt.Errorf("wrong type for repos: %T", v) + } +} + +// Value - Implementation of valuer for database/sql for AdminsJSON. +func (a AdminsJSON) Value() (driver.Value, error) { + valueString, err := json.Marshal(a) + return string(valueString), err +} + +// Scan - Implement the database/sql scanner interface for AdminsJSON. +func (a *AdminsJSON) Scan(value interface{}) error { + switch v := value.(type) { + case []byte: + return json.Unmarshal(v, &a) + case string: + return json.Unmarshal([]byte(v), &a) + default: + return fmt.Errorf("wrong type for admins: %T", v) + } +} + +// Nullify ensures the valid flag for +// the sql.Null types are properly set. +// +// When a field within the Dashboard 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 *Dashboard) Nullify() *Dashboard { + if d == nil { + return nil + } + + // check if the Name field should be false + if len(d.Name.String) == 0 { + d.Name.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 + } + + // check if the UpdatedAt field should be false + if d.UpdatedAt.Int64 == 0 { + d.UpdatedAt.Valid = false + } + + // check if the UpdatedBy field should be false + if len(d.UpdatedBy.String) == 0 { + d.UpdatedBy.Valid = false + } + + return d +} + +// ToAPI converts the Dashboard type +// to an API Dashboard type. +func (d *Dashboard) ToAPI() *api.Dashboard { + dashboard := new(api.Dashboard) + + dashboard.SetID(d.ID.String()) + dashboard.SetName(d.Name.String) + dashboard.SetAdmins(d.Admins) + dashboard.SetCreatedAt(d.CreatedAt.Int64) + dashboard.SetCreatedBy(d.CreatedBy.String) + dashboard.SetUpdatedAt(d.UpdatedAt.Int64) + dashboard.SetUpdatedBy(d.UpdatedBy.String) + dashboard.SetRepos(d.Repos) + + return dashboard +} + +// Validate verifies the necessary fields for +// the Dashboard type are populated correctly. +func (d *Dashboard) Validate() error { + // verify the Name field is populated + if len(d.Name.String) == 0 { + return ErrEmptyDashName + } + + // ensure that all Dashboard string fields + // that can be returned as JSON are sanitized + // to avoid unsafe HTML content + d.Name = sql.NullString{String: util.Sanitize(d.Name.String), Valid: d.Name.Valid} + + return nil +} + +// DashboardFromAPI converts the API Dashboard type +// to a database Dashboard type. +func DashboardFromAPI(d *api.Dashboard) *Dashboard { + var ( + id uuid.UUID + err error + ) + + if d.GetID() == "" { + id = uuid.New() + } else { + id, err = uuid.Parse(d.GetID()) + if err != nil { + return nil + } + } + + dashboard := &Dashboard{ + ID: id, + Name: sql.NullString{String: d.GetName(), Valid: true}, + CreatedAt: sql.NullInt64{Int64: d.GetCreatedAt(), Valid: true}, + CreatedBy: sql.NullString{String: d.GetCreatedBy(), Valid: true}, + UpdatedAt: sql.NullInt64{Int64: d.GetUpdatedAt(), Valid: true}, + UpdatedBy: sql.NullString{String: d.GetUpdatedBy(), Valid: true}, + Admins: d.GetAdmins(), + Repos: d.GetRepos(), + } + + return dashboard.Nullify() +} diff --git a/database/types/dashboard_test.go b/database/types/dashboard_test.go new file mode 100644 index 000000000..f163e8b9c --- /dev/null +++ b/database/types/dashboard_test.go @@ -0,0 +1,231 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "database/sql" + "reflect" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/google/uuid" + + api "github.com/go-vela/server/api/types" +) + +func TestTypes_Dashboard_Nullify(t *testing.T) { + // setup types + var h *Dashboard + + want := &Dashboard{ + Name: 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}, + } + + // setup tests + tests := []struct { + dashboard *Dashboard + want *Dashboard + }{ + { + dashboard: testDashboard(), + want: testDashboard(), + }, + { + dashboard: h, + want: nil, + }, + { + dashboard: new(Dashboard), + want: want, + }, + } + + // run tests + for _, test := range tests { + got := test.dashboard.Nullify() + + if !reflect.DeepEqual(got, test.want) { + t.Errorf("Nullify is %v, want %v", got, test.want) + } + } +} + +func TestTypes_Dashboard_ToAPI(t *testing.T) { + // setup types + want := new(api.Dashboard) + want.SetID("c8da1302-07d6-11ea-882f-4893bca275b8") + want.SetName("vela") + want.SetCreatedAt(1) + want.SetCreatedBy("octocat") + want.SetUpdatedAt(2) + want.SetUpdatedBy("octokitty") + want.SetAdmins(testAdminsJSON()) + want.SetRepos(testDashReposJSON()) + + uuid, _ := uuid.Parse("c8da1302-07d6-11ea-882f-4893bca275b8") + h := &Dashboard{ + ID: uuid, + Name: sql.NullString{String: "vela", Valid: true}, + CreatedAt: sql.NullInt64{Int64: 1, Valid: true}, + CreatedBy: sql.NullString{String: "octocat", Valid: true}, + UpdatedAt: sql.NullInt64{Int64: 2, Valid: true}, + UpdatedBy: sql.NullString{String: "octokitty", Valid: true}, + Admins: testAdminsJSON(), + Repos: testDashReposJSON(), + } + + // run test + got := h.ToAPI() + + if !reflect.DeepEqual(got, want) { + t.Errorf("ToAPI is %v, want %v", got, want) + } +} + +func TestTypes_Dashboard_Validate(t *testing.T) { + uuid, _ := uuid.Parse("c8da1302-07d6-11ea-882f-4893bca275b8") + + // setup tests + tests := []struct { + failure bool + dashboard *Dashboard + }{ + { + failure: false, + dashboard: testDashboard(), + }, + { // no name set for dashboard + failure: true, + dashboard: &Dashboard{ + ID: uuid, + }, + }, + } + + // run tests + for _, test := range tests { + err := test.dashboard.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 TestTypes_DashboardFromAPI(t *testing.T) { + uuid, err := uuid.Parse("c8da1302-07d6-11ea-882f-4893bca275b8") + if err != nil { + t.Errorf("error parsing uuid: %v", err) + } + + // setup types + want := &Dashboard{ + ID: uuid, + Name: sql.NullString{String: "vela", Valid: true}, + CreatedAt: sql.NullInt64{Int64: 1, Valid: true}, + CreatedBy: sql.NullString{String: "octocat", Valid: true}, + UpdatedAt: sql.NullInt64{Int64: 2, Valid: true}, + UpdatedBy: sql.NullString{String: "octokitty", Valid: true}, + Admins: testAdminsJSON(), + Repos: testDashReposJSON(), + } + + d := new(api.Dashboard) + d.SetID("c8da1302-07d6-11ea-882f-4893bca275b8") + d.SetName("vela") + d.SetCreatedAt(1) + d.SetCreatedBy("octocat") + d.SetUpdatedAt(2) + d.SetUpdatedBy("octokitty") + d.SetAdmins(testAdminsJSON()) + d.SetRepos(testDashReposJSON()) + + // run test + got := DashboardFromAPI(d) + + if diff := cmp.Diff(got, want); diff != "" { + t.Errorf("DashboardFromAPI() mismatch (-want +got):\n%s", diff) + } + + // test empty uuid results in generated uuid + d.SetID("") + + //nolint:staticcheck // linter is lying + got = DashboardFromAPI(d) + + if len(got.ID) != 16 { + t.Errorf("Length is %d", len(got.ID)) + } + + // test poorly formed uuid results in nil dashboard + d.SetID("123-abc") + + got = DashboardFromAPI(d) + + if got != nil { + t.Errorf("DashboardFromAPI should have returned nil") + } +} + +// testDashboard is a test helper function to create a Dashboard +// type with all fields set to a fake value. +func testDashboard() *Dashboard { + uuid, _ := uuid.Parse("c8da1302-07d6-11ea-882f-4893bca275b8") + + return &Dashboard{ + ID: uuid, + Name: sql.NullString{String: "vela", Valid: true}, + CreatedAt: sql.NullInt64{Int64: time.Now().UTC().Unix(), Valid: true}, + CreatedBy: sql.NullString{String: "octocat", Valid: true}, + UpdatedAt: sql.NullInt64{Int64: time.Now().UTC().Unix(), Valid: true}, + UpdatedBy: sql.NullString{String: "octokitty", Valid: true}, + Admins: testAdminsJSON(), + Repos: testDashReposJSON(), + } +} + +// testDashReposJSON is a test helper function to create a DashReposJSON +// type with all fields set to a fake value. +func testDashReposJSON() DashReposJSON { + d := new(api.DashboardRepo) + + d.SetName("go-vela/server") + d.SetID(1) + d.SetBranches([]string{"main"}) + d.SetEvents([]string{"push", "tag"}) + + return DashReposJSON{d} +} + +// testAdminsJSON is a test helper function to create a DashReposJSON +// type with all fields set to a fake value. +func testAdminsJSON() AdminsJSON { + u1 := new(api.User) + + u1.SetName("octocat") + u1.SetID(1) + u1.SetActive(true) + u1.SetToken("foo") + + u2 := new(api.User) + + u2.SetName("octokitty") + u2.SetID(2) + u2.SetActive(true) + u2.SetToken("bar") + + return AdminsJSON{u1, u2} +} diff --git a/database/types/queue_build.go b/database/types/queue_build.go new file mode 100644 index 000000000..51f0cfd0a --- /dev/null +++ b/database/types/queue_build.go @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "database/sql" + + api "github.com/go-vela/server/api/types" +) + +// QueueBuild is the database representation of the builds in the queue. +type QueueBuild struct { + Status sql.NullString `sql:"status"` + Number sql.NullInt32 `sql:"number"` + Created sql.NullInt64 `sql:"created"` + FullName sql.NullString `sql:"full_name"` +} + +// ToAPI converts the QueueBuild type +// to a API QueueBuild type. +func (b *QueueBuild) ToAPI() *api.QueueBuild { + buildQueue := new(api.QueueBuild) + + buildQueue.SetStatus(b.Status.String) + buildQueue.SetNumber(b.Number.Int32) + buildQueue.SetCreated(b.Created.Int64) + buildQueue.SetFullName(b.FullName.String) + + return buildQueue +} + +// QueueBuildFromAPI converts the API QueueBuild type +// to a database build queue type. +func QueueBuildFromAPI(b *api.QueueBuild) *QueueBuild { + buildQueue := &QueueBuild{ + Status: sql.NullString{String: b.GetStatus(), Valid: true}, + Number: sql.NullInt32{Int32: b.GetNumber(), Valid: true}, + Created: sql.NullInt64{Int64: b.GetCreated(), Valid: true}, + FullName: sql.NullString{String: b.GetFullName(), Valid: true}, + } + + return buildQueue +} diff --git a/database/types/queue_build_test.go b/database/types/queue_build_test.go new file mode 100644 index 000000000..55a413230 --- /dev/null +++ b/database/types/queue_build_test.go @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "database/sql" + "reflect" + "testing" + + api "github.com/go-vela/server/api/types" +) + +func TestTypes_QueueBuild_ToAPI(t *testing.T) { + // setup types + want := new(api.QueueBuild) + + want.SetNumber(1) + want.SetStatus("running") + want.SetCreated(1563474076) + want.SetFullName("github/octocat") + + // run test + got := testQueueBuild().ToAPI() + + if !reflect.DeepEqual(got, want) { + t.Errorf("ToAPI is %v, want %v", got, want) + } +} + +func TestTypes_QueueBuild_FromAPI(t *testing.T) { + // setup types + b := new(api.QueueBuild) + + b.SetNumber(1) + b.SetStatus("running") + b.SetCreated(1563474076) + b.SetFullName("github/octocat") + + want := testQueueBuild() + + // run test + got := QueueBuildFromAPI(b) + + if !reflect.DeepEqual(got, want) { + t.Errorf("QueueBuildFromAPI is %v, want %v", got, want) + } +} + +// testQueueBuild is a test helper function to create a QueueBuild +// type with all fields set to a fake value. +func testQueueBuild() *QueueBuild { + return &QueueBuild{ + Number: sql.NullInt32{Int32: 1, Valid: true}, + Status: sql.NullString{String: "running", Valid: true}, + Created: sql.NullInt64{Int64: 1563474076, Valid: true}, + FullName: sql.NullString{String: "github/octocat", Valid: true}, + } +} diff --git a/database/types/repo.go b/database/types/repo.go new file mode 100644 index 000000000..e3780f851 --- /dev/null +++ b/database/types/repo.go @@ -0,0 +1,342 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "database/sql" + "encoding/base64" + "errors" + + "github.com/lib/pq" + + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/util" + "github.com/go-vela/types/constants" +) + +var ( + // ErrEmptyRepoFullName defines the error type when a + // Repo type has an empty FullName field provided. + ErrEmptyRepoFullName = errors.New("empty repo full_name provided") + + // ErrEmptyRepoHash defines the error type when a + // Repo type has an empty Hash field provided. + ErrEmptyRepoHash = errors.New("empty repo hash provided") + + // ErrEmptyRepoName defines the error type when a + // Repo type has an empty Name field provided. + ErrEmptyRepoName = errors.New("empty repo name provided") + + // ErrEmptyRepoOrg defines the error type when a + // Repo type has an empty Org field provided. + ErrEmptyRepoOrg = errors.New("empty repo org provided") + + // ErrEmptyRepoUserID defines the error type when a + // Repo type has an empty UserID field provided. + ErrEmptyRepoUserID = errors.New("empty repo user_id provided") + + // ErrEmptyRepoVisibility defines the error type when a + // Repo type has an empty Visibility field provided. + ErrEmptyRepoVisibility = errors.New("empty repo visibility provided") + + // ErrExceededTopicsLimit defines the error type when a + // Repo type has Topics field provided that exceeds the database limit. + ErrExceededTopicsLimit = errors.New("exceeded topics limit") +) + +// Repo is the database representation of a repo. +type Repo struct { + ID sql.NullInt64 `sql:"id"` + UserID sql.NullInt64 `sql:"user_id"` + Hash sql.NullString `sql:"hash"` + Org sql.NullString `sql:"org"` + Name sql.NullString `sql:"name"` + FullName sql.NullString `sql:"full_name"` + Link sql.NullString `sql:"link"` + Clone sql.NullString `sql:"clone"` + Branch sql.NullString `sql:"branch"` + Topics pq.StringArray `sql:"topics" gorm:"type:varchar(1020)"` + BuildLimit sql.NullInt64 `sql:"build_limit"` + Timeout sql.NullInt64 `sql:"timeout"` + Counter sql.NullInt32 `sql:"counter"` + Visibility sql.NullString `sql:"visibility"` + Private sql.NullBool `sql:"private"` + Trusted sql.NullBool `sql:"trusted"` + Active sql.NullBool `sql:"active"` + AllowEvents sql.NullInt64 `sql:"allow_events"` + PipelineType sql.NullString `sql:"pipeline_type"` + PreviousName sql.NullString `sql:"previous_name"` + ApproveBuild sql.NullString `sql:"approve_build"` + + Owner User `gorm:"foreignKey:UserID"` +} + +// Decrypt will manipulate the existing repo hash by +// base64 decoding that value. Then, a AES-256 cipher +// block is created from the encryption key in order to +// decrypt the base64 decoded secret value. +func (r *Repo) Decrypt(key string) error { + // base64 decode the encrypted repo hash + decoded, err := base64.StdEncoding.DecodeString(r.Hash.String) + if err != nil { + return err + } + + // decrypt the base64 decoded repo hash + decrypted, err := util.Decrypt(key, decoded) + if err != nil { + return err + } + + // set the decrypted repo hash + r.Hash = sql.NullString{ + String: string(decrypted), + Valid: true, + } + + // decrypt owner + err = r.Owner.Decrypt(key) + if err != nil { + return err + } + + return nil +} + +// Encrypt will manipulate the existing repo hash by +// creating a AES-256 cipher block from the encryption +// key in order to encrypt the repo hash. Then, the +// repo hash is base64 encoded for transport across +// network boundaries. +func (r *Repo) Encrypt(key string) error { + // encrypt the repo hash + encrypted, err := util.Encrypt(key, []byte(r.Hash.String)) + if err != nil { + return err + } + + // base64 encode the encrypted repo hash to make it network safe + r.Hash = sql.NullString{ + String: base64.StdEncoding.EncodeToString(encrypted), + Valid: true, + } + + return nil +} + +// Nullify ensures the valid flag for +// the sql.Null types are properly set. +// +// When a field within the Repo type is the zero +// value for the field, the valid flag is set to +// false causing it to be NULL in the database. +func (r *Repo) Nullify() *Repo { + if r == nil { + return nil + } + + // check if the ID field should be false + if r.ID.Int64 == 0 { + r.ID.Valid = false + } + + // check if the UserID field should be false + if r.UserID.Int64 == 0 { + r.UserID.Valid = false + } + + // check if the Hash field should be false + if len(r.Hash.String) == 0 { + r.Hash.Valid = false + } + + // check if the Org field should be false + if len(r.Org.String) == 0 { + r.Org.Valid = false + } + + // check if the Name field should be false + if len(r.Name.String) == 0 { + r.Name.Valid = false + } + + // check if the FullName field should be false + if len(r.FullName.String) == 0 { + r.FullName.Valid = false + } + + // check if the Link field should be false + if len(r.Link.String) == 0 { + r.Link.Valid = false + } + + // check if the Clone field should be false + if len(r.Clone.String) == 0 { + r.Clone.Valid = false + } + + // check if the Branch field should be false + if len(r.Branch.String) == 0 { + r.Branch.Valid = false + } + + // check if the BuildLimit field should be false + if r.BuildLimit.Int64 == 0 { + r.BuildLimit.Valid = false + } + + // check if the Timeout field should be false + if r.Timeout.Int64 == 0 { + r.Timeout.Valid = false + } + + // check if the AllowEvents field should be false + if r.AllowEvents.Int64 == 0 { + r.AllowEvents.Valid = false + } + + // check if the Visibility field should be false + if len(r.Visibility.String) == 0 { + r.Visibility.Valid = false + } + + // check if the PipelineType field should be false + if len(r.PipelineType.String) == 0 { + r.PipelineType.Valid = false + } + + // check if the PreviousName field should be false + if len(r.PreviousName.String) == 0 { + r.PreviousName.Valid = false + } + + // check if the ApproveForkBuild field should be false + if len(r.ApproveBuild.String) == 0 { + r.ApproveBuild.Valid = false + } + + return r +} + +// ToAPI converts the Repo type +// to an API Repo type. +func (r *Repo) ToAPI() *api.Repo { + repo := new(api.Repo) + + repo.SetID(r.ID.Int64) + repo.SetOwner(r.Owner.ToAPI().Crop()) + repo.SetHash(r.Hash.String) + repo.SetOrg(r.Org.String) + repo.SetName(r.Name.String) + repo.SetFullName(r.FullName.String) + repo.SetLink(r.Link.String) + repo.SetClone(r.Clone.String) + repo.SetBranch(r.Branch.String) + repo.SetTopics(r.Topics) + repo.SetBuildLimit(r.BuildLimit.Int64) + repo.SetTimeout(r.Timeout.Int64) + repo.SetCounter(int(r.Counter.Int32)) + repo.SetVisibility(r.Visibility.String) + repo.SetPrivate(r.Private.Bool) + repo.SetTrusted(r.Trusted.Bool) + repo.SetActive(r.Active.Bool) + repo.SetAllowEvents(api.NewEventsFromMask(r.AllowEvents.Int64)) + repo.SetPipelineType(r.PipelineType.String) + repo.SetPreviousName(r.PreviousName.String) + repo.SetApproveBuild(r.ApproveBuild.String) + + return repo +} + +// Validate verifies the necessary fields for +// the Repo type are populated correctly. +func (r *Repo) Validate() error { + // verify the UserID field is populated + if r.UserID.Int64 <= 0 { + return ErrEmptyRepoUserID + } + + // verify the Hash field is populated + if len(r.Hash.String) == 0 { + return ErrEmptyRepoHash + } + + // verify the Org field is populated + if len(r.Org.String) == 0 { + return ErrEmptyRepoOrg + } + + // verify the Name field is populated + if len(r.Name.String) == 0 { + return ErrEmptyRepoName + } + + // verify the FullName field is populated + if len(r.FullName.String) == 0 { + return ErrEmptyRepoFullName + } + + // verify the Visibility field is populated + if len(r.Visibility.String) == 0 { + return ErrEmptyRepoVisibility + } + + // calculate total size of favorites while sanitizing entries + total := 0 + + for i, t := range r.Topics { + r.Topics[i] = util.Sanitize(t) + total += len(t) + } + + // verify the Favorites field is within the database constraints + // len is to factor in number of comma separators included in the database field, + // removing 1 due to the last item not having an appended comma + if (total + len(r.Topics) - 1) > constants.TopicsMaxSize { + return ErrExceededTopicsLimit + } + + // ensure that all Repo string fields + // that can be returned as JSON are sanitized + // to avoid unsafe HTML content + r.Org = sql.NullString{String: util.Sanitize(r.Org.String), Valid: r.Org.Valid} + r.Name = sql.NullString{String: util.Sanitize(r.Name.String), Valid: r.Name.Valid} + r.FullName = sql.NullString{String: util.Sanitize(r.FullName.String), Valid: r.FullName.Valid} + r.Link = sql.NullString{String: util.Sanitize(r.Link.String), Valid: r.Link.Valid} + r.Clone = sql.NullString{String: util.Sanitize(r.Clone.String), Valid: r.Clone.Valid} + r.Branch = sql.NullString{String: util.Sanitize(r.Branch.String), Valid: r.Branch.Valid} + r.Visibility = sql.NullString{String: util.Sanitize(r.Visibility.String), Valid: r.Visibility.Valid} + r.PipelineType = sql.NullString{String: util.Sanitize(r.PipelineType.String), Valid: r.PipelineType.Valid} + + return nil +} + +// RepoFromAPI converts the API Repo type +// to a database repo type. +func RepoFromAPI(r *api.Repo) *Repo { + repo := &Repo{ + ID: sql.NullInt64{Int64: r.GetID(), Valid: true}, + UserID: sql.NullInt64{Int64: r.GetOwner().GetID(), Valid: true}, + Hash: sql.NullString{String: r.GetHash(), Valid: true}, + Org: sql.NullString{String: r.GetOrg(), Valid: true}, + Name: sql.NullString{String: r.GetName(), Valid: true}, + FullName: sql.NullString{String: r.GetFullName(), Valid: true}, + Link: sql.NullString{String: r.GetLink(), Valid: true}, + Clone: sql.NullString{String: r.GetClone(), Valid: true}, + Branch: sql.NullString{String: r.GetBranch(), Valid: true}, + Topics: pq.StringArray(r.GetTopics()), + BuildLimit: sql.NullInt64{Int64: r.GetBuildLimit(), Valid: true}, + Timeout: sql.NullInt64{Int64: r.GetTimeout(), Valid: true}, + Counter: sql.NullInt32{Int32: int32(r.GetCounter()), Valid: true}, + Visibility: sql.NullString{String: r.GetVisibility(), Valid: true}, + Private: sql.NullBool{Bool: r.GetPrivate(), Valid: true}, + Trusted: sql.NullBool{Bool: r.GetTrusted(), Valid: true}, + Active: sql.NullBool{Bool: r.GetActive(), Valid: true}, + AllowEvents: sql.NullInt64{Int64: r.GetAllowEvents().ToDatabase(), Valid: true}, + PipelineType: sql.NullString{String: r.GetPipelineType(), Valid: true}, + PreviousName: sql.NullString{String: r.GetPreviousName(), Valid: true}, + ApproveBuild: sql.NullString{String: r.GetApproveBuild(), Valid: true}, + } + + return repo.Nullify() +} diff --git a/database/types/repo_test.go b/database/types/repo_test.go new file mode 100644 index 000000000..f060e9141 --- /dev/null +++ b/database/types/repo_test.go @@ -0,0 +1,388 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "database/sql" + "reflect" + "testing" + + "github.com/google/go-cmp/cmp" + + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" + "github.com/go-vela/types/constants" +) + +func TestTypes_Repo_Decrypt(t *testing.T) { + // setup types + key := "C639A572E14D5075C526FDDD43E4ECF6" + encrypted := testRepo() + + err := encrypted.Encrypt(key) + if err != nil { + t.Errorf("unable to encrypt repo: %v", err) + } + + err = encrypted.Owner.Encrypt(key) + if err != nil { + t.Errorf("unable to encrypt user: %v", err) + } + + // setup tests + tests := []struct { + failure bool + key string + repo Repo + }{ + { + failure: false, + key: key, + repo: *encrypted, + }, + { + failure: true, + key: "", + repo: *encrypted, + }, + { + failure: true, + key: key, + repo: *testRepo(), + }, + } + + // run tests + for _, test := range tests { + err := test.repo.Decrypt(test.key) + + if test.failure { + if err == nil { + t.Errorf("Decrypt should have returned err") + } + + continue + } + + if err != nil { + t.Errorf("Decrypt returned err: %v", err) + } + } +} + +func TestTypes_Repo_Encrypt(t *testing.T) { + // setup types + key := "C639A572E14D5075C526FDDD43E4ECF6" + + // setup tests + tests := []struct { + failure bool + key string + repo *Repo + }{ + { + failure: false, + key: key, + repo: testRepo(), + }, + { + failure: true, + key: "", + repo: testRepo(), + }, + } + + // run tests + for _, test := range tests { + err := test.repo.Encrypt(test.key) + + if test.failure { + if err == nil { + t.Errorf("Encrypt should have returned err") + } + + continue + } + + if err != nil { + t.Errorf("Encrypt returned err: %v", err) + } + } +} + +func TestTypes_Repo_Nullify(t *testing.T) { + // setup types + var r *Repo + + want := &Repo{ + ID: sql.NullInt64{Int64: 0, Valid: false}, + UserID: sql.NullInt64{Int64: 0, Valid: false}, + Hash: sql.NullString{String: "", Valid: false}, + Org: sql.NullString{String: "", Valid: false}, + Name: sql.NullString{String: "", Valid: false}, + FullName: sql.NullString{String: "", Valid: false}, + Link: sql.NullString{String: "", Valid: false}, + Clone: sql.NullString{String: "", Valid: false}, + Branch: sql.NullString{String: "", Valid: false}, + Timeout: sql.NullInt64{Int64: 0, Valid: false}, + AllowEvents: sql.NullInt64{Int64: 0, Valid: false}, + Visibility: sql.NullString{String: "", Valid: false}, + PipelineType: sql.NullString{String: "", Valid: false}, + ApproveBuild: sql.NullString{String: "", Valid: false}, + } + + // setup tests + tests := []struct { + repo *Repo + want *Repo + }{ + { + repo: testRepo(), + want: testRepo(), + }, + { + repo: r, + want: nil, + }, + { + repo: new(Repo), + want: want, + }, + } + + // run tests + for _, test := range tests { + got := test.repo.Nullify() + + if !reflect.DeepEqual(got, test.want) { + t.Errorf("Nullify is %v, want %v", got, test.want) + } + } +} + +func TestTypes_Repo_ToAPI(t *testing.T) { + // setup types + want := new(api.Repo) + e := api.NewEventsFromMask(1) + + owner := testutils.APIUser().Crop() + owner.SetID(1) + owner.SetName("octocat") + owner.SetActive(true) + owner.SetToken("superSecretToken") + owner.SetRefreshToken("superSecretRefreshToken") + + want.SetID(1) + want.SetOwner(owner) + want.SetHash("superSecretHash") + want.SetOrg("github") + want.SetName("octocat") + want.SetFullName("github/octocat") + want.SetLink("https://github.com/github/octocat") + want.SetClone("https://github.com/github/octocat.git") + want.SetBranch("main") + want.SetTopics([]string{"cloud", "security"}) + want.SetBuildLimit(10) + want.SetTimeout(30) + want.SetCounter(0) + want.SetVisibility("public") + want.SetPrivate(false) + want.SetTrusted(false) + want.SetActive(true) + want.SetAllowEvents(e) + want.SetPipelineType("yaml") + want.SetPreviousName("oldName") + want.SetApproveBuild(constants.ApproveNever) + + // run test + got := testRepo().ToAPI() + + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("ToAPI() mismatch (-want +got):\n%s", diff) + } +} + +func TestTypes_Repo_Validate(t *testing.T) { + // setup types + topics := []string{} + longTopic := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + + for len(topics) < 21 { + topics = append(topics, longTopic) + } + + // setup tests + tests := []struct { + failure bool + repo *Repo + }{ + { + failure: false, + repo: testRepo(), + }, + { // no user_id set for repo + failure: true, + repo: &Repo{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + Hash: sql.NullString{String: "superSecretHash", Valid: true}, + Org: sql.NullString{String: "github", Valid: true}, + Name: sql.NullString{String: "octocat", Valid: true}, + FullName: sql.NullString{String: "github/octocat", Valid: true}, + Visibility: sql.NullString{String: "public", Valid: true}, + }, + }, + { // no hash set for repo + failure: true, + repo: &Repo{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + UserID: sql.NullInt64{Int64: 1, Valid: true}, + Org: sql.NullString{String: "github", Valid: true}, + Name: sql.NullString{String: "octocat", Valid: true}, + FullName: sql.NullString{String: "github/octocat", Valid: true}, + Visibility: sql.NullString{String: "public", Valid: true}, + }, + }, + { // no org set for repo + failure: true, + repo: &Repo{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + UserID: sql.NullInt64{Int64: 1, Valid: true}, + Hash: sql.NullString{String: "superSecretHash", Valid: true}, + Name: sql.NullString{String: "octocat", Valid: true}, + FullName: sql.NullString{String: "github/octocat", Valid: true}, + Visibility: sql.NullString{String: "public", Valid: true}, + }, + }, + { // no name set for repo + failure: true, + repo: &Repo{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + UserID: sql.NullInt64{Int64: 1, Valid: true}, + Hash: sql.NullString{String: "superSecretHash", Valid: true}, + Org: sql.NullString{String: "github", Valid: true}, + FullName: sql.NullString{String: "github/octocat", Valid: true}, + Visibility: sql.NullString{String: "public", Valid: true}, + }, + }, + { // no full_name set for repo + failure: true, + repo: &Repo{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + UserID: sql.NullInt64{Int64: 1, Valid: true}, + Hash: sql.NullString{String: "superSecretHash", Valid: true}, + Org: sql.NullString{String: "github", Valid: true}, + Name: sql.NullString{String: "octocat", Valid: true}, + Visibility: sql.NullString{String: "public", Valid: true}, + }, + }, + { // no visibility set for repo + failure: true, + repo: &Repo{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + UserID: sql.NullInt64{Int64: 1, Valid: true}, + Hash: sql.NullString{String: "superSecretHash", Valid: true}, + Org: sql.NullString{String: "github", Valid: true}, + Name: sql.NullString{String: "octocat", Valid: true}, + FullName: sql.NullString{String: "github/octocat", Valid: true}, + }, + }, + { // topics exceed max size + failure: true, + repo: &Repo{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + UserID: sql.NullInt64{Int64: 1, Valid: true}, + Hash: sql.NullString{String: "superSecretHash", Valid: true}, + Org: sql.NullString{String: "github", Valid: true}, + Name: sql.NullString{String: "octocat", Valid: true}, + FullName: sql.NullString{String: "github/octocat", Valid: true}, + Topics: topics, + }, + }, + } + + // run tests + for _, test := range tests { + err := test.repo.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 TestTypes_RepoFromAPI(t *testing.T) { + // setup types + r := new(api.Repo) + owner := testutils.APIUser() + owner.SetID(1) + + r.SetID(1) + r.SetOwner(owner) + r.SetHash("superSecretHash") + r.SetOrg("github") + r.SetName("octocat") + r.SetFullName("github/octocat") + r.SetLink("https://github.com/github/octocat") + r.SetClone("https://github.com/github/octocat.git") + r.SetBranch("main") + r.SetTopics([]string{"cloud", "security"}) + r.SetBuildLimit(10) + r.SetTimeout(30) + r.SetCounter(0) + r.SetVisibility("public") + r.SetPrivate(false) + r.SetTrusted(false) + r.SetActive(true) + r.SetAllowEvents(api.NewEventsFromMask(1)) + r.SetPipelineType("yaml") + r.SetPreviousName("oldName") + r.SetApproveBuild(constants.ApproveNever) + + want := testRepo() + want.Owner = User{} + + // run test + got := RepoFromAPI(r) + + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("FromAPI() mismatch (-want +got):\n%s", diff) + } +} + +// testRepo is a test helper function to create a Repo +// type with all fields set to a fake value. +func testRepo() *Repo { + return &Repo{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + UserID: sql.NullInt64{Int64: 1, Valid: true}, + Hash: sql.NullString{String: "superSecretHash", Valid: true}, + Org: sql.NullString{String: "github", Valid: true}, + Name: sql.NullString{String: "octocat", Valid: true}, + FullName: sql.NullString{String: "github/octocat", Valid: true}, + Link: sql.NullString{String: "https://github.com/github/octocat", Valid: true}, + Clone: sql.NullString{String: "https://github.com/github/octocat.git", Valid: true}, + Branch: sql.NullString{String: "main", Valid: true}, + Topics: []string{"cloud", "security"}, + BuildLimit: sql.NullInt64{Int64: 10, Valid: true}, + Timeout: sql.NullInt64{Int64: 30, Valid: true}, + Counter: sql.NullInt32{Int32: 0, Valid: true}, + Visibility: sql.NullString{String: "public", Valid: true}, + Private: sql.NullBool{Bool: false, Valid: true}, + Trusted: sql.NullBool{Bool: false, Valid: true}, + Active: sql.NullBool{Bool: true, Valid: true}, + AllowEvents: sql.NullInt64{Int64: 1, Valid: true}, + PipelineType: sql.NullString{String: "yaml", Valid: true}, + PreviousName: sql.NullString{String: "oldName", Valid: true}, + ApproveBuild: sql.NullString{String: constants.ApproveNever, Valid: true}, + + Owner: *testUser(), + } +} diff --git a/database/types/user.go b/database/types/user.go new file mode 100644 index 000000000..0bfd13e2a --- /dev/null +++ b/database/types/user.go @@ -0,0 +1,261 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "database/sql" + "encoding/base64" + "errors" + "regexp" + + "github.com/lib/pq" + + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/util" + "github.com/go-vela/types/constants" +) + +var ( + // userRegex defines the regex pattern for validating + // the Name field for the User type. + userRegex = regexp.MustCompile("^[a-zA-Z0-9_-]{0,38}$") + + // ErrEmptyUserName defines the error type when a + // User type has an empty Name field provided. + ErrEmptyUserName = errors.New("empty user name provided") + + // ErrEmptyUserRefreshToken defines the error type when a + // User type has an empty RefreshToken field provided. + ErrEmptyUserRefreshToken = errors.New("empty user refresh token provided") + + // ErrEmptyUserToken defines the error type when a + // User type has an empty Token field provided. + ErrEmptyUserToken = errors.New("empty user token provided") + + // ErrInvalidUserName defines the error type when a + // User type has an invalid Name field provided. + ErrInvalidUserName = errors.New("invalid user name provided") + + // ErrExceededFavoritesLimit defines the error type when a + // User type has Favorites field provided that exceeds the database limit. + ErrExceededFavoritesLimit = errors.New("exceeded favorites limit") + + // ErrExceededDashboardsLimit defines the error type when a + // User type has Dashboards field provided that exceeds the database limit. + ErrExceededDashboardsLimit = errors.New("exceeded dashboards limit") +) + +// User is the database representation of a user. +type User struct { + ID sql.NullInt64 `sql:"id"` + Name sql.NullString `sql:"name"` + RefreshToken sql.NullString `sql:"refresh_token"` + Token sql.NullString `sql:"token"` + Favorites pq.StringArray `sql:"favorites" gorm:"type:varchar(5000)"` + Active sql.NullBool `sql:"active"` + Admin sql.NullBool `sql:"admin"` + Dashboards pq.StringArray `sql:"dashboards" gorm:"type:varchar(5000)"` +} + +// Decrypt will manipulate the existing user tokens by +// base64 decoding them. Then, a AES-256 cipher +// block is created from the encryption key in order to +// decrypt the base64 decoded user tokens. +func (u *User) Decrypt(key string) error { + // base64 decode the encrypted user token + decoded, err := base64.StdEncoding.DecodeString(u.Token.String) + if err != nil { + return err + } + + // decrypt the base64 decoded user token + decrypted, err := util.Decrypt(key, decoded) + if err != nil { + return err + } + + // set the decrypted user token + u.Token = sql.NullString{ + String: string(decrypted), + Valid: true, + } + + // base64 decode the encrypted user refresh token + decoded, err = base64.StdEncoding.DecodeString(u.RefreshToken.String) + if err != nil { + return err + } + + // decrypt the base64 decoded user refresh token + decrypted, err = util.Decrypt(key, decoded) + if err != nil { + return err + } + + // set the decrypted user refresh token + u.RefreshToken = sql.NullString{ + String: string(decrypted), + Valid: true, + } + + return nil +} + +// Encrypt will manipulate the existing user tokens by +// creating a AES-256 cipher block from the encryption +// key in order to encrypt the user tokens. Then, the +// user tokens are base64 encoded for transport across +// network boundaries. +func (u *User) Encrypt(key string) error { + // encrypt the user token + encrypted, err := util.Encrypt(key, []byte(u.Token.String)) + if err != nil { + return err + } + + // base64 encode the encrypted user token to make it network safe + u.Token = sql.NullString{ + String: base64.StdEncoding.EncodeToString(encrypted), + Valid: true, + } + + // encrypt the user refresh token + encrypted, err = util.Encrypt(key, []byte(u.RefreshToken.String)) + if err != nil { + return err + } + + // base64 encode the encrypted user refresh token to make it network safe + u.RefreshToken = sql.NullString{ + String: base64.StdEncoding.EncodeToString(encrypted), + Valid: true, + } + + return nil +} + +// Nullify ensures the valid flag for +// the sql.Null types are properly set. +// +// When a field within the User type is the zero +// value for the field, the valid flag is set to +// false causing it to be NULL in the database. +func (u *User) Nullify() *User { + if u == nil { + return nil + } + + // check if the ID field should be false + if u.ID.Int64 == 0 { + u.ID.Valid = false + } + + // check if the Name field should be false + if len(u.Name.String) == 0 { + u.Name.Valid = false + } + + // check if the RefreshToken field should be false + if len(u.RefreshToken.String) == 0 { + u.RefreshToken.Valid = false + } + + // check if the Token field should be false + if len(u.Token.String) == 0 { + u.Token.Valid = false + } + + return u +} + +// ToAPI converts the User type +// to an API User type. +func (u *User) ToAPI() *api.User { + user := new(api.User) + + user.SetID(u.ID.Int64) + user.SetName(u.Name.String) + user.SetRefreshToken(u.RefreshToken.String) + user.SetToken(u.Token.String) + user.SetActive(u.Active.Bool) + user.SetAdmin(u.Admin.Bool) + user.SetFavorites(u.Favorites) + user.SetDashboards(u.Dashboards) + + return user +} + +// Validate verifies the necessary fields for +// the User type are populated correctly. +func (u *User) Validate() error { + // verify the Name field is populated + if len(u.Name.String) == 0 { + return ErrEmptyUserName + } + + // verify the Token field is populated + if len(u.Token.String) == 0 { + return ErrEmptyUserToken + } + + // verify the Name field is valid + if !userRegex.MatchString(u.Name.String) { + return ErrInvalidUserName + } + + // calculate total size of favorites + total := 0 + for _, f := range u.Favorites { + total += len(f) + } + + // verify the Favorites field is within the database constraints + // len is to factor in number of comma separators included in the database field, + // removing 1 due to the last item not having an appended comma + if (total + len(u.Favorites) - 1) > constants.FavoritesMaxSize { + return ErrExceededFavoritesLimit + } + + // calculate totalDashboards size of dashboards + totalDashboards := 0 + for _, d := range u.Dashboards { + totalDashboards += len(d) + } + + // verify the Dashboards field is within the database constraints + // len is to factor in number of comma separators included in the database field, + // removing 1 due to the last item not having an appended comma + if (totalDashboards + len(u.Dashboards) - 1) > constants.FavoritesMaxSize { + return ErrExceededDashboardsLimit + } + + // ensure that all User string fields + // that can be returned as JSON are sanitized + // to avoid unsafe HTML content + u.Name = sql.NullString{String: util.Sanitize(u.Name.String), Valid: u.Name.Valid} + + // ensure that all Favorites are sanitized + // to avoid unsafe HTML content + for i, v := range u.Favorites { + u.Favorites[i] = util.Sanitize(v) + } + + return nil +} + +// UserFromAPI converts the API User type +// to a database User type. +func UserFromAPI(u *api.User) *User { + user := &User{ + ID: sql.NullInt64{Int64: u.GetID(), Valid: true}, + Name: sql.NullString{String: u.GetName(), Valid: true}, + RefreshToken: sql.NullString{String: u.GetRefreshToken(), Valid: true}, + Token: sql.NullString{String: u.GetToken(), Valid: true}, + Active: sql.NullBool{Bool: u.GetActive(), Valid: true}, + Admin: sql.NullBool{Bool: u.GetAdmin(), Valid: true}, + Favorites: pq.StringArray(u.GetFavorites()), + Dashboards: pq.StringArray(u.GetDashboards()), + } + + return user.Nullify() +} diff --git a/database/types/user_test.go b/database/types/user_test.go new file mode 100644 index 000000000..9edf57abf --- /dev/null +++ b/database/types/user_test.go @@ -0,0 +1,292 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "database/sql" + "reflect" + "strconv" + "testing" + + api "github.com/go-vela/server/api/types" +) + +func TestTypes_User_Decrypt(t *testing.T) { + // setup types + key := "C639A572E14D5075C526FDDD43E4ECF6" + encrypted := testUser() + + err := encrypted.Encrypt(key) + if err != nil { + t.Errorf("unable to encrypt user: %v", err) + } + + // setup tests + tests := []struct { + failure bool + key string + user User + }{ + { + failure: false, + key: key, + user: *encrypted, + }, + { + failure: true, + key: "", + user: *encrypted, + }, + { + failure: true, + key: key, + user: *testUser(), + }, + } + + // run tests + for _, test := range tests { + err := test.user.Decrypt(test.key) + + if test.failure { + if err == nil { + t.Errorf("Decrypt should have returned err") + } + + continue + } + + if err != nil { + t.Errorf("Decrypt returned err: %v", err) + } + } +} + +func TestTypes_User_Encrypt(t *testing.T) { + // setup types + key := "C639A572E14D5075C526FDDD43E4ECF6" + + // setup tests + tests := []struct { + failure bool + key string + user *User + }{ + { + failure: false, + key: key, + user: testUser(), + }, + { + failure: true, + key: "", + user: testUser(), + }, + } + + // run tests + for _, test := range tests { + err := test.user.Encrypt(test.key) + + if test.failure { + if err == nil { + t.Errorf("Encrypt should have returned err") + } + + continue + } + + if err != nil { + t.Errorf("Encrypt returned err: %v", err) + } + } +} + +func TestTypes_User_Nullify(t *testing.T) { + // setup types + var u *User + + want := &User{ + ID: sql.NullInt64{Int64: 0, Valid: false}, + Name: sql.NullString{String: "", Valid: false}, + RefreshToken: sql.NullString{String: "", Valid: false}, + Token: sql.NullString{String: "", Valid: false}, + Active: sql.NullBool{Bool: false, Valid: false}, + Admin: sql.NullBool{Bool: false, Valid: false}, + } + + // setup tests + tests := []struct { + user *User + want *User + }{ + { + user: testUser(), + want: testUser(), + }, + { + user: u, + want: nil, + }, + { + user: new(User), + want: want, + }, + } + + // run tests + for _, test := range tests { + got := test.user.Nullify() + + if !reflect.DeepEqual(got, test.want) { + t.Errorf("Nullify is %v, want %v", got, test.want) + } + } +} + +func TestTypes_User_ToAPI(t *testing.T) { + // setup types + want := new(api.User) + + want.SetID(1) + want.SetName("octocat") + want.SetRefreshToken("superSecretRefreshToken") + want.SetToken("superSecretToken") + want.SetFavorites([]string{"github/octocat"}) + want.SetActive(true) + want.SetAdmin(false) + want.SetDashboards([]string{"45bcf19b-c151-4e2d-b8c6-80a62ba2eae7"}) + + // run test + got := testUser().ToAPI() + + if !reflect.DeepEqual(got, want) { + t.Errorf("ToAPI is %v, want %v", got, want) + } +} + +func TestTypes_User_Validate(t *testing.T) { + // setup tests + tests := []struct { + failure bool + user *User + }{ + { + failure: false, + user: testUser(), + }, + { // no name set for user + failure: true, + user: &User{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + Token: sql.NullString{String: "superSecretToken", Valid: true}, + }, + }, + { // no token set for user + failure: true, + user: &User{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + Name: sql.NullString{String: "octocat", Valid: true}, + }, + }, + { // invalid name set for user + failure: true, + user: &User{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + Name: sql.NullString{String: "!@#$%^&*()", Valid: true}, + RefreshToken: sql.NullString{String: "superSecretRefreshToken", Valid: true}, + Token: sql.NullString{String: "superSecretToken", Valid: true}, + }, + }, + { // invalid favorites set for user + failure: true, + user: &User{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + Name: sql.NullString{String: "octocat", Valid: true}, + Token: sql.NullString{String: "superSecretToken", Valid: true}, + Favorites: exceededField(), + }, + }, + { // invalid dashboards set for user + failure: true, + user: &User{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + Name: sql.NullString{String: "octocat", Valid: true}, + Token: sql.NullString{String: "superSecretToken", Valid: true}, + Dashboards: exceededField(), + }, + }, + } + + // run tests + for _, test := range tests { + err := test.user.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 TestFromAPI(t *testing.T) { + // setup types + u := new(api.User) + + u.SetID(1) + u.SetName("octocat") + u.SetRefreshToken("superSecretRefreshToken") + u.SetToken("superSecretToken") + u.SetFavorites([]string{"github/octocat"}) + u.SetActive(true) + u.SetAdmin(false) + u.SetDashboards([]string{"45bcf19b-c151-4e2d-b8c6-80a62ba2eae7"}) + + want := testUser() + + // run test + got := UserFromAPI(u) + + if !reflect.DeepEqual(got, want) { + t.Errorf("FromAPI is %v, want %v", got, want) + } +} + +// testUser is a test helper function to create a User +// type with all fields set to a fake value. +func testUser() *User { + return &User{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + Name: sql.NullString{String: "octocat", Valid: true}, + RefreshToken: sql.NullString{String: "superSecretRefreshToken", Valid: true}, + Token: sql.NullString{String: "superSecretToken", Valid: true}, + Favorites: []string{"github/octocat"}, + Active: sql.NullBool{Bool: true, Valid: true}, + Admin: sql.NullBool{Bool: false, Valid: true}, + Dashboards: []string{"45bcf19b-c151-4e2d-b8c6-80a62ba2eae7"}, + } +} + +// exceededField returns a list of strings that exceed the maximum size of a field. +func exceededField() []string { + // initialize empty favorites + values := []string{} + + // add enough strings to exceed the character limit + for i := 0; i < 500; i++ { + // construct field + // use i to adhere to unique favorites + field := "github/octocat-" + strconv.Itoa(i) + + values = append(values, field) + } + + return values +} diff --git a/database/types/worker.go b/database/types/worker.go new file mode 100644 index 000000000..16062e65b --- /dev/null +++ b/database/types/worker.go @@ -0,0 +1,192 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "database/sql" + "errors" + "fmt" + + "github.com/lib/pq" + + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/util" + "github.com/go-vela/types/constants" +) + +var ( + // ErrEmptyWorkerHost defines the error type when a + // Worker type has an empty Host field provided. + ErrEmptyWorkerHost = errors.New("empty worker hostname provided") + + // ErrEmptyWorkerAddress defines the error type when a + // Worker type has an empty Address field provided. + ErrEmptyWorkerAddress = errors.New("empty worker address provided") + + // ErrExceededRunningBuildIDsLimit defines the error type when a + // Worker type has RunningBuildIDs field provided that exceeds the database limit. + ErrExceededRunningBuildIDsLimit = errors.New("exceeded running build ids limit") +) + +// Worker is the database representation of a worker. +type Worker struct { + ID sql.NullInt64 `sql:"id"` + Hostname sql.NullString `sql:"hostname"` + Address sql.NullString `sql:"address"` + Routes pq.StringArray `sql:"routes" gorm:"type:varchar(1000)"` + Active sql.NullBool `sql:"active"` + Status sql.NullString `sql:"status"` + LastStatusUpdateAt sql.NullInt64 `sql:"last_status_update_at"` + RunningBuildIDs pq.StringArray `sql:"running_build_ids" gorm:"type:varchar(500)"` + LastBuildStartedAt sql.NullInt64 `sql:"last_build_started_at"` + LastBuildFinishedAt sql.NullInt64 `sql:"last_build_finished_at"` + LastCheckedIn sql.NullInt64 `sql:"last_checked_in"` + BuildLimit sql.NullInt64 `sql:"build_limit"` +} + +// Nullify ensures the valid flag for +// the sql.Null types are properly set. +// +// When a field within the Build type is the zero +// value for the field, the valid flag is set to +// false causing it to be NULL in the database. +func (w *Worker) Nullify() *Worker { + if w == nil { + return nil + } + + // check if the ID field should be false + if w.ID.Int64 == 0 { + w.ID.Valid = false + } + + // check if the Hostname field should be false + if len(w.Hostname.String) == 0 { + w.Hostname.Valid = false + } + + // check if the Address field should be false + if len(w.Address.String) == 0 { + w.Address.Valid = false + } + + // check if the Status field should be false + if len(w.Status.String) == 0 { + w.Status.Valid = false + } + + // check if the LastStatusUpdateAt field should be false + if w.LastStatusUpdateAt.Int64 == 0 { + w.LastStatusUpdateAt.Valid = false + } + + // check if the LastBuildStartedAt field should be false + if w.LastBuildStartedAt.Int64 == 0 { + w.LastBuildStartedAt.Valid = false + } + + // check if the LastBuildFinishedAt field should be false + if w.LastBuildFinishedAt.Int64 == 0 { + w.LastBuildFinishedAt.Valid = false + } + + // check if the LastCheckedIn field should be false + if w.LastCheckedIn.Int64 == 0 { + w.LastCheckedIn.Valid = false + } + + if w.BuildLimit.Int64 == 0 { + w.BuildLimit.Valid = false + } + + return w +} + +// ToAPI converts the Worker type +// to an API Worker type. +func (w *Worker) ToAPI(builds []*api.Build) *api.Worker { + worker := new(api.Worker) + + worker.SetID(w.ID.Int64) + worker.SetHostname(w.Hostname.String) + worker.SetAddress(w.Address.String) + worker.SetRoutes(w.Routes) + worker.SetActive(w.Active.Bool) + worker.SetStatus(w.Status.String) + worker.SetLastStatusUpdateAt(w.LastStatusUpdateAt.Int64) + worker.SetRunningBuilds(builds) + worker.SetLastBuildStartedAt(w.LastBuildStartedAt.Int64) + worker.SetLastBuildFinishedAt(w.LastBuildFinishedAt.Int64) + worker.SetLastCheckedIn(w.LastCheckedIn.Int64) + worker.SetBuildLimit(w.BuildLimit.Int64) + + return worker +} + +// Validate verifies the necessary fields for +// the Worker type are populated correctly. +func (w *Worker) Validate() error { + // verify the Host field is populated + if len(w.Hostname.String) == 0 { + return ErrEmptyWorkerHost + } + + // verify the Address field is populated + if len(w.Address.String) == 0 { + return ErrEmptyWorkerAddress + } + + // calculate total size of RunningBuildIds + total := 0 + for _, f := range w.RunningBuildIDs { + total += len(f) + } + + // verify the RunningBuildIds field is within the database constraints + // len is to factor in number of comma separators included in the database field, + // removing 1 due to the last item not having an appended comma + if (total + len(w.RunningBuildIDs) - 1) > constants.RunningBuildIDsMaxSize { + return ErrExceededRunningBuildIDsLimit + } + + // ensure that all Worker string fields + // that can be returned as JSON are sanitized + // to avoid unsafe HTML content + w.Hostname = sql.NullString{String: util.Sanitize(w.Hostname.String), Valid: w.Hostname.Valid} + w.Address = sql.NullString{String: util.Sanitize(w.Address.String), Valid: w.Address.Valid} + + // ensure that all Routes are sanitized + // to avoid unsafe HTML content + for i, v := range w.Routes { + w.Routes[i] = util.Sanitize(v) + } + + return nil +} + +// WorkerFromAPI converts the API worker type +// to a database worker type. +func WorkerFromAPI(w *api.Worker) *Worker { + var rBs []string + + for _, b := range w.GetRunningBuilds() { + rBs = append(rBs, fmt.Sprint(b.GetID())) + } + + worker := &Worker{ + ID: sql.NullInt64{Int64: w.GetID(), Valid: true}, + Hostname: sql.NullString{String: w.GetHostname(), Valid: true}, + Address: sql.NullString{String: w.GetAddress(), Valid: true}, + Routes: pq.StringArray(w.GetRoutes()), + Active: sql.NullBool{Bool: w.GetActive(), Valid: true}, + Status: sql.NullString{String: w.GetStatus(), Valid: true}, + LastStatusUpdateAt: sql.NullInt64{Int64: w.GetLastStatusUpdateAt(), Valid: true}, + RunningBuildIDs: pq.StringArray(rBs), + LastBuildStartedAt: sql.NullInt64{Int64: w.GetLastBuildStartedAt(), Valid: true}, + LastBuildFinishedAt: sql.NullInt64{Int64: w.GetLastBuildFinishedAt(), Valid: true}, + LastCheckedIn: sql.NullInt64{Int64: w.GetLastCheckedIn(), Valid: true}, + BuildLimit: sql.NullInt64{Int64: w.GetBuildLimit(), Valid: true}, + } + + return worker.Nullify() +} diff --git a/database/types/worker_test.go b/database/types/worker_test.go new file mode 100644 index 000000000..ec835d1f1 --- /dev/null +++ b/database/types/worker_test.go @@ -0,0 +1,212 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "database/sql" + "reflect" + "strconv" + "testing" + + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" +) + +func TestTypes_Worker_Nullify(t *testing.T) { + // setup types + var w *Worker + + want := &Worker{ + ID: sql.NullInt64{Int64: 0, Valid: false}, + Hostname: sql.NullString{String: "", Valid: false}, + Address: sql.NullString{String: "", Valid: false}, + Active: sql.NullBool{Bool: false, Valid: false}, + Status: sql.NullString{String: "", Valid: false}, + LastStatusUpdateAt: sql.NullInt64{Int64: 0, Valid: false}, + LastBuildStartedAt: sql.NullInt64{Int64: 0, Valid: false}, + LastBuildFinishedAt: sql.NullInt64{Int64: 0, Valid: false}, + LastCheckedIn: sql.NullInt64{Int64: 0, Valid: false}, + BuildLimit: sql.NullInt64{Int64: 0, Valid: false}, + } + + // setup tests + tests := []struct { + repo *Worker + want *Worker + }{ + { + repo: testWorker(), + want: testWorker(), + }, + { + repo: w, + want: nil, + }, + { + repo: new(Worker), + want: want, + }, + } + + // run tests + for _, test := range tests { + got := test.repo.Nullify() + + if !reflect.DeepEqual(got, test.want) { + t.Errorf("Nullify is %v, want %v", got, test.want) + } + } +} + +func TestTypes_Worker_ToAPI(t *testing.T) { + // setup types + rB := testutils.APIBuild() + rB.SetID(1) + + want := new(api.Worker) + + want.SetID(1) + want.SetHostname("worker_0") + want.SetAddress("http://localhost:8080") + want.SetRoutes([]string{"vela"}) + want.SetActive(true) + want.SetStatus("available") + want.SetLastStatusUpdateAt(1563474077) + want.SetRunningBuilds([]*api.Build{rB}) + want.SetLastBuildStartedAt(1563474077) + want.SetLastBuildFinishedAt(1563474077) + want.SetLastCheckedIn(1563474077) + want.SetBuildLimit(2) + + // run test + got := testWorker().ToAPI(want.GetRunningBuilds()) + + if !reflect.DeepEqual(got, want) { + t.Errorf("ToAPI is %v, want %v", got, want) + } +} + +func TestTypes_Worker_Validate(t *testing.T) { + // setup tests + tests := []struct { + failure bool + worker *Worker + }{ + { + failure: false, + worker: testWorker(), + }, + { // no Hostname set for worker + failure: true, + worker: &Worker{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + Address: sql.NullString{String: "http://localhost:8080", Valid: true}, + Active: sql.NullBool{Bool: true, Valid: true}, + LastCheckedIn: sql.NullInt64{Int64: 1563474077, Valid: true}, + }, + }, + { // no Address set for worker + failure: true, + worker: &Worker{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + Hostname: sql.NullString{String: "worker_0", Valid: true}, + Active: sql.NullBool{Bool: true, Valid: true}, + LastCheckedIn: sql.NullInt64{Int64: 1563474077, Valid: true}, + }, + }, + { // invalid RunningBuildIDs set for worker + failure: true, + worker: &Worker{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + Address: sql.NullString{String: "http://localhost:8080", Valid: true}, + Hostname: sql.NullString{String: "worker_0", Valid: true}, + Active: sql.NullBool{Bool: true, Valid: true}, + RunningBuildIDs: exceededRunningBuildIDs(), + LastCheckedIn: sql.NullInt64{Int64: 1563474077, Valid: true}, + }, + }, + } + + // run tests + for _, test := range tests { + err := test.worker.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 TestTypes_Worker_WorkerFromAPI(t *testing.T) { + // setup types + rB := testutils.APIBuild() + rB.SetID(1) + + w := new(api.Worker) + + w.SetID(1) + w.SetHostname("worker_0") + w.SetAddress("http://localhost:8080") + w.SetRoutes([]string{"vela"}) + w.SetActive(true) + w.SetStatus("available") + w.SetLastStatusUpdateAt(1563474077) + w.SetRunningBuilds([]*api.Build{rB}) + w.SetLastBuildStartedAt(1563474077) + w.SetLastBuildFinishedAt(1563474077) + w.SetLastCheckedIn(1563474077) + w.SetBuildLimit(2) + + want := testWorker() + + // run test + got := WorkerFromAPI(w) + + if !reflect.DeepEqual(got, want) { + t.Errorf("WorkerFromLibrary is %v, want %v", got, want) + } +} + +// testWorker is a test helper function to create a Worker +// type with all fields set to a fake value. +func testWorker() *Worker { + return &Worker{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + Hostname: sql.NullString{String: "worker_0", Valid: true}, + Address: sql.NullString{String: "http://localhost:8080", Valid: true}, + Routes: []string{"vela"}, + Active: sql.NullBool{Bool: true, Valid: true}, + Status: sql.NullString{String: "available", Valid: true}, + LastStatusUpdateAt: sql.NullInt64{Int64: 1563474077, Valid: true}, + RunningBuildIDs: []string{"1"}, + LastBuildStartedAt: sql.NullInt64{Int64: 1563474077, Valid: true}, + LastBuildFinishedAt: sql.NullInt64{Int64: 1563474077, Valid: true}, + LastCheckedIn: sql.NullInt64{Int64: 1563474077, Valid: true}, + BuildLimit: sql.NullInt64{Int64: 2, Valid: true}, + } +} + +// exceededRunningBuildIDs returns a list of valid running builds that exceed the maximum size. +func exceededRunningBuildIDs() []string { + // initialize empty runningBuildIDs + runningBuildIDs := []string{} + + // add enough build ids to exceed the character limit + for i := 0; i < 50; i++ { + // construct runningBuildID + // use i to adhere to unique runningBuildIDs + runningBuildID := "1234567890-" + strconv.Itoa(i) + + runningBuildIDs = append(runningBuildIDs, runningBuildID) + } + + return runningBuildIDs +} diff --git a/database/user/count_test.go b/database/user/count_test.go index fd88de828..ebeb32181 100644 --- a/database/user/count_test.go +++ b/database/user/count_test.go @@ -8,16 +8,18 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestUser_Engine_CountUsers(t *testing.T) { // setup types - _userOne := testAPIUser() + _userOne := testutils.APIUser() _userOne.SetID(1) _userOne.SetName("foo") _userOne.SetToken("bar") - _userTwo := testAPIUser() + _userTwo := testutils.APIUser() _userTwo.SetID(2) _userTwo.SetName("baz") _userTwo.SetToken("bar") diff --git a/database/user/create.go b/database/user/create.go index cd6b9a761..b8cb1e59d 100644 --- a/database/user/create.go +++ b/database/user/create.go @@ -10,6 +10,7 @@ import ( "github.com/sirupsen/logrus" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" ) @@ -20,7 +21,7 @@ func (e *engine) CreateUser(ctx context.Context, u *api.User) (*api.User, error) }).Tracef("creating user %s in the database", u.GetName()) // cast the API type to database type - user := FromAPI(u) + user := types.UserFromAPI(u) // validate the necessary fields are populated // diff --git a/database/user/create_test.go b/database/user/create_test.go index 988cac912..97dea7f3e 100644 --- a/database/user/create_test.go +++ b/database/user/create_test.go @@ -8,11 +8,13 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestUser_Engine_CreateUser(t *testing.T) { // setup types - _user := testAPIUser() + _user := testutils.APIUser() _user.SetID(1) _user.SetName("foo") _user.SetToken("bar") diff --git a/database/user/delete.go b/database/user/delete.go index 848e08ca5..b7a7be169 100644 --- a/database/user/delete.go +++ b/database/user/delete.go @@ -8,6 +8,7 @@ import ( "github.com/sirupsen/logrus" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" ) @@ -18,7 +19,7 @@ func (e *engine) DeleteUser(ctx context.Context, u *api.User) error { }).Tracef("deleting user %s from the database", u.GetName()) // cast the API type to database type - user := FromAPI(u) + user := types.UserFromAPI(u) // send query to the database return e.client. diff --git a/database/user/delete_test.go b/database/user/delete_test.go index 6926929d9..2a282d856 100644 --- a/database/user/delete_test.go +++ b/database/user/delete_test.go @@ -7,11 +7,13 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestUser_Engine_DeleteUser(t *testing.T) { // setup types - _user := testAPIUser() + _user := testutils.APIUser() _user.SetID(1) _user.SetName("foo") _user.SetToken("bar") diff --git a/database/user/get.go b/database/user/get.go index 90e16a46e..e0f8d45d9 100644 --- a/database/user/get.go +++ b/database/user/get.go @@ -6,6 +6,7 @@ import ( "context" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" ) @@ -14,7 +15,7 @@ func (e *engine) GetUser(ctx context.Context, id int64) (*api.User, error) { e.logger.Tracef("getting user %d from the database", id) // variable to store query results - u := new(User) + u := new(types.User) // send query to the database and store result in variable err := e.client. diff --git a/database/user/get_name.go b/database/user/get_name.go index 87dd13bea..f74c07166 100644 --- a/database/user/get_name.go +++ b/database/user/get_name.go @@ -8,6 +8,7 @@ import ( "github.com/sirupsen/logrus" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" ) @@ -18,7 +19,7 @@ func (e *engine) GetUserForName(ctx context.Context, name string) (*api.User, er }).Tracef("getting user %s from the database", name) // variable to store query results - u := new(User) + u := new(types.User) // send query to the database and store result in variable err := e.client. diff --git a/database/user/get_name_test.go b/database/user/get_name_test.go index 72a9c1e08..b4bbe7f74 100644 --- a/database/user/get_name_test.go +++ b/database/user/get_name_test.go @@ -10,11 +10,12 @@ import ( "github.com/DATA-DOG/go-sqlmock" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" ) func TestUser_Engine_GetUserForName(t *testing.T) { // setup types - _user := testAPIUser() + _user := testutils.APIUser() _user.SetID(1) _user.SetName("foo") _user.SetToken("bar") diff --git a/database/user/get_test.go b/database/user/get_test.go index 213da30f8..3981799f3 100644 --- a/database/user/get_test.go +++ b/database/user/get_test.go @@ -10,11 +10,12 @@ import ( "github.com/DATA-DOG/go-sqlmock" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" ) func TestUser_Engine_GetUser(t *testing.T) { // setup types - _user := testAPIUser() + _user := testutils.APIUser() _user.SetID(1) _user.SetName("foo") _user.SetToken("bar") diff --git a/database/user/list.go b/database/user/list.go index 0fed81070..29b53f7f0 100644 --- a/database/user/list.go +++ b/database/user/list.go @@ -6,6 +6,7 @@ import ( "context" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" ) @@ -15,7 +16,7 @@ func (e *engine) ListUsers(ctx context.Context) ([]*api.User, error) { // variables to store query results and return value count := int64(0) - u := new([]User) + u := new([]types.User) users := []*api.User{} // count the results diff --git a/database/user/list_lite.go b/database/user/list_lite.go index 809b9c83f..d3ca1c49a 100644 --- a/database/user/list_lite.go +++ b/database/user/list_lite.go @@ -6,6 +6,7 @@ import ( "context" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" ) @@ -17,7 +18,7 @@ func (e *engine) ListLiteUsers(ctx context.Context, page, perPage int) ([]*api.U // variables to store query results and return values count := int64(0) - u := new([]User) + u := new([]types.User) users := []*api.User{} // count the results diff --git a/database/user/list_lite_test.go b/database/user/list_lite_test.go index 6f2888e50..31a4b1f0f 100644 --- a/database/user/list_lite_test.go +++ b/database/user/list_lite_test.go @@ -10,18 +10,19 @@ import ( "github.com/DATA-DOG/go-sqlmock" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" ) func TestUser_Engine_ListLiteUsers(t *testing.T) { // setup types - _userOne := testAPIUser() + _userOne := testutils.APIUser() _userOne.SetID(1) _userOne.SetName("foo") _userOne.SetToken("bar") _userOne.SetFavorites([]string{}) _userOne.SetDashboards([]string{}) - _userTwo := testAPIUser() + _userTwo := testutils.APIUser() _userTwo.SetID(2) _userTwo.SetName("baz") _userTwo.SetToken("bar") diff --git a/database/user/list_test.go b/database/user/list_test.go index 01a847ea8..ce2e7b3f7 100644 --- a/database/user/list_test.go +++ b/database/user/list_test.go @@ -10,18 +10,19 @@ import ( "github.com/DATA-DOG/go-sqlmock" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" ) func TestUser_Engine_ListUsers(t *testing.T) { // setup types - _userOne := testAPIUser() + _userOne := testutils.APIUser() _userOne.SetID(1) _userOne.SetName("foo") _userOne.SetToken("bar") _userOne.SetFavorites([]string{}) _userOne.SetDashboards([]string{}) - _userTwo := testAPIUser() + _userTwo := testutils.APIUser() _userTwo.SetID(2) _userTwo.SetName("baz") _userTwo.SetToken("bar") diff --git a/database/user/update.go b/database/user/update.go index 2779e6497..b785352eb 100644 --- a/database/user/update.go +++ b/database/user/update.go @@ -10,6 +10,7 @@ import ( "github.com/sirupsen/logrus" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" ) @@ -20,7 +21,7 @@ func (e *engine) UpdateUser(ctx context.Context, u *api.User) (*api.User, error) }).Tracef("updating user %s in the database", u.GetName()) // cast the library type to database type - user := FromAPI(u) + user := types.UserFromAPI(u) // validate the necessary fields are populated err := user.Validate() diff --git a/database/user/update_test.go b/database/user/update_test.go index 5fbb7ed8b..8170c6375 100644 --- a/database/user/update_test.go +++ b/database/user/update_test.go @@ -8,11 +8,13 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" ) func TestUser_Engine_UpdateUser(t *testing.T) { // setup types - _user := testAPIUser() + _user := testutils.APIUser() _user.SetID(1) _user.SetName("foo") _user.SetToken("bar") diff --git a/database/user/user.go b/database/user/user.go index a29295cbb..23948bfb3 100644 --- a/database/user/user.go +++ b/database/user/user.go @@ -4,51 +4,14 @@ package user import ( "context" - "database/sql" - "encoding/base64" - "errors" "fmt" - "regexp" - "github.com/lib/pq" "github.com/sirupsen/logrus" "gorm.io/gorm" - api "github.com/go-vela/server/api/types" - "github.com/go-vela/server/util" "github.com/go-vela/types/constants" ) -var ( - // userRegex defines the regex pattern for validating - // the Name field for the User type. - userRegex = regexp.MustCompile("^[a-zA-Z0-9_-]{0,38}$") - - // ErrEmptyUserName defines the error type when a - // User type has an empty Name field provided. - ErrEmptyUserName = errors.New("empty user name provided") - - // ErrEmptyUserRefreshToken defines the error type when a - // User type has an empty RefreshToken field provided. - ErrEmptyUserRefreshToken = errors.New("empty user refresh token provided") - - // ErrEmptyUserToken defines the error type when a - // User type has an empty Token field provided. - ErrEmptyUserToken = errors.New("empty user token provided") - - // ErrInvalidUserName defines the error type when a - // User type has an invalid Name field provided. - ErrInvalidUserName = errors.New("invalid user name provided") - - // ErrExceededFavoritesLimit defines the error type when a - // User type has Favorites field provided that exceeds the database limit. - ErrExceededFavoritesLimit = errors.New("exceeded favorites limit") - - // ErrExceededDashboardsLimit defines the error type when a - // User type has Dashboards field provided that exceeds the database limit. - ErrExceededDashboardsLimit = errors.New("exceeded dashboards limit") -) - type ( // config represents the settings required to create the engine that implements the UserInterface interface. config struct { @@ -75,18 +38,6 @@ type ( // https://pkg.go.dev/github.com/sirupsen/logrus#Entry logger *logrus.Entry } - - // User is the database representation of a user. - User struct { - ID sql.NullInt64 `sql:"id"` - Name sql.NullString `sql:"name"` - RefreshToken sql.NullString `sql:"refresh_token"` - Token sql.NullString `sql:"token"` - Favorites pq.StringArray `sql:"favorites" gorm:"type:varchar(5000)"` - Active sql.NullBool `sql:"active"` - Admin sql.NullBool `sql:"admin"` - Dashboards pq.StringArray `sql:"dashboards" gorm:"type:varchar(5000)"` - } ) // New creates and returns a Vela service for integrating with users in the database. @@ -130,206 +81,3 @@ func New(opts ...EngineOpt) (*engine, error) { return e, nil } - -// Decrypt will manipulate the existing user tokens by -// base64 decoding them. Then, a AES-256 cipher -// block is created from the encryption key in order to -// decrypt the base64 decoded user tokens. -func (u *User) Decrypt(key string) error { - // base64 decode the encrypted user token - decoded, err := base64.StdEncoding.DecodeString(u.Token.String) - if err != nil { - return err - } - - // decrypt the base64 decoded user token - decrypted, err := util.Decrypt(key, decoded) - if err != nil { - return err - } - - // set the decrypted user token - u.Token = sql.NullString{ - String: string(decrypted), - Valid: true, - } - - // base64 decode the encrypted user refresh token - decoded, err = base64.StdEncoding.DecodeString(u.RefreshToken.String) - if err != nil { - return err - } - - // decrypt the base64 decoded user refresh token - decrypted, err = util.Decrypt(key, decoded) - if err != nil { - return err - } - - // set the decrypted user refresh token - u.RefreshToken = sql.NullString{ - String: string(decrypted), - Valid: true, - } - - return nil -} - -// Encrypt will manipulate the existing user tokens by -// creating a AES-256 cipher block from the encryption -// key in order to encrypt the user tokens. Then, the -// user tokens are base64 encoded for transport across -// network boundaries. -func (u *User) Encrypt(key string) error { - // encrypt the user token - encrypted, err := util.Encrypt(key, []byte(u.Token.String)) - if err != nil { - return err - } - - // base64 encode the encrypted user token to make it network safe - u.Token = sql.NullString{ - String: base64.StdEncoding.EncodeToString(encrypted), - Valid: true, - } - - // encrypt the user refresh token - encrypted, err = util.Encrypt(key, []byte(u.RefreshToken.String)) - if err != nil { - return err - } - - // base64 encode the encrypted user refresh token to make it network safe - u.RefreshToken = sql.NullString{ - String: base64.StdEncoding.EncodeToString(encrypted), - Valid: true, - } - - return nil -} - -// Nullify ensures the valid flag for -// the sql.Null types are properly set. -// -// When a field within the User type is the zero -// value for the field, the valid flag is set to -// false causing it to be NULL in the database. -func (u *User) Nullify() *User { - if u == nil { - return nil - } - - // check if the ID field should be false - if u.ID.Int64 == 0 { - u.ID.Valid = false - } - - // check if the Name field should be false - if len(u.Name.String) == 0 { - u.Name.Valid = false - } - - // check if the RefreshToken field should be false - if len(u.RefreshToken.String) == 0 { - u.RefreshToken.Valid = false - } - - // check if the Token field should be false - if len(u.Token.String) == 0 { - u.Token.Valid = false - } - - return u -} - -// ToAPI converts the User type -// to an API User type. -func (u *User) ToAPI() *api.User { - user := new(api.User) - - user.SetID(u.ID.Int64) - user.SetName(u.Name.String) - user.SetRefreshToken(u.RefreshToken.String) - user.SetToken(u.Token.String) - user.SetActive(u.Active.Bool) - user.SetAdmin(u.Admin.Bool) - user.SetFavorites(u.Favorites) - user.SetDashboards(u.Dashboards) - - return user -} - -// Validate verifies the necessary fields for -// the User type are populated correctly. -func (u *User) Validate() error { - // verify the Name field is populated - if len(u.Name.String) == 0 { - return ErrEmptyUserName - } - - // verify the Token field is populated - if len(u.Token.String) == 0 { - return ErrEmptyUserToken - } - - // verify the Name field is valid - if !userRegex.MatchString(u.Name.String) { - return ErrInvalidUserName - } - - // calculate totalFavorites size of favorites - totalFavorites := 0 - for _, f := range u.Favorites { - totalFavorites += len(f) - } - - // verify the Favorites field is within the database constraints - // len is to factor in number of comma separators included in the database field, - // removing 1 due to the last item not having an appended comma - if (totalFavorites + len(u.Favorites) - 1) > constants.FavoritesMaxSize { - return ErrExceededFavoritesLimit - } - - // calculate totalDashboards size of dashboards - totalDashboards := 0 - for _, d := range u.Dashboards { - totalDashboards += len(d) - } - - // verify the Dashboards field is within the database constraints - // len is to factor in number of comma separators included in the database field, - // removing 1 due to the last item not having an appended comma - if (totalDashboards + len(u.Dashboards) - 1) > constants.FavoritesMaxSize { - return ErrExceededDashboardsLimit - } - - // ensure that all User string fields - // that can be returned as JSON are sanitized - // to avoid unsafe HTML content - u.Name = sql.NullString{String: util.Sanitize(u.Name.String), Valid: u.Name.Valid} - - // ensure that all Favorites are sanitized - // to avoid unsafe HTML content - for i, v := range u.Favorites { - u.Favorites[i] = util.Sanitize(v) - } - - return nil -} - -// FromAPI converts the API User type -// to a database User type. -func FromAPI(u *api.User) *User { - user := &User{ - ID: sql.NullInt64{Int64: u.GetID(), Valid: true}, - Name: sql.NullString{String: u.GetName(), Valid: true}, - RefreshToken: sql.NullString{String: u.GetRefreshToken(), Valid: true}, - Token: sql.NullString{String: u.GetToken(), Valid: true}, - Active: sql.NullBool{Bool: u.GetActive(), Valid: true}, - Admin: sql.NullBool{Bool: u.GetAdmin(), Valid: true}, - Favorites: pq.StringArray(u.GetFavorites()), - Dashboards: pq.StringArray(u.GetDashboards()), - } - - return user.Nullify() -} diff --git a/database/user/user_test.go b/database/user/user_test.go index 287ee9508..8e33e6e62 100644 --- a/database/user/user_test.go +++ b/database/user/user_test.go @@ -3,10 +3,8 @@ package user import ( - "database/sql" "database/sql/driver" "reflect" - "strconv" "testing" "github.com/DATA-DOG/go-sqlmock" @@ -14,8 +12,6 @@ import ( "gorm.io/driver/postgres" "gorm.io/driver/sqlite" "gorm.io/gorm" - - api "github.com/go-vela/server/api/types" ) func TestUser_New(t *testing.T) { @@ -172,21 +168,6 @@ func testSqlite(t *testing.T) *engine { return _engine } -// testAPIUser is a test helper function to create an API -// User type with all fields set to their zero values. -func testAPIUser() *api.User { - return &api.User{ - ID: new(int64), - Name: new(string), - RefreshToken: new(string), - Token: new(string), - Favorites: new([]string), - Active: new(bool), - Admin: new(bool), - Dashboards: new([]string), - } -} - // This will be used with the github.com/DATA-DOG/go-sqlmock library to compare values // that are otherwise not easily compared. These typically would be values generated // before adding or updating them in the database. @@ -198,283 +179,3 @@ type AnyArgument struct{} func (a AnyArgument) Match(_ driver.Value) bool { return true } - -func TestUser_Decrypt(t *testing.T) { - // setup types - key := "C639A572E14D5075C526FDDD43E4ECF6" - encrypted := testUser() - - err := encrypted.Encrypt(key) - if err != nil { - t.Errorf("unable to encrypt user: %v", err) - } - - // setup tests - tests := []struct { - failure bool - key string - user User - }{ - { - failure: false, - key: key, - user: *encrypted, - }, - { - failure: true, - key: "", - user: *encrypted, - }, - { - failure: true, - key: key, - user: *testUser(), - }, - } - - // run tests - for _, test := range tests { - err := test.user.Decrypt(test.key) - - if test.failure { - if err == nil { - t.Errorf("Decrypt should have returned err") - } - - continue - } - - if err != nil { - t.Errorf("Decrypt returned err: %v", err) - } - } -} - -func TestUser_Encrypt(t *testing.T) { - // setup types - key := "C639A572E14D5075C526FDDD43E4ECF6" - - // setup tests - tests := []struct { - failure bool - key string - user *User - }{ - { - failure: false, - key: key, - user: testUser(), - }, - { - failure: true, - key: "", - user: testUser(), - }, - } - - // run tests - for _, test := range tests { - err := test.user.Encrypt(test.key) - - if test.failure { - if err == nil { - t.Errorf("Encrypt should have returned err") - } - - continue - } - - if err != nil { - t.Errorf("Encrypt returned err: %v", err) - } - } -} - -func TestUser_Nullify(t *testing.T) { - // setup types - var u *User - - want := &User{ - ID: sql.NullInt64{Int64: 0, Valid: false}, - Name: sql.NullString{String: "", Valid: false}, - RefreshToken: sql.NullString{String: "", Valid: false}, - Token: sql.NullString{String: "", Valid: false}, - Active: sql.NullBool{Bool: false, Valid: false}, - Admin: sql.NullBool{Bool: false, Valid: false}, - } - - // setup tests - tests := []struct { - user *User - want *User - }{ - { - user: testUser(), - want: testUser(), - }, - { - user: u, - want: nil, - }, - { - user: new(User), - want: want, - }, - } - - // run tests - for _, test := range tests { - got := test.user.Nullify() - - if !reflect.DeepEqual(got, test.want) { - t.Errorf("Nullify is %v, want %v", got, test.want) - } - } -} - -func TestUser_ToAPI(t *testing.T) { - // setup types - want := new(api.User) - - want.SetID(1) - want.SetName("octocat") - want.SetRefreshToken("superSecretRefreshToken") - want.SetToken("superSecretToken") - want.SetFavorites([]string{"github/octocat"}) - want.SetActive(true) - want.SetAdmin(false) - want.SetDashboards([]string{"45bcf19b-c151-4e2d-b8c6-80a62ba2eae7"}) - - // run test - got := testUser().ToAPI() - - if !reflect.DeepEqual(got, want) { - t.Errorf("ToAPI is %v, want %v", got, want) - } -} - -func TestUser_Validate(t *testing.T) { - // setup tests - tests := []struct { - failure bool - user *User - }{ - { - failure: false, - user: testUser(), - }, - { // no name set for user - failure: true, - user: &User{ - ID: sql.NullInt64{Int64: 1, Valid: true}, - Token: sql.NullString{String: "superSecretToken", Valid: true}, - }, - }, - { // no token set for user - failure: true, - user: &User{ - ID: sql.NullInt64{Int64: 1, Valid: true}, - Name: sql.NullString{String: "octocat", Valid: true}, - }, - }, - { // invalid name set for user - failure: true, - user: &User{ - ID: sql.NullInt64{Int64: 1, Valid: true}, - Name: sql.NullString{String: "!@#$%^&*()", Valid: true}, - RefreshToken: sql.NullString{String: "superSecretRefreshToken", Valid: true}, - Token: sql.NullString{String: "superSecretToken", Valid: true}, - }, - }, - { // invalid favorites set for user - failure: true, - user: &User{ - ID: sql.NullInt64{Int64: 1, Valid: true}, - Name: sql.NullString{String: "octocat", Valid: true}, - Token: sql.NullString{String: "superSecretToken", Valid: true}, - Favorites: exceededField(), - }, - }, - { // invalid dashboards set for user - failure: true, - user: &User{ - ID: sql.NullInt64{Int64: 1, Valid: true}, - Name: sql.NullString{String: "octocat", Valid: true}, - Token: sql.NullString{String: "superSecretToken", Valid: true}, - Dashboards: exceededField(), - }, - }, - } - - // run tests - for _, test := range tests { - err := test.user.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 TestFromAPI(t *testing.T) { - // setup types - u := new(api.User) - - u.SetID(1) - u.SetName("octocat") - u.SetRefreshToken("superSecretRefreshToken") - u.SetToken("superSecretToken") - u.SetFavorites([]string{"github/octocat"}) - u.SetActive(true) - u.SetAdmin(false) - u.SetDashboards([]string{"45bcf19b-c151-4e2d-b8c6-80a62ba2eae7"}) - - want := testUser() - - // run test - got := FromAPI(u) - - if !reflect.DeepEqual(got, want) { - t.Errorf("FromAPI is %v, want %v", got, want) - } -} - -// testUser is a test helper function to create a User -// type with all fields set to a fake value. -func testUser() *User { - return &User{ - ID: sql.NullInt64{Int64: 1, Valid: true}, - Name: sql.NullString{String: "octocat", Valid: true}, - RefreshToken: sql.NullString{String: "superSecretRefreshToken", Valid: true}, - Token: sql.NullString{String: "superSecretToken", Valid: true}, - Favorites: []string{"github/octocat"}, - Active: sql.NullBool{Bool: true, Valid: true}, - Admin: sql.NullBool{Bool: false, Valid: true}, - Dashboards: []string{"45bcf19b-c151-4e2d-b8c6-80a62ba2eae7"}, - } -} - -// exceededField returns a list of strings that exceed the maximum size of a field. -func exceededField() []string { - // initialize empty favorites - values := []string{} - - // add enough strings to exceed the character limit - for i := 0; i < 500; i++ { - // construct field - // use i to adhere to unique favorites - field := "github/octocat-" + strconv.Itoa(i) - - values = append(values, field) - } - - return values -} diff --git a/database/worker/create.go b/database/worker/create.go index 43232a71d..c566ecd0e 100644 --- a/database/worker/create.go +++ b/database/worker/create.go @@ -8,6 +8,7 @@ import ( "github.com/sirupsen/logrus" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" ) @@ -20,7 +21,7 @@ func (e *engine) CreateWorker(ctx context.Context, w *api.Worker) (*api.Worker, // cast the library type to database type // // https://pkg.go.dev/github.com/go-vela/types/database#WorkerFromLibrary - worker := FromAPI(w) + worker := types.WorkerFromAPI(w) // validate the necessary fields are populated // diff --git a/database/worker/delete.go b/database/worker/delete.go index a20e46487..4972efc98 100644 --- a/database/worker/delete.go +++ b/database/worker/delete.go @@ -8,6 +8,7 @@ import ( "github.com/sirupsen/logrus" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" ) @@ -20,7 +21,7 @@ func (e *engine) DeleteWorker(ctx context.Context, w *api.Worker) error { // cast the library type to database type // // https://pkg.go.dev/github.com/go-vela/types/database#WorkerFromLibrary - worker := FromAPI(w) + worker := types.WorkerFromAPI(w) // send query to the database return e.client. diff --git a/database/worker/get.go b/database/worker/get.go index 7531fd05a..7aca60b76 100644 --- a/database/worker/get.go +++ b/database/worker/get.go @@ -6,6 +6,7 @@ import ( "context" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" ) @@ -14,7 +15,7 @@ func (e *engine) GetWorker(ctx context.Context, id int64) (*api.Worker, error) { e.logger.Tracef("getting worker %d from the database", id) // variable to store query results - w := new(Worker) + w := new(types.Worker) // send query to the database and store result in variable err := e.client. diff --git a/database/worker/get_hostname.go b/database/worker/get_hostname.go index 6f046f8dd..ec37b9200 100644 --- a/database/worker/get_hostname.go +++ b/database/worker/get_hostname.go @@ -8,6 +8,7 @@ import ( "github.com/sirupsen/logrus" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" ) @@ -18,7 +19,7 @@ func (e *engine) GetWorkerForHostname(ctx context.Context, hostname string) (*ap }).Tracef("getting worker %s from the database", hostname) // variable to store query results - w := new(Worker) + w := new(types.Worker) // send query to the database and store result in variable err := e.client. diff --git a/database/worker/list.go b/database/worker/list.go index daa9a7e06..a8adc1a79 100644 --- a/database/worker/list.go +++ b/database/worker/list.go @@ -8,6 +8,7 @@ import ( "strconv" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" ) @@ -16,7 +17,7 @@ func (e *engine) ListWorkers(ctx context.Context, active string, before, after i e.logger.Trace("listing all workers from the database") // variables to store query results and return value - results := new([]Worker) + results := new([]types.Worker) workers := []*api.Worker{} // build query with checked in constraints diff --git a/database/worker/update.go b/database/worker/update.go index 4626ce746..996d0c0af 100644 --- a/database/worker/update.go +++ b/database/worker/update.go @@ -8,6 +8,7 @@ import ( "github.com/sirupsen/logrus" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" ) @@ -20,7 +21,7 @@ func (e *engine) UpdateWorker(ctx context.Context, w *api.Worker) (*api.Worker, // cast the library type to database type // // https://pkg.go.dev/github.com/go-vela/types/database#WorkerFromLibrary - worker := FromAPI(w) + worker := types.WorkerFromAPI(w) // validate the necessary fields are populated // diff --git a/database/worker/worker.go b/database/worker/worker.go index f05c7198c..18e4d90d9 100644 --- a/database/worker/worker.go +++ b/database/worker/worker.go @@ -4,33 +4,14 @@ package worker import ( "context" - "database/sql" - "errors" "fmt" "strconv" - "github.com/lib/pq" "github.com/sirupsen/logrus" "gorm.io/gorm" api "github.com/go-vela/server/api/types" - "github.com/go-vela/server/util" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" -) - -var ( - // ErrEmptyWorkerHost defines the error type when a - // Worker type has an empty Host field provided. - ErrEmptyWorkerHost = errors.New("empty worker hostname provided") - - // ErrEmptyWorkerAddress defines the error type when a - // Worker type has an empty Address field provided. - ErrEmptyWorkerAddress = errors.New("empty worker address provided") - - // ErrExceededRunningBuildIDsLimit defines the error type when a - // Worker type has RunningBuildIDs field provided that exceeds the database limit. - ErrExceededRunningBuildIDsLimit = errors.New("exceeded running build ids limit") ) type ( @@ -57,22 +38,6 @@ type ( // https://pkg.go.dev/github.com/sirupsen/logrus#Entry logger *logrus.Entry } - - // Worker is the database representation of a worker. - Worker struct { - ID sql.NullInt64 `sql:"id"` - Hostname sql.NullString `sql:"hostname"` - Address sql.NullString `sql:"address"` - Routes pq.StringArray `sql:"routes" gorm:"type:varchar(1000)"` - Active sql.NullBool `sql:"active"` - Status sql.NullString `sql:"status"` - LastStatusUpdateAt sql.NullInt64 `sql:"last_status_update_at"` - RunningBuildIDs pq.StringArray `sql:"running_build_ids" gorm:"type:varchar(500)"` - LastBuildStartedAt sql.NullInt64 `sql:"last_build_started_at"` - LastBuildFinishedAt sql.NullInt64 `sql:"last_build_finished_at"` - LastCheckedIn sql.NullInt64 `sql:"last_checked_in"` - BuildLimit sql.NullInt64 `sql:"build_limit"` - } ) // New creates and returns a Vela service for integrating with workers in the database. @@ -117,157 +82,10 @@ func New(opts ...EngineOpt) (*engine, error) { return e, nil } -// Nullify ensures the valid flag for -// the sql.Null types are properly set. -// -// When a field within the Build type is the zero -// value for the field, the valid flag is set to -// false causing it to be NULL in the database. -func (w *Worker) Nullify() *Worker { - if w == nil { - return nil - } - - // check if the ID field should be false - if w.ID.Int64 == 0 { - w.ID.Valid = false - } - - // check if the Hostname field should be false - if len(w.Hostname.String) == 0 { - w.Hostname.Valid = false - } - - // check if the Address field should be false - if len(w.Address.String) == 0 { - w.Address.Valid = false - } - - // check if the Status field should be false - if len(w.Status.String) == 0 { - w.Status.Valid = false - } - - // check if the LastStatusUpdateAt field should be false - if w.LastStatusUpdateAt.Int64 == 0 { - w.LastStatusUpdateAt.Valid = false - } - - // check if the LastBuildStartedAt field should be false - if w.LastBuildStartedAt.Int64 == 0 { - w.LastBuildStartedAt.Valid = false - } - - // check if the LastBuildFinishedAt field should be false - if w.LastBuildFinishedAt.Int64 == 0 { - w.LastBuildFinishedAt.Valid = false - } - - // check if the LastCheckedIn field should be false - if w.LastCheckedIn.Int64 == 0 { - w.LastCheckedIn.Valid = false - } - - if w.BuildLimit.Int64 == 0 { - w.BuildLimit.Valid = false - } - - return w -} - -// ToAPI converts the Worker type -// to an API Worker type. -func (w *Worker) ToAPI(builds []*library.Build) *api.Worker { - worker := new(api.Worker) - - worker.SetID(w.ID.Int64) - worker.SetHostname(w.Hostname.String) - worker.SetAddress(w.Address.String) - worker.SetRoutes(w.Routes) - worker.SetActive(w.Active.Bool) - worker.SetStatus(w.Status.String) - worker.SetLastStatusUpdateAt(w.LastStatusUpdateAt.Int64) - worker.SetRunningBuilds(builds) - worker.SetLastBuildStartedAt(w.LastBuildStartedAt.Int64) - worker.SetLastBuildFinishedAt(w.LastBuildFinishedAt.Int64) - worker.SetLastCheckedIn(w.LastCheckedIn.Int64) - worker.SetBuildLimit(w.BuildLimit.Int64) - - return worker -} - -// Validate verifies the necessary fields for -// the Worker type are populated correctly. -func (w *Worker) Validate() error { - // verify the Host field is populated - if len(w.Hostname.String) == 0 { - return ErrEmptyWorkerHost - } - - // verify the Address field is populated - if len(w.Address.String) == 0 { - return ErrEmptyWorkerAddress - } - - // calculate total size of RunningBuildIds - total := 0 - for _, f := range w.RunningBuildIDs { - total += len(f) - } - - // verify the RunningBuildIds field is within the database constraints - // len is to factor in number of comma separators included in the database field, - // removing 1 due to the last item not having an appended comma - if (total + len(w.RunningBuildIDs) - 1) > constants.RunningBuildIDsMaxSize { - return ErrExceededRunningBuildIDsLimit - } - - // ensure that all Worker string fields - // that can be returned as JSON are sanitized - // to avoid unsafe HTML content - w.Hostname = sql.NullString{String: util.Sanitize(w.Hostname.String), Valid: w.Hostname.Valid} - w.Address = sql.NullString{String: util.Sanitize(w.Address.String), Valid: w.Address.Valid} - - // ensure that all Routes are sanitized - // to avoid unsafe HTML content - for i, v := range w.Routes { - w.Routes[i] = util.Sanitize(v) - } - - return nil -} - -// FromAPI converts the API worker type -// to a database worker type. -func FromAPI(w *api.Worker) *Worker { - var rBs []string - - for _, b := range w.GetRunningBuilds() { - rBs = append(rBs, fmt.Sprint(b.GetID())) - } - - worker := &Worker{ - ID: sql.NullInt64{Int64: w.GetID(), Valid: true}, - Hostname: sql.NullString{String: w.GetHostname(), Valid: true}, - Address: sql.NullString{String: w.GetAddress(), Valid: true}, - Routes: pq.StringArray(w.GetRoutes()), - Active: sql.NullBool{Bool: w.GetActive(), Valid: true}, - Status: sql.NullString{String: w.GetStatus(), Valid: true}, - LastStatusUpdateAt: sql.NullInt64{Int64: w.GetLastStatusUpdateAt(), Valid: true}, - RunningBuildIDs: pq.StringArray(rBs), - LastBuildStartedAt: sql.NullInt64{Int64: w.GetLastBuildStartedAt(), Valid: true}, - LastBuildFinishedAt: sql.NullInt64{Int64: w.GetLastBuildFinishedAt(), Valid: true}, - LastCheckedIn: sql.NullInt64{Int64: w.GetLastCheckedIn(), Valid: true}, - BuildLimit: sql.NullInt64{Int64: w.GetBuildLimit(), Valid: true}, - } - - return worker.Nullify() -} - // convertToBuilds is a helper function that generates build objects with ID fields given a list of IDs. -func convertToBuilds(ids []string) []*library.Build { +func convertToBuilds(ids []string) []*api.Build { // create stripped build objects holding the IDs - var rBs []*library.Build + var rBs []*api.Build for _, b := range ids { id, err := strconv.ParseInt(b, 10, 64) @@ -275,7 +93,7 @@ func convertToBuilds(ids []string) []*library.Build { return nil } - build := new(library.Build) + build := new(api.Build) build.SetID(id) rBs = append(rBs, build) diff --git a/database/worker/worker_test.go b/database/worker/worker_test.go index 9a4201218..bf54eb4da 100644 --- a/database/worker/worker_test.go +++ b/database/worker/worker_test.go @@ -13,7 +13,6 @@ import ( "gorm.io/gorm" api "github.com/go-vela/server/api/types" - "github.com/go-vela/types/library" ) func TestWorker_New(t *testing.T) { @@ -108,27 +107,27 @@ func TestWorker_New(t *testing.T) { } func TestWorker_convertToBuilds(t *testing.T) { - _buildOne := new(library.Build) + _buildOne := new(api.Build) _buildOne.SetID(1) - _buildTwo := new(library.Build) + _buildTwo := new(api.Build) _buildTwo.SetID(2) // setup tests tests := []struct { name string ids []string - want []*library.Build + want []*api.Build }{ { name: "one id", ids: []string{"1"}, - want: []*library.Build{_buildOne}, + want: []*api.Build{_buildOne}, }, { name: "multiple ids", ids: []string{"1", "2"}, - want: []*library.Build{_buildOne, _buildTwo}, + want: []*api.Build{_buildOne, _buildTwo}, }, { name: "not int64", @@ -210,7 +209,7 @@ func testSqlite(t *testing.T) *engine { // testWorker is a test helper function to create a library // Worker type with all fields set to their zero values. func testWorker() *api.Worker { - b := new(library.Build) + b := new(api.Build) b.SetID(1) return &api.Worker{ @@ -221,7 +220,7 @@ func testWorker() *api.Worker { Active: new(bool), Status: new(string), LastStatusUpdateAt: new(int64), - RunningBuilds: &[]*library.Build{b}, + RunningBuilds: &[]*api.Build{b}, LastBuildStartedAt: new(int64), LastBuildFinishedAt: new(int64), LastCheckedIn: new(int64), diff --git a/internal/webhook.go b/internal/webhook.go index ace36987e..9c193fe58 100644 --- a/internal/webhook.go +++ b/internal/webhook.go @@ -29,7 +29,7 @@ type PullRequest struct { type Webhook struct { Hook *library.Hook Repo *api.Repo - Build *library.Build + Build *api.Build PullRequest PullRequest Deployment *library.Deployment } diff --git a/internal/webhook_test.go b/internal/webhook_test.go index 6b072090b..4e421854c 100644 --- a/internal/webhook_test.go +++ b/internal/webhook_test.go @@ -5,8 +5,8 @@ package internal import ( "testing" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" ) func TestWebhook_ShouldSkip(t *testing.T) { @@ -92,8 +92,8 @@ func TestWebhook_ShouldSkip(t *testing.T) { } } -func testPushBuild(message, title, event string) *library.Build { - b := new(library.Build) +func testPushBuild(message, title, event string) *api.Build { + b := new(api.Build) b.SetEvent(event) diff --git a/mock/server/build.go b/mock/server/build.go index 1d15a5c10..37466b910 100644 --- a/mock/server/build.go +++ b/mock/server/build.go @@ -10,6 +10,7 @@ import ( "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types" "github.com/go-vela/types/library" ) @@ -18,7 +19,52 @@ const ( // BuildResp represents a JSON return for a single build. BuildResp = `{ "id": 1, - "repo_id": 1, + "repo": { + "id": 1, + "owner": { + "id": 1, + "name": "octocat", + "favorites": [], + "active": true, + "admin": false + }, + "org": "github", + "counter": 10, + "name": "octocat", + "full_name": "github/octocat", + "link": "https://github.com/github/octocat", + "clone": "https://github.com/github/octocat", + "branch": "main", + "build_limit": 10, + "timeout": 60, + "visibility": "public", + "private": false, + "trusted": true, + "pipeline_type": "yaml", + "topics": [], + "active": true, + "allow_events": { + "push": { + "branch": true, + "tag": true + }, + "pull_request": { + "opened": true, + "synchronize": true, + "reopened": true, + "edited": false + }, + "deployment": { + "created": true + }, + "comment": { + "created": false, + "edited": false + } + }, + "approve_build": "fork-always", + "previous_name": "" + }, "pipeline_id": 1, "number": 1, "parent": 1, @@ -171,7 +217,7 @@ const ( func getBuilds(c *gin.Context) { data := []byte(BuildsResp) - var body []library.Build + var body []api.Build _ = json.Unmarshal(data, &body) c.JSON(http.StatusOK, body) @@ -191,7 +237,7 @@ func getBuild(c *gin.Context) { data := []byte(BuildResp) - var body library.Build + var body api.Build _ = json.Unmarshal(data, &body) c.JSON(http.StatusOK, body) @@ -223,7 +269,7 @@ func getLogs(c *gin.Context) { func addBuild(c *gin.Context) { data := []byte(BuildResp) - var body library.Build + var body api.Build _ = json.Unmarshal(data, &body) c.JSON(http.StatusCreated, body) @@ -247,7 +293,7 @@ func updateBuild(c *gin.Context) { data := []byte(BuildResp) - var body library.Build + var body api.Build _ = json.Unmarshal(data, &body) c.JSON(http.StatusOK, body) @@ -286,7 +332,7 @@ func restartBuild(c *gin.Context) { data := []byte(BuildResp) - var body library.Build + var body api.Build _ = json.Unmarshal(data, &body) c.JSON(http.StatusCreated, body) @@ -340,7 +386,7 @@ func buildQueue(c *gin.Context) { data := []byte(BuildQueueResp) - var body []library.BuildQueue + var body []api.QueueBuild _ = json.Unmarshal(data, &body) c.JSON(http.StatusOK, body) diff --git a/mock/server/build_test.go b/mock/server/build_test.go index 572fa4300..0d7c4825a 100644 --- a/mock/server/build_test.go +++ b/mock/server/build_test.go @@ -7,11 +7,11 @@ import ( "reflect" "testing" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" ) func TestBuild_ActiveBuildResp(t *testing.T) { - testBuild := library.Build{} + testBuild := api.Build{} err := json.Unmarshal([]byte(BuildResp), &testBuild) if err != nil { diff --git a/queue/models/item.go b/queue/models/item.go index f0a5f4fa3..83b370d48 100644 --- a/queue/models/item.go +++ b/queue/models/item.go @@ -4,7 +4,6 @@ package models import ( api "github.com/go-vela/server/api/types" - "github.com/go-vela/types/library" ) // ItemVersion allows the worker to detect items that were queued before an Vela server @@ -15,17 +14,15 @@ const ItemVersion uint64 = 3 // Item is the queue representation of an item to publish to the queue. type Item struct { - Build *library.Build `json:"build"` - Repo *api.Repo `json:"repo"` + Build *api.Build `json:"build"` // The 0-value is the implicit ItemVersion for queued Items that pre-date adding the field. ItemVersion uint64 `json:"item_version"` } -// ToItem creates a queue item from a build, repo and user. -func ToItem(b *library.Build, r *api.Repo) *Item { +// ToItem creates a queue item from a build. +func ToItem(b *api.Build) *Item { return &Item{ Build: b, - Repo: r, ItemVersion: ItemVersion, } } diff --git a/queue/models/item_test.go b/queue/models/item_test.go index 94be05c22..ba14ef5e4 100644 --- a/queue/models/item_test.go +++ b/queue/models/item_test.go @@ -7,7 +7,6 @@ import ( "testing" api "github.com/go-vela/server/api/types" - "github.com/go-vela/types/library" ) func TestTypes_ToItem(t *testing.T) { @@ -18,9 +17,30 @@ func TestTypes_ToItem(t *testing.T) { str := "foo" e := new(api.Events) - b := &library.Build{ - ID: &num64, - RepoID: &num64, + b := &api.Build{ + ID: &num64, + Repo: &api.Repo{ + ID: &num64, + Owner: &api.User{ + ID: &num64, + Name: &str, + Token: &str, + Active: &booL, + Admin: &booL, + }, + Org: &str, + Name: &str, + FullName: &str, + Link: &str, + Clone: &str, + Branch: &str, + Timeout: &num64, + Visibility: &str, + Private: &booL, + Trusted: &booL, + Active: &booL, + AllowEvents: e, + }, Number: &num, Parent: &num, Event: &str, @@ -42,32 +62,31 @@ func TestTypes_ToItem(t *testing.T) { Ref: &str, BaseRef: &str, } - r := &api.Repo{ - ID: &num64, - Owner: &api.User{ - ID: &num64, - Name: &str, - Token: &str, - Active: &booL, - Admin: &booL, - }, - Org: &str, - Name: &str, - FullName: &str, - Link: &str, - Clone: &str, - Branch: &str, - Timeout: &num64, - Visibility: &str, - Private: &booL, - Trusted: &booL, - Active: &booL, - AllowEvents: e, - } want := &Item{ - Build: &library.Build{ - ID: &num64, - RepoID: &num64, + Build: &api.Build{ + ID: &num64, + Repo: &api.Repo{ + ID: &num64, + Owner: &api.User{ + ID: &num64, + Name: &str, + Token: &str, + Active: &booL, + Admin: &booL, + }, + Org: &str, + Name: &str, + FullName: &str, + Link: &str, + Clone: &str, + Branch: &str, + Timeout: &num64, + Visibility: &str, + Private: &booL, + Trusted: &booL, + Active: &booL, + AllowEvents: e, + }, Number: &num, Parent: &num, Event: &str, @@ -89,33 +108,11 @@ func TestTypes_ToItem(t *testing.T) { Ref: &str, BaseRef: &str, }, - Repo: &api.Repo{ - ID: &num64, - Owner: &api.User{ - ID: &num64, - Name: &str, - Token: &str, - Active: &booL, - Admin: &booL, - }, - Org: &str, - Name: &str, - FullName: &str, - Link: &str, - Clone: &str, - Branch: &str, - Timeout: &num64, - Visibility: &str, - Private: &booL, - Trusted: &booL, - Active: &booL, - AllowEvents: e, - }, ItemVersion: ItemVersion, } // run test - got := ToItem(b, r) + got := ToItem(b) if !reflect.DeepEqual(got, want) { t.Errorf("ToItem is %v, want %v", got, want) diff --git a/queue/redis/length_test.go b/queue/redis/length_test.go index cf02377aa..545f9f54a 100644 --- a/queue/redis/length_test.go +++ b/queue/redis/length_test.go @@ -17,7 +17,6 @@ func TestRedis_Length(t *testing.T) { // use global variables in redis_test.go _item := &models.Item{ Build: _build, - Repo: _repo, } // setup queue item diff --git a/queue/redis/pop_test.go b/queue/redis/pop_test.go index a5ae4fd0b..b2ade0b40 100644 --- a/queue/redis/pop_test.go +++ b/queue/redis/pop_test.go @@ -19,7 +19,6 @@ func TestRedis_Pop(t *testing.T) { // use global variables in redis_test.go _item := &models.Item{ Build: _build, - Repo: _repo, } var signed []byte diff --git a/queue/redis/push_test.go b/queue/redis/push_test.go index 75acc317e..c8fe1bc7f 100644 --- a/queue/redis/push_test.go +++ b/queue/redis/push_test.go @@ -15,7 +15,6 @@ func TestRedis_Push(t *testing.T) { // use global variables in redis_test.go _item := &models.Item{ Build: _build, - Repo: _repo, } // setup queue item diff --git a/queue/redis/redis_test.go b/queue/redis/redis_test.go index ee67e682e..474d57de9 100644 --- a/queue/redis/redis_test.go +++ b/queue/redis/redis_test.go @@ -10,7 +10,6 @@ import ( "github.com/alicebob/miniredis/v2" api "github.com/go-vela/server/api/types" - "github.com/go-vela/types/library" ) // The following functions were taken from @@ -47,8 +46,29 @@ func Strings(v []string) *[]string { return &v } var ( _signingPrivateKey = "tCIevHOBq6DdN5SSBtteXUusjjd0fOqzk2eyi0DMq04NewmShNKQeUbbp3vkvIckb4pCxc+vxUo+mYf/vzOaSg==" _signingPublicKey = "DXsJkoTSkHlG26d75LyHJG+KQsXPr8VKPpmH/78zmko=" - _build = &library.Build{ - ID: Int64(1), + _build = &api.Build{ + ID: Int64(1), + Repo: &api.Repo{ + ID: Int64(1), + Owner: &api.User{ + ID: Int64(1), + Name: String("octocat"), + Token: nil, + Active: Bool(true), + Admin: Bool(false), + }, + Org: String("github"), + Name: String("octocat"), + FullName: String("github/octocat"), + Link: String("https://github.com/github/octocat"), + Clone: String("https://github.com/github/octocat.git"), + Branch: String("main"), + Timeout: Int64(60), + Visibility: String("public"), + Private: Bool(false), + Trusted: Bool(false), + Active: Bool(true), + }, Number: Int(1), Parent: Int(1), Event: String("push"), @@ -73,28 +93,6 @@ var ( Runtime: String("docker"), Distribution: String("linux"), } - - _repo = &api.Repo{ - ID: Int64(1), - Owner: &api.User{ - ID: Int64(1), - Name: String("octocat"), - Token: nil, - Active: Bool(true), - Admin: Bool(false), - }, - Org: String("github"), - Name: String("octocat"), - FullName: String("github/octocat"), - Link: String("https://github.com/github/octocat"), - Clone: String("https://github.com/github/octocat.git"), - Branch: String("main"), - Timeout: Int64(60), - Visibility: String("public"), - Private: Bool(false), - Trusted: Bool(false), - Active: Bool(true), - } ) func TestRedis_New(t *testing.T) { diff --git a/router/middleware/build/build.go b/router/middleware/build/build.go index 3c574e3e0..06273e532 100644 --- a/router/middleware/build/build.go +++ b/router/middleware/build/build.go @@ -10,16 +10,16 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/go-vela/types/library" ) // Retrieve gets the build in the given context. -func Retrieve(c *gin.Context) *library.Build { +func Retrieve(c *gin.Context) *api.Build { return FromContext(c) } diff --git a/router/middleware/build/build_test.go b/router/middleware/build/build_test.go index 01cb48bd6..d6d600b30 100644 --- a/router/middleware/build/build_test.go +++ b/router/middleware/build/build_test.go @@ -6,21 +6,21 @@ import ( "context" "net/http" "net/http/httptest" - "reflect" "testing" "github.com/gin-gonic/gin" + "github.com/google/go-cmp/cmp" api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" - "github.com/go-vela/types/library" ) func TestBuild_Retrieve(t *testing.T) { // setup types - want := new(library.Build) + want := new(api.Build) want.SetID(1) // setup context @@ -39,10 +39,12 @@ func TestBuild_Retrieve(t *testing.T) { func TestBuild_Establish(t *testing.T) { // setup types - owner := new(api.User) + owner := testutils.APIUser().Crop() owner.SetID(1) + owner.SetName("octocat") + owner.SetToken("foo") - r := new(api.Repo) + r := testutils.APIRepo() r.SetID(1) r.SetOwner(owner) r.SetHash("baz") @@ -51,9 +53,9 @@ func TestBuild_Establish(t *testing.T) { r.SetFullName("foo/bar") r.SetVisibility("public") - want := new(library.Build) + want := new(api.Build) want.SetID(1) - want.SetRepoID(1) + want.SetRepo(r) want.SetPipelineID(0) want.SetNumber(1) want.SetParent(1) @@ -87,7 +89,7 @@ func TestBuild_Establish(t *testing.T) { want.SetApprovedAt(0) want.SetApprovedBy("") - got := new(library.Build) + got := new(api.Build) // setup database db, err := database.NewTest() @@ -98,11 +100,24 @@ func TestBuild_Establish(t *testing.T) { defer func() { _ = db.DeleteBuild(context.TODO(), want) _ = db.DeleteRepo(context.TODO(), r) + _ = db.DeleteUser(context.TODO(), owner) db.Close() }() - _, _ = db.CreateRepo(context.TODO(), r) - _, _ = db.CreateBuild(context.TODO(), want) + _, err = db.CreateUser(context.TODO(), owner) + if err != nil { + t.Errorf("unable to create test user: %v", err) + } + + _, err = db.CreateRepo(context.TODO(), r) + if err != nil { + t.Errorf("unable to create test repo: %v", err) + } + + _, err = db.CreateBuild(context.TODO(), want) + if err != nil { + t.Errorf("unable to create test build: %v", err) + } // setup context gin.SetMode(gin.TestMode) @@ -129,8 +144,8 @@ func TestBuild_Establish(t *testing.T) { t.Errorf("Establish returned %v, want %v", resp.Code, http.StatusOK) } - if !reflect.DeepEqual(got, want) { - t.Errorf("Establish is %v, want %v", got, want) + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("Establish mismatch (-want +got):\n%s", diff) } } diff --git a/router/middleware/build/context.go b/router/middleware/build/context.go index 99f358add..6870f5364 100644 --- a/router/middleware/build/context.go +++ b/router/middleware/build/context.go @@ -5,7 +5,7 @@ package build import ( "context" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" ) const key = "build" @@ -16,13 +16,13 @@ type Setter interface { } // FromContext returns the Build associated with this context. -func FromContext(c context.Context) *library.Build { +func FromContext(c context.Context) *api.Build { value := c.Value(key) if value == nil { return nil } - b, ok := value.(*library.Build) + b, ok := value.(*api.Build) if !ok { return nil } @@ -32,6 +32,6 @@ func FromContext(c context.Context) *library.Build { // ToContext adds the Build to this context if it supports // the Setter interface. -func ToContext(c Setter, b *library.Build) { +func ToContext(c Setter, b *api.Build) { c.Set(key, b) } diff --git a/router/middleware/build/context_test.go b/router/middleware/build/context_test.go index 66fd2d88b..4a30a1988 100644 --- a/router/middleware/build/context_test.go +++ b/router/middleware/build/context_test.go @@ -7,13 +7,13 @@ import ( "github.com/gin-gonic/gin" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" ) func TestBuild_FromContext(t *testing.T) { // setup types bID := int64(1) - want := &library.Build{ID: &bID} + want := &api.Build{ID: &bID} // setup context gin.SetMode(gin.TestMode) @@ -72,7 +72,7 @@ func TestBuild_FromContext_Empty(t *testing.T) { func TestBuild_ToContext(t *testing.T) { // setup types bID := int64(1) - want := &library.Build{ID: &bID} + want := &api.Build{ID: &bID} // setup context gin.SetMode(gin.TestMode) diff --git a/router/middleware/logger_test.go b/router/middleware/logger_test.go index 1521eba32..25e3dad14 100644 --- a/router/middleware/logger_test.go +++ b/router/middleware/logger_test.go @@ -29,11 +29,6 @@ import ( func TestMiddleware_Logger(t *testing.T) { // setup types - b := new(library.Build) - b.SetID(1) - b.SetRepoID(1) - b.SetNumber(1) - r := new(api.Repo) r.SetID(1) r.GetOwner().SetID(1) @@ -41,6 +36,11 @@ func TestMiddleware_Logger(t *testing.T) { r.SetName("bar") r.SetFullName("foo/bar") + b := new(api.Build) + b.SetID(1) + b.SetRepo(r) + b.SetNumber(1) + svc := new(library.Service) svc.SetID(1) svc.SetRepoID(1) @@ -171,9 +171,9 @@ func TestMiddleware_Logger_Sanitize(t *testing.T) { r.SetFullName("foo/bar") logRepo, _ := json.Marshal(r) - b := new(library.Build) + b := new(api.Build) b.SetID(1) - b.SetRepoID(1) + b.SetRepo(r) b.SetNumber(1) b.SetEmail("octocat@github.com") logBuild, _ := json.Marshal(b) diff --git a/router/middleware/perm/perm_test.go b/router/middleware/perm/perm_test.go index b34293f91..8ca690b50 100644 --- a/router/middleware/perm/perm_test.go +++ b/router/middleware/perm/perm_test.go @@ -24,7 +24,6 @@ import ( "github.com/go-vela/server/scm" "github.com/go-vela/server/scm/github" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" ) func TestPerm_MustPlatformAdmin(t *testing.T) { @@ -408,9 +407,9 @@ func TestPerm_MustBuildAccess(t *testing.T) { r.SetFullName("foo/bar") r.SetVisibility("public") - b := new(library.Build) + b := new(api.Build) b.SetID(1) - b.SetRepoID(1) + b.SetRepo(r) b.SetNumber(1) tm := &token.Manager{ @@ -497,9 +496,9 @@ func TestPerm_MustBuildAccess_PlatAdmin(t *testing.T) { r.SetFullName("foo/bar") r.SetVisibility("public") - b := new(library.Build) + b := new(api.Build) b.SetID(1) - b.SetRepoID(1) + b.SetRepo(r) b.SetNumber(1) u := new(api.User) @@ -592,9 +591,9 @@ func TestPerm_MustBuildToken_WrongBuild(t *testing.T) { r.SetFullName("foo/bar") r.SetVisibility("public") - b := new(library.Build) + b := new(api.Build) b.SetID(1) - b.SetRepoID(1) + b.SetRepo(r) b.SetNumber(1) tm := &token.Manager{ @@ -681,9 +680,9 @@ func TestPerm_MustSecretAdmin_BuildToken_Repo(t *testing.T) { r.SetFullName("foo/bar") r.SetVisibility("public") - b := new(library.Build) + b := new(api.Build) b.SetID(1) - b.SetRepoID(1) + b.SetRepo(r) b.SetNumber(1) tm := &token.Manager{ @@ -767,9 +766,9 @@ func TestPerm_MustSecretAdmin_BuildToken_Org(t *testing.T) { r.SetFullName("foo/bar") r.SetVisibility("public") - b := new(library.Build) + b := new(api.Build) b.SetID(1) - b.SetRepoID(1) + b.SetRepo(r) b.SetNumber(1) tm := &token.Manager{ @@ -853,9 +852,9 @@ func TestPerm_MustSecretAdmin_BuildToken_Shared(t *testing.T) { r.SetFullName("foo/bar") r.SetVisibility("public") - b := new(library.Build) + b := new(api.Build) b.SetID(1) - b.SetRepoID(1) + b.SetRepo(r) b.SetNumber(1) tm := &token.Manager{ @@ -1846,9 +1845,9 @@ func TestPerm_MustRead_WorkerBuildToken(t *testing.T) { r.SetFullName("foo/bar") r.SetVisibility("private") - b := new(library.Build) + b := new(api.Build) b.SetID(1) - b.SetRepoID(1) + b.SetRepo(r) b.SetNumber(1) mto := &token.MintTokenOpts{ diff --git a/router/middleware/pipeline/pipeline.go b/router/middleware/pipeline/pipeline.go index c8d8fc4dc..e2bf396ea 100644 --- a/router/middleware/pipeline/pipeline.go +++ b/router/middleware/pipeline/pipeline.go @@ -9,6 +9,7 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/compiler" "github.com/go-vela/server/database" "github.com/go-vela/server/internal" @@ -74,13 +75,15 @@ func Establish() gin.HandlerFunc { return } + b := new(api.Build) + b.SetRepo(r) + // parse and compile the pipeline configuration file _, pipeline, err = compiler.FromContext(c). Duplicate(). WithCommit(p). WithMetadata(c.MustGet("metadata").(*internal.Metadata)). - WithRepo(r). - WithUser(u). + WithBuild(b). Compile(config) if err != nil { retErr := fmt.Errorf("unable to compile pipeline configuration for %s: %w", entry, err) diff --git a/router/middleware/repo/repo_test.go b/router/middleware/repo/repo_test.go index 6c683c5a5..d2bb0d512 100644 --- a/router/middleware/repo/repo_test.go +++ b/router/middleware/repo/repo_test.go @@ -13,8 +13,8 @@ import ( api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/server/router/middleware/org" - "github.com/go-vela/types/constants" ) func TestRepo_Retrieve(t *testing.T) { @@ -37,12 +37,11 @@ func TestRepo_Retrieve(t *testing.T) { func TestRepo_Establish(t *testing.T) { // setup types - owner := new(api.User) + owner := testutils.APIUser().Crop() owner.SetID(1) owner.SetName("foo") owner.SetActive(false) - owner.SetToken(constants.SecretMask) - owner.SetRefreshToken(constants.SecretMask) + owner.SetToken("bar") want := new(api.Repo) want.SetID(1) diff --git a/router/middleware/service/service_test.go b/router/middleware/service/service_test.go index fcf7fc585..65869cea0 100644 --- a/router/middleware/service/service_test.go +++ b/router/middleware/service/service_test.go @@ -51,9 +51,9 @@ func TestService_Establish(t *testing.T) { r.SetFullName("foo/bar") r.SetVisibility("public") - b := new(library.Build) + b := new(api.Build) b.SetID(1) - b.SetRepoID(1) + b.SetRepo(r) b.SetNumber(1) want := new(library.Service) @@ -215,9 +215,9 @@ func TestService_Establish_NoServiceParameter(t *testing.T) { r.SetFullName("foo/bar") r.SetVisibility("public") - b := new(library.Build) + b := new(api.Build) b.SetID(1) - b.SetRepoID(1) + b.SetRepo(r) b.SetNumber(1) // setup database @@ -274,9 +274,9 @@ func TestService_Establish_InvalidServiceParameter(t *testing.T) { r.SetFullName("foo/bar") r.SetVisibility("public") - b := new(library.Build) + b := new(api.Build) b.SetID(1) - b.SetRepoID(1) + b.SetRepo(r) b.SetNumber(1) // setup database @@ -330,9 +330,9 @@ func TestService_Establish_NoService(t *testing.T) { r.SetFullName("foo/bar") r.SetVisibility("public") - b := new(library.Build) + b := new(api.Build) b.SetID(1) - b.SetRepoID(1) + b.SetRepo(r) b.SetNumber(1) // setup database diff --git a/router/middleware/step/step_test.go b/router/middleware/step/step_test.go index 6e26dd5ba..b96141e5b 100644 --- a/router/middleware/step/step_test.go +++ b/router/middleware/step/step_test.go @@ -52,9 +52,9 @@ func TestStep_Establish(t *testing.T) { r.SetFullName("foo/bar") r.SetVisibility("public") - b := new(library.Build) + b := new(api.Build) b.SetID(1) - b.SetRepoID(1) + b.SetRepo(r) b.SetNumber(1) want := new(library.Step) @@ -221,9 +221,9 @@ func TestStep_Establish_NoStepParameter(t *testing.T) { r.SetFullName("foo/bar") r.SetVisibility("public") - b := new(library.Build) + b := new(api.Build) b.SetID(1) - b.SetRepoID(1) + b.SetRepo(r) b.SetNumber(1) // setup database @@ -280,9 +280,9 @@ func TestStep_Establish_InvalidStepParameter(t *testing.T) { r.SetFullName("foo/bar") r.SetVisibility("public") - b := new(library.Build) + b := new(api.Build) b.SetID(1) - b.SetRepoID(1) + b.SetRepo(r) b.SetNumber(1) // setup database @@ -339,9 +339,9 @@ func TestStep_Establish_NoStep(t *testing.T) { r.SetFullName("foo/bar") r.SetVisibility("public") - b := new(library.Build) + b := new(api.Build) b.SetID(1) - b.SetRepoID(1) + b.SetRepo(r) b.SetNumber(1) // setup database diff --git a/router/middleware/worker/worker_test.go b/router/middleware/worker/worker_test.go index a59f11190..d39d43842 100644 --- a/router/middleware/worker/worker_test.go +++ b/router/middleware/worker/worker_test.go @@ -13,7 +13,6 @@ import ( api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" - "github.com/go-vela/types/library" ) func TestWorker_Retrieve(t *testing.T) { @@ -36,7 +35,7 @@ func TestWorker_Retrieve(t *testing.T) { func TestWorker_Establish(t *testing.T) { // setup types - b := new(library.Build) + b := new(api.Build) b.SetID(1) want := new(api.Worker) @@ -47,7 +46,7 @@ func TestWorker_Establish(t *testing.T) { want.SetActive(true) want.SetStatus("available") want.SetLastStatusUpdateAt(12345) - want.SetRunningBuilds([]*library.Build{b}) + want.SetRunningBuilds([]*api.Build{b}) want.SetLastBuildStartedAt(12345) want.SetLastBuildFinishedAt(12345) want.SetLastCheckedIn(12345) diff --git a/scm/github/repo.go b/scm/github/repo.go index 712dada46..c9b143763 100644 --- a/scm/github/repo.go +++ b/scm/github/repo.go @@ -281,7 +281,7 @@ func (c *client) Update(ctx context.Context, u *api.User, r *api.Repo, hookID in } // Status sends the commit status for the given SHA from the GitHub repo. -func (c *client) Status(ctx context.Context, u *api.User, b *library.Build, org, name string) error { +func (c *client) Status(ctx context.Context, u *api.User, b *api.Build, org, name string) error { c.Logger.WithFields(logrus.Fields{ "build": b.GetNumber(), "org": org, @@ -394,7 +394,7 @@ func (c *client) Status(ctx context.Context, u *api.User, b *library.Build, org, } // StepStatus sends the commit status for the given SHA to the GitHub repo with the step as the context. -func (c *client) StepStatus(ctx context.Context, u *api.User, b *library.Build, s *library.Step, org, name string) error { +func (c *client) StepStatus(ctx context.Context, u *api.User, b *api.Build, s *library.Step, org, name string) error { c.Logger.WithFields(logrus.Fields{ "build": b.GetNumber(), "org": org, diff --git a/scm/github/repo_test.go b/scm/github/repo_test.go index d7c073892..7ef874181 100644 --- a/scm/github/repo_test.go +++ b/scm/github/repo_test.go @@ -850,9 +850,12 @@ func TestGithub_Status_Deployment(t *testing.T) { u.SetName("foo") u.SetToken("bar") - b := new(library.Build) + r := new(api.Repo) + r.SetID(1) + + b := new(api.Build) b.SetID(1) - b.SetRepoID(1) + b.SetRepo(r) b.SetNumber(1) b.SetEvent(constants.EventDeploy) b.SetStatus(constants.StatusRunning) @@ -895,9 +898,12 @@ func TestGithub_Status_Running(t *testing.T) { u.SetName("foo") u.SetToken("bar") - b := new(library.Build) + r := new(api.Repo) + r.SetID(1) + + b := new(api.Build) b.SetID(1) - b.SetRepoID(1) + b.SetRepo(r) b.SetNumber(1) b.SetEvent(constants.EventPush) b.SetStatus(constants.StatusRunning) @@ -956,9 +962,12 @@ func TestGithub_Status_Success(t *testing.T) { u.SetName("foo") u.SetToken("bar") - b := new(library.Build) + r := new(api.Repo) + r.SetID(1) + + b := new(api.Build) b.SetID(1) - b.SetRepoID(1) + b.SetRepo(r) b.SetNumber(1) b.SetEvent(constants.EventPush) b.SetStatus(constants.StatusRunning) @@ -1017,9 +1026,12 @@ func TestGithub_Status_Failure(t *testing.T) { u.SetName("foo") u.SetToken("bar") - b := new(library.Build) + r := new(api.Repo) + r.SetID(1) + + b := new(api.Build) b.SetID(1) - b.SetRepoID(1) + b.SetRepo(r) b.SetNumber(1) b.SetEvent(constants.EventPush) b.SetStatus(constants.StatusRunning) @@ -1078,9 +1090,12 @@ func TestGithub_Status_Killed(t *testing.T) { u.SetName("foo") u.SetToken("bar") - b := new(library.Build) + r := new(api.Repo) + r.SetID(1) + + b := new(api.Build) b.SetID(1) - b.SetRepoID(1) + b.SetRepo(r) b.SetNumber(1) b.SetEvent(constants.EventPush) b.SetStatus(constants.StatusRunning) @@ -1139,9 +1154,12 @@ func TestGithub_Status_Skipped(t *testing.T) { u.SetName("foo") u.SetToken("bar") - b := new(library.Build) + r := new(api.Repo) + r.SetID(1) + + b := new(api.Build) b.SetID(1) - b.SetRepoID(1) + b.SetRepo(r) b.SetNumber(1) b.SetEvent(constants.EventPush) b.SetStatus(constants.StatusSkipped) @@ -1200,9 +1218,12 @@ func TestGithub_Status_Error(t *testing.T) { u.SetName("foo") u.SetToken("bar") - b := new(library.Build) + r := new(api.Repo) + r.SetID(1) + + b := new(api.Build) b.SetID(1) - b.SetRepoID(1) + b.SetRepo(r) b.SetNumber(1) b.SetEvent(constants.EventPush) b.SetStatus(constants.StatusRunning) diff --git a/scm/github/webhook.go b/scm/github/webhook.go index 315d2ec45..0d0f1fb50 100644 --- a/scm/github/webhook.go +++ b/scm/github/webhook.go @@ -148,7 +148,7 @@ func (c *client) processPushEvent(h *library.Hook, payload *github.PushEvent) (* r.SetTopics(repo.Topics) // convert payload to library build - b := new(library.Build) + b := new(api.Build) b.SetEvent(constants.EventPush) b.SetClone(repo.GetCloneURL()) b.SetSource(payload.GetHeadCommit().GetURL()) @@ -276,7 +276,7 @@ func (c *client) processPREvent(h *library.Hook, payload *github.PullRequestEven r.SetTopics(repo.Topics) // convert payload to library build - b := new(library.Build) + b := new(api.Build) b.SetEvent(constants.EventPull) b.SetEventAction(payload.GetAction()) b.SetClone(repo.GetCloneURL()) @@ -361,7 +361,7 @@ func (c *client) processDeploymentEvent(h *library.Hook, payload *github.Deploym r.SetTopics(repo.Topics) // convert payload to library build - b := new(library.Build) + b := new(api.Build) b.SetEvent(constants.EventDeploy) b.SetEventAction(constants.ActionCreated) b.SetClone(repo.GetCloneURL()) @@ -477,7 +477,7 @@ func (c *client) processIssueCommentEvent(h *library.Hook, payload *github.Issue r.SetTopics(repo.Topics) // convert payload to library build - b := new(library.Build) + b := new(api.Build) b.SetEvent(constants.EventComment) b.SetEventAction(payload.GetAction()) b.SetClone(repo.GetCloneURL()) diff --git a/scm/github/webhook_test.go b/scm/github/webhook_test.go index 41a6a8153..baf8bf722 100644 --- a/scm/github/webhook_test.go +++ b/scm/github/webhook_test.go @@ -67,7 +67,7 @@ func TestGithub_ProcessWebhook_Push(t *testing.T) { wantRepo.SetPrivate(false) wantRepo.SetTopics([]string{"go", "vela"}) - wantBuild := new(library.Build) + wantBuild := new(api.Build) wantBuild.SetEvent("push") wantBuild.SetClone("https://github.com/Codertocat/Hello-World.git") wantBuild.SetSource("https://github.com/Codertocat/Hello-World/commit/9c93babf58917cd6f6f6772b5df2b098f507ff95") @@ -145,7 +145,7 @@ func TestGithub_ProcessWebhook_Push_NoSender(t *testing.T) { wantRepo.SetPrivate(false) wantRepo.SetTopics([]string{"go", "vela"}) - wantBuild := new(library.Build) + wantBuild := new(api.Build) wantBuild.SetEvent("push") wantBuild.SetClone("https://github.com/Codertocat/Hello-World.git") wantBuild.SetSource("https://github.com/Codertocat/Hello-World/commit/9c93babf58917cd6f6f6772b5df2b098f507ff95") @@ -221,7 +221,7 @@ func TestGithub_ProcessWebhook_Push_Branch_Delete(t *testing.T) { wantRepo.SetPrivate(false) wantRepo.SetTopics([]string{"go", "vela"}) - wantBuild := new(library.Build) + wantBuild := new(api.Build) wantBuild.SetEvent("delete") wantBuild.SetEventAction("branch") wantBuild.SetClone("https://github.com/Codertocat/Hello-World.git") @@ -298,7 +298,7 @@ func TestGithub_ProcessWebhook_Push_Tag_Delete(t *testing.T) { wantRepo.SetPrivate(false) wantRepo.SetTopics([]string{"go", "vela"}) - wantBuild := new(library.Build) + wantBuild := new(api.Build) wantBuild.SetEvent("delete") wantBuild.SetEventAction("tag") wantBuild.SetClone("https://github.com/Codertocat/Hello-World.git") @@ -357,7 +357,7 @@ func TestGithub_ProcessWebhook_PullRequest(t *testing.T) { wantRepo.SetPrivate(false) wantRepo.SetTopics(nil) - wantBuild := new(library.Build) + wantBuild := new(api.Build) wantBuild.SetEvent("pull_request") wantBuild.SetEventAction("opened") wantBuild.SetClone("https://github.com/Codertocat/Hello-World.git") @@ -373,7 +373,7 @@ func TestGithub_ProcessWebhook_PullRequest(t *testing.T) { wantBuild.SetBaseRef("main") wantBuild.SetHeadRef("changes") - wantBuild2 := new(library.Build) + wantBuild2 := new(api.Build) wantBuild2.SetEvent("pull_request") wantBuild2.SetEventAction("labeled") wantBuild2.SetClone("https://github.com/Codertocat/Hello-World.git") @@ -389,7 +389,7 @@ func TestGithub_ProcessWebhook_PullRequest(t *testing.T) { wantBuild2.SetBaseRef("main") wantBuild2.SetHeadRef("changes") - wantBuild3 := new(library.Build) + wantBuild3 := new(api.Build) wantBuild3.SetEvent("pull_request") wantBuild3.SetEventAction("unlabeled") wantBuild3.SetClone("https://github.com/Codertocat/Hello-World.git") @@ -405,7 +405,7 @@ func TestGithub_ProcessWebhook_PullRequest(t *testing.T) { wantBuild3.SetBaseRef("main") wantBuild3.SetHeadRef("changes") - wantBuild4 := new(library.Build) + wantBuild4 := new(api.Build) wantBuild4.SetEvent("pull_request") wantBuild4.SetEventAction("edited") wantBuild4.SetClone("https://github.com/Codertocat/Hello-World.git") @@ -588,7 +588,7 @@ func TestGithub_ProcessWebhook_Deployment(t *testing.T) { wantRepo.SetPrivate(false) wantRepo.SetTopics(nil) - wantBuild := new(library.Build) + wantBuild := new(api.Build) wantBuild.SetEvent(constants.EventDeploy) wantBuild.SetEventAction(constants.ActionCreated) wantBuild.SetClone("https://github.com/Codertocat/Hello-World.git") @@ -619,7 +619,7 @@ func TestGithub_ProcessWebhook_Deployment(t *testing.T) { file string hook *library.Hook repo *api.Repo - build *library.Build + build *api.Build deploymentPayload raw.StringSliceMap deployment *library.Deployment } @@ -723,7 +723,7 @@ func TestGithub_ProcessWebhook_Deployment_Commit(t *testing.T) { wantRepo.SetPrivate(false) wantRepo.SetTopics(nil) - wantBuild := new(library.Build) + wantBuild := new(api.Build) wantBuild.SetEvent(constants.EventDeploy) wantBuild.SetEventAction(constants.ActionCreated) wantBuild.SetClone("https://github.com/Codertocat/Hello-World.git") @@ -994,7 +994,7 @@ func TestGithub_ProcessWebhook_IssueComment_PR(t *testing.T) { wantRepo.SetPrivate(false) wantRepo.SetTopics(nil) - wantBuild := new(library.Build) + wantBuild := new(api.Build) wantBuild.SetEvent("comment") wantBuild.SetEventAction("created") wantBuild.SetClone("https://github.com/Codertocat/Hello-World.git") diff --git a/scm/service.go b/scm/service.go index f8f2bc14e..b65a529eb 100644 --- a/scm/service.go +++ b/scm/service.go @@ -110,10 +110,10 @@ type Service interface { Update(context.Context, *api.User, *api.Repo, int64) (bool, error) // Status defines a function that sends the // commit status for the given SHA from a repo. - Status(context.Context, *api.User, *library.Build, string, string) error + Status(context.Context, *api.User, *api.Build, string, string) error // StepStatus defines a function that sends the // commit status for the given SHA for a specified step context. - StepStatus(context.Context, *api.User, *library.Build, *library.Step, string, string) error + StepStatus(context.Context, *api.User, *api.Build, *library.Step, string, string) error // ListUserRepos defines a function that retrieves // all repos with admin rights for the user. ListUserRepos(context.Context, *api.User) ([]*api.Repo, error) From 33155bffb4925cc236d2e579229fb701931131d6 Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Wed, 1 May 2024 10:11:21 -0400 Subject: [PATCH 39/71] fix(dashboards): use v7 uuid for primary key (#1115) --- database/types/dashboard.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/database/types/dashboard.go b/database/types/dashboard.go index 181824b7e..ba3b58efb 100644 --- a/database/types/dashboard.go +++ b/database/types/dashboard.go @@ -28,7 +28,7 @@ var ( type ( // Dashboard is the database representation of a dashboard. Dashboard struct { - ID uuid.UUID `gorm:"type:uuid;default:uuid_generate_v4()"` + ID uuid.UUID `gorm:"type:uuid;default:uuid_generate_v7()"` Name sql.NullString `sql:"name"` CreatedAt sql.NullInt64 `sql:"created_at"` CreatedBy sql.NullString `sql:"created_by"` From 58ef7e861ce4f1d35048bd9248a38cbf7437d971 Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Thu, 2 May 2024 12:06:59 -0400 Subject: [PATCH 40/71] fix(dashboards): add limit to repos for dashboards and dashboards for users (#1116) * fix(dashboards): add limit to repos * also add user dashboard limit --- constants/limit.go | 39 ++++++++++++++++++++++++++++++++ database/types/dashboard.go | 6 +++++ database/types/dashboard_test.go | 15 ++++++++++++ database/types/user.go | 14 +++--------- database/types/user_test.go | 8 +++---- 5 files changed, 67 insertions(+), 15 deletions(-) diff --git a/constants/limit.go b/constants/limit.go index 046b6c19b..8b492ec3e 100644 --- a/constants/limit.go +++ b/constants/limit.go @@ -3,6 +3,45 @@ package constants // Limits and constraints. const ( + // BuildLimitMin defines the minimum value for repo concurrent build limit. + BuildLimitMin = 1 + + // BuildLimitMax defines the maximum value for repo concurrent build limit. + BuildLimitMax = 30 + + // BuildLimitDefault defines the default value for repo concurrent build limit. + BuildLimitDefault = 10 + + // BuildTimeoutMin defines the minimum value in minutes for repo build timeout. + BuildTimeoutMin = 1 + + // BuildTimeoutMax defines the maximum value in minutes for repo build timeout. + BuildTimeoutMax = 90 + + // BuildTimeoutDefault defines the default value in minutes for repo build timeout. + BuildTimeoutDefault = 30 + + // FavoritesMaxSize defines the maximum size in characters for user favorites. + FavoritesMaxSize = 5000 + + // RunningBuildIDsMaxSize defines the maximum size in characters for worker RunningBuildIDs. + RunningBuildIDsMaxSize = 500 + + // TopicsMaxSize defines the maximum size in characters for repo topics. Ex: GitHub has a 20-topic, 50-char limit. + TopicsMaxSize = 1020 + + // DeployBuildsMaxSize defines the maximum size in characters for deployment builds. + DeployBuildsMaxSize = 500 + + // ReportStepStatusLimit defines the maximum number of steps in a pipeline that may report their status to the SCM. + ReportStepStatusLimit = 10 + + // DashboardRepoLimit defines the maximum number of repos that can be assigned to a dashboard. + DashboardRepoLimit = 10 + + // UserDashboardLimit defines the maximum number of dashboards that can be assigned to a user. + UserDashboardLimit = 10 + // DashboardAdminMaxSize defines the maximum size in characters for dashboard admins. DashboardAdminMaxSize = 5000 ) diff --git a/database/types/dashboard.go b/database/types/dashboard.go index ba3b58efb..0d6023058 100644 --- a/database/types/dashboard.go +++ b/database/types/dashboard.go @@ -12,6 +12,7 @@ import ( "github.com/google/uuid" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/constants" "github.com/go-vela/server/util" ) @@ -142,6 +143,11 @@ func (d *Dashboard) Validate() error { return ErrEmptyDashName } + // verify the number of repos + if len(d.Repos) > constants.DashboardRepoLimit { + return fmt.Errorf("exceeded repos limit of %d", constants.DashboardRepoLimit) + } + // ensure that all Dashboard string fields // that can be returned as JSON are sanitized // to avoid unsafe HTML content diff --git a/database/types/dashboard_test.go b/database/types/dashboard_test.go index f163e8b9c..60ca2cfa0 100644 --- a/database/types/dashboard_test.go +++ b/database/types/dashboard_test.go @@ -90,6 +90,17 @@ func TestTypes_Dashboard_ToAPI(t *testing.T) { func TestTypes_Dashboard_Validate(t *testing.T) { uuid, _ := uuid.Parse("c8da1302-07d6-11ea-882f-4893bca275b8") + dashRepo := new(api.DashboardRepo) + dashRepo.SetName("dashboard-repo") + + dashRepos := []*api.DashboardRepo{} + for i := 0; i < 11; i++ { + dashRepos = append(dashRepos, dashRepo) + } + + exceededReposDashboard := testDashboard() + exceededReposDashboard.Repos = DashReposJSON(dashRepos) + // setup tests tests := []struct { failure bool @@ -105,6 +116,10 @@ func TestTypes_Dashboard_Validate(t *testing.T) { ID: uuid, }, }, + { // hit repo limit + failure: true, + dashboard: exceededReposDashboard, + }, } // run tests diff --git a/database/types/user.go b/database/types/user.go index 0bfd13e2a..bde757a6b 100644 --- a/database/types/user.go +++ b/database/types/user.go @@ -11,8 +11,8 @@ import ( "github.com/lib/pq" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/constants" "github.com/go-vela/server/util" - "github.com/go-vela/types/constants" ) var ( @@ -216,16 +216,8 @@ func (u *User) Validate() error { return ErrExceededFavoritesLimit } - // calculate totalDashboards size of dashboards - totalDashboards := 0 - for _, d := range u.Dashboards { - totalDashboards += len(d) - } - - // verify the Dashboards field is within the database constraints - // len is to factor in number of comma separators included in the database field, - // removing 1 due to the last item not having an appended comma - if (totalDashboards + len(u.Dashboards) - 1) > constants.FavoritesMaxSize { + // validate number of dashboards + if len(u.Dashboards) > constants.UserDashboardLimit { return ErrExceededDashboardsLimit } diff --git a/database/types/user_test.go b/database/types/user_test.go index 9edf57abf..3d02427e8 100644 --- a/database/types/user_test.go +++ b/database/types/user_test.go @@ -204,7 +204,7 @@ func TestTypes_User_Validate(t *testing.T) { ID: sql.NullInt64{Int64: 1, Valid: true}, Name: sql.NullString{String: "octocat", Valid: true}, Token: sql.NullString{String: "superSecretToken", Valid: true}, - Favorites: exceededField(), + Favorites: exceededField(500), }, }, { // invalid dashboards set for user @@ -213,7 +213,7 @@ func TestTypes_User_Validate(t *testing.T) { ID: sql.NullInt64{Int64: 1, Valid: true}, Name: sql.NullString{String: "octocat", Valid: true}, Token: sql.NullString{String: "superSecretToken", Valid: true}, - Dashboards: exceededField(), + Dashboards: exceededField(11), }, }, } @@ -275,12 +275,12 @@ func testUser() *User { } // exceededField returns a list of strings that exceed the maximum size of a field. -func exceededField() []string { +func exceededField(indexes int) []string { // initialize empty favorites values := []string{} // add enough strings to exceed the character limit - for i := 0; i < 500; i++ { + for i := 0; i < indexes; i++ { // construct field // use i to adhere to unique favorites field := "github/octocat-" + strconv.Itoa(i) From 76931994b10c91d56c1332cc57a52d7c4d8f61ab Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Fri, 3 May 2024 10:05:56 -0400 Subject: [PATCH 41/71] fix(events): add action to deployment check (#1117) * fix(events): add action to deployment check * fix compiler tests --- api/types/events.go | 2 +- api/types/events_test.go | 2 +- compiler/native/compile_test.go | 6 +++--- go.mod | 2 +- go.sum | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/api/types/events.go b/api/types/events.go index 2dc6f1e28..8bf27db8c 100644 --- a/api/types/events.go +++ b/api/types/events.go @@ -130,7 +130,7 @@ func (e *Events) Allowed(event, action string) bool { allowed = e.GetComment().GetCreated() case constants.EventComment + ":" + constants.ActionEdited: allowed = e.GetComment().GetEdited() - case constants.EventDeploy: + case constants.EventDeploy + ":" + constants.ActionCreated: allowed = e.GetDeployment().GetCreated() case constants.EventSchedule: allowed = e.GetSchedule().GetRun() diff --git a/api/types/events_test.go b/api/types/events_test.go index 447a84c54..68f6f5709 100644 --- a/api/types/events_test.go +++ b/api/types/events_test.go @@ -340,7 +340,7 @@ func TestTypes_Events_Allowed(t *testing.T) { {event: "pull_request", action: "reopened", want: true}, {event: "pull_request", action: "labeled", want: false}, {event: "pull_request", action: "unlabeled", want: true}, - {event: "deployment", want: false}, + {event: "deployment", action: "created", want: false}, {event: "comment", action: "created", want: true}, {event: "comment", action: "edited", want: false}, {event: "schedule", want: true}, diff --git a/compiler/native/compile_test.go b/compiler/native/compile_test.go index ed9563045..811f9855e 100644 --- a/compiler/native/compile_test.go +++ b/compiler/native/compile_test.go @@ -3317,7 +3317,7 @@ func Test_CompileLite(t *testing.T) { Pull: "not_present", Ruleset: yaml.Ruleset{ If: yaml.Rules{ - Event: []string{"deployment"}, + Event: []string{"deployment:created"}, Target: []string{"production"}, }, Matcher: "filepath", @@ -3396,7 +3396,7 @@ func Test_CompileLite(t *testing.T) { pipelineType: "", substitute: true, ruleData: &pipeline.RuleData{ - Event: "deployment", + Event: "deployment:created", Target: "production", Path: []string{"README.md"}, }, @@ -3421,7 +3421,7 @@ func Test_CompileLite(t *testing.T) { Pull: "not_present", Ruleset: yaml.Ruleset{ If: yaml.Rules{ - Event: []string{"deployment"}, + Event: []string{"deployment:created"}, Target: []string{"production"}, }, Matcher: "filepath", diff --git a/go.mod b/go.mod index bc25fc72b..aefa64a29 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/ghodss/yaml v1.0.0 github.com/gin-gonic/gin v1.9.1 github.com/go-playground/assert/v2 v2.2.0 - github.com/go-vela/types v0.23.4-0.20240405205548-f24f795ac0b7 + github.com/go-vela/types v0.23.4-0.20240417135026-fb4a95c30338 github.com/golang-jwt/jwt/v5 v5.2.1 github.com/google/go-cmp v0.6.0 github.com/google/go-github/v61 v61.0.0 diff --git a/go.sum b/go.sum index 1f35c936b..3b30dd8ed 100644 --- a/go.sum +++ b/go.sum @@ -85,8 +85,8 @@ github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw= github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= -github.com/go-vela/types v0.23.4-0.20240405205548-f24f795ac0b7 h1:3mN7ej69dMH3Vis3G/tPLzLL0Rfp8nR5qd0gpj5ejRM= -github.com/go-vela/types v0.23.4-0.20240405205548-f24f795ac0b7/go.mod h1:mEF9dLkk00rUXf/t39n2WvXZgJbxnPEEWy+DHqIlRUo= +github.com/go-vela/types v0.23.4-0.20240417135026-fb4a95c30338 h1:I0v47dOdAvjX7lOFN4s28uONChmluD6TNgFL1hpav60= +github.com/go-vela/types v0.23.4-0.20240417135026-fb4a95c30338/go.mod h1:vISsYDdjz9RPEK6qZ+MxtrdZEjTVU4K30NomB3826u8= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= From 38cd71424d3975d1a35fcf4e722b3f406ae03584 Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Mon, 6 May 2024 10:45:31 -0400 Subject: [PATCH 42/71] enhance(mock): add dashboard responses from server in mock (#1118) * init commit * add to server * proper dash card resp in mock * fix copypasta --- mock/server/dashboard.go | 252 ++++++++++++++++++++++++++++++++++ mock/server/dashboard_test.go | 59 ++++++++ mock/server/server.go | 6 + 3 files changed, 317 insertions(+) create mode 100644 mock/server/dashboard.go create mode 100644 mock/server/dashboard_test.go diff --git a/mock/server/dashboard.go b/mock/server/dashboard.go new file mode 100644 index 000000000..bd560d7c2 --- /dev/null +++ b/mock/server/dashboard.go @@ -0,0 +1,252 @@ +// SPDX-License-Identifier: Apache-2.0 + +package server + +import ( + "encoding/json" + "fmt" + "net/http" + "strings" + + "github.com/gin-gonic/gin" + + api "github.com/go-vela/server/api/types" + "github.com/go-vela/types" +) + +const ( + // DashboardResp represents a JSON return for a dashboard. + DashboardResp = `{ + "id": "c976470d-34c1-49b2-9a98-1035871c576b", + "name": "my-dashboard", + "created_at": 1714573212, + "created_by": "Octocat", + "updated_at": 1714573212, + "updated_by": "Octocat", + "admins": [ + { + "id": 1, + "name": "Octocat", + "active": true + } + ], + "repos": [ + { + "id": 1, + "name": "Octocat/vela-repo", + "branches": [ + "main" + ], + "events": [ + "push" + ] + } + ] +}` + + // DashCardResp represents a JSON return for a DashCard. + DashCardResp = `{ + "dashboard": { + "id": "6e9f84c3-d853-4afb-b56e-99ff200264c0", + "name": "dashboard-1", + "created_at": 1714677999, + "created_by": "Octocat", + "updated_at": 1714678173, + "updated_by": "Octocat", + "admins": [ + { + "id": 1, + "name": "Octocat", + "active": true + } + ], + "repos": [ + { + "id": 2, + "name": "Octocat/test-repo" + }, + { + "id": 1, + "name": "Octocat/test-repo-2" + } + ] + }, + "repos": [ + { + "org": "Octocat", + "name": "test-repo", + "counter": 1, + "builds": [ + { + "number": 1, + "started": 1714678666, + "finished": 1714678672, + "sender": "Octocat", + "status": "failure", + "event": "deployment", + "branch": "refs/heads/main", + "link": "http://vela/Octocat/test-repo/1" + } + ] + }, + { + "org": "Octocat", + "name": "test-repo-2" + } + ] +}` + + // DashCardsResp represents a JSON return for multiple DashCards. + DashCardsResp = `[ +{ + "dashboard": { + "id": "6e9f84c3-d853-4afb-b56e-99ff200264c0", + "name": "dashboard-1", + "created_at": 1714677999, + "created_by": "Octocat", + "updated_at": 1714678173, + "updated_by": "Octocat", + "admins": [ + { + "id": 1, + "name": "Octocat", + "active": true + } + ], + "repos": [ + { + "id": 2, + "name": "Octocat/test-repo" + }, + { + "id": 1, + "name": "Octocat/test-repo-2" + } + ] + }, + "repos": [ + { + "org": "Octocat", + "name": "test-repo", + "counter": 1, + "builds": [ + { + "number": 1, + "started": 1714678666, + "finished": 1714678672, + "sender": "Octocat", + "status": "failure", + "event": "deployment", + "branch": "refs/heads/main", + "link": "http://vela/Octocat/test-repo/1" + } + ] + }, + { + "org": "Octocat", + "name": "test-repo-2" + } + ] +}, +{ + "dashboard": { + "id": "6e9f84c3-d853-4afb-b56e-99ff200264c1", + "name": "dashboard-2", + "created_at": 1714677999, + "created_by": "Octocat", + "updated_at": 1714678173, + "updated_by": "Octocat", + "admins": [ + { + "id": 1, + "name": "Octocat", + "active": true + } + ], + "repos": [ + { + "id": 2, + "name": "Octocat/test-repo" + }, + { + "id": 1, + "name": "Octocat/test-repo-2" + } + ] + }, + "repos": [ + { + "org": "Octocat", + "name": "test-repo", + "counter": 1, + "builds": [ + { + "number": 1, + "started": 1714678666, + "finished": 1714678672, + "sender": "Octocat", + "status": "failure", + "event": "deployment", + "branch": "refs/heads/main", + "link": "http://vela/Octocat/test-repo/1" + } + ] + }, + { + "org": "Octocat", + "name": "test-repo-2" + } + ] +} +]` +) + +// getDashboards returns mock JSON for a http GET. +func getDashboards(c *gin.Context) { + data := []byte(DashCardsResp) + + var body []api.Dashboard + _ = json.Unmarshal(data, &body) + + c.JSON(http.StatusOK, body) +} + +// getDashboard has a param :dashboard returns mock JSON for a http GET. +func getDashboard(c *gin.Context) { + d := c.Param("dashboard") + + if strings.EqualFold(d, "0") { + msg := fmt.Sprintf("Dashboard %s does not exist", d) + + c.AbortWithStatusJSON(http.StatusNotFound, types.Error{Message: &msg}) + + return + } + + data := []byte(DashCardResp) + + var body api.Dashboard + _ = json.Unmarshal(data, &body) + + c.JSON(http.StatusOK, body) +} + +// addDashboard returns mock JSON for a http POST. +func addDashboard(c *gin.Context) { + data := []byte(DashboardResp) + + var body api.Dashboard + _ = json.Unmarshal(data, &body) + + c.JSON(http.StatusCreated, body) +} + +// updateDashboard returns mock JSON for a http PUT. +func updateDashboard(c *gin.Context) { + data := []byte(DashboardResp) + + var body api.Dashboard + _ = json.Unmarshal(data, &body) + + c.JSON(http.StatusOK, body) +} diff --git a/mock/server/dashboard_test.go b/mock/server/dashboard_test.go new file mode 100644 index 000000000..de09a0257 --- /dev/null +++ b/mock/server/dashboard_test.go @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: Apache-2.0 + +package server + +import ( + "encoding/json" + "reflect" + "testing" + + api "github.com/go-vela/server/api/types" +) + +func TestDashboard_ActiveDashboardResp(t *testing.T) { + testDashboard := api.Dashboard{} + + err := json.Unmarshal([]byte(DashboardResp), &testDashboard) + if err != nil { + t.Errorf("error unmarshaling dashboard: %v", err) + } + + tDashboard := reflect.TypeOf(testDashboard) + + for i := 0; i < tDashboard.NumField(); i++ { + if reflect.ValueOf(testDashboard).Field(i).IsNil() { + t.Errorf("DashboardResp missing field %s", tDashboard.Field(i).Name) + } + } + + testDashCard := api.DashCard{} + + err = json.Unmarshal([]byte(DashCardResp), &testDashCard) + if err != nil { + t.Errorf("error unmarshaling dash card: %v", err) + } + + tDashCard := reflect.TypeOf(testDashCard) + + for i := 0; i < tDashCard.NumField(); i++ { + if reflect.ValueOf(testDashCard).Field(i).IsNil() { + t.Errorf("DashCardResp missing field %s", tDashCard.Field(i).Name) + } + } + + testDashCards := []api.DashCard{} + err = json.Unmarshal([]byte(DashCardsResp), &testDashCards) + if err != nil { + t.Errorf("error unmarshaling dash cards: %v", err) + } + + for _, testDashCard := range testDashCards { + tDashCard := reflect.TypeOf(testDashCard) + + for i := 0; i < tDashCard.NumField(); i++ { + if reflect.ValueOf(testDashCard).Field(i).IsNil() { + t.Errorf("DashboardsResp missing field %s", tDashboard.Field(i).Name) + } + } + } +} diff --git a/mock/server/server.go b/mock/server/server.go index 0b7dcff79..fb6161ccd 100644 --- a/mock/server/server.go +++ b/mock/server/server.go @@ -43,6 +43,12 @@ func FakeHandler() http.Handler { e.GET("/api/v1/repos/:org/:repo/builds/:build/token", buildToken) e.GET("/api/v1/repos/:org/:repo/builds/:build/executable", buildExecutable) + // mock endpoints for dashboard calls + e.GET("/api/v1/dashboards/:dashboard", getDashboard) + e.GET("/api/v1/user/dashboards", getDashboards) + e.POST("/api/v1/dashboards", addDashboard) + e.PUT("/api/v1/dashboards/:dashboard", updateDashboard) + // mock endpoints for deployment calls e.GET("/api/v1/deployments/:org/:repo", getDeployments) e.POST("/api/v1/deployments/:org/:repo", addDeployment) From 993a937238015bc04fe5fb1c2e4d29f2fd8f940d Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Mon, 6 May 2024 10:48:26 -0400 Subject: [PATCH 43/71] fix(dashboards): add active status on repo partial (#1119) --- api/dashboard/get.go | 1 + api/types/dashboard.go | 1 + 2 files changed, 2 insertions(+) diff --git a/api/dashboard/get.go b/api/dashboard/get.go index f36f92ee4..da4239667 100644 --- a/api/dashboard/get.go +++ b/api/dashboard/get.go @@ -98,6 +98,7 @@ func buildRepoPartials(c context.Context, repos []*types.DashboardRepo) ([]types repo.Org = dbRepo.GetOrg() repo.Name = dbRepo.GetName() repo.Counter = dbRepo.GetCounter() + repo.Active = dbRepo.GetActive() // list last 5 builds for repo given the branch and event filters builds, err := database.FromContext(c).ListBuildsForDashboardRepo(c, dbRepo, r.GetBranches(), r.GetEvents()) diff --git a/api/types/dashboard.go b/api/types/dashboard.go index 053942daf..11c3883ee 100644 --- a/api/types/dashboard.go +++ b/api/types/dashboard.go @@ -12,6 +12,7 @@ type RepoPartial struct { Org string `json:"org,omitempty"` Name string `json:"name,omitempty"` Counter int `json:"counter,omitempty"` + Active bool `json:"active,omitempty"` Builds []BuildPartial `json:"builds,omitempty"` } From 8ad123451469039e0125af1943e916c211415642 Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Mon, 6 May 2024 11:41:18 -0400 Subject: [PATCH 44/71] fix(mock): correct type for mock response (#1121) --- mock/server/dashboard.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mock/server/dashboard.go b/mock/server/dashboard.go index bd560d7c2..c2a017050 100644 --- a/mock/server/dashboard.go +++ b/mock/server/dashboard.go @@ -205,7 +205,7 @@ const ( func getDashboards(c *gin.Context) { data := []byte(DashCardsResp) - var body []api.Dashboard + var body []api.DashCard _ = json.Unmarshal(data, &body) c.JSON(http.StatusOK, body) @@ -225,7 +225,7 @@ func getDashboard(c *gin.Context) { data := []byte(DashCardResp) - var body api.Dashboard + var body api.DashCard _ = json.Unmarshal(data, &body) c.JSON(http.StatusOK, body) From 7f1a4c0aa6a36030eea51386cd22452ee615473f Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Tue, 7 May 2024 15:43:21 -0400 Subject: [PATCH 45/71] fix(ci): use intermediate env var for PR title (#1122) --- .github/workflows/validate-pr-title.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/validate-pr-title.yml b/.github/workflows/validate-pr-title.yml index ec3674f79..84ffec5ac 100644 --- a/.github/workflows/validate-pr-title.yml +++ b/.github/workflows/validate-pr-title.yml @@ -13,5 +13,7 @@ jobs: steps: - name: validate title + env: + TITLE: ${{ github.event.pull_request.title }} run: | - 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) + echo "$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) From 300ca456e3bbbf1bc8167dbae0db177370be690b Mon Sep 17 00:00:00 2001 From: Win San Date: Wed, 8 May 2024 08:37:21 -0500 Subject: [PATCH 46/71] feat(schedule)!: show schedule errors and nest object (#1108) * Update schedule error logging * Migrate schedule from types to server * Update schedule function names & comments * Turn Schedule into a nested object * Populate owner in Schedule - Preload owner in Repo, which is nested in Schedule - Update unit tests to reflect change - Update integration tests to reflect change * Update tests to reflect nested Schedule * Run lintfix * Fix naming and string formatting * Add check before clearing Schedule error --------- Co-authored-by: David May <49894298+wass3rw3rk@users.noreply.github.com> Co-authored-by: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Co-authored-by: david may <1301201+wass3r@users.noreply.github.com> --- api/admin/build.go | 2 +- api/build/approve.go | 2 +- api/schedule/create.go | 8 +- api/schedule/update.go | 4 +- api/types/schedule.go | 368 +++++++++++++++++++++ api/types/schedule_test.go | 232 +++++++++++++ cmd/vela-server/schedule.go | 45 ++- database/build/opts.go | 4 +- database/integration_test.go | 70 ++-- database/resource.go | 1 + database/schedule/count_active_test.go | 72 +++- database/schedule/count_repo_test.go | 84 +++-- database/schedule/count_test.go | 74 ++++- database/schedule/create.go | 21 +- database/schedule/create_test.go | 65 +++- database/schedule/delete.go | 10 +- database/schedule/delete_test.go | 53 ++- database/schedule/get.go | 18 +- database/schedule/get_repo.go | 17 +- database/schedule/get_repo_test.go | 100 +++++- database/schedule/get_test.go | 96 +++++- database/schedule/interface.go | 17 +- database/schedule/list.go | 20 +- database/schedule/list_active.go | 20 +- database/schedule/list_active_test.go | 114 +++++-- database/schedule/list_repo.go | 21 +- database/schedule/list_repo_test.go | 120 +++++-- database/schedule/list_test.go | 117 +++++-- database/schedule/opts.go | 10 + database/schedule/schedule.go | 2 + database/schedule/schedule_test.go | 43 --- database/schedule/table.go | 2 + database/schedule/update.go | 20 +- database/schedule/update_test.go | 129 ++++++-- database/testutils/api_resources.go | 17 + database/types/repo_test.go | 2 +- database/types/schedule.go | 155 +++++++++ database/types/schedule_test.go | 234 +++++++++++++ mock/server/schedule.go | 182 ++++++++-- mock/server/schedule_test.go | 4 +- router/middleware/schedule/context.go | 8 +- router/middleware/schedule/context_test.go | 6 +- router/middleware/schedule/schedule.go | 4 +- 43 files changed, 2219 insertions(+), 374 deletions(-) create mode 100644 api/types/schedule.go create mode 100644 api/types/schedule_test.go create mode 100644 database/types/schedule.go create mode 100644 database/types/schedule_test.go diff --git a/api/admin/build.go b/api/admin/build.go index 5e8d06694..1a4fe0489 100644 --- a/api/admin/build.go +++ b/api/admin/build.go @@ -45,7 +45,7 @@ import ( // "$ref": "#/definitions/Error" // AllBuildsQueue represents the API handler to -// captures all running and pending builds stored in the database. +// capture all running and pending builds stored in the database. func AllBuildsQueue(c *gin.Context) { // capture middleware values ctx := c.Request.Context() diff --git a/api/build/approve.go b/api/build/approve.go index cd022bd79..16c1fcc65 100644 --- a/api/build/approve.go +++ b/api/build/approve.go @@ -70,7 +70,7 @@ import ( // schema: // "$ref": "#/definitions/Error" -// CreateBuild represents the API handler to approve a build to run in the configured backend. +// ApproveBuild represents the API handler to approve a build to run in the configured backend. func ApproveBuild(c *gin.Context) { // capture middleware values b := build.Retrieve(c) diff --git a/api/schedule/create.go b/api/schedule/create.go index 7a9439b8c..a691230e6 100644 --- a/api/schedule/create.go +++ b/api/schedule/create.go @@ -11,11 +11,11 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/go-vela/types/library" ) // swagger:operation POST /api/v1/schedules/{org}/{repo} schedules CreateSchedule @@ -81,7 +81,7 @@ func CreateSchedule(c *gin.Context) { minimumFrequency := c.Value("scheduleminimumfrequency").(time.Duration) // capture body from API request - input := new(library.Schedule) + input := new(api.Schedule) err := c.Bind(input) if err != nil { @@ -127,11 +127,11 @@ func CreateSchedule(c *gin.Context) { return } - s := new(library.Schedule) + s := new(api.Schedule) // update fields in schedule object s.SetCreatedBy(u.GetName()) - s.SetRepoID(r.GetID()) + s.SetRepo(r) s.SetName(input.GetName()) s.SetEntry(input.GetEntry()) s.SetCreatedAt(time.Now().UTC().Unix()) diff --git a/api/schedule/update.go b/api/schedule/update.go index 41da289ec..c29678570 100644 --- a/api/schedule/update.go +++ b/api/schedule/update.go @@ -10,12 +10,12 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/schedule" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/go-vela/types/library" ) // swagger:operation PUT /api/v1/schedules/{org}/{repo}/{schedule} schedules UpdateSchedule @@ -88,7 +88,7 @@ func UpdateSchedule(c *gin.Context) { }).Infof("updating schedule %s", scheduleName) // capture body from API request - input := new(library.Schedule) + input := new(api.Schedule) err := c.Bind(input) if err != nil { diff --git a/api/types/schedule.go b/api/types/schedule.go new file mode 100644 index 000000000..c21568a27 --- /dev/null +++ b/api/types/schedule.go @@ -0,0 +1,368 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "fmt" +) + +// Schedule is the API representation of a schedule for a repo. +// +// swagger:model Schedule +type Schedule struct { + ID *int64 `json:"id,omitempty"` + Repo *Repo `json:"repo,omitempty"` + Active *bool `json:"active,omitempty"` + Name *string `json:"name,omitempty"` + Entry *string `json:"entry,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty"` + CreatedBy *string `json:"created_by,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` + ScheduledAt *int64 `json:"scheduled_at,omitempty"` + Branch *string `json:"branch,omitempty"` + Error *string `json:"error,omitempty"` +} + +// GetID returns the ID field. +// +// When the provided Schedule type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (s *Schedule) GetID() int64 { + // return zero value if Schedule type or ID field is nil + if s == nil || s.ID == nil { + return 0 + } + + return *s.ID +} + +// GetRepo returns the Repo field. +// +// When the provided Schedule type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (s *Schedule) GetRepo() *Repo { + // return zero value if Schedule type or RepoID field is nil + if s == nil || s.Repo == nil { + return new(Repo) + } + + return s.Repo +} + +// GetActive returns the Active field. +// +// When the provided Schedule type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (s *Schedule) GetActive() bool { + // return zero value if Schedule type or Active field is nil + if s == nil || s.Active == nil { + return false + } + + return *s.Active +} + +// GetName returns the Name field. +// +// When the provided Schedule type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (s *Schedule) GetName() string { + // return zero value if Schedule type or Name field is nil + if s == nil || s.Name == nil { + return "" + } + + return *s.Name +} + +// GetEntry returns the Entry field. +// +// When the provided Schedule type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (s *Schedule) GetEntry() string { + // return zero value if Schedule type or Entry field is nil + if s == nil || s.Entry == nil { + return "" + } + + return *s.Entry +} + +// GetCreatedAt returns the CreatedAt field. +// +// When the provided Schedule type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (s *Schedule) GetCreatedAt() int64 { + // return zero value if Schedule type or CreatedAt field is nil + if s == nil || s.CreatedAt == nil { + return 0 + } + + return *s.CreatedAt +} + +// GetCreatedBy returns the CreatedBy field. +// +// When the provided Schedule type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (s *Schedule) GetCreatedBy() string { + // return zero value if Schedule type or CreatedBy field is nil + if s == nil || s.CreatedBy == nil { + return "" + } + + return *s.CreatedBy +} + +// GetUpdatedAt returns the UpdatedAt field. +// +// When the provided Schedule type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (s *Schedule) GetUpdatedAt() int64 { + // return zero value if Schedule type or UpdatedAt field is nil + if s == nil || s.UpdatedAt == nil { + return 0 + } + + return *s.UpdatedAt +} + +// GetUpdatedBy returns the UpdatedBy field. +// +// When the provided Schedule type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (s *Schedule) GetUpdatedBy() string { + // return zero value if Schedule type or UpdatedBy field is nil + if s == nil || s.UpdatedBy == nil { + return "" + } + + return *s.UpdatedBy +} + +// GetScheduledAt returns the ScheduledAt field. +// +// When the provided Schedule type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (s *Schedule) GetScheduledAt() int64 { + // return zero value if Schedule type or ScheduledAt field is nil + if s == nil || s.ScheduledAt == nil { + return 0 + } + + return *s.ScheduledAt +} + +// GetBranch returns the Branch field. +// +// When the provided Schedule type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (s *Schedule) GetBranch() string { + // return zero value if Schedule type or ScheduledAt field is nil + if s == nil || s.Branch == nil { + return "" + } + + return *s.Branch +} + +// GetError returns the Error field. +// +// When the provided Schedule type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (s *Schedule) GetError() string { + // return zero value if Schedule type or Error field is nil + if s == nil || s.Error == nil { + return "" + } + + return *s.Error +} + +// SetID sets the ID field. +// +// When the provided Schedule type is nil, it +// will set nothing and immediately return. +func (s *Schedule) SetID(id int64) { + // return if Schedule type is nil + if s == nil { + return + } + + s.ID = &id +} + +// SetRepo sets the Repo field. +// +// When the provided Schedule type is nil, it +// will set nothing and immediately return. +func (s *Schedule) SetRepo(v *Repo) { + // return if Schedule type is nil + if s == nil { + return + } + + s.Repo = v +} + +// SetActive sets the Active field. +// +// When the provided Schedule type is nil, it +// will set nothing and immediately return. +func (s *Schedule) SetActive(active bool) { + // return if Schedule type is nil + if s == nil { + return + } + + s.Active = &active +} + +// SetName sets the Name field. +// +// When the provided Schedule type is nil, it +// will set nothing and immediately return. +func (s *Schedule) SetName(name string) { + // return if Schedule type is nil + if s == nil { + return + } + + s.Name = &name +} + +// SetEntry sets the Entry field. +// +// When the provided Schedule type is nil, it +// will set nothing and immediately return. +func (s *Schedule) SetEntry(entry string) { + // return if Schedule type is nil + if s == nil { + return + } + + s.Entry = &entry +} + +// SetCreatedAt sets the CreatedAt field. +// +// When the provided Schedule type is nil, it +// will set nothing and immediately return. +func (s *Schedule) SetCreatedAt(createdAt int64) { + // return if Schedule type is nil + if s == nil { + return + } + + s.CreatedAt = &createdAt +} + +// SetCreatedBy sets the CreatedBy field. +// +// When the provided Schedule type is nil, it +// will set nothing and immediately return. +func (s *Schedule) SetCreatedBy(createdBy string) { + // return if Schedule type is nil + if s == nil { + return + } + + s.CreatedBy = &createdBy +} + +// SetUpdatedAt sets the UpdatedAt field. +// +// When the provided Schedule type is nil, it +// will set nothing and immediately return. +func (s *Schedule) SetUpdatedAt(updatedAt int64) { + // return if Schedule type is nil + if s == nil { + return + } + + s.UpdatedAt = &updatedAt +} + +// SetUpdatedBy sets the UpdatedBy field. +// +// When the provided Schedule type is nil, it +// will set nothing and immediately return. +func (s *Schedule) SetUpdatedBy(updatedBy string) { + // return if Schedule type is nil + if s == nil { + return + } + + s.UpdatedBy = &updatedBy +} + +// SetScheduledAt sets the ScheduledAt field. +// +// When the provided Schedule type is nil, it +// will set nothing and immediately return. +func (s *Schedule) SetScheduledAt(scheduledAt int64) { + // return if Schedule type is nil + if s == nil { + return + } + + s.ScheduledAt = &scheduledAt +} + +// SetBranch sets the Branch field. +// +// When the provided Schedule type is nil, it +// will set nothing and immediately return. +func (s *Schedule) SetBranch(branch string) { + // return if Schedule type is nil + if s == nil { + return + } + + s.Branch = &branch +} + +// SetError sets the Error field. +// +// When the provided Schedule type is nil, it +// will set nothing and immediately return. +func (s *Schedule) SetError(err string) { + // return if Schedule type is nil + if s == nil { + return + } + + s.Error = &err +} + +// String implements the Stringer interface for the Schedule type. +func (s *Schedule) String() string { + return fmt.Sprintf(`{ + Active: %t, + CreatedAt: %d, + CreatedBy: %s, + Entry: %s, + ID: %d, + Name: %s, + Repo: %v, + ScheduledAt: %d, + UpdatedAt: %d, + UpdatedBy: %s, + Branch: %s, + Error: %s, +}`, + s.GetActive(), + s.GetCreatedAt(), + s.GetCreatedBy(), + s.GetEntry(), + s.GetID(), + s.GetName(), + s.GetRepo(), + s.GetScheduledAt(), + s.GetUpdatedAt(), + s.GetUpdatedBy(), + s.GetBranch(), + s.GetError(), + ) +} diff --git a/api/types/schedule_test.go b/api/types/schedule_test.go new file mode 100644 index 000000000..ca5bb09db --- /dev/null +++ b/api/types/schedule_test.go @@ -0,0 +1,232 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "fmt" + "strings" + "testing" + "time" +) + +func TestTypes_Schedule_Getters(t *testing.T) { + tests := []struct { + name string + schedule *Schedule + want *Schedule + }{ + { + name: "schedule with fields", + schedule: testSchedule(), + want: testSchedule(), + }, + { + name: "schedule with empty fields", + schedule: new(Schedule), + want: new(Schedule), + }, + { + name: "empty schedule", + schedule: nil, + want: nil, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + if test.schedule.GetID() != test.want.GetID() { + t.Errorf("GetID is %v, want %v", test.schedule.GetID(), test.want.GetID()) + } + + if test.schedule.GetRepo().GetID() != test.want.GetRepo().GetID() { + t.Errorf("GetRepoID is %v, want %v", test.schedule.GetRepo().GetID(), test.want.GetRepo().GetID()) + } + + if test.schedule.GetActive() != test.want.GetActive() { + t.Errorf("GetActive is %v, want %v", test.schedule.GetActive(), test.want.GetActive()) + } + + if test.schedule.GetName() != test.want.GetName() { + t.Errorf("GetName is %v, want %v", test.schedule.GetName(), test.want.GetName()) + } + + if test.schedule.GetEntry() != test.want.GetEntry() { + t.Errorf("GetEntry is %v, want %v", test.schedule.GetEntry(), test.want.GetEntry()) + } + + if test.schedule.GetCreatedAt() != test.want.GetCreatedAt() { + t.Errorf("GetCreatedAt is %v, want %v", test.schedule.GetCreatedAt(), test.want.GetCreatedAt()) + } + + if test.schedule.GetCreatedBy() != test.want.GetCreatedBy() { + t.Errorf("GetCreatedBy is %v, want %v", test.schedule.GetCreatedBy(), test.want.GetCreatedBy()) + } + + if test.schedule.GetUpdatedAt() != test.want.GetUpdatedAt() { + t.Errorf("GetUpdatedAt is %v, want %v", test.schedule.GetUpdatedAt(), test.want.GetUpdatedAt()) + } + + if test.schedule.GetUpdatedBy() != test.want.GetUpdatedBy() { + t.Errorf("GetUpdatedBy is %v, want %v", test.schedule.GetUpdatedBy(), test.want.GetUpdatedBy()) + } + + if test.schedule.GetScheduledAt() != test.want.GetScheduledAt() { + t.Errorf("GetScheduledAt is %v, want %v", test.schedule.GetScheduledAt(), test.want.GetScheduledAt()) + } + + if test.schedule.GetBranch() != test.want.GetBranch() { + t.Errorf("GetBranch is %v, want %v", test.schedule.GetBranch(), test.want.GetBranch()) + } + + if test.schedule.GetError() != test.want.GetError() { + t.Errorf("GetError is %v, want %v", test.schedule.GetError(), test.want.GetError()) + } + }) + } +} + +func TestTypes_Schedule_Setters(t *testing.T) { + tests := []struct { + name string + schedule *Schedule + want *Schedule + }{ + { + name: "schedule with fields", + schedule: testSchedule(), + want: testSchedule(), + }, + { + name: "schedule with empty fields", + schedule: new(Schedule), + want: new(Schedule), + }, + { + name: "empty schedule", + schedule: nil, + want: nil, + }, + } + + // run tests + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + test.schedule.SetID(test.want.GetID()) + test.schedule.SetRepo(test.want.GetRepo()) + test.schedule.SetActive(test.want.GetActive()) + test.schedule.SetName(test.want.GetName()) + test.schedule.SetEntry(test.want.GetEntry()) + test.schedule.SetCreatedAt(test.want.GetCreatedAt()) + test.schedule.SetCreatedBy(test.want.GetCreatedBy()) + test.schedule.SetUpdatedAt(test.want.GetUpdatedAt()) + test.schedule.SetUpdatedBy(test.want.GetUpdatedBy()) + test.schedule.SetScheduledAt(test.want.GetScheduledAt()) + test.schedule.SetBranch(test.want.GetBranch()) + test.schedule.SetError(test.want.GetError()) + + if test.schedule.GetID() != test.want.GetID() { + t.Errorf("SetID is %v, want %v", test.schedule.GetID(), test.want.GetID()) + } + + if test.schedule.GetRepo().GetID() != test.want.GetRepo().GetID() { + t.Errorf("SetRepoID is %v, want %v", test.schedule.GetRepo().GetID(), test.want.GetRepo().GetID()) + } + + if test.schedule.GetActive() != test.want.GetActive() { + t.Errorf("SetActive is %v, want %v", test.schedule.GetActive(), test.want.GetActive()) + } + + if test.schedule.GetName() != test.want.GetName() { + t.Errorf("SetName is %v, want %v", test.schedule.GetName(), test.want.GetName()) + } + + if test.schedule.GetEntry() != test.want.GetEntry() { + t.Errorf("SetEntry is %v, want %v", test.schedule.GetEntry(), test.want.GetEntry()) + } + + if test.schedule.GetCreatedAt() != test.want.GetCreatedAt() { + t.Errorf("SetCreatedAt is %v, want %v", test.schedule.GetCreatedAt(), test.want.GetCreatedAt()) + } + + if test.schedule.GetCreatedBy() != test.want.GetCreatedBy() { + t.Errorf("SetCreatedBy is %v, want %v", test.schedule.GetCreatedBy(), test.want.GetCreatedBy()) + } + + if test.schedule.GetUpdatedAt() != test.want.GetUpdatedAt() { + t.Errorf("SetUpdatedAt is %v, want %v", test.schedule.GetUpdatedAt(), test.want.GetUpdatedAt()) + } + + if test.schedule.GetUpdatedBy() != test.want.GetUpdatedBy() { + t.Errorf("SetUpdatedBy is %v, want %v", test.schedule.GetUpdatedBy(), test.want.GetUpdatedBy()) + } + + if test.schedule.GetScheduledAt() != test.want.GetScheduledAt() { + t.Errorf("SetScheduledAt is %v, want %v", test.schedule.GetScheduledAt(), test.want.GetScheduledAt()) + } + + if test.schedule.GetBranch() != test.want.GetBranch() { + t.Errorf("SetBranch is %v, want %v", test.schedule.GetBranch(), test.want.GetBranch()) + } + + if test.schedule.GetError() != test.want.GetError() { + t.Errorf("SetError is %v, want %v", test.schedule.GetError(), test.want.GetError()) + } + }) + } +} + +func TestTypes_Schedule_String(t *testing.T) { + s := testSchedule() + + want := fmt.Sprintf(`{ + Active: %t, + CreatedAt: %d, + CreatedBy: %s, + Entry: %s, + ID: %d, + Name: %s, + Repo: %v, + ScheduledAt: %d, + UpdatedAt: %d, + UpdatedBy: %s, + Branch: %s, + Error: %s, +}`, + s.GetActive(), + s.GetCreatedAt(), + s.GetCreatedBy(), + s.GetEntry(), + s.GetID(), + s.GetName(), + s.GetRepo(), + s.GetScheduledAt(), + s.GetUpdatedAt(), + s.GetUpdatedBy(), + s.GetBranch(), + s.GetError(), + ) + + got := s.String() + if !strings.EqualFold(got, want) { + t.Errorf("String is %v, want %v", got, want) + } +} + +// testSchedule is a test helper function to create a Schedule type with all fields set to a fake value. +func testSchedule() *Schedule { + s := new(Schedule) + s.SetID(1) + s.SetRepo(testRepo()) + s.SetActive(true) + s.SetName("nightly") + s.SetEntry("0 0 * * *") + s.SetCreatedAt(time.Now().UTC().Unix()) + s.SetCreatedBy("user1") + s.SetUpdatedAt(time.Now().Add(time.Hour * 1).UTC().Unix()) + s.SetUpdatedBy("user2") + s.SetScheduledAt(time.Now().Add(time.Hour * 2).UTC().Unix()) + s.SetBranch("main") + s.SetError("unable to trigger build for schedule nightly: unknown character") + + return s +} diff --git a/cmd/vela-server/schedule.go b/cmd/vela-server/schedule.go index ee4a32acd..b86e70b79 100644 --- a/cmd/vela-server/schedule.go +++ b/cmd/vela-server/schedule.go @@ -21,7 +21,6 @@ import ( "github.com/go-vela/server/scm" "github.com/go-vela/server/util" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" ) const ( @@ -55,7 +54,7 @@ func processSchedules(ctx context.Context, start time.Time, compiler compiler.En // amount of time to get to the end of the list. schedule, err := database.GetSchedule(ctx, s.GetID()) if err != nil { - logrus.WithError(err).Warnf("%s %s", scheduleErr, schedule.GetName()) + handleError(ctx, database, err, schedule) continue } @@ -75,7 +74,7 @@ func processSchedules(ctx context.Context, start time.Time, compiler compiler.En // i.e. if it's 4:02 on five minute intervals, this will be 4:00 prevTime, err := gronx.PrevTick(schedule.GetEntry(), true) if err != nil { - logrus.WithError(err).Warnf("%s %s", scheduleErr, schedule.GetName()) + handleError(ctx, database, err, schedule) continue } @@ -85,7 +84,7 @@ func processSchedules(ctx context.Context, start time.Time, compiler compiler.En // i.e. if it's 4:02 on five minute intervals, this will be 4:05 nextTime, err := gronx.NextTickAfter(schedule.GetEntry(), scheduled, true) if err != nil { - logrus.WithError(err).Warnf("%s %s", scheduleErr, schedule.GetName()) + handleError(ctx, database, err, schedule) continue } @@ -117,7 +116,7 @@ func processSchedules(ctx context.Context, start time.Time, compiler compiler.En // send API call to update schedule for ensuring scheduled_at field is set _, err = database.UpdateSchedule(ctx, schedule, false) if err != nil { - logrus.WithError(err).Warnf("%s %s", scheduleErr, schedule.GetName()) + handleError(ctx, database, err, schedule) continue } @@ -125,19 +124,32 @@ func processSchedules(ctx context.Context, start time.Time, compiler compiler.En // process the schedule and trigger a new build err = processSchedule(ctx, schedule, compiler, database, metadata, queue, scm, allowList) if err != nil { - logrus.WithError(err).Warnf("%s %s", scheduleErr, schedule.GetName()) + handleError(ctx, database, err, schedule) continue } + + // successfully scheduled build so clear error message, if not already cleared + if schedule.GetError() != "" { + schedule.SetError("") + + // send API call to update schedule with the error message field cleared + _, err = database.UpdateSchedule(ctx, schedule, true) + if err != nil { + handleError(ctx, database, err, schedule) + + continue + } + } } return nil } // processSchedule will, given a schedule, process it and trigger a new build. -func processSchedule(ctx context.Context, s *library.Schedule, compiler compiler.Engine, database database.Interface, metadata *internal.Metadata, queue queue.Service, scm scm.Service, allowList []string) error { +func processSchedule(ctx context.Context, s *api.Schedule, compiler compiler.Engine, database database.Interface, metadata *internal.Metadata, queue queue.Service, scm scm.Service, allowList []string) error { // send API call to capture the repo for the schedule - r, err := database.GetRepo(ctx, s.GetRepoID()) + r, err := database.GetRepo(ctx, s.GetRepo().GetID()) if err != nil { return fmt.Errorf("unable to fetch repo: %w", err) } @@ -203,3 +215,20 @@ func processSchedule(ctx context.Context, s *library.Schedule, compiler compiler return nil } + +func handleError(ctx context.Context, database database.Interface, err error, schedule *api.Schedule) { + // log the error message + logrus.WithError(err).Warnf("%s %s: %s", scheduleErr, schedule.GetName(), err.Error()) + + // format the error message + msg := fmt.Sprintf("%s %s: %s", scheduleErr, schedule.GetName(), err.Error()) + + // update the message field with the error message + schedule.SetError(msg) + + // send API call to update schedule to ensure message field is set + _, err = database.UpdateSchedule(ctx, schedule, true) + if err != nil { + logrus.WithError(err).Warnf("%s %s: %s", scheduleErr, schedule.GetName(), err.Error()) + } +} diff --git a/database/build/opts.go b/database/build/opts.go index 0c3a661be..a83ef0a16 100644 --- a/database/build/opts.go +++ b/database/build/opts.go @@ -22,10 +22,10 @@ func WithClient(client *gorm.DB) EngineOpt { } } -// WithEncryptionKey sets the encryption key in the database engine for Repos. +// WithEncryptionKey sets the encryption key in the database engine for Builds. func WithEncryptionKey(key string) EngineOpt { return func(e *engine) error { - // set the encryption key in the repo engine + // set the encryption key in the build engine e.config.EncryptionKey = key return nil diff --git a/database/integration_test.go b/database/integration_test.go index 36e2cb5a6..4f28bbb4e 100644 --- a/database/integration_test.go +++ b/database/integration_test.go @@ -43,7 +43,7 @@ type Resources struct { Logs []*library.Log Pipelines []*library.Pipeline Repos []*api.Repo - Schedules []*library.Schedule + Schedules []*api.Schedule Secrets []*library.Secret Services []*library.Service Steps []*library.Step @@ -1278,11 +1278,25 @@ func testSchedules(t *testing.T, db Interface, resources *Resources) { methods[element.Method(i).Name] = false } - ctx := context.TODO() + // create owners + for _, user := range resources.Users { + _, err := db.CreateUser(context.TODO(), user) + if err != nil { + t.Errorf("unable to create user %d: %v", user.GetID(), err) + } + } + + // create the repos + for _, repo := range resources.Repos { + _, err := db.CreateRepo(context.TODO(), repo) + if err != nil { + t.Errorf("unable to create repo %d: %v", repo.GetID(), err) + } + } // create the schedules for _, schedule := range resources.Schedules { - _, err := db.CreateSchedule(ctx, schedule) + _, err := db.CreateSchedule(context.TODO(), schedule) if err != nil { t.Errorf("unable to create schedule %d: %v", schedule.GetID(), err) } @@ -1290,7 +1304,7 @@ func testSchedules(t *testing.T, db Interface, resources *Resources) { methods["CreateSchedule"] = true // count the schedules - count, err := db.CountSchedules(ctx) + count, err := db.CountSchedules(context.TODO()) if err != nil { t.Errorf("unable to count schedules: %v", err) } @@ -1300,7 +1314,7 @@ func testSchedules(t *testing.T, db Interface, resources *Resources) { methods["CountSchedules"] = true // count the schedules for a repo - count, err = db.CountSchedulesForRepo(ctx, resources.Repos[0]) + count, err = db.CountSchedulesForRepo(context.TODO(), resources.Repos[0]) if err != nil { t.Errorf("unable to count schedules for repo %d: %v", resources.Repos[0].GetID(), err) } @@ -1310,7 +1324,7 @@ func testSchedules(t *testing.T, db Interface, resources *Resources) { methods["CountSchedulesForRepo"] = true // list the schedules - list, err := db.ListSchedules(ctx) + list, err := db.ListSchedules(context.TODO()) if err != nil { t.Errorf("unable to list schedules: %v", err) } @@ -1320,7 +1334,7 @@ func testSchedules(t *testing.T, db Interface, resources *Resources) { methods["ListSchedules"] = true // list the active schedules - list, err = db.ListActiveSchedules(ctx) + list, err = db.ListActiveSchedules(context.TODO()) if err != nil { t.Errorf("unable to list schedules: %v", err) } @@ -1330,22 +1344,22 @@ func testSchedules(t *testing.T, db Interface, resources *Resources) { methods["ListActiveSchedules"] = true // list the schedules for a repo - list, count, err = db.ListSchedulesForRepo(ctx, resources.Repos[0], 1, 10) + list, count, err = db.ListSchedulesForRepo(context.TODO(), resources.Repos[0], 1, 10) if err != nil { t.Errorf("unable to count schedules for repo %d: %v", resources.Repos[0].GetID(), err) } if int(count) != len(resources.Schedules) { t.Errorf("ListSchedulesForRepo() is %v, want %v", count, len(resources.Schedules)) } - if !cmp.Equal(list, []*library.Schedule{resources.Schedules[1], resources.Schedules[0]}, CmpOptApproxUpdatedAt()) { - t.Errorf("ListSchedulesForRepo() is %v, want %v", list, []*library.Schedule{resources.Schedules[1], resources.Schedules[0]}) + if !cmp.Equal(list, []*api.Schedule{resources.Schedules[1], resources.Schedules[0]}, CmpOptApproxUpdatedAt()) { + t.Errorf("ListSchedulesForRepo() is %v, want %v", list, []*api.Schedule{resources.Schedules[1], resources.Schedules[0]}) } methods["ListSchedulesForRepo"] = true // lookup the schedules by name for _, schedule := range resources.Schedules { - repo := resources.Repos[schedule.GetRepoID()-1] - got, err := db.GetScheduleForRepo(ctx, repo, schedule.GetName()) + repo := resources.Repos[schedule.GetRepo().GetID()-1] + got, err := db.GetScheduleForRepo(context.TODO(), repo, schedule.GetName()) if err != nil { t.Errorf("unable to get schedule %d for repo %d: %v", schedule.GetID(), repo.GetID(), err) } @@ -1358,7 +1372,7 @@ func testSchedules(t *testing.T, db Interface, resources *Resources) { // update the schedules for _, schedule := range resources.Schedules { schedule.SetUpdatedAt(time.Now().UTC().Unix()) - got, err := db.UpdateSchedule(ctx, schedule, true) + got, err := db.UpdateSchedule(context.TODO(), schedule, true) if err != nil { t.Errorf("unable to update schedule %d: %v", schedule.GetID(), err) } @@ -1372,13 +1386,29 @@ func testSchedules(t *testing.T, db Interface, resources *Resources) { // delete the schedules for _, schedule := range resources.Schedules { - err = db.DeleteSchedule(ctx, schedule) + err = db.DeleteSchedule(context.TODO(), schedule) if err != nil { t.Errorf("unable to delete schedule %d: %v", schedule.GetID(), err) } } methods["DeleteSchedule"] = true + // delete the repos + for _, repo := range resources.Repos { + err = db.DeleteRepo(context.TODO(), repo) + if err != nil { + t.Errorf("unable to delete repo %d: %v", repo.GetID(), err) + } + } + + // delete the owners + for _, user := range resources.Users { + err := db.DeleteUser(context.TODO(), user) + if err != nil { + t.Errorf("unable to delete user %d: %v", user.GetID(), err) + } + } + // ensure we called all the methods we expected to for method, called := range methods { if !called { @@ -2462,9 +2492,9 @@ func newResources() *Resources { pipelineTwo.SetTemplates(false) pipelineTwo.SetData([]byte("version: 1")) - scheduleOne := new(library.Schedule) + scheduleOne := new(api.Schedule) scheduleOne.SetID(1) - scheduleOne.SetRepoID(1) + scheduleOne.SetRepo(repoOne) scheduleOne.SetActive(true) scheduleOne.SetName("nightly") scheduleOne.SetEntry("0 0 * * *") @@ -2474,10 +2504,11 @@ func newResources() *Resources { scheduleOne.SetUpdatedBy("octokitty") scheduleOne.SetScheduledAt(time.Now().Add(time.Hour * 2).UTC().Unix()) scheduleOne.SetBranch("main") + scheduleOne.SetError("no version: YAML property provided") - scheduleTwo := new(library.Schedule) + scheduleTwo := new(api.Schedule) scheduleTwo.SetID(2) - scheduleTwo.SetRepoID(1) + scheduleTwo.SetRepo(repoOne) scheduleTwo.SetActive(true) scheduleTwo.SetName("hourly") scheduleTwo.SetEntry("0 * * * *") @@ -2487,6 +2518,7 @@ func newResources() *Resources { scheduleTwo.SetUpdatedBy("octokitty") scheduleTwo.SetScheduledAt(time.Now().Add(time.Hour * 2).UTC().Unix()) scheduleTwo.SetBranch("main") + scheduleTwo.SetError("no version: YAML property provided") secretOrg := new(library.Secret) secretOrg.SetID(1) @@ -2654,7 +2686,7 @@ func newResources() *Resources { Logs: []*library.Log{logServiceOne, logServiceTwo, logStepOne, logStepTwo}, Pipelines: []*library.Pipeline{pipelineOne, pipelineTwo}, Repos: []*api.Repo{repoOne, repoTwo}, - Schedules: []*library.Schedule{scheduleOne, scheduleTwo}, + Schedules: []*api.Schedule{scheduleOne, scheduleTwo}, Secrets: []*library.Secret{secretOrg, secretRepo, secretShared}, Services: []*library.Service{serviceOne, serviceTwo}, Steps: []*library.Step{stepOne, stepTwo}, diff --git a/database/resource.go b/database/resource.go index cbdad190c..21b805227 100644 --- a/database/resource.go +++ b/database/resource.go @@ -122,6 +122,7 @@ func (e *engine) NewResources(ctx context.Context) error { e.ScheduleInterface, err = schedule.New( schedule.WithContext(e.ctx), schedule.WithClient(e.client), + schedule.WithEncryptionKey(e.config.EncryptionKey), schedule.WithLogger(e.logger), schedule.WithSkipCreation(e.config.SkipCreation), ) diff --git a/database/schedule/count_active_test.go b/database/schedule/count_active_test.go index 6fb88849f..6c496965f 100644 --- a/database/schedule/count_active_test.go +++ b/database/schedule/count_active_test.go @@ -4,36 +4,78 @@ package schedule import ( "context" - "reflect" "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/google/go-cmp/cmp" + + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" + "github.com/go-vela/types/constants" ) func TestSchedule_Engine_CountActiveSchedules(t *testing.T) { - _scheduleOne := testSchedule() + // setup types + _owner := testutils.APIUser() + _owner.SetID(1) + _owner.SetName("octocat") + _owner.SetToken("superSecretToken") + _owner.SetRefreshToken("superSecretRefreshToken") + _owner.SetFavorites([]string{"github/octocat"}) + _owner.SetActive(true) + _owner.SetAdmin(false) + _owner.SetDashboards([]string{"45bcf19b-c151-4e2d-b8c6-80a62ba2eae7"}) + + _repo := testutils.APIRepo() + _repo.SetID(1) + _repo.SetOwner(_owner.Crop()) + _repo.SetHash("MzM4N2MzMDAtNmY4Mi00OTA5LWFhZDAtNWIzMTlkNTJkODMy") + _repo.SetOrg("github") + _repo.SetName("octocat") + _repo.SetFullName("github/octocat") + _repo.SetLink("https://github.com/github/octocat") + _repo.SetClone("https://github.com/github/octocat.git") + _repo.SetBranch("main") + _repo.SetTopics([]string{"cloud", "security"}) + _repo.SetBuildLimit(10) + _repo.SetTimeout(30) + _repo.SetCounter(0) + _repo.SetVisibility("public") + _repo.SetPrivate(false) + _repo.SetTrusted(false) + _repo.SetActive(true) + _repo.SetAllowEvents(api.NewEventsFromMask(1)) + _repo.SetPipelineType("") + _repo.SetPreviousName("") + _repo.SetApproveBuild(constants.ApproveNever) + + _scheduleOne := testutils.APISchedule() _scheduleOne.SetID(1) - _scheduleOne.SetRepoID(1) + _scheduleOne.SetRepo(_repo) _scheduleOne.SetActive(true) _scheduleOne.SetName("nightly") _scheduleOne.SetEntry("0 0 * * *") - _scheduleOne.SetCreatedAt(1) - _scheduleOne.SetCreatedBy("user1") - _scheduleOne.SetUpdatedAt(1) - _scheduleOne.SetUpdatedBy("user2") + _scheduleOne.SetCreatedAt(1713476291) + _scheduleOne.SetCreatedBy("octocat") + _scheduleOne.SetUpdatedAt(3013476291) + _scheduleOne.SetUpdatedBy("octokitty") + _scheduleOne.SetScheduledAt(2013476291) _scheduleOne.SetBranch("main") + _scheduleOne.SetError("no version: YAML property provided") - _scheduleTwo := testSchedule() + _scheduleTwo := testutils.APISchedule() _scheduleTwo.SetID(2) - _scheduleTwo.SetRepoID(2) + _scheduleTwo.SetRepo(_repo) _scheduleTwo.SetActive(false) _scheduleTwo.SetName("hourly") _scheduleTwo.SetEntry("0 * * * *") - _scheduleTwo.SetCreatedAt(1) - _scheduleTwo.SetCreatedBy("user1") - _scheduleTwo.SetUpdatedAt(1) - _scheduleTwo.SetUpdatedBy("user2") + _scheduleTwo.SetCreatedAt(1713476291) + _scheduleTwo.SetCreatedBy("octocat") + _scheduleTwo.SetUpdatedAt(3013476291) + _scheduleTwo.SetUpdatedBy("octokitty") + _scheduleTwo.SetScheduledAt(2013476291) _scheduleTwo.SetBranch("main") + _scheduleTwo.SetError("no version: YAML property provided") _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() @@ -95,8 +137,8 @@ func TestSchedule_Engine_CountActiveSchedules(t *testing.T) { t.Errorf("CountActiveSchedules for %s returned err: %v", test.name, err) } - if !reflect.DeepEqual(got, test.want) { - t.Errorf("CountActiveSchedules for %s is %v, want %v", test.name, got, test.want) + if diff := cmp.Diff(test.want, got); diff != "" { + t.Errorf("CountActiveSchedules for %s mismatch (-want +got):\n%s", test.name, diff) } }) } diff --git a/database/schedule/count_repo_test.go b/database/schedule/count_repo_test.go index 9618f9cf8..360894fc1 100644 --- a/database/schedule/count_repo_test.go +++ b/database/schedule/count_repo_test.go @@ -4,46 +4,84 @@ package schedule import ( "context" - "reflect" "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/google/go-cmp/cmp" + + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" + "github.com/go-vela/types/constants" ) func TestSchedule_Engine_CountSchedulesForRepo(t *testing.T) { - _repo := testRepo() + // setup types + _owner := testutils.APIUser() + _owner.SetID(1) + _owner.SetName("octocat") + _owner.SetToken("superSecretToken") + _owner.SetRefreshToken("superSecretRefreshToken") + _owner.SetFavorites([]string{"github/octocat"}) + _owner.SetActive(true) + _owner.SetAdmin(false) + _owner.SetDashboards([]string{"45bcf19b-c151-4e2d-b8c6-80a62ba2eae7"}) + + _repo := testutils.APIRepo() _repo.SetID(1) - _repo.SetOrg("foo") - _repo.SetName("bar") - _repo.SetFullName("foo/bar") - - _scheduleOne := testSchedule() + _repo.SetOwner(_owner.Crop()) + _repo.SetHash("MzM4N2MzMDAtNmY4Mi00OTA5LWFhZDAtNWIzMTlkNTJkODMy") + _repo.SetOrg("github") + _repo.SetName("octocat") + _repo.SetFullName("github/octocat") + _repo.SetLink("https://github.com/github/octocat") + _repo.SetClone("https://github.com/github/octocat.git") + _repo.SetBranch("main") + _repo.SetTopics([]string{"cloud", "security"}) + _repo.SetBuildLimit(10) + _repo.SetTimeout(30) + _repo.SetCounter(0) + _repo.SetVisibility("public") + _repo.SetPrivate(false) + _repo.SetTrusted(false) + _repo.SetActive(true) + _repo.SetAllowEvents(api.NewEventsFromMask(1)) + _repo.SetPipelineType("") + _repo.SetPreviousName("") + _repo.SetApproveBuild(constants.ApproveNever) + + _scheduleOne := testutils.APISchedule() _scheduleOne.SetID(1) - _scheduleOne.SetRepoID(1) + _scheduleOne.SetRepo(_repo) + _scheduleOne.SetActive(true) _scheduleOne.SetName("nightly") _scheduleOne.SetEntry("0 0 * * *") - _scheduleOne.SetCreatedAt(1) - _scheduleOne.SetCreatedBy("user1") - _scheduleOne.SetUpdatedAt(1) - _scheduleOne.SetUpdatedBy("user2") + _scheduleOne.SetCreatedAt(1713476291) + _scheduleOne.SetCreatedBy("octocat") + _scheduleOne.SetUpdatedAt(3013476291) + _scheduleOne.SetUpdatedBy("octokitty") + _scheduleOne.SetScheduledAt(2013476291) _scheduleOne.SetBranch("main") + _scheduleOne.SetError("no version: YAML property provided") - _scheduleTwo := testSchedule() + _scheduleTwo := testutils.APISchedule() _scheduleTwo.SetID(2) - _scheduleTwo.SetRepoID(2) + _scheduleTwo.SetRepo(_repo) + _scheduleTwo.SetActive(false) _scheduleTwo.SetName("hourly") _scheduleTwo.SetEntry("0 * * * *") - _scheduleTwo.SetCreatedAt(1) - _scheduleTwo.SetCreatedBy("user1") - _scheduleTwo.SetUpdatedAt(1) - _scheduleTwo.SetUpdatedBy("user2") + _scheduleTwo.SetCreatedAt(1713476291) + _scheduleTwo.SetCreatedBy("octocat") + _scheduleTwo.SetUpdatedAt(3013476291) + _scheduleTwo.SetUpdatedBy("octokitty") + _scheduleTwo.SetScheduledAt(2013476291) _scheduleTwo.SetBranch("main") + _scheduleTwo.SetError("no version: YAML property provided") _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() // create expected result in mock - _rows := sqlmock.NewRows([]string{"count"}).AddRow(1) + _rows := sqlmock.NewRows([]string{"count"}).AddRow(2) // ensure the mock expects the query _mock.ExpectQuery(`SELECT count(*) FROM "schedules" WHERE repo_id = $1`).WithArgs(1).WillReturnRows(_rows) @@ -72,13 +110,13 @@ func TestSchedule_Engine_CountSchedulesForRepo(t *testing.T) { failure: false, name: "postgres", database: _postgres, - want: 1, + want: 2, }, { failure: false, name: "sqlite3", database: _sqlite, - want: 1, + want: 2, }, } @@ -99,8 +137,8 @@ func TestSchedule_Engine_CountSchedulesForRepo(t *testing.T) { t.Errorf("CountSchedulesForRepo for %s returned err: %v", test.name, err) } - if !reflect.DeepEqual(got, test.want) { - t.Errorf("CountSchedulesForRepo for %s is %v, want %v", test.name, got, test.want) + if diff := cmp.Diff(test.want, got); diff != "" { + t.Errorf("CountSchedulesForRepo for %s mismatch (-want +got):\n%s", test.name, diff) } }) } diff --git a/database/schedule/count_test.go b/database/schedule/count_test.go index 98090ab8f..0338ff7fb 100644 --- a/database/schedule/count_test.go +++ b/database/schedule/count_test.go @@ -4,34 +4,78 @@ package schedule import ( "context" - "reflect" "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/google/go-cmp/cmp" + + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" + "github.com/go-vela/types/constants" ) func TestSchedule_Engine_CountSchedules(t *testing.T) { - _scheduleOne := testSchedule() + // setup types + _owner := testutils.APIUser() + _owner.SetID(1) + _owner.SetName("octocat") + _owner.SetToken("superSecretToken") + _owner.SetRefreshToken("superSecretRefreshToken") + _owner.SetFavorites([]string{"github/octocat"}) + _owner.SetActive(true) + _owner.SetAdmin(false) + _owner.SetDashboards([]string{"45bcf19b-c151-4e2d-b8c6-80a62ba2eae7"}) + + _repo := testutils.APIRepo() + _repo.SetID(1) + _repo.SetOwner(_owner.Crop()) + _repo.SetHash("MzM4N2MzMDAtNmY4Mi00OTA5LWFhZDAtNWIzMTlkNTJkODMy") + _repo.SetOrg("github") + _repo.SetName("octocat") + _repo.SetFullName("github/octocat") + _repo.SetLink("https://github.com/github/octocat") + _repo.SetClone("https://github.com/github/octocat.git") + _repo.SetBranch("main") + _repo.SetTopics([]string{"cloud", "security"}) + _repo.SetBuildLimit(10) + _repo.SetTimeout(30) + _repo.SetCounter(0) + _repo.SetVisibility("public") + _repo.SetPrivate(false) + _repo.SetTrusted(false) + _repo.SetActive(true) + _repo.SetAllowEvents(api.NewEventsFromMask(1)) + _repo.SetPipelineType("") + _repo.SetPreviousName("") + _repo.SetApproveBuild(constants.ApproveNever) + + _scheduleOne := testutils.APISchedule() _scheduleOne.SetID(1) - _scheduleOne.SetRepoID(1) + _scheduleOne.SetRepo(_repo) + _scheduleOne.SetActive(true) _scheduleOne.SetName("nightly") _scheduleOne.SetEntry("0 0 * * *") - _scheduleOne.SetCreatedAt(1) - _scheduleOne.SetCreatedBy("user1") - _scheduleOne.SetUpdatedAt(1) - _scheduleOne.SetUpdatedBy("user2") + _scheduleOne.SetCreatedAt(1713476291) + _scheduleOne.SetCreatedBy("octocat") + _scheduleOne.SetUpdatedAt(3013476291) + _scheduleOne.SetUpdatedBy("octokitty") + _scheduleOne.SetScheduledAt(2013476291) _scheduleOne.SetBranch("main") + _scheduleOne.SetError("no version: YAML property provided") - _scheduleTwo := testSchedule() + _scheduleTwo := testutils.APISchedule() _scheduleTwo.SetID(2) - _scheduleTwo.SetRepoID(2) + _scheduleTwo.SetRepo(_repo) + _scheduleTwo.SetActive(false) _scheduleTwo.SetName("hourly") _scheduleTwo.SetEntry("0 * * * *") - _scheduleTwo.SetCreatedAt(1) - _scheduleTwo.SetCreatedBy("user1") - _scheduleTwo.SetUpdatedAt(1) - _scheduleTwo.SetUpdatedBy("user2") + _scheduleTwo.SetCreatedAt(1713476291) + _scheduleTwo.SetCreatedBy("octocat") + _scheduleTwo.SetUpdatedAt(3013476291) + _scheduleTwo.SetUpdatedBy("octokitty") + _scheduleTwo.SetScheduledAt(2013476291) _scheduleTwo.SetBranch("main") + _scheduleTwo.SetError("no version: YAML property provided") _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() @@ -93,8 +137,8 @@ func TestSchedule_Engine_CountSchedules(t *testing.T) { t.Errorf("CountSchedules for %s returned err: %v", test.name, err) } - if !reflect.DeepEqual(got, test.want) { - t.Errorf("CountSchedules for %s is %v, want %v", test.name, got, test.want) + if diff := cmp.Diff(test.want, got); diff != "" { + t.Errorf("CountSchedules for %s mismatch (-want +got):\n%s", test.name, diff) } }) } diff --git a/database/schedule/create.go b/database/schedule/create.go index bb7ac2beb..9b349a7d1 100644 --- a/database/schedule/create.go +++ b/database/schedule/create.go @@ -7,19 +7,19 @@ import ( "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" ) // CreateSchedule creates a new schedule in the database. -func (e *engine) CreateSchedule(ctx context.Context, s *library.Schedule) (*library.Schedule, error) { +func (e *engine) CreateSchedule(ctx context.Context, s *api.Schedule) (*api.Schedule, error) { e.logger.WithFields(logrus.Fields{ "schedule": s.GetName(), }).Tracef("creating schedule %s in the database", s.GetName()) - // cast the library type to database type - schedule := database.ScheduleFromLibrary(s) + // cast the API type to database type + schedule := types.ScheduleFromAPI(s) // validate the necessary fields are populated err := schedule.Validate() @@ -28,7 +28,14 @@ func (e *engine) CreateSchedule(ctx context.Context, s *library.Schedule) (*libr } // send query to the database - result := e.client.Table(constants.TableSchedule).Create(schedule) + err = e.client.Table(constants.TableSchedule).Create(schedule).Error + if err != nil { + return nil, err + } + + // set repo to provided repo if creation successful + result := schedule.ToAPI() + result.SetRepo(s.GetRepo()) - return schedule.ToLibrary(), result.Error + return result, nil } diff --git a/database/schedule/create_test.go b/database/schedule/create_test.go index 7a2a42cc2..7858d4014 100644 --- a/database/schedule/create_test.go +++ b/database/schedule/create_test.go @@ -4,23 +4,64 @@ package schedule import ( "context" - "reflect" "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/google/go-cmp/cmp" + + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" + "github.com/go-vela/types/constants" ) func TestSchedule_Engine_CreateSchedule(t *testing.T) { - _schedule := testSchedule() + // setup types + _owner := testutils.APIUser() + _owner.SetID(1) + _owner.SetName("octocat") + _owner.SetToken("superSecretToken") + _owner.SetRefreshToken("superSecretRefreshToken") + _owner.SetFavorites([]string{"github/octocat"}) + _owner.SetActive(true) + _owner.SetAdmin(false) + _owner.SetDashboards([]string{"45bcf19b-c151-4e2d-b8c6-80a62ba2eae7"}) + + _repo := testutils.APIRepo() + _repo.SetID(1) + _repo.SetOwner(_owner.Crop()) + _repo.SetHash("MzM4N2MzMDAtNmY4Mi00OTA5LWFhZDAtNWIzMTlkNTJkODMy") + _repo.SetOrg("github") + _repo.SetName("octocat") + _repo.SetFullName("github/octocat") + _repo.SetLink("https://github.com/github/octocat") + _repo.SetClone("https://github.com/github/octocat.git") + _repo.SetBranch("main") + _repo.SetTopics([]string{"cloud", "security"}) + _repo.SetBuildLimit(10) + _repo.SetTimeout(30) + _repo.SetCounter(0) + _repo.SetVisibility("public") + _repo.SetPrivate(false) + _repo.SetTrusted(false) + _repo.SetActive(true) + _repo.SetAllowEvents(api.NewEventsFromMask(1)) + _repo.SetPipelineType("") + _repo.SetPreviousName("") + _repo.SetApproveBuild(constants.ApproveNever) + + _schedule := testutils.APISchedule() _schedule.SetID(1) - _schedule.SetRepoID(1) + _schedule.SetRepo(_repo) + _schedule.SetActive(true) _schedule.SetName("nightly") _schedule.SetEntry("0 0 * * *") - _schedule.SetCreatedAt(1) - _schedule.SetCreatedBy("user1") - _schedule.SetUpdatedAt(1) - _schedule.SetUpdatedBy("user2") + _schedule.SetCreatedAt(1713476291) + _schedule.SetCreatedBy("octocat") + _schedule.SetUpdatedAt(3013476291) + _schedule.SetUpdatedBy("octokitty") + _schedule.SetScheduledAt(2013476291) _schedule.SetBranch("main") + _schedule.SetError("no version: YAML property provided") _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() @@ -30,9 +71,9 @@ func TestSchedule_Engine_CreateSchedule(t *testing.T) { // ensure the mock expects the query _mock.ExpectQuery(`INSERT INTO "schedules" -("repo_id","active","name","entry","created_at","created_by","updated_at","updated_by","scheduled_at","branch","id") -VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11) RETURNING "id"`). - WithArgs(1, false, "nightly", "0 0 * * *", 1, "user1", 1, "user2", nil, "main", 1). +("repo_id","active","name","entry","created_at","created_by","updated_at","updated_by","scheduled_at","branch","error","id") +VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12) RETURNING "id"`). + WithArgs(1, true, "nightly", "0 0 * * *", 1713476291, "octocat", 3013476291, "octokitty", 2013476291, "main", "no version: YAML property provided", 1). WillReturnRows(_rows) _sqlite := testSqlite(t) @@ -73,8 +114,8 @@ VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11) RETURNING "id"`). t.Errorf("CreateSchedule for %s returned err: %v", test.name, err) } - if !reflect.DeepEqual(got, _schedule) { - t.Errorf("CreateSchedule for %s returned %s, want %s", test.name, got, _schedule) + if diff := cmp.Diff(_schedule, got); diff != "" { + t.Errorf("CreateSchedule for %s mismatch (-want +got):\n%s", test.name, diff) } }) } diff --git a/database/schedule/delete.go b/database/schedule/delete.go index 0d3386da1..bc63c2f10 100644 --- a/database/schedule/delete.go +++ b/database/schedule/delete.go @@ -7,19 +7,19 @@ import ( "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" ) // DeleteSchedule deletes an existing schedule from the database. -func (e *engine) DeleteSchedule(ctx context.Context, s *library.Schedule) error { +func (e *engine) DeleteSchedule(ctx context.Context, s *api.Schedule) error { e.logger.WithFields(logrus.Fields{ "schedule": s.GetName(), }).Tracef("deleting schedule %s in the database", s.GetName()) - // cast the library type to database type - schedule := database.ScheduleFromLibrary(s) + // cast the API type to database type + schedule := types.ScheduleFromAPI(s) // send query to the database return e.client. diff --git a/database/schedule/delete_test.go b/database/schedule/delete_test.go index 7a0a8ae76..d633bf38e 100644 --- a/database/schedule/delete_test.go +++ b/database/schedule/delete_test.go @@ -7,19 +7,60 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" + "github.com/go-vela/types/constants" ) func TestSchedule_Engine_DeleteSchedule(t *testing.T) { - _schedule := testSchedule() + // setup types + _owner := testutils.APIUser() + _owner.SetID(1) + _owner.SetName("octocat") + _owner.SetToken("superSecretToken") + _owner.SetRefreshToken("superSecretRefreshToken") + _owner.SetFavorites([]string{"github/octocat"}) + _owner.SetActive(true) + _owner.SetAdmin(false) + _owner.SetDashboards([]string{"45bcf19b-c151-4e2d-b8c6-80a62ba2eae7"}) + + _repo := testutils.APIRepo() + _repo.SetID(1) + _repo.SetOwner(_owner.Crop()) + _repo.SetHash("MzM4N2MzMDAtNmY4Mi00OTA5LWFhZDAtNWIzMTlkNTJkODMy") + _repo.SetOrg("github") + _repo.SetName("octocat") + _repo.SetFullName("github/octocat") + _repo.SetLink("https://github.com/github/octocat") + _repo.SetClone("https://github.com/github/octocat.git") + _repo.SetBranch("main") + _repo.SetTopics([]string{"cloud", "security"}) + _repo.SetBuildLimit(10) + _repo.SetTimeout(30) + _repo.SetCounter(0) + _repo.SetVisibility("public") + _repo.SetPrivate(false) + _repo.SetTrusted(false) + _repo.SetActive(true) + _repo.SetAllowEvents(api.NewEventsFromMask(1)) + _repo.SetPipelineType("") + _repo.SetPreviousName("") + _repo.SetApproveBuild(constants.ApproveNever) + + _schedule := testutils.APISchedule() _schedule.SetID(1) - _schedule.SetRepoID(1) + _schedule.SetRepo(_repo) + _schedule.SetActive(true) _schedule.SetName("nightly") _schedule.SetEntry("0 0 * * *") - _schedule.SetCreatedAt(1) - _schedule.SetCreatedBy("user1") - _schedule.SetUpdatedAt(1) - _schedule.SetUpdatedBy("user2") + _schedule.SetCreatedAt(1713476291) + _schedule.SetCreatedBy("octocat") + _schedule.SetUpdatedAt(3013476291) + _schedule.SetUpdatedBy("octokitty") + _schedule.SetScheduledAt(2013476291) _schedule.SetBranch("main") + _schedule.SetError("no version: YAML property provided") _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() diff --git a/database/schedule/get.go b/database/schedule/get.go index 518bbd339..e8097bc51 100644 --- a/database/schedule/get.go +++ b/database/schedule/get.go @@ -5,21 +5,23 @@ package schedule import ( "context" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" ) // GetSchedule gets a schedule by ID from the database. -func (e *engine) GetSchedule(ctx context.Context, id int64) (*library.Schedule, error) { +func (e *engine) GetSchedule(ctx context.Context, id int64) (*api.Schedule, error) { e.logger.Tracef("getting schedule %d from the database", id) // variable to store query results - s := new(database.Schedule) + s := new(types.Schedule) // send query to the database and store result in variable err := e.client. Table(constants.TableSchedule). + Preload("Repo"). + Preload("Repo.Owner"). Where("id = ?", id). Take(s). Error @@ -27,5 +29,11 @@ func (e *engine) GetSchedule(ctx context.Context, id int64) (*library.Schedule, return nil, err } - return s.ToLibrary(), nil + // decrypt hash value for repo + err = s.Repo.Decrypt(e.config.EncryptionKey) + if err != nil { + e.logger.Errorf("unable to decrypt repo %d: %v", s.Repo.ID.Int64, err) + } + + return s.ToAPI(), nil } diff --git a/database/schedule/get_repo.go b/database/schedule/get_repo.go index 6bc362e3d..0af4d1f7d 100644 --- a/database/schedule/get_repo.go +++ b/database/schedule/get_repo.go @@ -8,13 +8,12 @@ import ( "github.com/sirupsen/logrus" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" ) // GetScheduleForRepo gets a schedule by repo ID and name from the database. -func (e *engine) GetScheduleForRepo(ctx context.Context, r *api.Repo, name string) (*library.Schedule, error) { +func (e *engine) GetScheduleForRepo(ctx context.Context, r *api.Repo, name string) (*api.Schedule, error) { e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), @@ -22,11 +21,13 @@ func (e *engine) GetScheduleForRepo(ctx context.Context, r *api.Repo, name strin }).Tracef("getting schedule %s/%s from the database", r.GetFullName(), name) // variable to store query results - s := new(database.Schedule) + s := new(types.Schedule) // send query to the database and store result in variable err := e.client. Table(constants.TableSchedule). + Preload("Repo"). + Preload("Repo.Owner"). Where("repo_id = ?", r.GetID()). Where("name = ?", name). Take(s). @@ -35,5 +36,11 @@ func (e *engine) GetScheduleForRepo(ctx context.Context, r *api.Repo, name strin return nil, err } - return s.ToLibrary(), nil + // decrypt hash value for repo + err = s.Repo.Decrypt(e.config.EncryptionKey) + if err != nil { + e.logger.Errorf("unable to decrypt repo %d: %v", s.Repo.ID.Int64, err) + } + + return s.ToAPI(), nil } diff --git a/database/schedule/get_repo_test.go b/database/schedule/get_repo_test.go index 0d6a6184c..40a92a761 100644 --- a/database/schedule/get_repo_test.go +++ b/database/schedule/get_repo_test.go @@ -4,42 +4,86 @@ package schedule import ( "context" - "reflect" "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/google/go-cmp/cmp" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" + "github.com/go-vela/server/database/types" + "github.com/go-vela/types/constants" ) func TestSchedule_Engine_GetScheduleForRepo(t *testing.T) { - _repo := testRepo() + // setup types + _owner := testutils.APIUser() + _owner.SetID(1) + _owner.SetName("octocat") + _owner.SetToken("superSecretToken") + _owner.SetRefreshToken("superSecretRefreshToken") + _owner.SetFavorites([]string{"github/octocat"}) + _owner.SetActive(true) + _owner.SetAdmin(false) + _owner.SetDashboards([]string{"45bcf19b-c151-4e2d-b8c6-80a62ba2eae7"}) + + _repo := testutils.APIRepo() _repo.SetID(1) - _repo.SetOrg("foo") - _repo.SetName("bar") - _repo.SetFullName("foo/bar") - - _schedule := testSchedule() + _repo.SetOwner(_owner.Crop()) + _repo.SetHash("MzM4N2MzMDAtNmY4Mi00OTA5LWFhZDAtNWIzMTlkNTJkODMy") + _repo.SetOrg("github") + _repo.SetName("octocat") + _repo.SetFullName("github/octocat") + _repo.SetLink("https://github.com/github/octocat") + _repo.SetClone("https://github.com/github/octocat.git") + _repo.SetBranch("main") + _repo.SetTopics([]string{"cloud", "security"}) + _repo.SetBuildLimit(10) + _repo.SetTimeout(30) + _repo.SetCounter(0) + _repo.SetVisibility("public") + _repo.SetPrivate(false) + _repo.SetTrusted(false) + _repo.SetActive(true) + _repo.SetAllowEvents(api.NewEventsFromMask(1)) + _repo.SetPipelineType("") + _repo.SetPreviousName("") + _repo.SetApproveBuild(constants.ApproveNever) + + _schedule := testutils.APISchedule() _schedule.SetID(1) - _schedule.SetRepoID(1) + _schedule.SetRepo(_repo) + _schedule.SetActive(true) _schedule.SetName("nightly") _schedule.SetEntry("0 0 * * *") - _schedule.SetCreatedAt(1) - _schedule.SetCreatedBy("user1") - _schedule.SetUpdatedAt(1) - _schedule.SetUpdatedBy("user2") + _schedule.SetCreatedAt(1713476291) + _schedule.SetCreatedBy("octocat") + _schedule.SetUpdatedAt(3013476291) + _schedule.SetUpdatedBy("octokitty") + _schedule.SetScheduledAt(2013476291) _schedule.SetBranch("main") + _schedule.SetError("no version: YAML property provided") _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() // create expected result in mock _rows := sqlmock.NewRows( - []string{"id", "repo_id", "active", "name", "entry", "created_at", "created_by", "updated_at", "updated_by", "scheduled_at", "branch"}, - ).AddRow(1, 1, false, "nightly", "0 0 * * *", 1, "user1", 1, "user2", nil, "main") + []string{"id", "repo_id", "active", "name", "entry", "created_at", "created_by", "updated_at", "updated_by", "scheduled_at", "branch", "error"}). + AddRow(1, 1, true, "nightly", "0 0 * * *", 1713476291, "octocat", 3013476291, "octokitty", 2013476291, "main", "no version: YAML property provided") + + _repoRows := sqlmock.NewRows( + []string{"id", "user_id", "hash", "org", "name", "full_name", "link", "clone", "branch", "topics", "build_limit", "timeout", "counter", "visibility", "private", "trusted", "active", "allow_events", "pipeline_type", "previous_name", "approve_build"}). + AddRow(1, 1, "MzM4N2MzMDAtNmY4Mi00OTA5LWFhZDAtNWIzMTlkNTJkODMy", "github", "octocat", "github/octocat", "https://github.com/github/octocat", "https://github.com/github/octocat.git", "main", "{cloud,security}", 10, 30, 0, "public", false, false, true, 1, "", "", constants.ApproveNever) + + _userRows := sqlmock.NewRows( + []string{"id", "name", "token", "refresh_token", "favorites", "active", "admin", "dashboards"}). + AddRow(1, "octocat", "superSecretToken", "superSecretRefreshToken", "{}", true, false, "{}") // ensure the mock expects the query _mock.ExpectQuery(`SELECT * FROM "schedules" WHERE repo_id = $1 AND name = $2 LIMIT $3`).WithArgs(1, "nightly", 1).WillReturnRows(_rows) + _mock.ExpectQuery(`SELECT * FROM "repos" WHERE "repos"."id" = $1`).WithArgs(1).WillReturnRows(_repoRows) + _mock.ExpectQuery(`SELECT * FROM "users" WHERE "users"."id" = $1`).WithArgs(1).WillReturnRows(_userRows) _sqlite := testSqlite(t) defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() @@ -49,12 +93,32 @@ func TestSchedule_Engine_GetScheduleForRepo(t *testing.T) { t.Errorf("unable to create test schedule for sqlite: %v", err) } + err = _sqlite.client.AutoMigrate(&types.Repo{}) + if err != nil { + t.Errorf("unable to create build table for sqlite: %v", err) + } + + err = _sqlite.client.Table(constants.TableRepo).Create(types.RepoFromAPI(_repo)).Error + if err != nil { + t.Errorf("unable to create test repo for sqlite: %v", err) + } + + err = _sqlite.client.AutoMigrate(&types.User{}) + if err != nil { + t.Errorf("unable to create build table for sqlite: %v", err) + } + + err = _sqlite.client.Table(constants.TableUser).Create(types.UserFromAPI(_owner)).Error + if err != nil { + t.Errorf("unable to create test user for sqlite: %v", err) + } + // setup tests tests := []struct { failure bool name string database *engine - want *library.Schedule + want *api.Schedule }{ { failure: false, @@ -87,8 +151,8 @@ func TestSchedule_Engine_GetScheduleForRepo(t *testing.T) { t.Errorf("GetScheduleForRepo for %s returned err: %v", test.name, err) } - if !reflect.DeepEqual(got, test.want) { - t.Errorf("GetScheduleForRepo for %s is %v, want %v", test.name, got, test.want) + if diff := cmp.Diff(test.want, got); diff != "" { + t.Errorf("GetScheduleForRepo for %s mismatch (-want +got):\n%s", test.name, diff) } }) } diff --git a/database/schedule/get_test.go b/database/schedule/get_test.go index 3c62b8908..2f5b81952 100644 --- a/database/schedule/get_test.go +++ b/database/schedule/get_test.go @@ -4,36 +4,86 @@ package schedule import ( "context" - "reflect" "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/google/go-cmp/cmp" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" + "github.com/go-vela/server/database/types" + "github.com/go-vela/types/constants" ) func TestSchedule_Engine_GetSchedule(t *testing.T) { - _schedule := testSchedule() + // setup types + _owner := testutils.APIUser() + _owner.SetID(1) + _owner.SetName("octocat") + _owner.SetToken("superSecretToken") + _owner.SetRefreshToken("superSecretRefreshToken") + _owner.SetFavorites([]string{"github/octocat"}) + _owner.SetActive(true) + _owner.SetAdmin(false) + _owner.SetDashboards([]string{"45bcf19b-c151-4e2d-b8c6-80a62ba2eae7"}) + + _repo := testutils.APIRepo() + _repo.SetID(1) + _repo.SetOwner(_owner.Crop()) + _repo.SetHash("MzM4N2MzMDAtNmY4Mi00OTA5LWFhZDAtNWIzMTlkNTJkODMy") + _repo.SetOrg("github") + _repo.SetName("octocat") + _repo.SetFullName("github/octocat") + _repo.SetLink("https://github.com/github/octocat") + _repo.SetClone("https://github.com/github/octocat.git") + _repo.SetBranch("main") + _repo.SetTopics([]string{"cloud", "security"}) + _repo.SetBuildLimit(10) + _repo.SetTimeout(30) + _repo.SetCounter(0) + _repo.SetVisibility("public") + _repo.SetPrivate(false) + _repo.SetTrusted(false) + _repo.SetActive(true) + _repo.SetAllowEvents(api.NewEventsFromMask(1)) + _repo.SetPipelineType("") + _repo.SetPreviousName("") + _repo.SetApproveBuild(constants.ApproveNever) + + _schedule := testutils.APISchedule() _schedule.SetID(1) - _schedule.SetRepoID(1) + _schedule.SetRepo(_repo) + _schedule.SetActive(true) _schedule.SetName("nightly") _schedule.SetEntry("0 0 * * *") - _schedule.SetCreatedAt(1) - _schedule.SetCreatedBy("user1") - _schedule.SetUpdatedAt(1) - _schedule.SetUpdatedBy("user2") + _schedule.SetCreatedAt(1713476291) + _schedule.SetCreatedBy("octocat") + _schedule.SetUpdatedAt(3013476291) + _schedule.SetUpdatedBy("octokitty") + _schedule.SetScheduledAt(2013476291) _schedule.SetBranch("main") + _schedule.SetError("no version: YAML property provided") _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() // create expected result in mock _rows := sqlmock.NewRows( - []string{"id", "repo_id", "active", "name", "entry", "created_at", "created_by", "updated_at", "updated_by", "scheduled_at", "branch"}, - ).AddRow(1, 1, false, "nightly", "0 0 * * *", 1, "user1", 1, "user2", nil, "main") + []string{"id", "repo_id", "active", "name", "entry", "created_at", "created_by", "updated_at", "updated_by", "scheduled_at", "branch", "error"}). + AddRow(1, 1, true, "nightly", "0 0 * * *", 1713476291, "octocat", 3013476291, "octokitty", 2013476291, "main", "no version: YAML property provided") + + _repoRows := sqlmock.NewRows( + []string{"id", "user_id", "hash", "org", "name", "full_name", "link", "clone", "branch", "topics", "build_limit", "timeout", "counter", "visibility", "private", "trusted", "active", "allow_events", "pipeline_type", "previous_name", "approve_build"}). + AddRow(1, 1, "MzM4N2MzMDAtNmY4Mi00OTA5LWFhZDAtNWIzMTlkNTJkODMy", "github", "octocat", "github/octocat", "https://github.com/github/octocat", "https://github.com/github/octocat.git", "main", "{cloud,security}", 10, 30, 0, "public", false, false, true, 1, "", "", constants.ApproveNever) + + _userRows := sqlmock.NewRows( + []string{"id", "name", "token", "refresh_token", "favorites", "active", "admin", "dashboards"}). + AddRow(1, "octocat", "superSecretToken", "superSecretRefreshToken", "{}", true, false, "{}") // ensure the mock expects the query _mock.ExpectQuery(`SELECT * FROM "schedules" WHERE id = $1 LIMIT $2`).WithArgs(1, 1).WillReturnRows(_rows) + _mock.ExpectQuery(`SELECT * FROM "repos" WHERE "repos"."id" = $1`).WithArgs(1).WillReturnRows(_repoRows) + _mock.ExpectQuery(`SELECT * FROM "users" WHERE "users"."id" = $1`).WithArgs(1).WillReturnRows(_userRows) _sqlite := testSqlite(t) defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() @@ -43,12 +93,32 @@ func TestSchedule_Engine_GetSchedule(t *testing.T) { t.Errorf("unable to create test schedule for sqlite: %v", err) } + err = _sqlite.client.AutoMigrate(&types.Repo{}) + if err != nil { + t.Errorf("unable to create build table for sqlite: %v", err) + } + + err = _sqlite.client.Table(constants.TableRepo).Create(types.RepoFromAPI(_repo)).Error + if err != nil { + t.Errorf("unable to create test repo for sqlite: %v", err) + } + + err = _sqlite.client.AutoMigrate(&types.User{}) + if err != nil { + t.Errorf("unable to create build table for sqlite: %v", err) + } + + err = _sqlite.client.Table(constants.TableUser).Create(types.UserFromAPI(_owner)).Error + if err != nil { + t.Errorf("unable to create test user for sqlite: %v", err) + } + // setup tests tests := []struct { failure bool name string database *engine - want *library.Schedule + want *api.Schedule }{ { failure: false, @@ -81,8 +151,8 @@ func TestSchedule_Engine_GetSchedule(t *testing.T) { t.Errorf("GetSchedule for %s returned err: %v", test.name, err) } - if !reflect.DeepEqual(got, test.want) { - t.Errorf("GetSchedule for %s is %v, want %v", test.name, got, test.want) + if diff := cmp.Diff(test.want, got); diff != "" { + t.Errorf("GetSchedule for %s mismatch (-want +got):\n%s", test.name, diff) } }) } diff --git a/database/schedule/interface.go b/database/schedule/interface.go index b25b3c363..f4d284b45 100644 --- a/database/schedule/interface.go +++ b/database/schedule/interface.go @@ -6,7 +6,6 @@ import ( "context" api "github.com/go-vela/server/api/types" - "github.com/go-vela/types/library" ) // ScheduleInterface represents the Vela interface for schedule @@ -32,19 +31,19 @@ type ScheduleInterface interface { // CountSchedulesForRepo defines a function that gets the count of schedules by repo ID. CountSchedulesForRepo(context.Context, *api.Repo) (int64, error) // CreateSchedule defines a function that creates a new schedule. - CreateSchedule(context.Context, *library.Schedule) (*library.Schedule, error) + CreateSchedule(context.Context, *api.Schedule) (*api.Schedule, error) // DeleteSchedule defines a function that deletes an existing schedule. - DeleteSchedule(context.Context, *library.Schedule) error + DeleteSchedule(context.Context, *api.Schedule) error // GetSchedule defines a function that gets a schedule by ID. - GetSchedule(context.Context, int64) (*library.Schedule, error) + GetSchedule(context.Context, int64) (*api.Schedule, error) // GetScheduleForRepo defines a function that gets a schedule by repo ID and name. - GetScheduleForRepo(context.Context, *api.Repo, string) (*library.Schedule, error) + GetScheduleForRepo(context.Context, *api.Repo, string) (*api.Schedule, error) // ListActiveSchedules defines a function that gets a list of all active schedules. - ListActiveSchedules(context.Context) ([]*library.Schedule, error) + ListActiveSchedules(context.Context) ([]*api.Schedule, error) // ListSchedules defines a function that gets a list of all schedules. - ListSchedules(context.Context) ([]*library.Schedule, error) + ListSchedules(context.Context) ([]*api.Schedule, error) // ListSchedulesForRepo defines a function that gets a list of schedules by repo ID. - ListSchedulesForRepo(context.Context, *api.Repo, int, int) ([]*library.Schedule, int64, error) + ListSchedulesForRepo(context.Context, *api.Repo, int, int) ([]*api.Schedule, int64, error) // UpdateSchedule defines a function that updates an existing schedule. - UpdateSchedule(context.Context, *library.Schedule, bool) (*library.Schedule, error) + UpdateSchedule(context.Context, *api.Schedule, bool) (*api.Schedule, error) } diff --git a/database/schedule/list.go b/database/schedule/list.go index f3196651f..7df0c2248 100644 --- a/database/schedule/list.go +++ b/database/schedule/list.go @@ -5,19 +5,19 @@ package schedule import ( "context" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" ) // ListSchedules gets a list of all schedules from the database. -func (e *engine) ListSchedules(ctx context.Context) ([]*library.Schedule, error) { +func (e *engine) ListSchedules(ctx context.Context) ([]*api.Schedule, error) { e.logger.Trace("listing all schedules from the database") // variables to store query results and return value count := int64(0) - s := new([]database.Schedule) - schedules := []*library.Schedule{} + s := new([]types.Schedule) + schedules := []*api.Schedule{} // count the results count, err := e.CountSchedules(ctx) @@ -33,6 +33,8 @@ func (e *engine) ListSchedules(ctx context.Context) ([]*library.Schedule, error) // send query to the database and store result in variable err = e.client. Table(constants.TableSchedule). + Preload("Repo"). + Preload("Repo.Owner"). Find(&s). Error if err != nil { @@ -44,8 +46,14 @@ func (e *engine) ListSchedules(ctx context.Context) ([]*library.Schedule, error) // https://golang.org/doc/faq#closures_and_goroutines tmp := schedule + // decrypt hash value for repo + err = tmp.Repo.Decrypt(e.config.EncryptionKey) + if err != nil { + e.logger.Errorf("unable to decrypt repo %d: %v", tmp.ID.Int64, err) + } + // convert query result to API type - schedules = append(schedules, tmp.ToLibrary()) + schedules = append(schedules, tmp.ToAPI()) } return schedules, nil diff --git a/database/schedule/list_active.go b/database/schedule/list_active.go index b91ad63e8..d53b8201d 100644 --- a/database/schedule/list_active.go +++ b/database/schedule/list_active.go @@ -5,19 +5,19 @@ package schedule import ( "context" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" ) // ListActiveSchedules gets a list of all active schedules from the database. -func (e *engine) ListActiveSchedules(ctx context.Context) ([]*library.Schedule, error) { +func (e *engine) ListActiveSchedules(ctx context.Context) ([]*api.Schedule, error) { e.logger.Trace("listing all active schedules from the database") // variables to store query results and return value count := int64(0) - s := new([]database.Schedule) - schedules := []*library.Schedule{} + s := new([]types.Schedule) + schedules := []*api.Schedule{} // count the results count, err := e.CountActiveSchedules(ctx) @@ -33,6 +33,8 @@ func (e *engine) ListActiveSchedules(ctx context.Context) ([]*library.Schedule, // send query to the database and store result in variable err = e.client. Table(constants.TableSchedule). + Preload("Repo"). + Preload("Repo.Owner"). Where("active = ?", true). Find(&s). Error @@ -45,8 +47,14 @@ func (e *engine) ListActiveSchedules(ctx context.Context) ([]*library.Schedule, // https://golang.org/doc/faq#closures_and_goroutines tmp := schedule + // decrypt hash value for repo + err = tmp.Repo.Decrypt(e.config.EncryptionKey) + if err != nil { + e.logger.Errorf("unable to decrypt repo %d: %v", tmp.Repo.ID.Int64, err) + } + // convert query result to API type - schedules = append(schedules, tmp.ToLibrary()) + schedules = append(schedules, tmp.ToAPI()) } return schedules, nil diff --git a/database/schedule/list_active_test.go b/database/schedule/list_active_test.go index 8154780bd..e3179e020 100644 --- a/database/schedule/list_active_test.go +++ b/database/schedule/list_active_test.go @@ -4,55 +4,106 @@ package schedule import ( "context" - "reflect" "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/google/go-cmp/cmp" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" + "github.com/go-vela/server/database/types" + "github.com/go-vela/types/constants" ) func TestSchedule_Engine_ListActiveSchedules(t *testing.T) { - _scheduleOne := testSchedule() + // setup types + _owner := testutils.APIUser() + _owner.SetID(1) + _owner.SetName("octocat") + _owner.SetToken("superSecretToken") + _owner.SetRefreshToken("superSecretRefreshToken") + _owner.SetFavorites([]string{"github/octocat"}) + _owner.SetActive(true) + _owner.SetAdmin(false) + _owner.SetDashboards([]string{"45bcf19b-c151-4e2d-b8c6-80a62ba2eae7"}) + + _repo := testutils.APIRepo() + _repo.SetID(1) + _repo.SetOwner(_owner.Crop()) + _repo.SetHash("MzM4N2MzMDAtNmY4Mi00OTA5LWFhZDAtNWIzMTlkNTJkODMy") + _repo.SetOrg("github") + _repo.SetName("octocat") + _repo.SetFullName("github/octocat") + _repo.SetLink("https://github.com/github/octocat") + _repo.SetClone("https://github.com/github/octocat.git") + _repo.SetBranch("main") + _repo.SetTopics([]string{"cloud", "security"}) + _repo.SetBuildLimit(10) + _repo.SetTimeout(30) + _repo.SetCounter(0) + _repo.SetVisibility("public") + _repo.SetPrivate(false) + _repo.SetTrusted(false) + _repo.SetActive(true) + _repo.SetAllowEvents(api.NewEventsFromMask(1)) + _repo.SetPipelineType("") + _repo.SetPreviousName("") + _repo.SetApproveBuild(constants.ApproveNever) + + _scheduleOne := testutils.APISchedule() _scheduleOne.SetID(1) - _scheduleOne.SetRepoID(1) + _scheduleOne.SetRepo(_repo) _scheduleOne.SetActive(true) _scheduleOne.SetName("nightly") _scheduleOne.SetEntry("0 0 * * *") - _scheduleOne.SetCreatedAt(1) - _scheduleOne.SetCreatedBy("user1") - _scheduleOne.SetUpdatedAt(1) - _scheduleOne.SetUpdatedBy("user2") + _scheduleOne.SetCreatedAt(1713476291) + _scheduleOne.SetCreatedBy("octocat") + _scheduleOne.SetUpdatedAt(3013476291) + _scheduleOne.SetUpdatedBy("octokitty") + _scheduleOne.SetScheduledAt(2013476291) _scheduleOne.SetBranch("main") + _scheduleOne.SetError("no version: YAML property provided") - _scheduleTwo := testSchedule() + _scheduleTwo := testutils.APISchedule() _scheduleTwo.SetID(2) - _scheduleTwo.SetRepoID(2) + _scheduleTwo.SetRepo(_repo) _scheduleTwo.SetActive(false) _scheduleTwo.SetName("hourly") _scheduleTwo.SetEntry("0 * * * *") - _scheduleTwo.SetCreatedAt(1) - _scheduleTwo.SetCreatedBy("user1") - _scheduleTwo.SetUpdatedAt(1) - _scheduleTwo.SetUpdatedBy("user2") + _scheduleTwo.SetCreatedAt(1713476291) + _scheduleTwo.SetCreatedBy("octocat") + _scheduleTwo.SetUpdatedAt(3013476291) + _scheduleTwo.SetUpdatedBy("octokitty") + _scheduleTwo.SetScheduledAt(2013476291) _scheduleTwo.SetBranch("main") + _scheduleTwo.SetError("no version: YAML property provided") _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() // create expected result in mock - _rows := sqlmock.NewRows([]string{"count"}).AddRow(2) + _rows := sqlmock.NewRows([]string{"count"}).AddRow(1) // ensure the mock expects the query _mock.ExpectQuery(`SELECT count(*) FROM "schedules" WHERE active = $1`).WithArgs(true).WillReturnRows(_rows) // create expected result in mock _rows = sqlmock.NewRows( - []string{"id", "repo_id", "active", "name", "entry", "created_at", "created_by", "updated_at", "updated_by", "scheduled_at", "branch"}). - AddRow(1, 1, true, "nightly", "0 0 * * *", 1, "user1", 1, "user2", nil, "main") + []string{"id", "repo_id", "active", "name", "entry", "created_at", "created_by", "updated_at", "updated_by", "scheduled_at", "branch", "error"}). + AddRow(1, 1, true, "nightly", "0 0 * * *", 1713476291, "octocat", 3013476291, "octokitty", 2013476291, "main", "no version: YAML property provided") + + _repoRows := sqlmock.NewRows( + []string{"id", "user_id", "hash", "org", "name", "full_name", "link", "clone", "branch", "topics", "build_limit", "timeout", "counter", "visibility", "private", "trusted", "active", "allow_events", "pipeline_type", "previous_name", "approve_build"}). + AddRow(1, 1, "MzM4N2MzMDAtNmY4Mi00OTA5LWFhZDAtNWIzMTlkNTJkODMy", "github", "octocat", "github/octocat", "https://github.com/github/octocat", "https://github.com/github/octocat.git", "main", "{cloud,security}", 10, 30, 0, "public", false, false, true, 1, "", "", constants.ApproveNever) + + _userRows := sqlmock.NewRows( + []string{"id", "name", "token", "refresh_token", "favorites", "active", "admin", "dashboards"}). + AddRow(1, "octocat", "superSecretToken", "superSecretRefreshToken", "{}", true, false, "{}") // ensure the mock expects the query _mock.ExpectQuery(`SELECT * FROM "schedules" WHERE active = $1`).WithArgs(true).WillReturnRows(_rows) + _mock.ExpectQuery(`SELECT * FROM "repos" WHERE "repos"."id" = $1`).WithArgs(1).WillReturnRows(_repoRows) + _mock.ExpectQuery(`SELECT * FROM "users" WHERE "users"."id" = $1`).WithArgs(1).WillReturnRows(_userRows) _sqlite := testSqlite(t) defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() @@ -66,25 +117,44 @@ func TestSchedule_Engine_ListActiveSchedules(t *testing.T) { if err != nil { t.Errorf("unable to create test schedule for sqlite: %v", err) } + err = _sqlite.client.AutoMigrate(&types.Repo{}) + if err != nil { + t.Errorf("unable to create build table for sqlite: %v", err) + } + + err = _sqlite.client.Table(constants.TableRepo).Create(types.RepoFromAPI(_repo)).Error + if err != nil { + t.Errorf("unable to create test repo for sqlite: %v", err) + } + + err = _sqlite.client.AutoMigrate(&types.User{}) + if err != nil { + t.Errorf("unable to create build table for sqlite: %v", err) + } + + err = _sqlite.client.Table(constants.TableUser).Create(types.UserFromAPI(_owner)).Error + if err != nil { + t.Errorf("unable to create test user for sqlite: %v", err) + } // setup tests tests := []struct { failure bool name string database *engine - want []*library.Schedule + want []*api.Schedule }{ { failure: false, name: "postgres", database: _postgres, - want: []*library.Schedule{_scheduleOne}, + want: []*api.Schedule{_scheduleOne}, }, { failure: false, name: "sqlite3", database: _sqlite, - want: []*library.Schedule{_scheduleOne}, + want: []*api.Schedule{_scheduleOne}, }, } @@ -105,8 +175,8 @@ func TestSchedule_Engine_ListActiveSchedules(t *testing.T) { t.Errorf("ListActiveSchedules for %s returned err: %v", test.name, err) } - if !reflect.DeepEqual(got, test.want) { - t.Errorf("ListActiveSchedules for %s is %v, want %v", test.name, got, test.want) + if diff := cmp.Diff(test.want, got); diff != "" { + t.Errorf("ListActiveSchedules for %s mismatch (-want +got):\n%s", test.name, diff) } }) } diff --git a/database/schedule/list_repo.go b/database/schedule/list_repo.go index 9f3de5e5a..d26f6a198 100644 --- a/database/schedule/list_repo.go +++ b/database/schedule/list_repo.go @@ -8,13 +8,12 @@ import ( "github.com/sirupsen/logrus" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" ) // ListSchedulesForRepo gets a list of schedules by repo ID from the database. -func (e *engine) ListSchedulesForRepo(ctx context.Context, r *api.Repo, page, perPage int) ([]*library.Schedule, int64, error) { +func (e *engine) ListSchedulesForRepo(ctx context.Context, r *api.Repo, page, perPage int) ([]*api.Schedule, int64, error) { e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), @@ -22,8 +21,8 @@ func (e *engine) ListSchedulesForRepo(ctx context.Context, r *api.Repo, page, pe // variables to store query results and return value count := int64(0) - s := new([]database.Schedule) - schedules := []*library.Schedule{} + s := new([]types.Schedule) + schedules := []*api.Schedule{} // count the results count, err := e.CountSchedulesForRepo(ctx, r) @@ -42,6 +41,8 @@ func (e *engine) ListSchedulesForRepo(ctx context.Context, r *api.Repo, page, pe // send query to the database and store result in variable err = e.client. Table(constants.TableSchedule). + Preload("Repo"). + Preload("Repo.Owner"). Where("repo_id = ?", r.GetID()). Order("id DESC"). Limit(perPage). @@ -57,8 +58,14 @@ func (e *engine) ListSchedulesForRepo(ctx context.Context, r *api.Repo, page, pe // https://golang.org/doc/faq#closures_and_goroutines tmp := schedule - // convert query result to library type - schedules = append(schedules, tmp.ToLibrary()) + // decrypt hash value for repo + err = tmp.Repo.Decrypt(e.config.EncryptionKey) + if err != nil { + e.logger.Errorf("unable to decrypt repo %d: %v", tmp.Repo.ID.Int64, err) + } + + // convert query result to API type + schedules = append(schedules, tmp.ToAPI()) } return schedules, count, nil diff --git a/database/schedule/list_repo_test.go b/database/schedule/list_repo_test.go index 4753a2b34..43b1fcf58 100644 --- a/database/schedule/list_repo_test.go +++ b/database/schedule/list_repo_test.go @@ -4,42 +4,79 @@ package schedule import ( "context" - "reflect" "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/google/go-cmp/cmp" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" + "github.com/go-vela/server/database/types" + "github.com/go-vela/types/constants" ) func TestSchedule_Engine_ListSchedulesForRepo(t *testing.T) { - _repo := testRepo() + // setup types + _owner := testutils.APIUser() + _owner.SetID(1) + _owner.SetName("octocat") + _owner.SetToken("superSecretToken") + _owner.SetRefreshToken("superSecretRefreshToken") + _owner.SetFavorites([]string{"github/octocat"}) + _owner.SetActive(true) + _owner.SetAdmin(false) + _owner.SetDashboards([]string{"45bcf19b-c151-4e2d-b8c6-80a62ba2eae7"}) + + _repo := testutils.APIRepo() _repo.SetID(1) - _repo.SetOrg("foo") - _repo.SetName("bar") - _repo.SetFullName("foo/bar") - - _scheduleOne := testSchedule() + _repo.SetOwner(_owner.Crop()) + _repo.SetHash("MzM4N2MzMDAtNmY4Mi00OTA5LWFhZDAtNWIzMTlkNTJkODMy") + _repo.SetOrg("github") + _repo.SetName("octocat") + _repo.SetFullName("github/octocat") + _repo.SetLink("https://github.com/github/octocat") + _repo.SetClone("https://github.com/github/octocat.git") + _repo.SetBranch("main") + _repo.SetTopics([]string{"cloud", "security"}) + _repo.SetBuildLimit(10) + _repo.SetTimeout(30) + _repo.SetCounter(0) + _repo.SetVisibility("public") + _repo.SetPrivate(false) + _repo.SetTrusted(false) + _repo.SetActive(true) + _repo.SetAllowEvents(api.NewEventsFromMask(1)) + _repo.SetPipelineType("") + _repo.SetPreviousName("") + _repo.SetApproveBuild(constants.ApproveNever) + + _scheduleOne := testutils.APISchedule() _scheduleOne.SetID(1) - _scheduleOne.SetRepoID(1) + _scheduleOne.SetRepo(_repo) + _scheduleOne.SetActive(true) _scheduleOne.SetName("nightly") _scheduleOne.SetEntry("0 0 * * *") - _scheduleOne.SetCreatedAt(1) - _scheduleOne.SetCreatedBy("user1") - _scheduleOne.SetUpdatedAt(1) - _scheduleOne.SetUpdatedBy("user2") + _scheduleOne.SetCreatedAt(1713476291) + _scheduleOne.SetCreatedBy("octocat") + _scheduleOne.SetUpdatedAt(3013476291) + _scheduleOne.SetUpdatedBy("octokitty") + _scheduleOne.SetScheduledAt(2013476291) _scheduleOne.SetBranch("main") + _scheduleOne.SetError("no version: YAML property provided") - _scheduleTwo := testSchedule() + _scheduleTwo := testutils.APISchedule() _scheduleTwo.SetID(2) - _scheduleTwo.SetRepoID(2) + _scheduleTwo.SetRepo(_repo) + _scheduleTwo.SetActive(false) _scheduleTwo.SetName("hourly") _scheduleTwo.SetEntry("0 * * * *") - _scheduleTwo.SetCreatedAt(1) - _scheduleTwo.SetCreatedBy("user1") - _scheduleTwo.SetUpdatedAt(1) - _scheduleTwo.SetUpdatedBy("user2") + _scheduleTwo.SetCreatedAt(1713476291) + _scheduleTwo.SetCreatedBy("octocat") + _scheduleTwo.SetUpdatedAt(3013476291) + _scheduleTwo.SetUpdatedBy("octokitty") + _scheduleTwo.SetScheduledAt(2013476291) _scheduleTwo.SetBranch("main") + _scheduleTwo.SetError("no version: YAML property provided") _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() @@ -52,11 +89,22 @@ func TestSchedule_Engine_ListSchedulesForRepo(t *testing.T) { // create expected result in mock _rows = sqlmock.NewRows( - []string{"id", "repo_id", "active", "name", "entry", "created_at", "created_by", "updated_at", "updated_by", "scheduled_at", "branch"}). - AddRow(1, 1, false, "nightly", "0 0 * * *", 1, "user1", 1, "user2", nil, "main") + []string{"id", "repo_id", "active", "name", "entry", "created_at", "created_by", "updated_at", "updated_by", "scheduled_at", "branch", "error"}). + AddRow(1, 1, true, "nightly", "0 0 * * *", 1713476291, "octocat", 3013476291, "octokitty", 2013476291, "main", "no version: YAML property provided"). + AddRow(2, 1, false, "hourly", "0 * * * *", 1713476291, "octocat", 3013476291, "octokitty", 2013476291, "main", "no version: YAML property provided") + + _repoRows := sqlmock.NewRows( + []string{"id", "user_id", "hash", "org", "name", "full_name", "link", "clone", "branch", "topics", "build_limit", "timeout", "counter", "visibility", "private", "trusted", "active", "allow_events", "pipeline_type", "previous_name", "approve_build"}). + AddRow(1, 1, "MzM4N2MzMDAtNmY4Mi00OTA5LWFhZDAtNWIzMTlkNTJkODMy", "github", "octocat", "github/octocat", "https://github.com/github/octocat", "https://github.com/github/octocat.git", "main", "{cloud,security}", 10, 30, 0, "public", false, false, true, 1, "", "", constants.ApproveNever) + + _userRows := sqlmock.NewRows( + []string{"id", "name", "token", "refresh_token", "favorites", "active", "admin", "dashboards"}). + AddRow(1, "octocat", "superSecretToken", "superSecretRefreshToken", "{}", true, false, "{}") // ensure the mock expects the query _mock.ExpectQuery(`SELECT * FROM "schedules" WHERE repo_id = $1 ORDER BY id DESC LIMIT $2`).WithArgs(1, 10).WillReturnRows(_rows) + _mock.ExpectQuery(`SELECT * FROM "repos" WHERE "repos"."id" = $1`).WithArgs(1).WillReturnRows(_repoRows) + _mock.ExpectQuery(`SELECT * FROM "users" WHERE "users"."id" = $1`).WithArgs(1).WillReturnRows(_userRows) _sqlite := testSqlite(t) defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() @@ -71,24 +119,44 @@ func TestSchedule_Engine_ListSchedulesForRepo(t *testing.T) { t.Errorf("unable to create test schedule for sqlite: %v", err) } + err = _sqlite.client.AutoMigrate(&types.Repo{}) + if err != nil { + t.Errorf("unable to create build table for sqlite: %v", err) + } + + err = _sqlite.client.Table(constants.TableRepo).Create(types.RepoFromAPI(_repo)).Error + if err != nil { + t.Errorf("unable to create test repo for sqlite: %v", err) + } + + err = _sqlite.client.AutoMigrate(&types.User{}) + if err != nil { + t.Errorf("unable to create build table for sqlite: %v", err) + } + + err = _sqlite.client.Table(constants.TableUser).Create(types.UserFromAPI(_owner)).Error + if err != nil { + t.Errorf("unable to create test user for sqlite: %v", err) + } + // setup tests tests := []struct { failure bool name string database *engine - want []*library.Schedule + want []*api.Schedule }{ { failure: false, name: "postgres", database: _postgres, - want: []*library.Schedule{_scheduleOne}, + want: []*api.Schedule{_scheduleOne, _scheduleTwo}, }, { failure: false, name: "sqlite3", database: _sqlite, - want: []*library.Schedule{_scheduleOne}, + want: []*api.Schedule{_scheduleTwo, _scheduleOne}, }, } @@ -109,8 +177,8 @@ func TestSchedule_Engine_ListSchedulesForRepo(t *testing.T) { t.Errorf("ListSchedulesForRepo for %s returned err: %v", test.name, err) } - if !reflect.DeepEqual(got, test.want) { - t.Errorf("ListSchedulesForRepo for %s is %v, want %v", test.name, got, test.want) + if diff := cmp.Diff(test.want, got); diff != "" { + t.Errorf("ListSchedulesForRepo for %s mismatch (-want +got):\n%s", test.name, diff) } }) } diff --git a/database/schedule/list_test.go b/database/schedule/list_test.go index d8a5b2ae8..8338c5dc1 100644 --- a/database/schedule/list_test.go +++ b/database/schedule/list_test.go @@ -4,36 +4,79 @@ package schedule import ( "context" - "reflect" "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/google/go-cmp/cmp" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" + "github.com/go-vela/server/database/types" + "github.com/go-vela/types/constants" ) func TestSchedule_Engine_ListSchedules(t *testing.T) { - _scheduleOne := testSchedule() + // setup types + _owner := testutils.APIUser() + _owner.SetID(1) + _owner.SetName("octocat") + _owner.SetToken("superSecretToken") + _owner.SetRefreshToken("superSecretRefreshToken") + _owner.SetFavorites([]string{"github/octocat"}) + _owner.SetActive(true) + _owner.SetAdmin(false) + _owner.SetDashboards([]string{"45bcf19b-c151-4e2d-b8c6-80a62ba2eae7"}) + + _repo := testutils.APIRepo() + _repo.SetID(1) + _repo.SetOwner(_owner.Crop()) + _repo.SetHash("MzM4N2MzMDAtNmY4Mi00OTA5LWFhZDAtNWIzMTlkNTJkODMy") + _repo.SetOrg("github") + _repo.SetName("octocat") + _repo.SetFullName("github/octocat") + _repo.SetLink("https://github.com/github/octocat") + _repo.SetClone("https://github.com/github/octocat.git") + _repo.SetBranch("main") + _repo.SetTopics([]string{"cloud", "security"}) + _repo.SetBuildLimit(10) + _repo.SetTimeout(30) + _repo.SetCounter(0) + _repo.SetVisibility("public") + _repo.SetPrivate(false) + _repo.SetTrusted(false) + _repo.SetActive(true) + _repo.SetAllowEvents(api.NewEventsFromMask(1)) + _repo.SetPipelineType("") + _repo.SetPreviousName("") + _repo.SetApproveBuild(constants.ApproveNever) + + _scheduleOne := testutils.APISchedule() _scheduleOne.SetID(1) - _scheduleOne.SetRepoID(1) + _scheduleOne.SetRepo(_repo) + _scheduleOne.SetActive(true) _scheduleOne.SetName("nightly") _scheduleOne.SetEntry("0 0 * * *") - _scheduleOne.SetCreatedAt(1) - _scheduleOne.SetCreatedBy("user1") - _scheduleOne.SetUpdatedAt(1) - _scheduleOne.SetUpdatedBy("user2") + _scheduleOne.SetCreatedAt(1713476291) + _scheduleOne.SetCreatedBy("octocat") + _scheduleOne.SetUpdatedAt(3013476291) + _scheduleOne.SetUpdatedBy("octokitty") + _scheduleOne.SetScheduledAt(2013476291) _scheduleOne.SetBranch("main") + _scheduleOne.SetError("no version: YAML property provided") - _scheduleTwo := testSchedule() + _scheduleTwo := testutils.APISchedule() _scheduleTwo.SetID(2) - _scheduleTwo.SetRepoID(2) + _scheduleTwo.SetRepo(_repo) + _scheduleTwo.SetActive(false) _scheduleTwo.SetName("hourly") _scheduleTwo.SetEntry("0 * * * *") - _scheduleTwo.SetCreatedAt(1) - _scheduleTwo.SetCreatedBy("user1") - _scheduleTwo.SetUpdatedAt(1) - _scheduleTwo.SetUpdatedBy("user2") + _scheduleTwo.SetCreatedAt(1713476291) + _scheduleTwo.SetCreatedBy("octocat") + _scheduleTwo.SetUpdatedAt(3013476291) + _scheduleTwo.SetUpdatedBy("octokitty") + _scheduleTwo.SetScheduledAt(2013476291) _scheduleTwo.SetBranch("main") + _scheduleTwo.SetError("no version: YAML property provided") _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() @@ -46,12 +89,22 @@ func TestSchedule_Engine_ListSchedules(t *testing.T) { // create expected result in mock _rows = sqlmock.NewRows( - []string{"id", "repo_id", "active", "name", "entry", "created_at", "created_by", "updated_at", "updated_by", "scheduled_at", "branch"}). - AddRow(1, 1, false, "nightly", "0 0 * * *", 1, "user1", 1, "user2", nil, "main"). - AddRow(2, 2, false, "hourly", "0 * * * *", 1, "user1", 1, "user2", nil, "main") + []string{"id", "repo_id", "active", "name", "entry", "created_at", "created_by", "updated_at", "updated_by", "scheduled_at", "branch", "error"}). + AddRow(1, 1, true, "nightly", "0 0 * * *", 1713476291, "octocat", 3013476291, "octokitty", 2013476291, "main", "no version: YAML property provided"). + AddRow(2, 1, false, "hourly", "0 * * * *", 1713476291, "octocat", 3013476291, "octokitty", 2013476291, "main", "no version: YAML property provided") + + _repoRows := sqlmock.NewRows( + []string{"id", "user_id", "hash", "org", "name", "full_name", "link", "clone", "branch", "topics", "build_limit", "timeout", "counter", "visibility", "private", "trusted", "active", "allow_events", "pipeline_type", "previous_name", "approve_build"}). + AddRow(1, 1, "MzM4N2MzMDAtNmY4Mi00OTA5LWFhZDAtNWIzMTlkNTJkODMy", "github", "octocat", "github/octocat", "https://github.com/github/octocat", "https://github.com/github/octocat.git", "main", "{cloud,security}", 10, 30, 0, "public", false, false, true, 1, "", "", constants.ApproveNever) + + _userRows := sqlmock.NewRows( + []string{"id", "name", "token", "refresh_token", "favorites", "active", "admin", "dashboards"}). + AddRow(1, "octocat", "superSecretToken", "superSecretRefreshToken", "{}", true, false, "{}") // ensure the mock expects the query _mock.ExpectQuery(`SELECT * FROM "schedules"`).WillReturnRows(_rows) + _mock.ExpectQuery(`SELECT * FROM "repos" WHERE "repos"."id" = $1`).WithArgs(1).WillReturnRows(_repoRows) + _mock.ExpectQuery(`SELECT * FROM "users" WHERE "users"."id" = $1`).WithArgs(1).WillReturnRows(_userRows) _sqlite := testSqlite(t) defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() @@ -66,24 +119,44 @@ func TestSchedule_Engine_ListSchedules(t *testing.T) { t.Errorf("unable to create test schedule for sqlite: %v", err) } + err = _sqlite.client.AutoMigrate(&types.Repo{}) + if err != nil { + t.Errorf("unable to create build table for sqlite: %v", err) + } + + err = _sqlite.client.Table(constants.TableRepo).Create(types.RepoFromAPI(_repo)).Error + if err != nil { + t.Errorf("unable to create test repo for sqlite: %v", err) + } + + err = _sqlite.client.AutoMigrate(&types.User{}) + if err != nil { + t.Errorf("unable to create build table for sqlite: %v", err) + } + + err = _sqlite.client.Table(constants.TableUser).Create(types.UserFromAPI(_owner)).Error + if err != nil { + t.Errorf("unable to create test user for sqlite: %v", err) + } + // setup tests tests := []struct { failure bool name string database *engine - want []*library.Schedule + want []*api.Schedule }{ { failure: false, name: "postgres", database: _postgres, - want: []*library.Schedule{_scheduleOne, _scheduleTwo}, + want: []*api.Schedule{_scheduleOne, _scheduleTwo}, }, { failure: false, name: "sqlite3", database: _sqlite, - want: []*library.Schedule{_scheduleOne, _scheduleTwo}, + want: []*api.Schedule{_scheduleOne, _scheduleTwo}, }, } @@ -104,8 +177,8 @@ func TestSchedule_Engine_ListSchedules(t *testing.T) { t.Errorf("ListSchedules for %s returned err: %v", test.name, err) } - if !reflect.DeepEqual(got, test.want) { - t.Errorf("ListSchedules for %s is %v, want %v", test.name, got, test.want) + if diff := cmp.Diff(test.want, got); diff != "" { + t.Errorf("ListSchedules for %s mismatch (-want +got):\n%s", test.name, diff) } }) } diff --git a/database/schedule/opts.go b/database/schedule/opts.go index 7eb9c2adb..c3a0af1eb 100644 --- a/database/schedule/opts.go +++ b/database/schedule/opts.go @@ -22,6 +22,16 @@ func WithClient(client *gorm.DB) EngineOpt { } } +// WithEncryptionKey sets the encryption key in the database engine for Schedules. +func WithEncryptionKey(key string) EngineOpt { + return func(e *engine) error { + // set the encryption key in the schedule engine + e.config.EncryptionKey = key + + return nil + } +} + // WithLogger sets the github.com/sirupsen/logrus logger in the database engine for Schedules. func WithLogger(logger *logrus.Entry) EngineOpt { return func(e *engine) error { diff --git a/database/schedule/schedule.go b/database/schedule/schedule.go index b338d2f95..b7a83b2dd 100644 --- a/database/schedule/schedule.go +++ b/database/schedule/schedule.go @@ -15,6 +15,8 @@ import ( type ( // config represents the settings required to create the engine that implements the ScheduleInterface interface. config struct { + // specifies the encryption key to use for the Schedule engine + EncryptionKey string // specifies to skip creating tables and indexes for the Schedule engine SkipCreation bool } diff --git a/database/schedule/schedule_test.go b/database/schedule/schedule_test.go index 5c227f4c2..a7d4cb936 100644 --- a/database/schedule/schedule_test.go +++ b/database/schedule/schedule_test.go @@ -14,9 +14,6 @@ import ( "gorm.io/driver/postgres" "gorm.io/driver/sqlite" "gorm.io/gorm" - - api "github.com/go-vela/server/api/types" - "github.com/go-vela/types/library" ) func TestSchedule_New(t *testing.T) { @@ -173,46 +170,6 @@ func testSqlite(t *testing.T) *engine { return _engine } -// testSchedule is a test helper function to create an API Schedule type with all fields set to their zero values. -func testSchedule() *library.Schedule { - return &library.Schedule{ - ID: new(int64), - RepoID: new(int64), - Active: new(bool), - Name: new(string), - Entry: new(string), - CreatedAt: new(int64), - CreatedBy: new(string), - UpdatedAt: new(int64), - UpdatedBy: new(string), - ScheduledAt: new(int64), - Branch: new(string), - } -} - -// testRepo is a test helper function to create a library Repo type with all fields set to their zero values. -func testRepo() *api.Repo { - return &api.Repo{ - ID: new(int64), - BuildLimit: new(int64), - Timeout: new(int64), - Counter: new(int), - PipelineType: new(string), - Hash: new(string), - Org: new(string), - Name: new(string), - FullName: new(string), - Link: new(string), - Clone: new(string), - Branch: new(string), - Visibility: new(string), - PreviousName: new(string), - Private: new(bool), - Trusted: new(bool), - Active: new(bool), - } -} - // This will be used with the github.com/DATA-DOG/go-sqlmock library to compare values // that are otherwise not easily compared. These typically would be values generated // before adding or updating them in the database. diff --git a/database/schedule/table.go b/database/schedule/table.go index ea8e99cb3..82ae8fdaf 100644 --- a/database/schedule/table.go +++ b/database/schedule/table.go @@ -25,6 +25,7 @@ schedules ( updated_by VARCHAR(250), scheduled_at INTEGER, branch VARCHAR(250), + error VARCHAR(250), UNIQUE(repo_id, name) ); ` @@ -45,6 +46,7 @@ schedules ( updated_by TEXT, scheduled_at INTEGER, branch TEXT, + error TEXT, UNIQUE(repo_id, name) ); ` diff --git a/database/schedule/update.go b/database/schedule/update.go index ca90e13b4..790ef89f3 100644 --- a/database/schedule/update.go +++ b/database/schedule/update.go @@ -7,19 +7,19 @@ import ( "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/types" "github.com/go-vela/types/constants" - "github.com/go-vela/types/database" - "github.com/go-vela/types/library" ) // UpdateSchedule updates an existing schedule in the database. -func (e *engine) UpdateSchedule(ctx context.Context, s *library.Schedule, fields bool) (*library.Schedule, error) { +func (e *engine) UpdateSchedule(ctx context.Context, s *api.Schedule, fields bool) (*api.Schedule, error) { e.logger.WithFields(logrus.Fields{ "schedule": s.GetName(), }).Tracef("updating schedule %s in the database", s.GetName()) - // cast the library type to database type - schedule := database.ScheduleFromLibrary(s) + // cast the API type to database type + schedule := types.ScheduleFromAPI(s) // validate the necessary fields are populated err := schedule.Validate() @@ -37,5 +37,13 @@ func (e *engine) UpdateSchedule(ctx context.Context, s *library.Schedule, fields err = e.client.Table(constants.TableSchedule).Model(schedule).UpdateColumn("scheduled_at", s.GetScheduledAt()).Error } - return schedule.ToLibrary(), err + if err != nil { + return nil, err + } + + // set repo to provided repo if creation successful + result := schedule.ToAPI() + result.SetRepo(s.GetRepo()) + + return result, nil } diff --git a/database/schedule/update_test.go b/database/schedule/update_test.go index 45f9dbdf8..f0b1ea2c0 100644 --- a/database/schedule/update_test.go +++ b/database/schedule/update_test.go @@ -4,38 +4,73 @@ package schedule import ( "context" - "reflect" "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/google/go-cmp/cmp" + + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" + "github.com/go-vela/types/constants" ) func TestSchedule_Engine_UpdateSchedule_Config(t *testing.T) { - _repo := testRepo() + // setup types + _owner := testutils.APIUser() + _owner.SetID(1) + _owner.SetName("octocat") + _owner.SetToken("superSecretToken") + _owner.SetRefreshToken("superSecretRefreshToken") + _owner.SetFavorites([]string{"github/octocat"}) + _owner.SetActive(true) + _owner.SetAdmin(false) + _owner.SetDashboards([]string{"45bcf19b-c151-4e2d-b8c6-80a62ba2eae7"}) + + _repo := testutils.APIRepo() _repo.SetID(1) - _repo.SetOrg("foo") - _repo.SetName("bar") - _repo.SetFullName("foo/bar") - - _schedule := testSchedule() + _repo.SetOwner(_owner.Crop()) + _repo.SetHash("MzM4N2MzMDAtNmY4Mi00OTA5LWFhZDAtNWIzMTlkNTJkODMy") + _repo.SetOrg("github") + _repo.SetName("octocat") + _repo.SetFullName("github/octocat") + _repo.SetLink("https://github.com/github/octocat") + _repo.SetClone("https://github.com/github/octocat.git") + _repo.SetBranch("main") + _repo.SetTopics([]string{"cloud", "security"}) + _repo.SetBuildLimit(10) + _repo.SetTimeout(30) + _repo.SetCounter(0) + _repo.SetVisibility("public") + _repo.SetPrivate(false) + _repo.SetTrusted(false) + _repo.SetActive(true) + _repo.SetAllowEvents(api.NewEventsFromMask(1)) + _repo.SetPipelineType("") + _repo.SetPreviousName("") + _repo.SetApproveBuild(constants.ApproveNever) + + _schedule := testutils.APISchedule() _schedule.SetID(1) - _schedule.SetRepoID(1) + _schedule.SetRepo(_repo) + _schedule.SetActive(true) _schedule.SetName("nightly") _schedule.SetEntry("0 0 * * *") - _schedule.SetCreatedAt(1) - _schedule.SetCreatedBy("user1") - _schedule.SetUpdatedAt(1) - _schedule.SetUpdatedBy("user2") + _schedule.SetCreatedAt(1713476291) + _schedule.SetCreatedBy("octocat") + _schedule.SetUpdatedAt(3013476291) + _schedule.SetUpdatedBy("octokitty") + _schedule.SetScheduledAt(2013476291) _schedule.SetBranch("main") + _schedule.SetError("no version: YAML property provided") _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() // ensure the mock expects the query _mock.ExpectExec(`UPDATE "schedules" -SET "repo_id"=$1,"active"=$2,"name"=$3,"entry"=$4,"created_at"=$5,"created_by"=$6,"updated_at"=$7,"updated_by"=$8,"scheduled_at"=$9,"branch"=$10 -WHERE "id" = $11`). - WithArgs(1, false, "nightly", "0 0 * * *", 1, "user1", NowTimestamp{}, "user2", nil, "main", 1). +SET "repo_id"=$1,"active"=$2,"name"=$3,"entry"=$4,"created_at"=$5,"created_by"=$6,"updated_at"=$7,"updated_by"=$8,"scheduled_at"=$9,"branch"=$10,"error"=$11 +WHERE "id" = $12`). + WithArgs(1, true, "nightly", "0 0 * * *", 1713476291, "octocat", NowTimestamp{}, "octokitty", 2013476291, "main", "no version: YAML property provided", 1). WillReturnResult(sqlmock.NewResult(1, 1)) _sqlite := testSqlite(t) @@ -82,38 +117,68 @@ WHERE "id" = $11`). t.Errorf("UpdateSchedule for %s returned err: %v", test.name, err) } - if !reflect.DeepEqual(got, _schedule) { - t.Errorf("UpdateSchedule for %s returned %s, want %s", test.name, got, _schedule) + if diff := cmp.Diff(_schedule, got); diff != "" { + t.Errorf("UpdateSchedule for %s mismatch (-want +got):\n%s", test.name, diff) } }) } } func TestSchedule_Engine_UpdateSchedule_NotConfig(t *testing.T) { - _repo := testRepo() + // setup types + _owner := testutils.APIUser() + _owner.SetID(1) + _owner.SetName("octocat") + _owner.SetToken("superSecretToken") + _owner.SetRefreshToken("superSecretRefreshToken") + _owner.SetFavorites([]string{"github/octocat"}) + _owner.SetActive(true) + _owner.SetAdmin(false) + _owner.SetDashboards([]string{"45bcf19b-c151-4e2d-b8c6-80a62ba2eae7"}) + + _repo := testutils.APIRepo() _repo.SetID(1) - _repo.SetOrg("foo") - _repo.SetName("bar") - _repo.SetFullName("foo/bar") - - _schedule := testSchedule() + _repo.SetOwner(_owner.Crop()) + _repo.SetHash("MzM4N2MzMDAtNmY4Mi00OTA5LWFhZDAtNWIzMTlkNTJkODMy") + _repo.SetOrg("github") + _repo.SetName("octocat") + _repo.SetFullName("github/octocat") + _repo.SetLink("https://github.com/github/octocat") + _repo.SetClone("https://github.com/github/octocat.git") + _repo.SetBranch("main") + _repo.SetTopics([]string{"cloud", "security"}) + _repo.SetBuildLimit(10) + _repo.SetTimeout(30) + _repo.SetCounter(0) + _repo.SetVisibility("public") + _repo.SetPrivate(false) + _repo.SetTrusted(false) + _repo.SetActive(true) + _repo.SetAllowEvents(api.NewEventsFromMask(1)) + _repo.SetPipelineType("") + _repo.SetPreviousName("") + _repo.SetApproveBuild(constants.ApproveNever) + + _schedule := testutils.APISchedule() _schedule.SetID(1) - _schedule.SetRepoID(1) + _schedule.SetRepo(_repo) + _schedule.SetActive(true) _schedule.SetName("nightly") _schedule.SetEntry("0 0 * * *") - _schedule.SetCreatedAt(1) - _schedule.SetCreatedBy("user1") - _schedule.SetUpdatedAt(1) - _schedule.SetUpdatedBy("user2") - _schedule.SetScheduledAt(1) + _schedule.SetCreatedAt(1713476291) + _schedule.SetCreatedBy("octocat") + _schedule.SetUpdatedAt(3013476291) + _schedule.SetUpdatedBy("octokitty") + _schedule.SetScheduledAt(2013476291) _schedule.SetBranch("main") + _schedule.SetError("no version: YAML property provided") _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() // ensure the mock expects the query _mock.ExpectExec(`UPDATE "schedules" SET "scheduled_at"=$1 WHERE "id" = $2`). - WithArgs(1, 1). + WithArgs(2013476291, 1). WillReturnResult(sqlmock.NewResult(1, 1)) _sqlite := testSqlite(t) @@ -159,8 +224,8 @@ func TestSchedule_Engine_UpdateSchedule_NotConfig(t *testing.T) { t.Errorf("UpdateSchedule for %s returned err: %v", test.name, err) } - if !reflect.DeepEqual(got, _schedule) { - t.Errorf("CreateSchedule for %s returned %s, want %s", test.name, got, _schedule) + if diff := cmp.Diff(_schedule, got); diff != "" { + t.Errorf("UpdateSchedule for %s mismatch (-want +got):\n%s", test.name, diff) } }) } diff --git a/database/testutils/api_resources.go b/database/testutils/api_resources.go index 78aec3aa6..06b34eba8 100644 --- a/database/testutils/api_resources.go +++ b/database/testutils/api_resources.go @@ -169,6 +169,23 @@ func APILog() *library.Log { } } +func APISchedule() *api.Schedule { + return &api.Schedule{ + ID: new(int64), + Repo: APIRepo(), + Active: new(bool), + Name: new(string), + Entry: new(string), + CreatedAt: new(int64), + CreatedBy: new(string), + UpdatedAt: new(int64), + UpdatedBy: new(string), + ScheduledAt: new(int64), + Branch: new(string), + Error: new(string), + } +} + func APIService() *library.Service { return &library.Service{ ID: new(int64), diff --git a/database/types/repo_test.go b/database/types/repo_test.go index f060e9141..d41ca7f8b 100644 --- a/database/types/repo_test.go +++ b/database/types/repo_test.go @@ -353,7 +353,7 @@ func TestTypes_RepoFromAPI(t *testing.T) { got := RepoFromAPI(r) if diff := cmp.Diff(want, got); diff != "" { - t.Errorf("FromAPI() mismatch (-want +got):\n%s", diff) + t.Errorf("RepoFromAPI() mismatch (-want +got):\n%s", diff) } } diff --git a/database/types/schedule.go b/database/types/schedule.go new file mode 100644 index 000000000..6d2ada21c --- /dev/null +++ b/database/types/schedule.go @@ -0,0 +1,155 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "database/sql" + "errors" + + "github.com/adhocore/gronx" + + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/util" +) + +var ( + // ErrEmptyScheduleEntry defines the error type when a Schedule type has an empty Entry field provided. + ErrEmptyScheduleEntry = errors.New("empty schedule entry provided") + + // ErrEmptyScheduleName defines the error type when a Schedule type has an empty Name field provided. + ErrEmptyScheduleName = errors.New("empty schedule name provided") + + // ErrEmptyScheduleRepoID defines the error type when a Schedule type has an empty RepoID field provided. + ErrEmptyScheduleRepoID = errors.New("empty schedule repo_id provided") + + // ErrInvalidScheduleEntry defines the error type when a Schedule type has an invalid Entry field provided. + ErrInvalidScheduleEntry = errors.New("invalid schedule entry provided") +) + +type Schedule struct { + ID sql.NullInt64 `sql:"id"` + RepoID sql.NullInt64 `sql:"repo_id"` + Active sql.NullBool `sql:"active"` + Name sql.NullString `sql:"name"` + Entry sql.NullString `sql:"entry"` + CreatedAt sql.NullInt64 `sql:"created_at"` + CreatedBy sql.NullString `sql:"created_by"` + UpdatedAt sql.NullInt64 `sql:"updated_at"` + UpdatedBy sql.NullString `sql:"updated_by"` + ScheduledAt sql.NullInt64 `sql:"scheduled_at"` + Branch sql.NullString `sql:"branch"` + Error sql.NullString `sql:"error"` + + Repo Repo `gorm:"foreignKey:RepoID"` +} + +// Nullify ensures the valid flag for +// the sql.Null types are properly set. +// +// When a field within the Schedule type is the zero +// value for the field, the valid flag is set to +// false causing it to be NULL in the database. +func (s *Schedule) Nullify() *Schedule { + if s == nil { + return nil + } + + // check if the ID field should be valid + s.ID.Valid = s.ID.Int64 != 0 + // check if the RepoID field should be valid + s.RepoID.Valid = s.RepoID.Int64 != 0 + // check if the ID field should be valid + s.Active.Valid = s.RepoID.Int64 != 0 + // check if the Name field should be valid + s.Name.Valid = len(s.Name.String) != 0 + // check if the Entry field should be valid + s.Entry.Valid = len(s.Entry.String) != 0 + // check if the CreatedAt field should be valid + s.CreatedAt.Valid = s.CreatedAt.Int64 != 0 + // check if the CreatedBy field should be valid + s.CreatedBy.Valid = len(s.CreatedBy.String) != 0 + // check if the UpdatedAt field should be valid + s.UpdatedAt.Valid = s.UpdatedAt.Int64 != 0 + // check if the UpdatedBy field should be valid + s.UpdatedBy.Valid = len(s.UpdatedBy.String) != 0 + // check if the ScheduledAt field should be valid + s.ScheduledAt.Valid = s.ScheduledAt.Int64 != 0 + // check if the Branch field should be valid + s.Branch.Valid = len(s.Branch.String) != 0 + // check if the Error field should be valid + s.Error.Valid = len(s.Error.String) != 0 + + return s +} + +// ToAPI converts the Schedule type +// to an API Schedule type. +func (s *Schedule) ToAPI() *api.Schedule { + schedule := new(api.Schedule) + + schedule.SetID(s.ID.Int64) + schedule.SetRepo(s.Repo.ToAPI()) + schedule.SetActive(s.Active.Bool) + schedule.SetName(s.Name.String) + schedule.SetEntry(s.Entry.String) + schedule.SetCreatedAt(s.CreatedAt.Int64) + schedule.SetCreatedBy(s.CreatedBy.String) + schedule.SetUpdatedAt(s.UpdatedAt.Int64) + schedule.SetUpdatedBy(s.UpdatedBy.String) + schedule.SetScheduledAt(s.ScheduledAt.Int64) + schedule.SetBranch(s.Branch.String) + schedule.SetError(s.Error.String) + + return schedule +} + +// Validate verifies the necessary fields for +// the Schedule type are populated correctly. +func (s *Schedule) Validate() error { + // verify the RepoID field is populated + if s.RepoID.Int64 <= 0 { + return ErrEmptyScheduleRepoID + } + + // verify the Name field is populated + if len(s.Name.String) <= 0 { + return ErrEmptyScheduleName + } + + // verify the Entry field is populated + if len(s.Entry.String) <= 0 { + return ErrEmptyScheduleEntry + } + + gron := gronx.New() + if !gron.IsValid(s.Entry.String) { + return ErrInvalidScheduleEntry + } + + // ensure that all Schedule string fields that can be returned as JSON are sanitized to avoid unsafe HTML content + s.Name = sql.NullString{String: util.Sanitize(s.Name.String), Valid: s.Name.Valid} + s.Entry = sql.NullString{String: util.Sanitize(s.Entry.String), Valid: s.Entry.Valid} + + return nil +} + +// ScheduleFromAPI converts the API Schedule type +// to a database Schedule type. +func ScheduleFromAPI(s *api.Schedule) *Schedule { + schedule := &Schedule{ + ID: sql.NullInt64{Int64: s.GetID(), Valid: true}, + RepoID: sql.NullInt64{Int64: s.GetRepo().GetID(), Valid: true}, + Active: sql.NullBool{Bool: s.GetActive(), Valid: true}, + Name: sql.NullString{String: s.GetName(), Valid: true}, + Entry: sql.NullString{String: s.GetEntry(), Valid: true}, + CreatedAt: sql.NullInt64{Int64: s.GetCreatedAt(), Valid: true}, + CreatedBy: sql.NullString{String: s.GetCreatedBy(), Valid: true}, + UpdatedAt: sql.NullInt64{Int64: s.GetUpdatedAt(), Valid: true}, + UpdatedBy: sql.NullString{String: s.GetUpdatedBy(), Valid: true}, + ScheduledAt: sql.NullInt64{Int64: s.GetScheduledAt(), Valid: true}, + Branch: sql.NullString{String: s.GetBranch(), Valid: true}, + Error: sql.NullString{String: s.GetError(), Valid: true}, + } + + return schedule.Nullify() +} diff --git a/database/types/schedule_test.go b/database/types/schedule_test.go new file mode 100644 index 000000000..dcf056218 --- /dev/null +++ b/database/types/schedule_test.go @@ -0,0 +1,234 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "database/sql" + "reflect" + "testing" + "time" + + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database/testutils" + "github.com/go-vela/types/constants" +) + +func TestTypes_Schedule_Nullify(t *testing.T) { + tests := []struct { + name string + schedule *Schedule + want *Schedule + }{ + { + name: "schedule with fields", + schedule: testSchedule(), + want: testSchedule(), + }, + { + name: "schedule with empty fields", + schedule: new(Schedule), + want: &Schedule{ + ID: sql.NullInt64{Int64: 0, Valid: false}, + RepoID: sql.NullInt64{Int64: 0, Valid: false}, + Active: sql.NullBool{Bool: false, Valid: false}, + Name: sql.NullString{String: "", Valid: false}, + Entry: 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}, + ScheduledAt: sql.NullInt64{Int64: 0, Valid: false}, + Branch: sql.NullString{String: "", Valid: false}, + Error: sql.NullString{String: "", Valid: false}, + }, + }, + { + name: "empty schedule", + schedule: nil, + want: nil, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got := test.schedule.Nullify() + if !reflect.DeepEqual(got, test.want) { + t.Errorf("Nullify is %v, want %v", got, test.want) + } + }) + } +} + +func TestTypes_Schedule_ToAPI(t *testing.T) { + // setup types + e := api.NewEventsFromMask(1) + + owner := testutils.APIUser().Crop() + owner.SetID(1) + owner.SetName("octocat") + owner.SetActive(true) + owner.SetToken("superSecretToken") + owner.SetRefreshToken("superSecretRefreshToken") + + repo := testutils.APIRepo() + repo.SetID(1) + repo.SetOwner(owner) + repo.SetHash("superSecretHash") + repo.SetOrg("github") + repo.SetName("octocat") + repo.SetFullName("github/octocat") + repo.SetLink("https://github.com/github/octocat") + repo.SetClone("https://github.com/github/octocat.git") + repo.SetBranch("main") + repo.SetTopics([]string{"cloud", "security"}) + repo.SetBuildLimit(10) + repo.SetTimeout(30) + repo.SetCounter(0) + repo.SetVisibility("public") + repo.SetPrivate(false) + repo.SetTrusted(false) + repo.SetActive(true) + repo.SetAllowEvents(e) + repo.SetPipelineType("yaml") + repo.SetPreviousName("oldName") + repo.SetApproveBuild(constants.ApproveNever) + + want := testutils.APISchedule() + want.SetID(1) + want.SetActive(true) + want.SetRepo(repo) + want.SetName("nightly") + want.SetEntry("0 0 * * *") + want.SetCreatedAt(time.Now().UTC().Unix()) + want.SetCreatedBy("user1") + want.SetUpdatedAt(time.Now().Add(time.Hour * 1).UTC().Unix()) + want.SetUpdatedBy("user2") + want.SetScheduledAt(time.Now().Add(time.Hour * 2).UTC().Unix()) + want.SetBranch("main") + want.SetError("unable to trigger build for schedule nightly: unknown character") + + // run test + got := testSchedule().ToAPI() + + if !reflect.DeepEqual(got, want) { + t.Errorf("ToAPI is %v, want %v", got, want) + } +} + +func TestTypes_Schedule_Validate(t *testing.T) { + tests := []struct { + name string + failure bool + schedule *Schedule + }{ + { + name: "schedule with valid fields", + failure: false, + schedule: testSchedule(), + }, + { + name: "schedule with invalid entry", + failure: true, + schedule: &Schedule{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + RepoID: sql.NullInt64{Int64: 1, Valid: true}, + Name: sql.NullString{String: "invalid", Valid: false}, + Entry: sql.NullString{String: "!@#$%^&*()", Valid: false}, + }, + }, + { + name: "schedule with missing entry", + failure: true, + schedule: &Schedule{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + RepoID: sql.NullInt64{Int64: 1, Valid: true}, + Name: sql.NullString{String: "nightly", Valid: false}, + }, + }, + { + name: "schedule with missing name", + failure: true, + schedule: &Schedule{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + RepoID: sql.NullInt64{Int64: 1, Valid: true}, + Entry: sql.NullString{String: "0 0 * * *", Valid: false}, + }, + }, + { + name: "schedule with missing repo_id", + failure: true, + schedule: &Schedule{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + Name: sql.NullString{String: "nightly", Valid: false}, + Entry: sql.NullString{String: "0 0 * * *", Valid: false}, + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + err := test.schedule.Validate() + if test.failure { + if err == nil { + t.Errorf("Validate should have returned err") + } + + return + } + + if err != nil { + t.Errorf("Validate returned err: %v", err) + } + }) + } +} + +func TestTypes_ScheduleFromAPI(t *testing.T) { + // setup types + s := new(api.Schedule) + repo := testutils.APIRepo() + repo.SetID(1) + + s.SetID(1) + s.SetActive(true) + s.SetRepo(repo) + s.SetName("nightly") + s.SetEntry("0 0 * * *") + s.SetCreatedAt(time.Now().UTC().Unix()) + s.SetCreatedBy("user1") + s.SetUpdatedAt(time.Now().Add(time.Hour * 1).UTC().Unix()) + s.SetUpdatedBy("user2") + s.SetScheduledAt(time.Now().Add(time.Hour * 2).UTC().Unix()) + s.SetBranch("main") + s.SetError("unable to trigger build for schedule nightly: unknown character") + + want := testSchedule() + want.Repo = Repo{} + + // run test + got := ScheduleFromAPI(s) + + if !reflect.DeepEqual(got, want) { + t.Errorf("ScheduleFromAPI is %v, want %v", got, want) + } +} + +// testSchedule is a test helper function to create a Schedule type with all fields set to a fake value. +func testSchedule() *Schedule { + return &Schedule{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + RepoID: sql.NullInt64{Int64: 1, Valid: true}, + Active: sql.NullBool{Bool: true, Valid: true}, + Name: sql.NullString{String: "nightly", Valid: true}, + Entry: sql.NullString{String: "0 0 * * *", Valid: true}, + CreatedAt: sql.NullInt64{Int64: time.Now().UTC().Unix(), Valid: true}, + CreatedBy: sql.NullString{String: "user1", Valid: true}, + UpdatedAt: sql.NullInt64{Int64: time.Now().Add(time.Hour * 1).UTC().Unix(), Valid: true}, + UpdatedBy: sql.NullString{String: "user2", Valid: true}, + ScheduledAt: sql.NullInt64{Int64: time.Now().Add(time.Hour * 2).UTC().Unix(), Valid: true}, + Branch: sql.NullString{String: "main", Valid: true}, + Error: sql.NullString{String: "unable to trigger build for schedule nightly: unknown character", Valid: true}, + + Repo: *testRepo(), + } +} diff --git a/mock/server/schedule.go b/mock/server/schedule.go index 417890cd7..390aa6b4a 100644 --- a/mock/server/schedule.go +++ b/mock/server/schedule.go @@ -10,28 +10,120 @@ import ( "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types" - "github.com/go-vela/types/library" ) const ( // ScheduleResp represents a JSON return for a single schedule. ScheduleResp = `{ - "id": 2, - "repo_id": 1, - "active": true, - "name": "foo", - "entry": "@weekly", - "created_at": 1683154980, - "created_by": "octocat", - "updated_at": 1683154980, - "updated_by": "octocat", - "scheduled_at": 0, - "branch": "main" -}` + "id": 2, + "repo": { + "id": 1, + "owner": { + "id": 1, + "name": "octocat", + "favorites": [], + "active": true, + "admin": false + }, + "org": "github", + "counter": 10, + "name": "octocat", + "full_name": "github/octocat", + "link": "https://github.com/github/octocat", + "clone": "https://github.com/github/octocat", + "branch": "main", + "build_limit": 10, + "timeout": 60, + "visibility": "public", + "private": false, + "trusted": true, + "pipeline_type": "yaml", + "topics": [], + "active": true, + "allow_events": { + "push": { + "branch": true, + "tag": true + }, + "pull_request": { + "opened": true, + "synchronize": true, + "reopened": true, + "edited": false + }, + "deployment": { + "created": true + }, + "comment": { + "created": false, + "edited": false + } + }, + "approve_build": "fork-always", + "previous_name": "" + }, + "active": true, + "name": "foo", + "entry": "@weekly", + "created_at": 1683154980, + "created_by": "octocat", + "updated_at": 1683154980, + "updated_by": "octocat", + "scheduled_at": 0, + "branch": "main", + "error": "error message" + }` SchedulesResp = `[ { "id": 2, + "repo": { + "id": 1, + "owner": { + "id": 1, + "name": "octocat", + "favorites": [], + "active": true, + "admin": false + }, + "org": "github", + "counter": 10, + "name": "octocat", + "full_name": "github/octocat", + "link": "https://github.com/github/octocat", + "clone": "https://github.com/github/octocat", + "branch": "main", + "build_limit": 10, + "timeout": 60, + "visibility": "public", + "private": false, + "trusted": true, + "pipeline_type": "yaml", + "topics": [], + "active": true, + "allow_events": { + "push": { + "branch": true, + "tag": true + }, + "pull_request": { + "opened": true, + "synchronize": true, + "reopened": true, + "edited": false + }, + "deployment": { + "created": true + }, + "comment": { + "created": false, + "edited": false + } + }, + "approve_build": "fork-always", + "previous_name": "" + }, "active": true, "name": "foo", "entry": "@weekly", @@ -40,11 +132,57 @@ const ( "updated_at": 1683154980, "updated_by": "octocat", "scheduled_at": 0, - "repo_id": 1, - "branch": "main" + "branch": "main", + "error": "error message" }, { "id": 1, + "repo": { + "id": 1, + "owner": { + "id": 1, + "name": "octocat", + "favorites": [], + "active": true, + "admin": false + }, + "org": "github", + "counter": 10, + "name": "octocat", + "full_name": "github/octocat", + "link": "https://github.com/github/octocat", + "clone": "https://github.com/github/octocat", + "branch": "main", + "build_limit": 10, + "timeout": 60, + "visibility": "public", + "private": false, + "trusted": true, + "pipeline_type": "yaml", + "topics": [], + "active": true, + "allow_events": { + "push": { + "branch": true, + "tag": true + }, + "pull_request": { + "opened": true, + "synchronize": true, + "reopened": true, + "edited": false + }, + "deployment": { + "created": true + }, + "comment": { + "created": false, + "edited": false + } + }, + "approve_build": "fork-always", + "previous_name": "" + }, "active": true, "name": "bar", "entry": "@weekly", @@ -54,16 +192,16 @@ const ( "updated_by": "octocat", "scheduled_at": 0, "repo_id": 1, - "branch": "main - } -]` + "branch": "main", + "error": "error message" + }]` ) // getSchedules returns mock JSON for a http GET. func getSchedules(c *gin.Context) { data := []byte(SchedulesResp) - var body []library.Schedule + var body []api.Schedule _ = json.Unmarshal(data, &body) c.JSON(http.StatusOK, body) @@ -85,7 +223,7 @@ func getSchedule(c *gin.Context) { data := []byte(ScheduleResp) - var body library.Schedule + var body api.Schedule _ = json.Unmarshal(data, &body) c.JSON(http.StatusOK, body) @@ -95,7 +233,7 @@ func getSchedule(c *gin.Context) { func addSchedule(c *gin.Context) { data := []byte(ScheduleResp) - var body library.Schedule + var body api.Schedule _ = json.Unmarshal(data, &body) c.JSON(http.StatusCreated, body) @@ -119,7 +257,7 @@ func updateSchedule(c *gin.Context) { data := []byte(ScheduleResp) - var body library.Schedule + var body api.Schedule _ = json.Unmarshal(data, &body) c.JSON(http.StatusOK, body) diff --git a/mock/server/schedule_test.go b/mock/server/schedule_test.go index b88c9f223..293676e02 100644 --- a/mock/server/schedule_test.go +++ b/mock/server/schedule_test.go @@ -7,11 +7,11 @@ import ( "reflect" "testing" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" ) func TestSchedule_ActiveScheduleResp(t *testing.T) { - testSchedule := library.Schedule{} + testSchedule := api.Schedule{} err := json.Unmarshal([]byte(ScheduleResp), &testSchedule) if err != nil { diff --git a/router/middleware/schedule/context.go b/router/middleware/schedule/context.go index 258c243ca..5c8920d01 100644 --- a/router/middleware/schedule/context.go +++ b/router/middleware/schedule/context.go @@ -5,7 +5,7 @@ package schedule import ( "context" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" ) const key = "schedule" @@ -16,13 +16,13 @@ type Setter interface { } // FromContext returns the Schedule associated with this context. -func FromContext(c context.Context) *library.Schedule { +func FromContext(c context.Context) *api.Schedule { value := c.Value(key) if value == nil { return nil } - s, ok := value.(*library.Schedule) + s, ok := value.(*api.Schedule) if !ok { return nil } @@ -32,6 +32,6 @@ func FromContext(c context.Context) *library.Schedule { // ToContext adds the Schedule to this context if it supports // the Setter interface. -func ToContext(c Setter, s *library.Schedule) { +func ToContext(c Setter, s *api.Schedule) { c.Set(key, s) } diff --git a/router/middleware/schedule/context_test.go b/router/middleware/schedule/context_test.go index 066a3a6cc..f0f841135 100644 --- a/router/middleware/schedule/context_test.go +++ b/router/middleware/schedule/context_test.go @@ -7,13 +7,13 @@ import ( "github.com/gin-gonic/gin" - "github.com/go-vela/types/library" + api "github.com/go-vela/server/api/types" ) func TestSchedule_FromContext(t *testing.T) { // setup types num := int64(1) - want := &library.Schedule{ID: &num} + want := &api.Schedule{ID: &num} // setup context gin.SetMode(gin.TestMode) @@ -72,7 +72,7 @@ func TestSchedule_FromContext_Empty(t *testing.T) { func TestSchedule_ToContext(t *testing.T) { // setup types num := int64(1) - want := &library.Schedule{ID: &num} + want := &api.Schedule{ID: &num} // setup context gin.SetMode(gin.TestMode) diff --git a/router/middleware/schedule/schedule.go b/router/middleware/schedule/schedule.go index 78c5f14e5..41864cef0 100644 --- a/router/middleware/schedule/schedule.go +++ b/router/middleware/schedule/schedule.go @@ -9,15 +9,15 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" - "github.com/go-vela/types/library" ) // Retrieve gets the schedule in the given context. -func Retrieve(c *gin.Context) *library.Schedule { +func Retrieve(c *gin.Context) *api.Schedule { return FromContext(c) } From 76400eb9b8c208c880497cb3adc126b243649e78 Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Wed, 8 May 2024 14:19:56 -0400 Subject: [PATCH 47/71] fix(ci): remove deprecated linter rules (#1123) --- .golangci.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 5b27708f8..f857a2c9f 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -71,7 +71,6 @@ linters: - bidichk # checks for dangerous unicode character sequences - bodyclose # checks whether HTTP response body is closed successfully - contextcheck # check the function whether use a non-inherited context - - deadcode # finds unused code - dupl # code clone detection - errcheck # checks for unchecked errors - errorlint # find misuses of errors @@ -97,14 +96,12 @@ linters: - nolintlint # reports ill-formed or insufficient nolint directives - revive # linter for go - staticcheck # applies static analysis checks, go vet on steroids - - structcheck # finds unused struct fields - stylecheck # replacement for golint - tenv # analyzer that detects using os.Setenv instead of t.Setenv since Go1.17 - typecheck # parses and type-checks go code, like the front-end of a go compiler - unconvert # remove unnecessary type conversions - unparam # reports unused function parameters - unused # checks for unused constants, variables, functions and types - - varcheck # finds unused global variables and constants - whitespace # detects leading and trailing whitespace - wsl # forces code to use empty lines From 8a744e48d224197478bb48a468186783b04c44db Mon Sep 17 00:00:00 2001 From: David May <49894298+wass3rw3rk@users.noreply.github.com> Date: Wed, 8 May 2024 16:04:06 -0500 Subject: [PATCH 48/71] fix(api-spec): add missing 404 responses in docs (#1124) --- api/dashboard/delete.go | 4 ++++ api/dashboard/get.go | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/api/dashboard/delete.go b/api/dashboard/delete.go index 14e81ffa5..a2798c940 100644 --- a/api/dashboard/delete.go +++ b/api/dashboard/delete.go @@ -40,6 +40,10 @@ import ( // description: Unauthorized to delete dashboard // schema: // "$ref": "#/definitions/Error" +// '404': +// description: Unable to find dashboard +// schema: +// "$ref": "#/definitions/Error" // '500': // description: Server error when deleting dashboard // schema: diff --git a/api/dashboard/get.go b/api/dashboard/get.go index da4239667..3535cb8b4 100644 --- a/api/dashboard/get.go +++ b/api/dashboard/get.go @@ -42,6 +42,10 @@ import ( // description: Unauthorized to retrieve dashboard // schema: // "$ref": "#/definitions/Error" +// '404': +// description: Unable to find dashboard +// schema: +// "$ref": "#/definitions/Error" // '500': // description: Server error when retrieving dashboard // schema: From 4421e304b842c050e6260c0e563bb15b4a3066e6 Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Fri, 10 May 2024 11:56:05 -0500 Subject: [PATCH 49/71] fix(compiler): aggregate templates for nested pipelines (#1125) --- compiler/native/expand.go | 4 ++++ compiler/native/expand_test.go | 19 ++++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/compiler/native/expand.go b/compiler/native/expand.go index e69066ef7..335ca5007 100644 --- a/compiler/native/expand.go +++ b/compiler/native/expand.go @@ -60,6 +60,7 @@ func (c *client) ExpandSteps(s *yaml.Build, tmpls map[string]*yaml.Template, r * secrets := s.Secrets services := s.Services environment := s.Environment + templates := s.Templates if len(environment) == 0 { environment = make(raw.StringSliceMap) @@ -139,6 +140,8 @@ func (c *client) ExpandSteps(s *yaml.Build, tmpls map[string]*yaml.Template, r * return s, fmt.Errorf("cannot use render_inline inside a called template (%s)", step.Template.Name) } + templates = append(templates, tmplBuild.Templates...) + tmplBuild, err = c.ExpandSteps(tmplBuild, mapFromTemplates(tmplBuild.Templates), r, depth-1) if err != nil { return s, err @@ -202,6 +205,7 @@ func (c *client) ExpandSteps(s *yaml.Build, tmpls map[string]*yaml.Template, r * s.Secrets = secrets s.Services = services s.Environment = environment + s.Templates = templates return s, nil } diff --git a/compiler/native/expand_test.go b/compiler/native/expand_test.go index cf6f3927f..0e69eed65 100644 --- a/compiler/native/expand_test.go +++ b/compiler/native/expand_test.go @@ -869,6 +869,19 @@ func TestNative_ExpandSteps_TemplateCallTemplate(t *testing.T) { "star": "test3", } + wantTemplates := yaml.TemplateSlice{ + { + Name: "chain", + Source: "github.example.com/faz/baz/template_calls_template.yml", + Type: "github", + }, + { + Name: "test", + Source: "github.example.com/foo/bar/long_template.yml", + Type: "github", + }, + } + // run test compiler, err := New(c) if err != nil { @@ -879,7 +892,7 @@ func TestNative_ExpandSteps_TemplateCallTemplate(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - build, err := compiler.ExpandSteps(&yaml.Build{Steps: steps, Services: yaml.ServiceSlice{}, Environment: globalEnvironment}, test.tmpls, new(pipeline.RuleData), compiler.TemplateDepth) + build, err := compiler.ExpandSteps(&yaml.Build{Steps: steps, Services: yaml.ServiceSlice{}, Environment: globalEnvironment, Templates: yaml.TemplateSlice{test.tmpls["chain"]}}, test.tmpls, new(pipeline.RuleData), compiler.TemplateDepth) if err != nil { t.Errorf("ExpandSteps_Type%s returned err: %v", test.name, err) } @@ -899,6 +912,10 @@ func TestNative_ExpandSteps_TemplateCallTemplate(t *testing.T) { if diff := cmp.Diff(build.Environment, wantEnvironment); diff != "" { t.Errorf("ExpandSteps()_Type%s mismatch (-want +got):\n%s", test.name, diff) } + + if diff := cmp.Diff(build.Templates, wantTemplates); diff != "" { + t.Errorf("ExpandSteps()_Type%s mismatch (-want +got):\n%s", test.name, diff) + } }) } } From 27f116370e14814a0403c61b829c6cd70f3c8e13 Mon Sep 17 00:00:00 2001 From: dave vader <48764154+plyr4@users.noreply.github.com> Date: Fri, 10 May 2024 14:38:12 -0500 Subject: [PATCH 50/71] feat!: db driven platform settings (#1110) --- api/admin/settings.go | 278 +++++++++++++++++ api/repo/create.go | 7 +- api/schedule/create.go | 36 +-- api/types/settings/compiler.go | 112 +++++++ api/types/settings/compiler_test.go | 116 +++++++ api/types/settings/platform.go | 285 ++++++++++++++++++ api/types/settings/platform_test.go | 195 ++++++++++++ api/types/settings/queue.go | 52 ++++ api/types/settings/queue_test.go | 90 ++++++ cmd/vela-server/compiler.go | 24 -- cmd/vela-server/main.go | 6 + cmd/vela-server/queue.go | 31 -- cmd/vela-server/schedule.go | 9 +- cmd/vela-server/server.go | 97 +++++- compiler/engine.go | 9 +- compiler/native/clone.go | 4 +- compiler/native/clone_test.go | 4 +- compiler/native/compile.go | 10 +- compiler/native/compile_test.go | 34 ++- compiler/native/environment_test.go | 12 +- compiler/native/expand.go | 6 +- compiler/native/expand_test.go | 35 ++- compiler/native/initialize_test.go | 6 +- compiler/native/native.go | 28 +- compiler/native/native_test.go | 73 +++-- compiler/native/parse.go | 2 +- compiler/native/parse_test.go | 24 +- compiler/native/script_test.go | 6 +- compiler/native/settings.go | 21 ++ compiler/native/substitute_test.go | 6 +- compiler/native/transform_test.go | 6 +- compiler/native/validate_test.go | 54 ++-- database/database.go | 2 + database/integration_test.go | 55 ++++ database/interface.go | 4 + database/resource.go | 14 + database/resource_test.go | 3 + database/secret/create_test.go | 7 +- database/secret/secret_test.go | 28 -- database/secret/update_test.go | 7 +- database/settings/create.go | 32 ++ database/settings/create_test.go | 82 +++++ database/settings/get.go | 31 ++ database/settings/get_test.go | 92 ++++++ database/settings/interface.go | 22 ++ database/settings/opts.go | 52 ++++ database/settings/opts_test.go | 208 +++++++++++++ database/settings/settings.go | 77 +++++ database/settings/settings_test.go | 171 +++++++++++ database/settings/table.go | 60 ++++ database/settings/table_test.go | 58 ++++ database/settings/update.go | 34 +++ database/settings/update_test.go | 87 ++++++ database/testutils/mock_args.go | 35 +++ database/types/settings.go | 218 ++++++++++++++ database/types/settings_test.go | 195 ++++++++++++ go.mod | 2 + go.sum | 4 + internal/image/doc.go | 9 + internal/image/image.go | 35 +++ internal/image/image_test.go | 76 +++++ mock/server/server.go | 3 + mock/server/settings.go | 119 ++++++++ mock/server/settings_test.go | 65 ++++ queue/queue.go | 22 ++ queue/redis/driver_test.go | 2 +- queue/redis/length.go | 6 +- queue/redis/length_test.go | 18 +- queue/redis/opts.go | 16 +- queue/redis/opts_test.go | 30 +- queue/redis/ping_test.go | 4 +- queue/redis/pop.go | 14 +- queue/redis/pop_test.go | 20 +- queue/redis/redis.go | 11 +- queue/redis/redis_test.go | 2 +- queue/redis/route.go | 4 +- queue/redis/settings.go | 19 ++ queue/service.go | 9 + queue/setup.go | 2 +- router/admin.go | 32 +- router/middleware/allowlist.go | 16 - router/middleware/allowlist_schedule.go | 16 - router/middleware/cli.go | 20 ++ router/middleware/cli/context.go | 37 +++ router/middleware/cli/context_test.go | 85 ++++++ router/middleware/cli/doc.go | 10 + ...allowlist_schedule_test.go => cli_test.go} | 20 +- router/middleware/compiler.go | 9 +- router/middleware/compiler_test.go | 33 +- router/middleware/pipeline/pipeline_test.go | 2 +- router/middleware/queue.go | 5 + router/middleware/settings.go | 20 ++ router/middleware/settings/context.go | 37 +++ router/middleware/settings/context_test.go | 106 +++++++ router/middleware/settings/doc.go | 10 + .../{allowlist_test.go => settings_test.go} | 18 +- router/middleware/worker_test.go | 4 +- 97 files changed, 3860 insertions(+), 364 deletions(-) create mode 100644 api/admin/settings.go create mode 100644 api/types/settings/compiler.go create mode 100644 api/types/settings/compiler_test.go create mode 100644 api/types/settings/platform.go create mode 100644 api/types/settings/platform_test.go create mode 100644 api/types/settings/queue.go create mode 100644 api/types/settings/queue_test.go delete mode 100644 cmd/vela-server/compiler.go delete mode 100644 cmd/vela-server/queue.go create mode 100644 compiler/native/settings.go create mode 100644 database/settings/create.go create mode 100644 database/settings/create_test.go create mode 100644 database/settings/get.go create mode 100644 database/settings/get_test.go create mode 100644 database/settings/interface.go create mode 100644 database/settings/opts.go create mode 100644 database/settings/opts_test.go create mode 100644 database/settings/settings.go create mode 100644 database/settings/settings_test.go create mode 100644 database/settings/table.go create mode 100644 database/settings/table_test.go create mode 100644 database/settings/update.go create mode 100644 database/settings/update_test.go create mode 100644 database/testutils/mock_args.go create mode 100644 database/types/settings.go create mode 100644 database/types/settings_test.go create mode 100644 internal/image/doc.go create mode 100644 internal/image/image.go create mode 100644 internal/image/image_test.go create mode 100644 mock/server/settings.go create mode 100644 mock/server/settings_test.go create mode 100644 queue/redis/settings.go delete mode 100644 router/middleware/allowlist.go delete mode 100644 router/middleware/allowlist_schedule.go create mode 100644 router/middleware/cli.go create mode 100644 router/middleware/cli/context.go create mode 100644 router/middleware/cli/context_test.go create mode 100644 router/middleware/cli/doc.go rename router/middleware/{allowlist_schedule_test.go => cli_test.go} (65%) create mode 100644 router/middleware/settings.go create mode 100644 router/middleware/settings/context.go create mode 100644 router/middleware/settings/context_test.go create mode 100644 router/middleware/settings/doc.go rename router/middleware/{allowlist_test.go => settings_test.go} (60%) diff --git a/api/admin/settings.go b/api/admin/settings.go new file mode 100644 index 000000000..0b067372b --- /dev/null +++ b/api/admin/settings.go @@ -0,0 +1,278 @@ +// SPDX-License-Identifier: Apache-2.0 + +package admin + +import ( + "fmt" + "net/http" + "time" + + "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + + "github.com/go-vela/server/api/types/settings" + "github.com/go-vela/server/compiler/native" + "github.com/go-vela/server/database" + "github.com/go-vela/server/internal/image" + "github.com/go-vela/server/queue" + cliMiddleware "github.com/go-vela/server/router/middleware/cli" + sMiddleware "github.com/go-vela/server/router/middleware/settings" + uMiddleware "github.com/go-vela/server/router/middleware/user" + "github.com/go-vela/server/util" +) + +// swagger:operation GET /api/v1/admin/settings admin GetSettings +// +// Get the currently configured settings. +// +// --- +// produces: +// - application/json +// security: +// - ApiKeyAuth: [] +// responses: +// '200': +// description: Successfully retrieved settings +// type: json +// schema: +// "$ref": "#/definitions/Platform" +// '404': +// description: Unable to retrieve settings +// schema: +// "$ref": "#/definitions/Error" + +// GetSettings represents the API handler to +// captures settings stored in the database. +func GetSettings(c *gin.Context) { + // capture middleware values + s := sMiddleware.FromContext(c) + + logrus.Info("Admin: reading settings") + + // check captured value because we aren't retrieving settings from the database + // instead we are retrieving the auto-refreshed middleware value + if s == nil { + retErr := fmt.Errorf("settings not found") + + util.HandleError(c, http.StatusNotFound, retErr) + + return + } + + c.JSON(http.StatusOK, s) +} + +// swagger:operation PUT /api/v1/admin/settings admin UpdateSettings +// +// Update the platform settings singleton in the database. +// +// --- +// produces: +// - application/json +// parameters: +// - in: body +// name: body +// description: Payload containing settings to update +// required: true +// schema: +// "$ref": "#/definitions/Platform" +// security: +// - ApiKeyAuth: [] +// responses: +// '200': +// description: Successfully updated platform settings in the database +// type: json +// schema: +// "$ref": "#/definitions/Platform" +// '400': +// description: Unable to update settings — bad request +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Unable to retrieve platform settings to update +// schema: +// "$ref": "#/definitions/Error" +// '500': +// description: Unable to update platform settings in the database +// schema: +// "$ref": "#/definitions/Error" + +// UpdateSettings represents the API handler to +// update the settings singleton stored in the database. +func UpdateSettings(c *gin.Context) { + // capture middleware values + s := sMiddleware.FromContext(c) + u := uMiddleware.FromContext(c) + ctx := c.Request.Context() + + logrus.Info("Admin: updating settings") + + // check captured value because we aren't retrieving settings from the database + // instead we are retrieving the auto-refreshed middleware value + if s == nil { + retErr := fmt.Errorf("settings not found") + + util.HandleError(c, http.StatusNotFound, retErr) + + return + } + + // duplicate settings to not alter the shared pointer + _s := new(settings.Platform) + _s.Update(s) + + // ensure we update the singleton record + _s.SetID(1) + + // capture body from API request + input := new(settings.Platform) + + err := c.Bind(input) + if err != nil { + retErr := fmt.Errorf("unable to decode JSON for settings: %w", err) + + util.HandleError(c, http.StatusBadRequest, retErr) + + return + } + + if input.Compiler != nil { + if input.CloneImage != nil { + // validate clone image + cloneImage := *input.CloneImage + + _, err = image.ParseWithError(cloneImage) + if err != nil { + retErr := fmt.Errorf("invalid clone image %s: %w", cloneImage, err) + + util.HandleError(c, http.StatusBadRequest, retErr) + + return + } + + _s.SetCloneImage(cloneImage) + } + + if input.TemplateDepth != nil { + _s.SetTemplateDepth(*input.TemplateDepth) + } + + if input.StarlarkExecLimit != nil { + _s.SetStarlarkExecLimit(*input.StarlarkExecLimit) + } + } + + if input.Queue != nil { + if input.Queue.Routes != nil { + _s.SetRoutes(input.GetRoutes()) + } + } + + if input.RepoAllowlist != nil { + _s.SetRepoAllowlist(input.GetRepoAllowlist()) + } + + if input.ScheduleAllowlist != nil { + _s.SetScheduleAllowlist(input.GetScheduleAllowlist()) + } + + _s.SetUpdatedBy(u.GetName()) + + // send API call to update the settings + _s, err = database.FromContext(c).UpdateSettings(ctx, _s) + if err != nil { + retErr := fmt.Errorf("unable to update settings: %w", err) + + util.HandleError(c, http.StatusInternalServerError, retErr) + + return + } + + c.JSON(http.StatusOK, _s) +} + +// swagger:operation DELETE /api/v1/admin/settings admin RestoreSettings +// +// Restore the currently configured settings to the environment defaults. +// +// --- +// produces: +// - application/json +// security: +// - ApiKeyAuth: [] +// responses: +// '200': +// description: Successfully restored default settings in the database +// type: json +// schema: +// "$ref": "#/definitions/Platform" +// '404': +// description: Unable to retrieve settings to restore +// schema: +// "$ref": "#/definitions/Error" +// '500': +// description: Unable to restore settings in the database +// schema: +// "$ref": "#/definitions/Error" + +// RestoreSettings represents the API handler to +// restore settings stored in the database to the environment defaults. +func RestoreSettings(c *gin.Context) { + // capture middleware values + s := sMiddleware.FromContext(c) + u := uMiddleware.FromContext(c) + cliCtx := cliMiddleware.FromContext(c) + ctx := c.Request.Context() + + logrus.Info("Admin: restoring settings") + + // check captured value because we aren't retrieving settings from the database + // instead we are retrieving the auto-refreshed middleware value + if s == nil { + retErr := fmt.Errorf("settings not found") + + util.HandleError(c, http.StatusNotFound, retErr) + + return + } + + compiler, err := native.FromCLIContext(cliCtx) + if err != nil { + retErr := fmt.Errorf("unable to restore settings: %w", err) + + util.HandleError(c, http.StatusInternalServerError, retErr) + + return + } + + queue, err := queue.FromCLIContext(cliCtx) + if err != nil { + retErr := fmt.Errorf("unable to restore settings: %w", err) + + util.HandleError(c, http.StatusInternalServerError, retErr) + + return + } + + s.SetUpdatedAt(time.Now().UTC().Unix()) + s.SetUpdatedBy(u.GetName()) + + // read in defaults supplied from the cli runtime + compilerSettings := compiler.GetSettings() + s.SetCompiler(compilerSettings) + + queueSettings := queue.GetSettings() + s.SetQueue(queueSettings) + + // send API call to update the settings + s, err = database.FromContext(c).UpdateSettings(ctx, s) + if err != nil { + retErr := fmt.Errorf("unable to update (restore) settings: %w", err) + + util.HandleError(c, http.StatusInternalServerError, retErr) + + return + } + + c.JSON(http.StatusOK, s) +} diff --git a/api/repo/create.go b/api/repo/create.go index 824f7d0f5..7249bbfa4 100644 --- a/api/repo/create.go +++ b/api/repo/create.go @@ -15,6 +15,7 @@ import ( "github.com/go-vela/server/api/types" "github.com/go-vela/server/api/types/actions" "github.com/go-vela/server/database" + "github.com/go-vela/server/router/middleware/settings" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" "github.com/go-vela/server/util" @@ -71,7 +72,8 @@ import ( func CreateRepo(c *gin.Context) { // capture middleware values u := user.Retrieve(c) - allowlist := c.Value("allowlist").([]string) + s := settings.FromContext(c) + defaultBuildLimit := c.Value("defaultBuildLimit").(int64) defaultTimeout := c.Value("defaultTimeout").(int64) maxBuildLimit := c.Value("maxBuildLimit").(int64) @@ -197,6 +199,7 @@ func CreateRepo(c *gin.Context) { return } + r.SetPipelineType(input.GetPipelineType()) } @@ -217,7 +220,7 @@ func CreateRepo(c *gin.Context) { ) // ensure repo is allowed to be activated - if !util.CheckAllowlist(r, allowlist) { + if !util.CheckAllowlist(r, s.GetRepoAllowlist()) { retErr := fmt.Errorf("unable to activate repo: %s is not on allowlist", r.GetFullName()) util.HandleError(c, http.StatusForbidden, retErr) diff --git a/api/schedule/create.go b/api/schedule/create.go index a691230e6..a63d60fa4 100644 --- a/api/schedule/create.go +++ b/api/schedule/create.go @@ -14,6 +14,7 @@ import ( api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/repo" + "github.com/go-vela/server/router/middleware/settings" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" ) @@ -77,7 +78,8 @@ func CreateSchedule(c *gin.Context) { u := user.Retrieve(c) r := repo.Retrieve(c) ctx := c.Request.Context() - allowlist := c.Value("allowlistschedule").([]string) + s := settings.FromContext(c) + minimumFrequency := c.Value("scheduleminimumfrequency").(time.Duration) // capture body from API request @@ -119,7 +121,7 @@ func CreateSchedule(c *gin.Context) { }).Infof("creating new schedule %s", input.GetName()) // ensure repo is allowed to create new schedules - if !util.CheckAllowlist(r, allowlist) { + if !util.CheckAllowlist(r, s.GetScheduleAllowlist()) { retErr := fmt.Errorf("unable to create schedule %s: %s is not on allowlist", input.GetName(), r.GetFullName()) util.HandleError(c, http.StatusForbidden, retErr) @@ -127,29 +129,29 @@ func CreateSchedule(c *gin.Context) { return } - s := new(api.Schedule) + schedule := new(api.Schedule) // update fields in schedule object - s.SetCreatedBy(u.GetName()) - s.SetRepo(r) - s.SetName(input.GetName()) - s.SetEntry(input.GetEntry()) - s.SetCreatedAt(time.Now().UTC().Unix()) - s.SetUpdatedAt(time.Now().UTC().Unix()) - s.SetUpdatedBy(u.GetName()) + schedule.SetCreatedBy(u.GetName()) + schedule.SetRepo(r) + schedule.SetName(input.GetName()) + schedule.SetEntry(input.GetEntry()) + schedule.SetCreatedAt(time.Now().UTC().Unix()) + schedule.SetUpdatedAt(time.Now().UTC().Unix()) + schedule.SetUpdatedBy(u.GetName()) if input.GetBranch() == "" { - s.SetBranch(r.GetBranch()) + schedule.SetBranch(r.GetBranch()) } else { - s.SetBranch(input.GetBranch()) + schedule.SetBranch(input.GetBranch()) } // set the active field based off the input provided if input.Active == nil { // default active field to true - s.SetActive(true) + schedule.SetActive(true) } else { - s.SetActive(input.GetActive()) + schedule.SetActive(input.GetActive()) } // send API call to capture the schedule from the database @@ -178,7 +180,7 @@ func CreateSchedule(c *gin.Context) { dbSchedule.SetActive(true) // send API call to update the schedule - s, err = database.FromContext(c).UpdateSchedule(ctx, dbSchedule, true) + schedule, err = database.FromContext(c).UpdateSchedule(ctx, dbSchedule, true) if err != nil { retErr := fmt.Errorf("unable to set schedule %s to active: %w", dbSchedule.GetName(), err) @@ -188,7 +190,7 @@ func CreateSchedule(c *gin.Context) { } } else { // send API call to create the schedule - s, err = database.FromContext(c).CreateSchedule(ctx, s) + schedule, err = database.FromContext(c).CreateSchedule(ctx, schedule) if err != nil { retErr := fmt.Errorf("unable to create new schedule %s: %w", r.GetName(), err) @@ -198,7 +200,7 @@ func CreateSchedule(c *gin.Context) { } } - c.JSON(http.StatusCreated, s) + c.JSON(http.StatusCreated, schedule) } // validateEntry validates the entry for a minimum frequency. diff --git a/api/types/settings/compiler.go b/api/types/settings/compiler.go new file mode 100644 index 000000000..a18a31401 --- /dev/null +++ b/api/types/settings/compiler.go @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: Apache-2.0 + +package settings + +import "fmt" + +type Compiler struct { + CloneImage *string `json:"clone_image,omitempty"` + TemplateDepth *int `json:"template_depth,omitempty"` + StarlarkExecLimit *uint64 `json:"starlark_exec_limit,omitempty"` +} + +// GetCloneImage returns the CloneImage field. +// +// When the provided Compiler type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (cs *Compiler) GetCloneImage() string { + // return zero value if Settings type or CloneImage field is nil + if cs == nil || cs.CloneImage == nil { + return "" + } + + return *cs.CloneImage +} + +// GetTemplateDepth returns the TemplateDepth field. +// +// When the provided Compiler type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (cs *Compiler) GetTemplateDepth() int { + // return zero value if Settings type or TemplateDepth field is nil + if cs == nil || cs.TemplateDepth == nil { + return 0 + } + + return *cs.TemplateDepth +} + +// GetStarlarkExecLimit returns the StarlarkExecLimit field. +// +// When the provided Compiler type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (cs *Compiler) GetStarlarkExecLimit() uint64 { + // return zero value if Compiler type or StarlarkExecLimit field is nil + if cs == nil || cs.StarlarkExecLimit == nil { + return 0 + } + + return *cs.StarlarkExecLimit +} + +// SetCloneImage sets the CloneImage field. +// +// When the provided Compiler type is nil, it +// will set nothing and immediately return. +func (cs *Compiler) SetCloneImage(v string) { + // return if Compiler type is nil + if cs == nil { + return + } + + cs.CloneImage = &v +} + +// SetTemplateDepth sets the TemplateDepth field. +// +// When the provided Compiler type is nil, it +// will set nothing and immediately return. +func (cs *Compiler) SetTemplateDepth(v int) { + // return if Compiler type is nil + if cs == nil { + return + } + + cs.TemplateDepth = &v +} + +// SetStarlarkExecLimit sets the StarlarkExecLimit field. +// +// When the provided Compiler type is nil, it +// will set nothing and immediately return. +func (cs *Compiler) SetStarlarkExecLimit(v uint64) { + // return if Compiler type is nil + if cs == nil { + return + } + + cs.StarlarkExecLimit = &v +} + +// String implements the Stringer interface for the Compiler type. +func (cs *Compiler) String() string { + return fmt.Sprintf(`{ + CloneImage: %s, + TemplateDepth: %d, + StarlarkExecLimit: %d, +}`, + cs.GetCloneImage(), + cs.GetTemplateDepth(), + cs.GetStarlarkExecLimit(), + ) +} + +// CompilerMockEmpty returns an empty Compiler type. +func CompilerMockEmpty() Compiler { + cs := Compiler{} + cs.SetCloneImage("") + cs.SetTemplateDepth(0) + cs.SetStarlarkExecLimit(0) + + return cs +} diff --git a/api/types/settings/compiler_test.go b/api/types/settings/compiler_test.go new file mode 100644 index 000000000..a224a9cb7 --- /dev/null +++ b/api/types/settings/compiler_test.go @@ -0,0 +1,116 @@ +// SPDX-License-Identifier: Apache-2.0 + +package settings + +import ( + "fmt" + "reflect" + "testing" +) + +func TestTypes_Compiler_Getters(t *testing.T) { + // setup tests + tests := []struct { + compiler *Compiler + want *Compiler + }{ + { + compiler: testCompilerSettings(), + want: testCompilerSettings(), + }, + { + compiler: new(Compiler), + want: new(Compiler), + }, + } + + // run tests + for _, test := range tests { + if !reflect.DeepEqual(test.compiler.GetCloneImage(), test.want.GetCloneImage()) { + t.Errorf("GetCloneImage is %v, want %v", test.compiler.GetCloneImage(), test.want.GetCloneImage()) + } + + if !reflect.DeepEqual(test.compiler.GetTemplateDepth(), test.want.GetTemplateDepth()) { + t.Errorf("GetTemplateDepth is %v, want %v", test.compiler.GetTemplateDepth(), test.want.GetTemplateDepth()) + } + + if !reflect.DeepEqual(test.compiler.GetStarlarkExecLimit(), test.want.GetStarlarkExecLimit()) { + t.Errorf("GetStarlarkExecLimit is %v, want %v", test.compiler.GetStarlarkExecLimit(), test.want.GetStarlarkExecLimit()) + } + } +} + +func TestTypes_Compiler_Setters(t *testing.T) { + // setup types + var cs *Compiler + + // setup tests + tests := []struct { + compiler *Compiler + want *Compiler + }{ + { + compiler: testCompilerSettings(), + want: testCompilerSettings(), + }, + { + compiler: cs, + want: new(Compiler), + }, + } + + // run tests + for _, test := range tests { + test.compiler.SetCloneImage(test.want.GetCloneImage()) + + if !reflect.DeepEqual(test.compiler.GetCloneImage(), test.want.GetCloneImage()) { + t.Errorf("SetCloneImage is %v, want %v", test.compiler.GetCloneImage(), test.want.GetCloneImage()) + } + + test.compiler.SetTemplateDepth(test.want.GetTemplateDepth()) + + if !reflect.DeepEqual(test.compiler.GetTemplateDepth(), test.want.GetTemplateDepth()) { + t.Errorf("SetTemplateDepth is %v, want %v", test.compiler.GetTemplateDepth(), test.want.GetTemplateDepth()) + } + + test.compiler.SetStarlarkExecLimit(test.want.GetStarlarkExecLimit()) + + if !reflect.DeepEqual(test.compiler.GetStarlarkExecLimit(), test.want.GetStarlarkExecLimit()) { + t.Errorf("SetStarlarkExecLimit is %v, want %v", test.compiler.GetStarlarkExecLimit(), test.want.GetStarlarkExecLimit()) + } + } +} + +func TestTypes_Compiler_String(t *testing.T) { + // setup types + cs := testCompilerSettings() + + want := fmt.Sprintf(`{ + CloneImage: %s, + TemplateDepth: %d, + StarlarkExecLimit: %d, +}`, + cs.GetCloneImage(), + cs.GetTemplateDepth(), + cs.GetStarlarkExecLimit(), + ) + + // run test + got := cs.String() + + if !reflect.DeepEqual(got, want) { + t.Errorf("String is %v, want %v", got, want) + } +} + +// testCompilerSettings is a test helper function to create a Compiler +// type with all fields set to a fake value. +func testCompilerSettings() *Compiler { + cs := new(Compiler) + + cs.SetCloneImage("target/vela-git:latest") + cs.SetTemplateDepth(1) + cs.SetStarlarkExecLimit(100) + + return cs +} diff --git a/api/types/settings/platform.go b/api/types/settings/platform.go new file mode 100644 index 000000000..f72698b66 --- /dev/null +++ b/api/types/settings/platform.go @@ -0,0 +1,285 @@ +// SPDX-License-Identifier: Apache-2.0 + +package settings + +import ( + "fmt" +) + +// Platform is the API representation of platform settingps. +// +// swagger:model Platform +type Platform struct { + ID *int64 `json:"id"` + *Queue `json:"queue"` + *Compiler `json:"compiler"` + RepoAllowlist *[]string `json:"repo_allowlist"` + ScheduleAllowlist *[]string `json:"schedule_allowlist"` + CreatedAt *int64 `json:"created_at,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty"` +} + +// GetID returns the ID field. +// +// When the provided Platform type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (ps *Platform) GetID() int64 { + // return zero value if Platform type or ID field is nil + if ps == nil || ps.ID == nil { + return 0 + } + + return *ps.ID +} + +// GetCompiler returns the Compiler field. +// +// When the provided Platform type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (ps *Platform) GetCompiler() Compiler { + // return zero value if Platform type or Compiler field is nil + if ps == nil || ps.Compiler == nil { + return Compiler{} + } + + return *ps.Compiler +} + +// GetQueue returns the Queue field. +// +// When the provided Platform type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (ps *Platform) GetQueue() Queue { + // return zero value if Platform type or Queue field is nil + if ps == nil || ps.Queue == nil { + return Queue{} + } + + return *ps.Queue +} + +// GetRepoAllowlist returns the RepoAllowlist field. +// +// When the provided Platform type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (ps *Platform) GetRepoAllowlist() []string { + // return zero value if Platform type or RepoAllowlist field is nil + if ps == nil || ps.RepoAllowlist == nil { + return []string{} + } + + return *ps.RepoAllowlist +} + +// GetScheduleAllowlist returns the ScheduleAllowlist field. +// +// When the provided Platform type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (ps *Platform) GetScheduleAllowlist() []string { + // return zero value if Platform type or ScheduleAllowlist field is nil + if ps == nil || ps.ScheduleAllowlist == nil { + return []string{} + } + + return *ps.ScheduleAllowlist +} + +// GetCreatedAt returns the CreatedAt field. +// +// When the provided Platform type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (ps *Platform) GetCreatedAt() int64 { + // return zero value if Platform type or CreatedAt field is nil + if ps == nil || ps.CreatedAt == nil { + return 0 + } + + return *ps.CreatedAt +} + +// GetUpdatedAt returns the UpdatedAt field. +// +// When the provided Platform type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (ps *Platform) GetUpdatedAt() int64 { + // return zero value if Platform type or UpdatedAt field is nil + if ps == nil || ps.UpdatedAt == nil { + return 0 + } + + return *ps.UpdatedAt +} + +// GetUpdatedBy returns the UpdatedBy field. +// +// When the provided Platform type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (ps *Platform) GetUpdatedBy() string { + // return zero value if Platform type or UpdatedBy field is nil + if ps == nil || ps.UpdatedBy == nil { + return "" + } + + return *ps.UpdatedBy +} + +// SetID sets the ID field. +// +// When the provided Platform type is nil, it +// will set nothing and immediately return. +func (ps *Platform) SetID(v int64) { + // return if Platform type is nil + if ps == nil { + return + } + + ps.ID = &v +} + +// SetCompiler sets the Compiler field. +// +// When the provided Compiler type is nil, it +// will set nothing and immediately return. +func (ps *Platform) SetCompiler(cs Compiler) { + // return if Platform type is nil + if ps == nil { + return + } + + ps.Compiler = &cs +} + +// SetQueue sets the Queue field. +// +// When the provided Queue type is nil, it +// will set nothing and immediately return. +func (ps *Platform) SetQueue(qs Queue) { + // return if Platform type is nil + if ps == nil { + return + } + + ps.Queue = &qs +} + +// SetRepoAllowlist sets the RepoAllowlist field. +// +// When the provided Platform type is nil, it +// will set nothing and immediately return. +func (ps *Platform) SetRepoAllowlist(v []string) { + // return if Platform type is nil + if ps == nil { + return + } + + ps.RepoAllowlist = &v +} + +// SetScheduleAllowlist sets the RepoAllowlist field. +// +// When the provided Platform type is nil, it +// will set nothing and immediately return. +func (ps *Platform) SetScheduleAllowlist(v []string) { + // return if Platform type is nil + if ps == nil { + return + } + + ps.ScheduleAllowlist = &v +} + +// SetCreatedAt sets the CreatedAt field. +// +// When the provided Platform type is nil, it +// will set nothing and immediately return. +func (ps *Platform) SetCreatedAt(v int64) { + // return if Platform type is nil + if ps == nil { + return + } + + ps.CreatedAt = &v +} + +// SetUpdatedAt sets the UpdatedAt field. +// +// When the provided Platform type is nil, it +// will set nothing and immediately return. +func (ps *Platform) SetUpdatedAt(v int64) { + // return if Platform type is nil + if ps == nil { + return + } + + ps.UpdatedAt = &v +} + +// SetUpdatedBy sets the UpdatedBy field. +// +// When the provided Platform type is nil, it +// will set nothing and immediately return. +func (ps *Platform) SetUpdatedBy(v string) { + // return if Platform type is nil + if ps == nil { + return + } + + ps.UpdatedBy = &v +} + +// Update takes another settings record and updates the internal fields, intended +// to be used when the refreshing settings record shared across the server. +func (ps *Platform) Update(newSettingps *Platform) { + if ps == nil { + return + } + + if newSettingps == nil { + return + } + + ps.SetCompiler(newSettingps.GetCompiler()) + ps.SetQueue(newSettingps.GetQueue()) + ps.SetRepoAllowlist(newSettingps.GetRepoAllowlist()) + ps.SetScheduleAllowlist(newSettingps.GetScheduleAllowlist()) +} + +// String implements the Stringer interface for the Platform type. +func (ps *Platform) String() string { + cs := ps.GetCompiler() + qs := ps.GetQueue() + + return fmt.Sprintf(`{ + ID: %d, + Compiler: %v, + Queue: %v, + RepoAllowlist: %v, + ScheduleAllowlist: %v, + CreatedAt: %d, + UpdatedAt: %d, + UpdatedBy: %s, +}`, + ps.GetID(), + cs.String(), + qs.String(), + ps.GetRepoAllowlist(), + ps.GetScheduleAllowlist(), + ps.GetCreatedAt(), + ps.GetUpdatedAt(), + ps.GetUpdatedBy(), + ) +} + +// PlatformMockEmpty returns an empty Platform type. +func PlatformMockEmpty() Platform { + ps := Platform{} + + ps.SetCompiler(CompilerMockEmpty()) + ps.SetQueue(QueueMockEmpty()) + + ps.SetRepoAllowlist([]string{}) + ps.SetScheduleAllowlist([]string{}) + + return ps +} diff --git a/api/types/settings/platform_test.go b/api/types/settings/platform_test.go new file mode 100644 index 000000000..56c9cec7b --- /dev/null +++ b/api/types/settings/platform_test.go @@ -0,0 +1,195 @@ +// SPDX-License-Identifier: Apache-2.0 + +package settings + +import ( + "fmt" + "reflect" + "testing" + + "github.com/google/go-cmp/cmp" +) + +func TestTypes_Platform_Getters(t *testing.T) { + // setup tests + tests := []struct { + platform *Platform + want *Platform + }{ + { + platform: testPlatformSettings(), + want: testPlatformSettings(), + }, + { + platform: new(Platform), + want: new(Platform), + }, + } + + // run tests + for _, test := range tests { + if !reflect.DeepEqual(test.platform.GetCompiler(), test.want.GetCompiler()) { + t.Errorf("GetCompiler is %v, want %v", test.platform.GetCompiler(), test.want.GetCompiler()) + } + + if !reflect.DeepEqual(test.platform.GetQueue(), test.want.GetQueue()) { + t.Errorf("GetQueue is %v, want %v", test.platform.GetQueue(), test.want.GetQueue()) + } + + if !reflect.DeepEqual(test.platform.GetRepoAllowlist(), test.want.GetRepoAllowlist()) { + t.Errorf("GetRepoAllowlist is %v, want %v", test.platform.GetRepoAllowlist(), test.want.GetRepoAllowlist()) + } + + if !reflect.DeepEqual(test.platform.GetScheduleAllowlist(), test.want.GetScheduleAllowlist()) { + t.Errorf("GetScheduleAllowlist is %v, want %v", test.platform.GetScheduleAllowlist(), test.want.GetScheduleAllowlist()) + } + } +} + +func TestTypes_Platform_Setters(t *testing.T) { + // setup types + var ps *Platform + + // setup tests + tests := []struct { + platform *Platform + want *Platform + }{ + { + platform: testPlatformSettings(), + want: testPlatformSettings(), + }, + { + platform: ps, + want: new(Platform), + }, + } + + // run tests + for _, test := range tests { + test.platform.SetCompiler(test.want.GetCompiler()) + + if !reflect.DeepEqual(test.platform.GetCompiler(), test.want.GetCompiler()) { + t.Errorf("SetCompiler is %v, want %v", test.platform.GetCompiler(), test.want.GetCompiler()) + } + + test.platform.SetQueue(test.want.GetQueue()) + + if !reflect.DeepEqual(test.platform.GetQueue(), test.want.GetQueue()) { + t.Errorf("SetQueue is %v, want %v", test.platform.GetQueue(), test.want.GetQueue()) + } + + test.platform.SetRepoAllowlist(test.want.GetRepoAllowlist()) + + if !reflect.DeepEqual(test.platform.GetRepoAllowlist(), test.want.GetRepoAllowlist()) { + t.Errorf("SetRepoAllowlist is %v, want %v", test.platform.GetRepoAllowlist(), test.want.GetRepoAllowlist()) + } + + test.platform.SetScheduleAllowlist(test.want.GetScheduleAllowlist()) + + if !reflect.DeepEqual(test.platform.GetScheduleAllowlist(), test.want.GetScheduleAllowlist()) { + t.Errorf("SetScheduleAllowlist is %v, want %v", test.platform.GetScheduleAllowlist(), test.want.GetScheduleAllowlist()) + } + } +} + +func TestTypes_Platform_Update(t *testing.T) { + // setup types + s := testPlatformSettings() + + // update fields + sUpdate := testPlatformSettings() + sUpdate.SetCompiler(Compiler{}) + sUpdate.SetQueue(Queue{}) + sUpdate.SetRepoAllowlist([]string{"foo"}) + sUpdate.SetScheduleAllowlist([]string{"bar"}) + + // setup tests + tests := []struct { + platform *Platform + want *Platform + }{ + { + platform: s, + want: testPlatformSettings(), + }, + { + platform: s, + want: sUpdate, + }, + } + + // run tests + for _, test := range tests { + test.platform.Update(test.want) + + if diff := cmp.Diff(test.want, test.platform); diff != "" { + t.Errorf("(Update: -want +got):\n%s", diff) + } + } +} + +func TestTypes_Platform_String(t *testing.T) { + // setup types + s := testPlatformSettings() + cs := s.GetCompiler() + qs := s.GetQueue() + + want := fmt.Sprintf(`{ + ID: %d, + Compiler: %v, + Queue: %v, + RepoAllowlist: %v, + ScheduleAllowlist: %v, + CreatedAt: %d, + UpdatedAt: %d, + UpdatedBy: %s, +}`, + s.GetID(), + cs.String(), + qs.String(), + s.GetRepoAllowlist(), + s.GetScheduleAllowlist(), + s.GetCreatedAt(), + s.GetUpdatedAt(), + s.GetUpdatedBy(), + ) + + // run test + got := s.String() + + if !reflect.DeepEqual(got, want) { + t.Errorf("String is %v, want %v", got, want) + } +} + +// testPlatformSettings is a test helper function to create a Platform +// type with all fields set to a fake value. +func testPlatformSettings() *Platform { + // setup platform + s := new(Platform) + s.SetID(1) + s.SetCreatedAt(1) + s.SetUpdatedAt(1) + s.SetUpdatedBy("vela-server") + s.SetRepoAllowlist([]string{"foo", "bar"}) + s.SetScheduleAllowlist([]string{"*"}) + + // setup types + // setup compiler + cs := new(Compiler) + + cs.SetCloneImage("target/vela-git:latest") + cs.SetTemplateDepth(1) + cs.SetStarlarkExecLimit(100) + + // setup queue + qs := new(Queue) + + qs.SetRoutes([]string{"vela"}) + + s.SetCompiler(*cs) + s.SetQueue(*qs) + + return s +} diff --git a/api/types/settings/queue.go b/api/types/settings/queue.go new file mode 100644 index 000000000..9bf54dfd1 --- /dev/null +++ b/api/types/settings/queue.go @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: Apache-2.0 + +package settings + +import "fmt" + +type Queue struct { + Routes *[]string `json:"routes,omitempty"` +} + +// GetRoutes returns the Routes field. +// +// When the provided Queue type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (qs *Queue) GetRoutes() []string { + // return zero value if Queue type or Routes field is nil + if qs == nil || qs.Routes == nil { + return []string{} + } + + return *qs.Routes +} + +// SetRoutes sets the Routes field. +// +// When the provided Queue type is nil, it +// will set nothing and immediately return. +func (qs *Queue) SetRoutes(v []string) { + // return if Queue type is nil + if qs == nil { + return + } + + qs.Routes = &v +} + +// String implements the Stringer interface for the Queue type. +func (qs *Queue) String() string { + return fmt.Sprintf(`{ + Routes: %v, +}`, + qs.GetRoutes(), + ) +} + +// QueueMockEmpty returns an empty Queue type. +func QueueMockEmpty() Queue { + qs := Queue{} + qs.SetRoutes([]string{}) + + return qs +} diff --git a/api/types/settings/queue_test.go b/api/types/settings/queue_test.go new file mode 100644 index 000000000..30389b881 --- /dev/null +++ b/api/types/settings/queue_test.go @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: Apache-2.0 + +package settings + +import ( + "fmt" + "reflect" + "testing" +) + +func TestTypes_Queue_Getters(t *testing.T) { + // setup tests + tests := []struct { + queue *Queue + want *Queue + }{ + { + queue: testQueueSettings(), + want: testQueueSettings(), + }, + { + queue: new(Queue), + want: new(Queue), + }, + } + + // run tests + for _, test := range tests { + if !reflect.DeepEqual(test.queue.GetRoutes(), test.want.GetRoutes()) { + t.Errorf("GetRoutes is %v, want %v", test.queue.GetRoutes(), test.want.GetRoutes()) + } + } +} + +func TestTypes_Queue_Setters(t *testing.T) { + // setup types + var qs *Queue + + // setup tests + tests := []struct { + queue *Queue + want *Queue + }{ + { + queue: testQueueSettings(), + want: testQueueSettings(), + }, + { + queue: qs, + want: new(Queue), + }, + } + + // run tests + for _, test := range tests { + test.queue.SetRoutes(test.want.GetRoutes()) + + if !reflect.DeepEqual(test.queue.GetRoutes(), test.want.GetRoutes()) { + t.Errorf("SetRoutes is %v, want %v", test.queue.GetRoutes(), test.want.GetRoutes()) + } + } +} + +func TestTypes_Queue_String(t *testing.T) { + // setup types + qs := testQueueSettings() + + want := fmt.Sprintf(`{ + Routes: %s, +}`, + qs.GetRoutes(), + ) + + // run test + got := qs.String() + + if !reflect.DeepEqual(got, want) { + t.Errorf("String is %v, want %v", got, want) + } +} + +// testQueueSettings is a test helper function to create a Queue +// type with all fields set to a fake value. +func testQueueSettings() *Queue { + qs := new(Queue) + + qs.SetRoutes([]string{"vela"}) + + return qs +} diff --git a/cmd/vela-server/compiler.go b/cmd/vela-server/compiler.go deleted file mode 100644 index 872f3fbd0..000000000 --- a/cmd/vela-server/compiler.go +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - -package main - -import ( - "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" - - "github.com/go-vela/server/compiler" - "github.com/go-vela/server/compiler/native" - "github.com/go-vela/types/constants" -) - -// helper function to setup the queue from the CLI arguments. -func setupCompiler(c *cli.Context) (compiler.Engine, error) { - logrus.Debug("Creating queue client from CLI configuration") - return setupCompilerNative(c) -} - -// helper function to setup the Kafka queue from the CLI arguments. -func setupCompilerNative(c *cli.Context) (compiler.Engine, error) { - logrus.Tracef("Creating %s compiler client from CLI configuration", constants.DriverKafka) - return native.New(c) -} diff --git a/cmd/vela-server/main.go b/cmd/vela-server/main.go index 5ce4c7bd7..7fa51ca27 100644 --- a/cmd/vela-server/main.go +++ b/cmd/vela-server/main.go @@ -79,6 +79,12 @@ func main() { Name: "vela-secret", Usage: "secret used for server <-> agent communication", }, + &cli.DurationFlag{ + EnvVars: []string{"VELA_PLATFORM_SETTINGS_REFRESH_INTERVAL", "VELA_SETTINGS_REFRESH_INTERVAL"}, + Name: "settings-refresh-interval", + Usage: "interval at which platform settings will be refreshed", + Value: 5 * time.Second, + }, &cli.StringFlag{ EnvVars: []string{"VELA_SERVER_PRIVATE_KEY"}, Name: "vela-server-private-key", diff --git a/cmd/vela-server/queue.go b/cmd/vela-server/queue.go deleted file mode 100644 index 7a3a74c41..000000000 --- a/cmd/vela-server/queue.go +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - -package main - -import ( - "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" - - "github.com/go-vela/server/queue" -) - -// helper function to setup the queue from the CLI arguments. -func setupQueue(c *cli.Context) (queue.Service, error) { - logrus.Debug("Creating queue client from CLI configuration") - - // queue configuration - _setup := &queue.Setup{ - Driver: c.String("queue.driver"), - Address: c.String("queue.addr"), - Cluster: c.Bool("queue.cluster"), - Routes: c.StringSlice("queue.routes"), - Timeout: c.Duration("queue.pop.timeout"), - PrivateKey: c.String("queue.private-key"), - PublicKey: c.String("queue.public-key"), - } - - // setup the queue - // - // https://pkg.go.dev/github.com/go-vela/server/queue?tab=doc#New - return queue.New(_setup) -} diff --git a/cmd/vela-server/schedule.go b/cmd/vela-server/schedule.go index b86e70b79..f2832935e 100644 --- a/cmd/vela-server/schedule.go +++ b/cmd/vela-server/schedule.go @@ -14,6 +14,7 @@ import ( "github.com/go-vela/server/api/build" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/api/types/settings" "github.com/go-vela/server/compiler" "github.com/go-vela/server/database" "github.com/go-vela/server/internal" @@ -29,7 +30,7 @@ const ( scheduleWait = "waiting to trigger build for schedule" ) -func processSchedules(ctx context.Context, start time.Time, compiler compiler.Engine, database database.Interface, metadata *internal.Metadata, queue queue.Service, scm scm.Service, allowList []string) error { +func processSchedules(ctx context.Context, start time.Time, settings *settings.Platform, compiler compiler.Engine, database database.Interface, metadata *internal.Metadata, queue queue.Service, scm scm.Service) error { logrus.Infof("processing active schedules to create builds") // send API call to capture the list of active schedules @@ -122,7 +123,7 @@ func processSchedules(ctx context.Context, start time.Time, compiler compiler.En } // process the schedule and trigger a new build - err = processSchedule(ctx, schedule, compiler, database, metadata, queue, scm, allowList) + err = processSchedule(ctx, schedule, settings, compiler, database, metadata, queue, scm) if err != nil { handleError(ctx, database, err, schedule) @@ -147,7 +148,7 @@ func processSchedules(ctx context.Context, start time.Time, compiler compiler.En } // processSchedule will, given a schedule, process it and trigger a new build. -func processSchedule(ctx context.Context, s *api.Schedule, compiler compiler.Engine, database database.Interface, metadata *internal.Metadata, queue queue.Service, scm scm.Service, allowList []string) error { +func processSchedule(ctx context.Context, s *api.Schedule, settings *settings.Platform, compiler compiler.Engine, database database.Interface, metadata *internal.Metadata, queue queue.Service, scm scm.Service) error { // send API call to capture the repo for the schedule r, err := database.GetRepo(ctx, s.GetRepo().GetID()) if err != nil { @@ -155,7 +156,7 @@ func processSchedule(ctx context.Context, s *api.Schedule, compiler compiler.Eng } // ensure repo has not been removed from allow list - if !util.CheckAllowlist(r, allowList) { + if !util.CheckAllowlist(r, settings.GetScheduleAllowlist()) { return fmt.Errorf("skipping schedule: repo %s no longer on allow list", r.GetFullName()) } diff --git a/cmd/vela-server/server.go b/cmd/vela-server/server.go index 7f25a43df..bae9ec326 100644 --- a/cmd/vela-server/server.go +++ b/cmd/vela-server/server.go @@ -4,6 +4,7 @@ package main import ( "context" + "errors" "fmt" "net/http" "net/url" @@ -16,13 +17,18 @@ import ( "github.com/sirupsen/logrus" "github.com/urfave/cli/v2" "golang.org/x/sync/errgroup" + "gorm.io/gorm" "k8s.io/apimachinery/pkg/util/wait" + "github.com/go-vela/server/api/types/settings" + "github.com/go-vela/server/compiler/native" "github.com/go-vela/server/database" + "github.com/go-vela/server/queue" "github.com/go-vela/server/router" "github.com/go-vela/server/router/middleware" ) +//nolint:funlen,gocyclo // ignore function length and cyclomatic complexity func server(c *cli.Context) error { // set log formatter switch c.String("log-formatter") { @@ -67,7 +73,7 @@ func server(c *cli.Context) error { logrus.SetLevel(logrus.PanicLevel) } - compiler, err := setupCompiler(c) + compiler, err := native.FromCLIContext(c) if err != nil { return err } @@ -77,7 +83,7 @@ func server(c *cli.Context) error { return err } - queue, err := setupQueue(c) + queue, err := queue.FromCLIContext(c) if err != nil { return err } @@ -97,7 +103,59 @@ func server(c *cli.Context) error { return err } + jitter := wait.Jitter(5*time.Second, 2.0) + + logrus.Infof("retrieving initial platform settings after %v delay", jitter) + + time.Sleep(jitter) + + ps, err := database.GetSettings(context.Background()) + if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { + return err + } + + // platform settings record does not exist + if err != nil { + logrus.Info("creating initial platform settings") + + // create initial settings record + ps = new(settings.Platform) + + // singleton record ID should always be 1 + ps.SetID(1) + + ps.SetCreatedAt(time.Now().UTC().Unix()) + ps.SetUpdatedAt(time.Now().UTC().Unix()) + ps.SetUpdatedBy("vela-server") + + // read in defaults supplied from the cli runtime + compilerSettings := compiler.GetSettings() + ps.SetCompiler(compilerSettings) + + queueSettings := queue.GetSettings() + ps.SetQueue(queueSettings) + + // set repos permitted to be added + ps.SetRepoAllowlist(c.StringSlice("vela-repo-allowlist")) + + // set repos permitted to use schedules + ps.SetScheduleAllowlist(c.StringSlice("vela-schedule-allowlist")) + + // create the settings record in the database + _, err = database.CreateSettings(context.Background(), ps) + if err != nil { + return err + } + } + + // update any internal settings, this occurs in middleware + // to keep settings refreshed for each request + queue.SetSettings(ps) + compiler.SetSettings(ps) + router := router.Load( + middleware.CLI(c), + middleware.Settings(ps), middleware.Compiler(compiler), middleware.Database(database), middleware.Logger(logrus.StandardLogger(), time.RFC3339), @@ -111,7 +169,6 @@ func server(c *cli.Context) error { middleware.QueueSigningPrivateKey(c.String("queue.private-key")), middleware.QueueSigningPublicKey(c.String("queue.public-key")), middleware.QueueAddress(c.String("queue.addr")), - middleware.Allowlist(c.StringSlice("vela-repo-allowlist")), middleware.DefaultBuildLimit(c.Int64("default-build-limit")), middleware.DefaultTimeout(c.Int64("default-build-timeout")), middleware.MaxBuildLimit(c.Int64("max-build-limit")), @@ -121,7 +178,6 @@ func server(c *cli.Context) error { middleware.DefaultRepoEvents(c.StringSlice("default-repo-events")), middleware.DefaultRepoEventsMask(c.Int64("default-repo-events-mask")), middleware.DefaultRepoApproveBuild(c.String("default-repo-approve-build")), - middleware.AllowlistSchedule(c.StringSlice("vela-schedule-allowlist")), middleware.ScheduleFrequency(c.Duration("schedule-minimum-frequency")), ) @@ -158,26 +214,52 @@ func server(c *cli.Context) error { select { case sig := <-signalChannel: logrus.Infof("received signal: %s", sig) + err := srv.Shutdown(ctx) if err != nil { logrus.Error(err) } + done() case <-gctx.Done(): logrus.Info("closing signal goroutine") + err := srv.Shutdown(ctx) if err != nil { logrus.Error(err) } + return gctx.Err() } return nil }) + // spawn goroutine for refreshing settings + g.Go(func() error { + interval := c.Duration("settings-refresh-interval") + + logrus.Infof("refreshing platform settings every %v", interval) + + for { + time.Sleep(interval) + + newSettings, err := database.GetSettings(context.Background()) + if err != nil { + logrus.WithError(err).Warn("unable to refresh platform settings") + + continue + } + + // update the internal fields for the shared settings record + ps.Update(newSettings) + } + }) + // spawn goroutine for starting the server g.Go(func() error { logrus.Infof("starting server on %s", addr.Host) + err = srv.ListenAndServe() if err != nil { // log a message indicating the failure of the server @@ -190,6 +272,7 @@ func server(c *cli.Context) error { // spawn goroutine for starting the scheduler g.Go(func() error { logrus.Info("starting scheduler") + for { // track the starting time for when the server begins processing schedules // @@ -214,7 +297,11 @@ func server(c *cli.Context) error { // sleep for a duration of time before processing schedules time.Sleep(jitter) - err = processSchedules(ctx, start, compiler, database, metadata, queue, scm, c.StringSlice("vela-schedule-allowlist")) + // update internal settings updated through refresh + compiler.SetSettings(ps) + queue.SetSettings(ps) + + err = processSchedules(ctx, start, ps, compiler, database, metadata, queue, scm) if err != nil { logrus.WithError(err).Warn("unable to process schedules") } else { diff --git a/compiler/engine.go b/compiler/engine.go index 3079148d4..59dca1469 100644 --- a/compiler/engine.go +++ b/compiler/engine.go @@ -4,6 +4,7 @@ package compiler import ( api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/api/types/settings" "github.com/go-vela/server/internal" "github.com/go-vela/types/library" "github.com/go-vela/types/pipeline" @@ -144,7 +145,13 @@ type Engine interface { // WithLabel defines a function that sets // the label(s) in the Engine. WithLabels([]string) Engine - // WithUser defines a function that sets + // WithPrivateGitHub defines a function that sets // the private github client in the Engine. WithPrivateGitHub(string, string) Engine + // GetSettings defines a function that returns new api settings + // with the compiler Engine fields filled. + GetSettings() settings.Compiler + // SetSettings defines a function that takes api settings + // and updates the compiler Engine. + SetSettings(*settings.Platform) } diff --git a/compiler/native/clone.go b/compiler/native/clone.go index 9075292f7..85016cfc6 100644 --- a/compiler/native/clone.go +++ b/compiler/native/clone.go @@ -30,7 +30,7 @@ func (c *client) CloneStage(p *yaml.Build) (*yaml.Build, error) { Steps: yaml.StepSlice{ &yaml.Step{ Detach: false, - Image: c.CloneImage, + Image: c.GetCloneImage(), Name: cloneStepName, Privileged: false, Pull: constants.PullNotPresent, @@ -63,7 +63,7 @@ func (c *client) CloneStep(p *yaml.Build) (*yaml.Build, error) { // create new clone step clone := &yaml.Step{ Detach: false, - Image: c.CloneImage, + Image: c.GetCloneImage(), Name: cloneStepName, Privileged: false, Pull: constants.PullNotPresent, diff --git a/compiler/native/clone_test.go b/compiler/native/clone_test.go index 120e3524f..304f703b2 100644 --- a/compiler/native/clone_test.go +++ b/compiler/native/clone_test.go @@ -84,7 +84,7 @@ func TestNative_CloneStage(t *testing.T) { // run tests for _, test := range tests { - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("unable to create new compiler: %v", err) } @@ -167,7 +167,7 @@ func TestNative_CloneStep(t *testing.T) { // run tests for _, test := range tests { - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Unable to create new compiler: %v", err) } diff --git a/compiler/native/compile.go b/compiler/native/compile.go index c33035149..0c739c310 100644 --- a/compiler/native/compile.go +++ b/compiler/native/compile.go @@ -75,7 +75,7 @@ func (c *client) Compile(v interface{}) (*pipeline.Build, *library.Pipeline, err switch { case p.Metadata.RenderInline: - newPipeline, err := c.compileInline(p, c.TemplateDepth) + newPipeline, err := c.compileInline(p, c.GetTemplateDepth()) if err != nil { return nil, _pipeline, err } @@ -110,7 +110,7 @@ func (c *client) CompileLite(v interface{}, ruleData *pipeline.RuleData, substit _pipeline.SetType(c.repo.GetPipelineType()) if p.Metadata.RenderInline { - newPipeline, err := c.compileInline(p, c.TemplateDepth) + newPipeline, err := c.compileInline(p, c.GetTemplateDepth()) if err != nil { return nil, _pipeline, err } @@ -167,7 +167,7 @@ func (c *client) CompileLite(v interface{}, ruleData *pipeline.RuleData, substit case len(p.Steps) > 0: // inject the templates into the steps - p, err = c.ExpandSteps(p, templates, ruleData, c.TemplateDepth) + p, err = c.ExpandSteps(p, templates, ruleData, c.GetTemplateDepth()) if err != nil { return nil, _pipeline, err } @@ -209,7 +209,7 @@ func (c *client) compileInline(p *yaml.Build, depth int) (*yaml.Build, error) { // return if max template depth has been reached if depth == 0 { - retErr := fmt.Errorf("max template depth of %d exceeded", c.TemplateDepth) + retErr := fmt.Errorf("max template depth of %d exceeded", c.GetTemplateDepth()) return nil, retErr } @@ -318,7 +318,7 @@ func (c *client) compileSteps(p *yaml.Build, _pipeline *library.Pipeline, tmpls } // inject the templates into the steps - p, err = c.ExpandSteps(p, tmpls, r, c.TemplateDepth) + p, err = c.ExpandSteps(p, tmpls, r, c.GetTemplateDepth()) if err != nil { return nil, _pipeline, err } diff --git a/compiler/native/compile_test.go b/compiler/native/compile_test.go index 811f9855e..15f2ab8f3 100644 --- a/compiler/native/compile_test.go +++ b/compiler/native/compile_test.go @@ -244,7 +244,7 @@ func TestNative_Compile_StagesPipeline(t *testing.T) { t.Errorf("Reading yaml file return err: %v", err) } - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Creating compiler returned err: %v", err) } @@ -582,7 +582,7 @@ func TestNative_Compile_StepsPipeline(t *testing.T) { t.Errorf("Reading yaml file return err: %v", err) } - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Creating compiler returned err: %v", err) } @@ -841,7 +841,7 @@ func TestNative_Compile_StagesPipelineTemplate(t *testing.T) { t.Errorf("Reading yaml file return err: %v", err) } - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Creating compiler returned err: %v", err) } @@ -1086,7 +1086,7 @@ func TestNative_Compile_StepsPipelineTemplate(t *testing.T) { t.Errorf("Reading yaml file return err: %v", err) } - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Creating compiler returned err: %v", err) } @@ -1207,7 +1207,7 @@ func TestNative_Compile_StepsPipelineTemplate_VelaFunction_TemplateName(t *testi t.Errorf("Reading yaml file return err: %v", err) } - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Creating compiler returned err: %v", err) } @@ -1328,7 +1328,7 @@ func TestNative_Compile_StepsPipelineTemplate_VelaFunction_TemplateName_Inline(t t.Errorf("Reading yaml file return err: %v", err) } - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Creating compiler returned err: %v", err) } @@ -1370,6 +1370,7 @@ func TestNative_Compile_InvalidType(t *testing.T) { set.String("github-url", s.URL, "doc") set.String("github-token", "", "doc") set.Int("max-template-depth", 5, "doc") + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) m := &internal.Metadata{ @@ -1407,7 +1408,7 @@ func TestNative_Compile_InvalidType(t *testing.T) { t.Errorf("Reading yaml file return err: %v", err) } - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Creating compiler returned err: %v", err) } @@ -1595,7 +1596,7 @@ func TestNative_Compile_Clone(t *testing.T) { t.Errorf("Reading yaml file return err: %v", err) } - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Creating compiler returned err: %v", err) } @@ -1803,7 +1804,7 @@ func TestNative_Compile_Pipeline_Type(t *testing.T) { t.Errorf("Reading yaml file return err: %v", err) } - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Creating compiler returned err: %v", err) } @@ -1828,6 +1829,7 @@ func TestNative_Compile_Pipeline_Type(t *testing.T) { func TestNative_Compile_NoStepsorStages(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) name := "foo" author := "author" @@ -1839,11 +1841,15 @@ func TestNative_Compile_NoStepsorStages(t *testing.T) { t.Errorf("Reading yaml file return err: %v", err) } - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Creating compiler returned err: %v", err) } + // todo: this needs to be fixed in compiler validation + // this is a dirty hack to make this test pass + compiler.SetCloneImage("") + compiler.repo = &api.Repo{Name: &author} compiler.build = &api.Build{Author: &name, Number: &number} @@ -1860,6 +1866,7 @@ func TestNative_Compile_NoStepsorStages(t *testing.T) { func TestNative_Compile_StepsandStages(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) name := "foo" author := "author" @@ -1871,7 +1878,7 @@ func TestNative_Compile_StepsandStages(t *testing.T) { t.Errorf("Reading yaml file return err: %v", err) } - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Creating compiler returned err: %v", err) } @@ -2952,7 +2959,7 @@ func Test_Compile_Inline(t *testing.T) { if err != nil { t.Errorf("Reading yaml file return err: %v", err) } - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Creating compiler returned err: %v", err) } @@ -3016,6 +3023,7 @@ func Test_CompileLite(t *testing.T) { set.String("github-url", s.URL, "doc") set.String("github-token", "", "doc") set.Int("max-template-depth", 5, "doc") + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) m := &internal.Metadata{ @@ -3823,7 +3831,7 @@ func Test_CompileLite(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Creating compiler returned err: %v", err) } diff --git a/compiler/native/environment_test.go b/compiler/native/environment_test.go index 1e090dad1..9c55ed41d 100644 --- a/compiler/native/environment_test.go +++ b/compiler/native/environment_test.go @@ -20,6 +20,7 @@ import ( func TestNative_EnvironmentStages(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) str := "foo" @@ -60,7 +61,7 @@ func TestNative_EnvironmentStages(t *testing.T) { } // run test - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Unable to create new compiler: %v", err) } @@ -78,6 +79,7 @@ func TestNative_EnvironmentStages(t *testing.T) { func TestNative_EnvironmentSteps(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) e := raw.StringSliceMap{ @@ -205,7 +207,7 @@ func TestNative_EnvironmentSteps(t *testing.T) { } // run test non-local - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Unable to create new compiler: %v", err) } @@ -253,6 +255,7 @@ func TestNative_EnvironmentSteps(t *testing.T) { func TestNative_EnvironmentServices(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) e := raw.StringSliceMap{ @@ -380,7 +383,7 @@ func TestNative_EnvironmentServices(t *testing.T) { } // run test - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Unable to create new compiler: %v", err) } @@ -398,6 +401,7 @@ func TestNative_EnvironmentServices(t *testing.T) { func TestNative_EnvironmentSecrets(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) e := raw.StringSliceMap{ @@ -538,7 +542,7 @@ func TestNative_EnvironmentSecrets(t *testing.T) { } // run test - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Unable to create new compiler: %v", err) } diff --git a/compiler/native/expand.go b/compiler/native/expand.go index 335ca5007..365946d60 100644 --- a/compiler/native/expand.go +++ b/compiler/native/expand.go @@ -28,7 +28,7 @@ func (c *client) ExpandStages(s *yaml.Build, tmpls map[string]*yaml.Template, r // iterate through all stages for _, stage := range s.Stages { // inject the templates into the steps for the stage - p, err := c.ExpandSteps(&yaml.Build{Steps: stage.Steps, Secrets: s.Secrets, Services: s.Services, Environment: s.Environment}, tmpls, r, c.TemplateDepth) + p, err := c.ExpandSteps(&yaml.Build{Steps: stage.Steps, Secrets: s.Secrets, Services: s.Services, Environment: s.Environment}, tmpls, r, c.GetTemplateDepth()) if err != nil { return nil, err } @@ -51,7 +51,7 @@ func (c *client) ExpandSteps(s *yaml.Build, tmpls map[string]*yaml.Template, r * // return if max template depth has been reached if depth == 0 { - retErr := fmt.Errorf("max template depth of %d exceeded", c.TemplateDepth) + retErr := fmt.Errorf("max template depth of %d exceeded", c.GetTemplateDepth()) return s, retErr } @@ -349,7 +349,7 @@ func (c *client) mergeTemplate(bytes []byte, tmpl *yaml.Template, step *yaml.Ste return native.Render(string(bytes), step.Name, step.Template.Name, step.Environment, step.Template.Variables) case constants.PipelineTypeStarlark: //nolint:lll // ignore long line length due to return - return starlark.Render(string(bytes), step.Name, step.Template.Name, step.Environment, step.Template.Variables, c.StarlarkExecLimit) + return starlark.Render(string(bytes), step.Name, step.Template.Name, step.Environment, step.Template.Variables, c.GetStarlarkExecLimit()) default: //nolint:lll // ignore long line length due to return return &yaml.Build{}, fmt.Errorf("format of %s is unsupported", tmpl.Format) diff --git a/compiler/native/expand_test.go b/compiler/native/expand_test.go index 0e69eed65..2f036f974 100644 --- a/compiler/native/expand_test.go +++ b/compiler/native/expand_test.go @@ -44,6 +44,7 @@ func TestNative_ExpandStages(t *testing.T) { set.String("github-url", s.URL, "doc") set.String("github-token", "", "doc") set.Int("max-template-depth", 5, "doc") + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) tmpls := map[string]*yaml.Template{ @@ -144,7 +145,7 @@ func TestNative_ExpandStages(t *testing.T) { } // run test -- missing private github - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Creating new compiler returned err: %v", err) } @@ -165,7 +166,7 @@ func TestNative_ExpandStages(t *testing.T) { } // run test - compiler, err = New(c) + compiler, err = FromCLIContext(c) if err != nil { t.Errorf("Creating new compiler returned err: %v", err) } @@ -226,6 +227,7 @@ func TestNative_ExpandSteps(t *testing.T) { set.String("github-url", s.URL, "doc") set.String("github-token", "", "doc") set.Int("max-template-depth", 5, "doc") + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) testRepo := new(api.Repo) @@ -346,7 +348,7 @@ func TestNative_ExpandSteps(t *testing.T) { } // run test - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Creating new compiler returned err: %v", err) } @@ -355,7 +357,7 @@ func TestNative_ExpandSteps(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - build, err := compiler.ExpandSteps(&yaml.Build{Steps: steps, Services: yaml.ServiceSlice{}, Environment: globalEnvironment}, test.tmpls, new(pipeline.RuleData), compiler.TemplateDepth) + build, err := compiler.ExpandSteps(&yaml.Build{Steps: steps, Services: yaml.ServiceSlice{}, Environment: globalEnvironment}, test.tmpls, new(pipeline.RuleData), compiler.GetTemplateDepth()) if err != nil { t.Errorf("ExpandSteps_Type%s returned err: %v", test.name, err) } @@ -404,6 +406,7 @@ func TestNative_ExpandStepsMulti(t *testing.T) { set.String("github-url", s.URL, "doc") set.String("github-token", "", "doc") set.Int("max-template-depth", 5, "doc") + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) tmpls := map[string]*yaml.Template{ @@ -615,7 +618,7 @@ func TestNative_ExpandStepsMulti(t *testing.T) { wantEnvironment := raw.StringSliceMap{} // run test - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Creating new compiler returned err: %v", err) } @@ -623,7 +626,7 @@ func TestNative_ExpandStepsMulti(t *testing.T) { ruledata := new(pipeline.RuleData) ruledata.Branch = "main" - build, err := compiler.ExpandSteps(&yaml.Build{Steps: steps, Services: yaml.ServiceSlice{}, Environment: raw.StringSliceMap{}}, tmpls, ruledata, compiler.TemplateDepth) + build, err := compiler.ExpandSteps(&yaml.Build{Steps: steps, Services: yaml.ServiceSlice{}, Environment: raw.StringSliceMap{}}, tmpls, ruledata, compiler.GetTemplateDepth()) if err != nil { t.Errorf("ExpandSteps returned err: %v", err) } @@ -670,6 +673,7 @@ func TestNative_ExpandStepsStarlark(t *testing.T) { set.String("github-url", s.URL, "doc") set.String("github-token", "", "doc") set.Int("max-template-depth", 5, "doc") + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) tmpls := map[string]*yaml.Template{ @@ -708,12 +712,12 @@ func TestNative_ExpandStepsStarlark(t *testing.T) { } // run test - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Creating new compiler returned err: %v", err) } - build, err := compiler.ExpandSteps(&yaml.Build{Steps: steps, Secrets: yaml.SecretSlice{}, Services: yaml.ServiceSlice{}, Environment: raw.StringSliceMap{}}, tmpls, new(pipeline.RuleData), compiler.TemplateDepth) + build, err := compiler.ExpandSteps(&yaml.Build{Steps: steps, Secrets: yaml.SecretSlice{}, Services: yaml.ServiceSlice{}, Environment: raw.StringSliceMap{}}, tmpls, new(pipeline.RuleData), compiler.GetTemplateDepth()) if err != nil { t.Errorf("ExpandSteps returned err: %v", err) } @@ -760,6 +764,7 @@ func TestNative_ExpandSteps_TemplateCallTemplate(t *testing.T) { set.String("github-url", s.URL, "doc") set.String("github-token", "", "doc") set.Int("max-template-depth", 5, "doc") + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) testBuild := new(api.Build) @@ -883,7 +888,7 @@ func TestNative_ExpandSteps_TemplateCallTemplate(t *testing.T) { } // run test - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Creating new compiler returned err: %v", err) } @@ -892,7 +897,7 @@ func TestNative_ExpandSteps_TemplateCallTemplate(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - build, err := compiler.ExpandSteps(&yaml.Build{Steps: steps, Services: yaml.ServiceSlice{}, Environment: globalEnvironment, Templates: yaml.TemplateSlice{test.tmpls["chain"]}}, test.tmpls, new(pipeline.RuleData), compiler.TemplateDepth) + build, err := compiler.ExpandSteps(&yaml.Build{Steps: steps, Services: yaml.ServiceSlice{}, Environment: globalEnvironment, Templates: yaml.TemplateSlice{test.tmpls["chain"]}}, test.tmpls, new(pipeline.RuleData), compiler.GetTemplateDepth()) if err != nil { t.Errorf("ExpandSteps_Type%s returned err: %v", test.name, err) } @@ -945,6 +950,7 @@ func TestNative_ExpandSteps_TemplateCallTemplate_CircularFail(t *testing.T) { set.String("github-url", s.URL, "doc") set.String("github-token", "", "doc") set.Int("max-template-depth", 5, "doc") + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) testBuild := new(api.Build) @@ -989,7 +995,7 @@ func TestNative_ExpandSteps_TemplateCallTemplate_CircularFail(t *testing.T) { } // run test - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Creating new compiler returned err: %v", err) } @@ -998,7 +1004,7 @@ func TestNative_ExpandSteps_TemplateCallTemplate_CircularFail(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - _, err := compiler.ExpandSteps(&yaml.Build{Steps: steps, Services: yaml.ServiceSlice{}, Environment: globalEnvironment}, test.tmpls, new(pipeline.RuleData), compiler.TemplateDepth) + _, err := compiler.ExpandSteps(&yaml.Build{Steps: steps, Services: yaml.ServiceSlice{}, Environment: globalEnvironment}, test.tmpls, new(pipeline.RuleData), compiler.GetTemplateDepth()) if err == nil { t.Errorf("ExpandSteps_Type%s should have returned an error", test.name) } @@ -1031,6 +1037,7 @@ func TestNative_ExpandSteps_CallTemplateWithRenderInline(t *testing.T) { set.String("github-url", s.URL, "doc") set.String("github-token", "", "doc") set.Int("max-template-depth", 5, "doc") + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) testBuild := new(api.Build) @@ -1075,7 +1082,7 @@ func TestNative_ExpandSteps_CallTemplateWithRenderInline(t *testing.T) { } // run test - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Creating new compiler returned err: %v", err) } @@ -1084,7 +1091,7 @@ func TestNative_ExpandSteps_CallTemplateWithRenderInline(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - _, err := compiler.ExpandSteps(&yaml.Build{Steps: steps, Services: yaml.ServiceSlice{}, Environment: globalEnvironment}, test.tmpls, new(pipeline.RuleData), compiler.TemplateDepth) + _, err := compiler.ExpandSteps(&yaml.Build{Steps: steps, Services: yaml.ServiceSlice{}, Environment: globalEnvironment}, test.tmpls, new(pipeline.RuleData), compiler.GetTemplateDepth()) if err == nil { t.Errorf("ExpandSteps_Type%s should have returned an error", test.name) } diff --git a/compiler/native/initialize_test.go b/compiler/native/initialize_test.go index 33276ffdb..ea196216a 100644 --- a/compiler/native/initialize_test.go +++ b/compiler/native/initialize_test.go @@ -15,6 +15,7 @@ import ( func TestNative_InitStage(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) str := "foo" @@ -61,7 +62,7 @@ func TestNative_InitStage(t *testing.T) { } // run test - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Unable to create new compiler: %v", err) } @@ -79,6 +80,7 @@ func TestNative_InitStage(t *testing.T) { func TestNative_InitStep(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) str := "foo" @@ -109,7 +111,7 @@ func TestNative_InitStep(t *testing.T) { }, } // run test - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Unable to create new compiler: %v", err) } diff --git a/compiler/native/native.go b/compiler/native/native.go index 026341063..93d93c5ea 100644 --- a/compiler/native/native.go +++ b/compiler/native/native.go @@ -3,16 +3,19 @@ package native import ( + "fmt" "time" "github.com/sirupsen/logrus" "github.com/urfave/cli/v2" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/api/types/settings" "github.com/go-vela/server/compiler" "github.com/go-vela/server/compiler/registry" "github.com/go-vela/server/compiler/registry/github" "github.com/go-vela/server/internal" + "github.com/go-vela/server/internal/image" ) type ModificationConfig struct { @@ -27,9 +30,8 @@ type client struct { PrivateGithub registry.Service UsePrivateGithub bool ModificationService ModificationConfig - CloneImage string - TemplateDepth int - StarlarkExecLimit uint64 + + settings.Compiler build *api.Build comment string @@ -43,10 +45,10 @@ type client struct { labels []string } -// New returns a Pipeline implementation that integrates with the supported registries. +// FromCLIContext returns a Pipeline implementation that integrates with the supported registries. // //nolint:revive // ignore returning unexported client -func New(ctx *cli.Context) (*client, error) { +func FromCLIContext(ctx *cli.Context) (*client, error) { logrus.Debug("Creating registry clients from CLI configuration") c := new(client) @@ -68,14 +70,24 @@ func New(ctx *cli.Context) (*client, error) { c.Github = github + c.Compiler = settings.Compiler{} + + cloneImage := ctx.String("clone-image") + + // validate clone image + _, err = image.ParseWithError(cloneImage) + if err != nil { + return nil, fmt.Errorf("invalid clone image %s: %w", cloneImage, err) + } + // set the clone image to use for the injected clone step - c.CloneImage = ctx.String("clone-image") + c.SetCloneImage(cloneImage) // set the template depth to use for nested templates - c.TemplateDepth = ctx.Int("max-template-depth") + c.SetTemplateDepth(ctx.Int("max-template-depth")) // set the starlark execution step limit for compiling starlark pipelines - c.StarlarkExecLimit = ctx.Uint64("compiler-starlark-exec-limit") + c.SetStarlarkExecLimit(ctx.Uint64("compiler-starlark-exec-limit")) if ctx.Bool("github-driver") { logrus.Tracef("setting up Private GitHub Client for %s", ctx.String("github-url")) diff --git a/compiler/native/native_test.go b/compiler/native/native_test.go index 835169e5d..6c5b6d2be 100644 --- a/compiler/native/native_test.go +++ b/compiler/native/native_test.go @@ -10,6 +10,7 @@ import ( "github.com/urfave/cli/v2" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/api/types/settings" "github.com/go-vela/server/compiler/registry/github" "github.com/go-vela/server/internal" ) @@ -17,14 +18,17 @@ import ( func TestNative_New(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) public, _ := github.New("", "") want := &client{ - Github: public, + Github: public, + Compiler: settings.CompilerMockEmpty(), } + want.SetCloneImage(defaultCloneImage) // run test - got, err := New(c) + got, err := FromCLIContext(c) if err != nil { t.Errorf("New returned err: %v", err) @@ -43,6 +47,7 @@ func TestNative_New_PrivateGithub(t *testing.T) { set.Bool("github-driver", true, "doc") set.String("github-url", url, "doc") set.String("github-token", token, "doc") + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) public, _ := github.New("", "") private, _ := github.New(url, token) @@ -50,10 +55,12 @@ func TestNative_New_PrivateGithub(t *testing.T) { Github: public, PrivateGithub: private, UsePrivateGithub: true, + Compiler: settings.CompilerMockEmpty(), } + want.SetCloneImage(defaultCloneImage) // run test - got, err := New(c) + got, err := FromCLIContext(c) if err != nil { t.Errorf("New returned err: %v", err) @@ -72,6 +79,7 @@ func TestNative_DuplicateRetainSettings(t *testing.T) { set.Bool("github-driver", true, "doc") set.String("github-url", url, "doc") set.String("github-token", token, "doc") + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) public, _ := github.New("", "") private, _ := github.New(url, token) @@ -79,10 +87,12 @@ func TestNative_DuplicateRetainSettings(t *testing.T) { Github: public, PrivateGithub: private, UsePrivateGithub: true, + Compiler: settings.CompilerMockEmpty(), } + want.SetCloneImage(defaultCloneImage) // run test - got, err := New(c) + got, err := FromCLIContext(c) if err != nil { t.Errorf("New returned err: %v", err) @@ -96,15 +106,16 @@ func TestNative_DuplicateRetainSettings(t *testing.T) { func TestNative_DuplicateStripBuild(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) id := int64(1) b := &api.Build{ID: &id} - want, _ := New(c) + want, _ := FromCLIContext(c) // run test - got, err := New(c) + got, err := FromCLIContext(c) if err != nil { t.Errorf("Unable to create new compiler: %v", err) } @@ -119,16 +130,17 @@ func TestNative_DuplicateStripBuild(t *testing.T) { func TestNative_WithBuild(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) id := int64(1) b := &api.Build{ID: &id} - want, _ := New(c) + want, _ := FromCLIContext(c) want.build = b // run test - got, err := New(c) + got, err := FromCLIContext(c) if err != nil { t.Errorf("Unable to create new compiler: %v", err) } @@ -141,15 +153,16 @@ func TestNative_WithBuild(t *testing.T) { func TestNative_WithFiles(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) f := []string{"foo"} - want, _ := New(c) + want, _ := FromCLIContext(c) want.files = f // run test - got, err := New(c) + got, err := FromCLIContext(c) if err != nil { t.Errorf("Unable to create new compiler: %v", err) } @@ -162,14 +175,15 @@ func TestNative_WithFiles(t *testing.T) { func TestNative_WithComment(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) comment := "ok to test" - want, _ := New(c) + want, _ := FromCLIContext(c) want.comment = comment // run test - got, err := New(c) + got, err := FromCLIContext(c) if err != nil { t.Errorf("Unable to create new compiler: %v", err) } @@ -182,14 +196,15 @@ func TestNative_WithComment(t *testing.T) { func TestNative_WithLocal(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) local := true - want, _ := New(c) + want, _ := FromCLIContext(c) want.local = true // run test - got, err := New(c) + got, err := FromCLIContext(c) if err != nil { t.Errorf("Unable to create new compiler: %v", err) } @@ -202,14 +217,15 @@ func TestNative_WithLocal(t *testing.T) { func TestNative_WithLocalTemplates(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) localTemplates := []string{"example:tmpl.yml", "exmpl:template.yml"} - want, _ := New(c) + want, _ := FromCLIContext(c) want.localTemplates = []string{"example:tmpl.yml", "exmpl:template.yml"} // run test - got, err := New(c) + got, err := FromCLIContext(c) if err != nil { t.Errorf("Unable to create new compiler: %v", err) } @@ -222,6 +238,7 @@ func TestNative_WithLocalTemplates(t *testing.T) { func TestNative_WithMetadata(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) m := &internal.Metadata{ @@ -244,11 +261,11 @@ func TestNative_WithMetadata(t *testing.T) { }, } - want, _ := New(c) + want, _ := FromCLIContext(c) want.metadata = m // run test - got, err := New(c) + got, err := FromCLIContext(c) if err != nil { t.Errorf("Unable to create new compiler: %v", err) } @@ -266,15 +283,16 @@ func TestNative_WithPrivateGitHub(t *testing.T) { set.Bool("github-driver", true, "doc") set.String("github-url", url, "doc") set.String("github-token", token, "doc") + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) private, _ := github.New(url, token) - want, _ := New(c) + want, _ := FromCLIContext(c) want.PrivateGithub = private // run test - got, err := New(c) + got, err := FromCLIContext(c) if err != nil { t.Errorf("Unable to create new compiler: %v", err) } @@ -287,16 +305,17 @@ func TestNative_WithPrivateGitHub(t *testing.T) { func TestNative_WithRepo(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) id := int64(1) r := &api.Repo{ID: &id} - want, _ := New(c) + want, _ := FromCLIContext(c) want.repo = r // run test - got, err := New(c) + got, err := FromCLIContext(c) if err != nil { t.Errorf("Unable to create new compiler: %v", err) } @@ -309,16 +328,17 @@ func TestNative_WithRepo(t *testing.T) { func TestNative_WithUser(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) id := int64(1) u := &api.User{ID: &id} - want, _ := New(c) + want, _ := FromCLIContext(c) want.user = u // run test - got, err := New(c) + got, err := FromCLIContext(c) if err != nil { t.Errorf("Unable to create new compiler: %v", err) } @@ -331,14 +351,15 @@ func TestNative_WithUser(t *testing.T) { func TestNative_WithLabels(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) labels := []string{"documentation", "enhancement"} - want, _ := New(c) + want, _ := FromCLIContext(c) want.labels = []string{"documentation", "enhancement"} // run test - got, err := New(c) + got, err := FromCLIContext(c) if err != nil { t.Errorf("Unable to create new compiler: %v", err) } diff --git a/compiler/native/parse.go b/compiler/native/parse.go index 9ccd525f1..0cd7a5819 100644 --- a/compiler/native/parse.go +++ b/compiler/native/parse.go @@ -71,7 +71,7 @@ func (c *client) Parse(v interface{}, pipelineType string, template *types.Templ // capture the raw pipeline configuration raw = []byte(parsedRaw) - p, err = starlark.RenderBuild(template.Name, parsedRaw, c.EnvironmentBuild(), template.Variables, c.StarlarkExecLimit) + p, err = starlark.RenderBuild(template.Name, parsedRaw, c.EnvironmentBuild(), template.Variables, c.GetStarlarkExecLimit()) if err != nil { return nil, raw, err } diff --git a/compiler/native/parse_test.go b/compiler/native/parse_test.go index dfe691fdb..e0aa9c512 100644 --- a/compiler/native/parse_test.go +++ b/compiler/native/parse_test.go @@ -21,7 +21,7 @@ import ( func TestNative_Parse_Metadata_Bytes(t *testing.T) { // setup types - client, _ := New(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) + client, _ := FromCLIContext(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) want := &yaml.Build{ Version: "1", Metadata: yaml.Metadata{ @@ -49,7 +49,7 @@ func TestNative_Parse_Metadata_Bytes(t *testing.T) { func TestNative_Parse_Metadata_File(t *testing.T) { // setup types - client, _ := New(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) + client, _ := FromCLIContext(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) want := &yaml.Build{ Version: "1", Metadata: yaml.Metadata{ @@ -79,7 +79,7 @@ func TestNative_Parse_Metadata_File(t *testing.T) { func TestNative_Parse_Metadata_Invalid(t *testing.T) { // setup types - client, _ := New(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) + client, _ := FromCLIContext(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) // run test got, _, err := client.Parse(nil, "", new(yaml.Template)) @@ -95,7 +95,7 @@ func TestNative_Parse_Metadata_Invalid(t *testing.T) { func TestNative_Parse_Metadata_Path(t *testing.T) { // setup types - client, _ := New(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) + client, _ := FromCLIContext(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) want := &yaml.Build{ Version: "1", Metadata: yaml.Metadata{ @@ -118,7 +118,7 @@ func TestNative_Parse_Metadata_Path(t *testing.T) { func TestNative_Parse_Metadata_Reader(t *testing.T) { // setup types - client, _ := New(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) + client, _ := FromCLIContext(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) want := &yaml.Build{ Version: "1", Metadata: yaml.Metadata{ @@ -146,7 +146,7 @@ func TestNative_Parse_Metadata_Reader(t *testing.T) { func TestNative_Parse_Metadata_String(t *testing.T) { // setup types - client, _ := New(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) + client, _ := FromCLIContext(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) want := &yaml.Build{ Version: "1", Metadata: yaml.Metadata{ @@ -174,7 +174,7 @@ func TestNative_Parse_Metadata_String(t *testing.T) { func TestNative_Parse_Parameters(t *testing.T) { // setup types - client, _ := New(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) + client, _ := FromCLIContext(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) want := &yaml.Build{ Metadata: yaml.Metadata{ Environment: []string{"steps", "services", "secrets"}, @@ -221,7 +221,7 @@ func TestNative_Parse_Parameters(t *testing.T) { func TestNative_Parse_StagesPipeline(t *testing.T) { // setup types - client, _ := New(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) + client, _ := FromCLIContext(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) want := &yaml.Build{ Version: "1", Metadata: yaml.Metadata{ @@ -350,7 +350,7 @@ func TestNative_Parse_StagesPipeline(t *testing.T) { func TestNative_Parse_StepsPipeline(t *testing.T) { // setup types tBool := true - client, _ := New(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) + client, _ := FromCLIContext(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) want := &yaml.Build{ Version: "1", Metadata: yaml.Metadata{ @@ -452,7 +452,7 @@ func TestNative_Parse_StepsPipeline(t *testing.T) { func TestNative_Parse_Secrets(t *testing.T) { // setup types - client, _ := New(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) + client, _ := FromCLIContext(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) want := &yaml.Build{ Metadata: yaml.Metadata{ Environment: []string{"steps", "services", "secrets"}, @@ -522,7 +522,7 @@ func TestNative_Parse_Secrets(t *testing.T) { func TestNative_Parse_Stages(t *testing.T) { // setup types - client, _ := New(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) + client, _ := FromCLIContext(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) want := &yaml.Build{ Metadata: yaml.Metadata{ Environment: []string{"steps", "services", "secrets"}, @@ -598,7 +598,7 @@ func TestNative_Parse_Stages(t *testing.T) { func TestNative_Parse_Steps(t *testing.T) { // setup types - client, _ := New(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) + client, _ := FromCLIContext(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) want := &yaml.Build{ Metadata: yaml.Metadata{ Environment: []string{"steps", "services", "secrets"}, diff --git a/compiler/native/script_test.go b/compiler/native/script_test.go index 308023e77..0f03e6865 100644 --- a/compiler/native/script_test.go +++ b/compiler/native/script_test.go @@ -16,6 +16,7 @@ import ( func TestNative_ScriptStages(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) baseEnv := environment(nil, nil, nil, nil) @@ -87,7 +88,7 @@ func TestNative_ScriptStages(t *testing.T) { } // run test - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Creating compiler returned err: %v", err) } @@ -105,6 +106,7 @@ func TestNative_ScriptStages(t *testing.T) { func TestNative_ScriptSteps(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) emptyEnv := environment(nil, nil, nil, nil) @@ -313,7 +315,7 @@ func TestNative_ScriptSteps(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Creating compiler returned err: %v", err) } diff --git a/compiler/native/settings.go b/compiler/native/settings.go new file mode 100644 index 000000000..12997ec9c --- /dev/null +++ b/compiler/native/settings.go @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: Apache-2.0 + +package native + +import ( + "github.com/go-vela/server/api/types/settings" +) + +// GetSettings retrieves the api settings type. +func (c *client) GetSettings() settings.Compiler { + return c.Compiler +} + +// SetSettings sets the api settings type. +func (c *client) SetSettings(s *settings.Platform) { + if s != nil { + c.SetCloneImage(s.GetCloneImage()) + c.SetTemplateDepth(s.GetTemplateDepth()) + c.SetStarlarkExecLimit(s.GetStarlarkExecLimit()) + } +} diff --git a/compiler/native/substitute_test.go b/compiler/native/substitute_test.go index 459bb2896..0be8eac03 100644 --- a/compiler/native/substitute_test.go +++ b/compiler/native/substitute_test.go @@ -19,6 +19,7 @@ func Test_client_SubstituteStages(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) tests := []struct { @@ -112,7 +113,7 @@ func Test_client_SubstituteStages(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Creating compiler returned err: %v", err) } @@ -137,6 +138,7 @@ func Test_client_SubstituteSteps(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) tests := []struct { @@ -236,7 +238,7 @@ func Test_client_SubstituteSteps(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Creating compiler returned err: %v", err) } diff --git a/compiler/native/transform_test.go b/compiler/native/transform_test.go index e8d596be3..bcd318103 100644 --- a/compiler/native/transform_test.go +++ b/compiler/native/transform_test.go @@ -17,6 +17,7 @@ import ( func TestNative_TransformStages(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) m := &internal.Metadata{ @@ -220,7 +221,7 @@ func TestNative_TransformStages(t *testing.T) { // run tests for _, test := range tests { - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("unable to create new compiler: %v", err) } @@ -257,6 +258,7 @@ func TestNative_TransformStages(t *testing.T) { func TestNative_TransformSteps(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) m := &internal.Metadata{ @@ -439,7 +441,7 @@ func TestNative_TransformSteps(t *testing.T) { // run tests for _, test := range tests { - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("unable to create new compiler: %v", err) } diff --git a/compiler/native/validate_test.go b/compiler/native/validate_test.go index 85896b4a1..226c75aa9 100644 --- a/compiler/native/validate_test.go +++ b/compiler/native/validate_test.go @@ -16,12 +16,13 @@ import ( func TestNative_Validate_NoVersion(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) p := &yaml.Build{} // run test - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Unable to create new compiler: %v", err) } @@ -35,6 +36,7 @@ func TestNative_Validate_NoVersion(t *testing.T) { func TestNative_Validate_NoStagesOrSteps(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) p := &yaml.Build{ @@ -42,7 +44,7 @@ func TestNative_Validate_NoStagesOrSteps(t *testing.T) { } // run test - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Unable to create new compiler: %v", err) } @@ -56,6 +58,7 @@ func TestNative_Validate_NoStagesOrSteps(t *testing.T) { func TestNative_Validate_StagesAndSteps(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) str := "foo" @@ -85,7 +88,7 @@ func TestNative_Validate_StagesAndSteps(t *testing.T) { } // run test - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Unable to create new compiler: %v", err) } @@ -99,6 +102,7 @@ func TestNative_Validate_StagesAndSteps(t *testing.T) { func TestNative_Validate_Services(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) str := "foo" @@ -122,7 +126,7 @@ func TestNative_Validate_Services(t *testing.T) { } // run test - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Unable to create new compiler: %v", err) } @@ -136,6 +140,7 @@ func TestNative_Validate_Services(t *testing.T) { func TestNative_Validate_Services_NoName(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) str := "foo" @@ -159,7 +164,7 @@ func TestNative_Validate_Services_NoName(t *testing.T) { } // run test - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Unable to create new compiler: %v", err) } @@ -173,6 +178,7 @@ func TestNative_Validate_Services_NoName(t *testing.T) { func TestNative_Validate_Services_NoImage(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) str := "foo" @@ -196,7 +202,7 @@ func TestNative_Validate_Services_NoImage(t *testing.T) { } // run test - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Unable to create new compiler: %v", err) } @@ -210,6 +216,7 @@ func TestNative_Validate_Services_NoImage(t *testing.T) { func TestNative_Validate_Stages(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) str := "foo" @@ -231,7 +238,7 @@ func TestNative_Validate_Stages(t *testing.T) { } // run test - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Unable to create new compiler: %v", err) } @@ -245,6 +252,7 @@ func TestNative_Validate_Stages(t *testing.T) { func TestNative_Validate_Stages_NoName(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) str := "foo" @@ -265,7 +273,7 @@ func TestNative_Validate_Stages_NoName(t *testing.T) { } // run test - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Unable to create new compiler: %v", err) } @@ -279,6 +287,7 @@ func TestNative_Validate_Stages_NoName(t *testing.T) { func TestNative_Validate_Stages_NoStepName(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) str := "foo" @@ -299,7 +308,7 @@ func TestNative_Validate_Stages_NoStepName(t *testing.T) { } // run test - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Unable to create new compiler: %v", err) } @@ -313,6 +322,7 @@ func TestNative_Validate_Stages_NoStepName(t *testing.T) { func TestNative_Validate_Stages_NoImage(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) str := "foo" @@ -333,7 +343,7 @@ func TestNative_Validate_Stages_NoImage(t *testing.T) { } // run test - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Unable to create new compiler: %v", err) } @@ -347,6 +357,7 @@ func TestNative_Validate_Stages_NoImage(t *testing.T) { func TestNative_Validate_Stages_NoCommands(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) str := "foo" @@ -367,7 +378,7 @@ func TestNative_Validate_Stages_NoCommands(t *testing.T) { } // run test - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Unable to create new compiler: %v", err) } @@ -381,6 +392,7 @@ func TestNative_Validate_Stages_NoCommands(t *testing.T) { func TestNative_Validate_Stages_NeedsSelfReference(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) str := "foo" @@ -403,7 +415,7 @@ func TestNative_Validate_Stages_NeedsSelfReference(t *testing.T) { } // run test - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Unable to create new compiler: %v", err) } @@ -417,6 +429,7 @@ func TestNative_Validate_Stages_NeedsSelfReference(t *testing.T) { func TestNative_Validate_Steps(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) str := "foo" @@ -433,7 +446,7 @@ func TestNative_Validate_Steps(t *testing.T) { } // run test - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Unable to create new compiler: %v", err) } @@ -447,6 +460,7 @@ func TestNative_Validate_Steps(t *testing.T) { func TestNative_Validate_Steps_NoName(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) p := &yaml.Build{ @@ -461,7 +475,7 @@ func TestNative_Validate_Steps_NoName(t *testing.T) { } // run test - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Unable to create new compiler: %v", err) } @@ -475,6 +489,7 @@ func TestNative_Validate_Steps_NoName(t *testing.T) { func TestNative_Validate_Steps_NoImage(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) str := "foo" @@ -490,7 +505,7 @@ func TestNative_Validate_Steps_NoImage(t *testing.T) { } // run test - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Unable to create new compiler: %v", err) } @@ -504,6 +519,7 @@ func TestNative_Validate_Steps_NoImage(t *testing.T) { func TestNative_Validate_Steps_NoCommands(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) str := "foo" @@ -519,7 +535,7 @@ func TestNative_Validate_Steps_NoCommands(t *testing.T) { } // run test - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Unable to create new compiler: %v", err) } @@ -533,6 +549,7 @@ func TestNative_Validate_Steps_NoCommands(t *testing.T) { func TestNative_Validate_Steps_ExceedReportAs(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) str := "foo" @@ -556,7 +573,7 @@ func TestNative_Validate_Steps_ExceedReportAs(t *testing.T) { } // run test - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Unable to create new compiler: %v", err) } @@ -571,6 +588,7 @@ func TestNative_Validate_Steps_ExceedReportAs(t *testing.T) { func TestNative_Validate_MultiReportAs(t *testing.T) { // setup types set := flag.NewFlagSet("test", 0) + set.String("clone-image", defaultCloneImage, "doc") c := cli.NewContext(nil, set, nil) str := "foo" @@ -595,7 +613,7 @@ func TestNative_Validate_MultiReportAs(t *testing.T) { } // run test - compiler, err := New(c) + compiler, err := FromCLIContext(c) if err != nil { t.Errorf("Unable to create new compiler: %v", err) } diff --git a/database/database.go b/database/database.go index 50d8ae956..5a9e982b2 100644 --- a/database/database.go +++ b/database/database.go @@ -23,6 +23,7 @@ import ( "github.com/go-vela/server/database/schedule" "github.com/go-vela/server/database/secret" "github.com/go-vela/server/database/service" + "github.com/go-vela/server/database/settings" "github.com/go-vela/server/database/step" "github.com/go-vela/server/database/user" "github.com/go-vela/server/database/worker" @@ -61,6 +62,7 @@ type ( // sirupsen/logrus logger used in database functions logger *logrus.Entry + settings.SettingsInterface build.BuildInterface dashboard.DashboardInterface executable.BuildExecutableInterface diff --git a/database/integration_test.go b/database/integration_test.go index 4f28bbb4e..db70091b3 100644 --- a/database/integration_test.go +++ b/database/integration_test.go @@ -13,6 +13,7 @@ import ( "github.com/google/go-cmp/cmp" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/api/types/settings" "github.com/go-vela/server/database/build" "github.com/go-vela/server/database/dashboard" "github.com/go-vela/server/database/deployment" @@ -24,6 +25,7 @@ import ( "github.com/go-vela/server/database/schedule" "github.com/go-vela/server/database/secret" "github.com/go-vela/server/database/service" + dbSettings "github.com/go-vela/server/database/settings" "github.com/go-vela/server/database/step" "github.com/go-vela/server/database/testutils" "github.com/go-vela/server/database/user" @@ -49,6 +51,7 @@ type Resources struct { Steps []*library.Step Users []*api.User Workers []*api.Worker + Platform []*settings.Platform } func TestDatabase_Integration(t *testing.T) { @@ -150,6 +153,8 @@ func TestDatabase_Integration(t *testing.T) { t.Run("test_workers", func(t *testing.T) { testWorkers(t, db, resources) }) + t.Run("test_settings", func(t *testing.T) { testSettings(t, db, resources) }) + err = db.Close() if err != nil { t.Errorf("unable to close database engine for %s: %v", test.name, err) @@ -2165,6 +2170,56 @@ func testWorkers(t *testing.T, db Interface, resources *Resources) { } } +func testSettings(t *testing.T, db Interface, resources *Resources) { + // create a variable to track the number of methods called for settings + methods := make(map[string]bool) + // capture the element type of the settings interface + element := reflect.TypeOf(new(dbSettings.SettingsInterface)).Elem() + // iterate through all methods found in the settings interface + for i := 0; i < element.NumMethod(); i++ { + // skip tracking the methods to create indexes and tables for settings + // since those are already called when the database engine starts + if strings.Contains(element.Method(i).Name, "Index") || + strings.Contains(element.Method(i).Name, "Table") { + continue + } + + // add the method name to the list of functions + methods[element.Method(i).Name] = false + } + + // create the settings + for _, s := range resources.Platform { + _, err := db.CreateSettings(context.TODO(), s) + if err != nil { + t.Errorf("unable to create settings %d: %v", s.GetID(), err) + } + } + methods["CreateSettings"] = true + + // update the settings + for _, s := range resources.Platform { + s.SetCloneImage("target/vela-git:abc123") + got, err := db.UpdateSettings(context.TODO(), s) + if err != nil { + t.Errorf("unable to update settings %d: %v", s.GetID(), err) + } + + if !cmp.Equal(got, s) { + t.Errorf("UpdateSettings() is %v, want %v", got, s) + } + } + methods["UpdateSettings"] = true + methods["GetSettings"] = true + + // ensure we called all the methods we expected to + for method, called := range methods { + if !called { + t.Errorf("method %s was not called for settings", method) + } + } +} + func newResources() *Resources { userOne := new(api.User) userOne.SetID(1) diff --git a/database/interface.go b/database/interface.go index 16a0fdf27..0d82da099 100644 --- a/database/interface.go +++ b/database/interface.go @@ -14,6 +14,7 @@ import ( "github.com/go-vela/server/database/schedule" "github.com/go-vela/server/database/secret" "github.com/go-vela/server/database/service" + "github.com/go-vela/server/database/settings" "github.com/go-vela/server/database/step" "github.com/go-vela/server/database/user" "github.com/go-vela/server/database/worker" @@ -34,6 +35,9 @@ type Interface interface { // Resource Interface Functions + // SettingsInterface defines the interface for platform settings stored in the database. + settings.SettingsInterface + // BuildInterface defines the interface for builds stored in the database. build.BuildInterface diff --git a/database/resource.go b/database/resource.go index 21b805227..486d2a137 100644 --- a/database/resource.go +++ b/database/resource.go @@ -16,15 +16,29 @@ import ( "github.com/go-vela/server/database/schedule" "github.com/go-vela/server/database/secret" "github.com/go-vela/server/database/service" + "github.com/go-vela/server/database/settings" "github.com/go-vela/server/database/step" "github.com/go-vela/server/database/user" "github.com/go-vela/server/database/worker" ) // NewResources creates and returns the database agnostic engines for resources. +// +//nolint:funlen // ignore function length func (e *engine) NewResources(ctx context.Context) error { var err error + // create the database agnostic engine for settings + e.SettingsInterface, err = settings.New( + settings.WithContext(e.ctx), + settings.WithClient(e.client), + settings.WithLogger(e.logger), + settings.WithSkipCreation(e.config.SkipCreation), + ) + if err != nil { + return err + } + // create the database agnostic engine for builds e.BuildInterface, err = build.New( build.WithContext(e.ctx), diff --git a/database/resource_test.go b/database/resource_test.go index dc99bb63b..a1371108b 100644 --- a/database/resource_test.go +++ b/database/resource_test.go @@ -19,6 +19,7 @@ import ( "github.com/go-vela/server/database/schedule" "github.com/go-vela/server/database/secret" "github.com/go-vela/server/database/service" + "github.com/go-vela/server/database/settings" "github.com/go-vela/server/database/step" "github.com/go-vela/server/database/user" "github.com/go-vela/server/database/worker" @@ -28,6 +29,8 @@ func TestDatabase_Engine_NewResources(t *testing.T) { _postgres, _mock := testPostgres(t) defer _postgres.Close() + // ensure the mock expects the settings queries + _mock.ExpectExec(settings.CreatePostgresTable).WillReturnResult(sqlmock.NewResult(1, 1)) // ensure the mock expects the build queries _mock.ExpectExec(build.CreatePostgresTable).WillReturnResult(sqlmock.NewResult(1, 1)) _mock.ExpectExec(build.CreateCreatedIndex).WillReturnResult(sqlmock.NewResult(1, 1)) diff --git a/database/secret/create_test.go b/database/secret/create_test.go index 7ec36795b..ed3d95591 100644 --- a/database/secret/create_test.go +++ b/database/secret/create_test.go @@ -9,6 +9,7 @@ import ( "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/types/library" ) @@ -63,21 +64,21 @@ func TestSecret_Engine_CreateSecret(t *testing.T) { _mock.ExpectQuery(`INSERT INTO "secrets" ("org","repo","team","name","value","type","images","allow_events","allow_command","allow_substitution","created_at","created_by","updated_at","updated_by","id") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15) RETURNING "id"`). - WithArgs("foo", "bar", nil, "baz", AnyArgument{}, "repo", nil, 1, false, false, 1, "user", 1, "user2", 1). + WithArgs("foo", "bar", nil, "baz", testutils.AnyArgument{}, "repo", nil, 1, false, false, 1, "user", 1, "user2", 1). WillReturnRows(_rows) // ensure the mock expects the org secrets query _mock.ExpectQuery(`INSERT INTO "secrets" ("org","repo","team","name","value","type","images","allow_events","allow_command","allow_substitution","created_at","created_by","updated_at","updated_by","id") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15) RETURNING "id"`). - WithArgs("foo", "*", nil, "bar", AnyArgument{}, "org", nil, 3, false, false, 1, "user", 1, "user2", 2). + WithArgs("foo", "*", nil, "bar", testutils.AnyArgument{}, "org", nil, 3, false, false, 1, "user", 1, "user2", 2). WillReturnRows(_rows) // ensure the mock expects the shared secrets query _mock.ExpectQuery(`INSERT INTO "secrets" ("org","repo","team","name","value","type","images","allow_events","allow_command","allow_substitution","created_at","created_by","updated_at","updated_by","id") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15) RETURNING "id"`). - WithArgs("foo", nil, "bar", "baz", AnyArgument{}, "shared", nil, 1, false, false, 1, "user", 1, "user2", 3). + WithArgs("foo", nil, "bar", "baz", testutils.AnyArgument{}, "shared", nil, 1, false, false, 1, "user", 1, "user2", 3). WillReturnRows(_rows) _sqlite := testSqlite(t) diff --git a/database/secret/secret_test.go b/database/secret/secret_test.go index fdc10818c..41bb4dd3a 100644 --- a/database/secret/secret_test.go +++ b/database/secret/secret_test.go @@ -3,10 +3,8 @@ package secret import ( - "database/sql/driver" "reflect" "testing" - "time" "github.com/DATA-DOG/go-sqlmock" "github.com/sirupsen/logrus" @@ -251,29 +249,3 @@ func testEvents() *library.Events { }, } } - -// This will be used with the github.com/DATA-DOG/go-sqlmock library to compare values -// that are otherwise not easily compared. These typically would be values generated -// before adding or updating them in the database. -// -// https://github.com/DATA-DOG/go-sqlmock#matching-arguments-like-timetime -type AnyArgument struct{} - -// Match satisfies sqlmock.Argument interface. -func (a AnyArgument) Match(_ driver.Value) bool { - return true -} - -// NowTimestamp is used to test whether timestamps get updated correctly to the current time with lenience. -type NowTimestamp struct{} - -// Match satisfies sqlmock.Argument interface. -func (t NowTimestamp) Match(v driver.Value) bool { - ts, ok := v.(int64) - if !ok { - return false - } - now := time.Now().Unix() - - return now-ts < 10 -} diff --git a/database/secret/update_test.go b/database/secret/update_test.go index 11b6245a1..e53d43b4e 100644 --- a/database/secret/update_test.go +++ b/database/secret/update_test.go @@ -9,6 +9,7 @@ import ( "github.com/DATA-DOG/go-sqlmock" + "github.com/go-vela/server/database/testutils" "github.com/go-vela/types/library" ) @@ -60,21 +61,21 @@ func TestSecret_Engine_UpdateSecret(t *testing.T) { _mock.ExpectExec(`UPDATE "secrets" SET "org"=$1,"repo"=$2,"team"=$3,"name"=$4,"value"=$5,"type"=$6,"images"=$7,"allow_events"=$8,"allow_command"=$9,"allow_substitution"=$10,"created_at"=$11,"created_by"=$12,"updated_at"=$13,"updated_by"=$14 WHERE "id" = $15`). - WithArgs("foo", "bar", nil, "baz", AnyArgument{}, "repo", nil, 1, false, false, 1, "user", AnyArgument{}, "user2", 1). + WithArgs("foo", "bar", nil, "baz", testutils.AnyArgument{}, "repo", nil, 1, false, false, 1, "user", testutils.AnyArgument{}, "user2", 1). WillReturnResult(sqlmock.NewResult(1, 1)) // ensure the mock expects the org query _mock.ExpectExec(`UPDATE "secrets" SET "org"=$1,"repo"=$2,"team"=$3,"name"=$4,"value"=$5,"type"=$6,"images"=$7,"allow_events"=$8,"allow_command"=$9,"allow_substitution"=$10,"created_at"=$11,"created_by"=$12,"updated_at"=$13,"updated_by"=$14 WHERE "id" = $15`). - WithArgs("foo", "*", nil, "bar", AnyArgument{}, "org", nil, 1, false, false, 1, "user", AnyArgument{}, "user2", 2). + WithArgs("foo", "*", nil, "bar", testutils.AnyArgument{}, "org", nil, 1, false, false, 1, "user", testutils.AnyArgument{}, "user2", 2). WillReturnResult(sqlmock.NewResult(1, 1)) // ensure the mock expects the shared query _mock.ExpectExec(`UPDATE "secrets" SET "org"=$1,"repo"=$2,"team"=$3,"name"=$4,"value"=$5,"type"=$6,"images"=$7,"allow_events"=$8,"allow_command"=$9,"allow_substitution"=$10,"created_at"=$11,"created_by"=$12,"updated_at"=$13,"updated_by"=$14 WHERE "id" = $15`). - WithArgs("foo", nil, "bar", "baz", AnyArgument{}, "shared", nil, 1, false, false, 1, "user", NowTimestamp{}, "user2", 3). + WithArgs("foo", nil, "bar", "baz", testutils.AnyArgument{}, "shared", nil, 1, false, false, 1, "user", testutils.NowTimestamp{}, "user2", 3). WillReturnResult(sqlmock.NewResult(1, 1)) _sqlite := testSqlite(t) diff --git a/database/settings/create.go b/database/settings/create.go new file mode 100644 index 000000000..0e86f7fbc --- /dev/null +++ b/database/settings/create.go @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: Apache-2.0 + +package settings + +import ( + "context" + + "github.com/go-vela/server/api/types/settings" + "github.com/go-vela/server/database/types" +) + +// CreateSettings creates a platform settings record in the database. +func (e *engine) CreateSettings(_ context.Context, s *settings.Platform) (*settings.Platform, error) { + e.logger.Tracef("creating platform settings in the database with %v", s.String()) + + // cast the api type to database type + settings := types.FromAPI(s) + + // validate the necessary fields are populated + err := settings.Validate() + if err != nil { + return nil, err + } + + // send query to the database + err = e.client.Table(TableSettings).Create(settings.Nullify()).Error + if err != nil { + return nil, err + } + + return s, nil +} diff --git a/database/settings/create_test.go b/database/settings/create_test.go new file mode 100644 index 000000000..e621bf76e --- /dev/null +++ b/database/settings/create_test.go @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: Apache-2.0 + +package settings + +import ( + "context" + "reflect" + "testing" + + "github.com/DATA-DOG/go-sqlmock" +) + +func TestSettings_Engine_CreateSettings(t *testing.T) { + // setup types + _settings := testSettings() + _settings.SetID(1) + _settings.SetCloneImage("target/vela-git:latest") + _settings.SetTemplateDepth(10) + _settings.SetStarlarkExecLimit(100) + _settings.SetRoutes([]string{"vela"}) + _settings.SetRepoAllowlist([]string{"octocat/hello-world"}) + _settings.SetScheduleAllowlist([]string{"*"}) + _settings.SetCreatedAt(1) + _settings.SetUpdatedAt(1) + _settings.SetUpdatedBy("") + + _postgres, _mock := testPostgres(t) + defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() + + // create expected result in mock + _rows := sqlmock.NewRows([]string{"id"}).AddRow(1) + + // ensure the mock expects the query + _mock.ExpectQuery(`INSERT INTO "settings" ("compiler","queue","repo_allowlist","schedule_allowlist","created_at","updated_at","updated_by","id") VALUES ($1,$2,$3,$4,$5,$6,$7,$8) RETURNING "id"`). + WithArgs(`{"clone_image":{"String":"target/vela-git:latest","Valid":true},"template_depth":{"Int64":10,"Valid":true},"starlark_exec_limit":{"Int64":100,"Valid":true}}`, + `{"routes":["vela"]}`, `{"octocat/hello-world"}`, `{"*"}`, 1, 1, ``, 1). + WillReturnRows(_rows) + + _sqlite := testSqlite(t) + defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() + + // setup tests + tests := []struct { + failure bool + name string + database *engine + }{ + { + failure: false, + name: "postgres", + database: _postgres, + }, + { + failure: false, + name: "sqlite3", + database: _sqlite, + }, + } + + // run tests + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got, err := test.database.CreateSettings(context.TODO(), _settings) + + if test.failure { + if err == nil { + t.Errorf("CreateSettings for %s should have returned err", test.name) + } + + return + } + + if err != nil { + t.Errorf("CreateSettings for %s returned err: %v", test.name, err) + } + + if !reflect.DeepEqual(got, _settings) { + t.Errorf("CreateSettings for %s returned %s, want %s", test.name, got, _settings) + } + }) + } +} diff --git a/database/settings/get.go b/database/settings/get.go new file mode 100644 index 000000000..0bba2e0f4 --- /dev/null +++ b/database/settings/get.go @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: Apache-2.0 + +package settings + +import ( + "context" + + "github.com/go-vela/server/api/types/settings" + "github.com/go-vela/server/database/types" +) + +// GetSettings gets platform settings from the database. +func (e *engine) GetSettings(ctx context.Context) (*settings.Platform, error) { + e.logger.Trace("getting platform settings from the database") + + // variable to store query results + s := new(types.Platform) + + // send query to the database and store result in variable + err := e.client. + Table(TableSettings). + Where("id = ?", 1). + Take(s). + Error + if err != nil { + return nil, err + } + + // return the settings + return s.ToAPI(), nil +} diff --git a/database/settings/get_test.go b/database/settings/get_test.go new file mode 100644 index 000000000..83196848b --- /dev/null +++ b/database/settings/get_test.go @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: Apache-2.0 + +package settings + +import ( + "context" + "reflect" + "testing" + + "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/api/types/settings" +) + +func TestSettings_Engine_GetSettings(t *testing.T) { + // setup types + _settings := testSettings() + _settings.SetID(1) + _settings.SetCloneImage("target/vela-git:latest") + _settings.SetTemplateDepth(10) + _settings.SetStarlarkExecLimit(100) + _settings.SetRoutes([]string{"vela"}) + _settings.SetRepoAllowlist([]string{"octocat/hello-world"}) + _settings.SetScheduleAllowlist([]string{"*"}) + _settings.SetCreatedAt(1) + _settings.SetUpdatedAt(1) + _settings.SetUpdatedBy("octocat") + + _postgres, _mock := testPostgres(t) + defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() + + // create expected result in mock + _rows := sqlmock.NewRows( + []string{"id", "compiler", "queue", "repo_allowlist", "schedule_allowlist", "created_at", "updated_at", "updated_by"}). + AddRow(1, `{"clone_image":{"String":"target/vela-git:latest","Valid":true},"template_depth":{"Int64":10,"Valid":true},"starlark_exec_limit":{"Int64":100,"Valid":true}}`, + `{"routes":["vela"]}`, `{"octocat/hello-world"}`, `{"*"}`, 1, 1, `octocat`) + + // ensure the mock expects the query + _mock.ExpectQuery(`SELECT * FROM "settings" WHERE id = $1 LIMIT $2`).WithArgs(1, 1).WillReturnRows(_rows) + + _sqlite := testSqlite(t) + defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() + + _, err := _sqlite.CreateSettings(context.TODO(), _settings) + if err != nil { + t.Errorf("unable to create test settings for sqlite: %v", err) + } + + // setup tests + tests := []struct { + failure bool + name string + database *engine + want *settings.Platform + }{ + { + failure: false, + name: "postgres", + database: _postgres, + want: _settings, + }, + { + failure: false, + name: "sqlite3", + database: _sqlite, + want: _settings, + }, + } + + // run tests + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got, err := test.database.GetSettings(context.TODO()) + + if test.failure { + if err == nil { + t.Errorf("GetSettings for %s should have returned err", test.name) + } + + return + } + + if err != nil { + t.Errorf("GetSettings for %s returned err: %v", test.name, err) + } + + if !reflect.DeepEqual(got, test.want) { + t.Errorf("GetSettings for %s is %v, want %v", test.name, got, test.want) + } + }) + } +} diff --git a/database/settings/interface.go b/database/settings/interface.go new file mode 100644 index 000000000..a7cc755cd --- /dev/null +++ b/database/settings/interface.go @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: Apache-2.0 + +package settings + +import ( + "context" + + "github.com/go-vela/server/api/types/settings" +) + +// SettingsInterface represents the Vela interface for settings +// functions with the supported Database backends. +// +//nolint:revive // ignore name stutter +type SettingsInterface interface { + // CreateSettings defines a function that creates a platform settings record. + CreateSettings(context.Context, *settings.Platform) (*settings.Platform, error) + // GetSettings defines a function that gets platform settings. + GetSettings(context.Context) (*settings.Platform, error) + // UpdateSettings defines a function that updates platform settings. + UpdateSettings(context.Context, *settings.Platform) (*settings.Platform, error) +} diff --git a/database/settings/opts.go b/database/settings/opts.go new file mode 100644 index 000000000..a9646d1bf --- /dev/null +++ b/database/settings/opts.go @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: Apache-2.0 + +package settings + +import ( + "context" + + "github.com/sirupsen/logrus" + "gorm.io/gorm" +) + +// EngineOpt represents a configuration option to initialize the database engine for Settings. +type EngineOpt func(*engine) error + +// WithClient sets the gorm.io/gorm client in the database engine for Settings. +func WithClient(client *gorm.DB) EngineOpt { + return func(e *engine) error { + // set the gorm.io/gorm client in the settings engine + e.client = client + + return nil + } +} + +// WithLogger sets the github.com/sirupsen/logrus logger in the database engine for Settings. +func WithLogger(logger *logrus.Entry) EngineOpt { + return func(e *engine) error { + // set the github.com/sirupsen/logrus logger in the settings engine + e.logger = logger + + return nil + } +} + +// WithSkipCreation sets the skip creation logic in the database engine for Settings. +func WithSkipCreation(skipCreation bool) EngineOpt { + return func(e *engine) error { + // set to skip creating tables and indexes in the settings engine + e.config.SkipCreation = skipCreation + + return nil + } +} + +// WithContext sets the context in the database engine for Settings. +func WithContext(ctx context.Context) EngineOpt { + return func(e *engine) error { + e.ctx = ctx + + return nil + } +} diff --git a/database/settings/opts_test.go b/database/settings/opts_test.go new file mode 100644 index 000000000..6fccdec17 --- /dev/null +++ b/database/settings/opts_test.go @@ -0,0 +1,208 @@ +// SPDX-License-Identifier: Apache-2.0 + +package settings + +import ( + "context" + "reflect" + "testing" + + "github.com/sirupsen/logrus" + "gorm.io/gorm" +) + +func TestSettings_EngineOpt_WithClient(t *testing.T) { + // setup types + e := &engine{client: new(gorm.DB)} + + // setup tests + tests := []struct { + failure bool + name string + client *gorm.DB + want *gorm.DB + }{ + { + failure: false, + name: "client set to new database", + client: new(gorm.DB), + want: new(gorm.DB), + }, + { + failure: false, + name: "client set to nil", + client: nil, + want: nil, + }, + } + + // run tests + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + err := WithClient(test.client)(e) + + if test.failure { + if err == nil { + t.Errorf("WithClient for %s should have returned err", test.name) + } + + return + } + + if err != nil { + t.Errorf("WithClient returned err: %v", err) + } + + if !reflect.DeepEqual(e.client, test.want) { + t.Errorf("WithClient is %v, want %v", e.client, test.want) + } + }) + } +} + +func TestSettings_EngineOpt_WithLogger(t *testing.T) { + // setup types + e := &engine{logger: new(logrus.Entry)} + + // setup tests + tests := []struct { + failure bool + name string + logger *logrus.Entry + want *logrus.Entry + }{ + { + failure: false, + name: "logger set to new entry", + logger: new(logrus.Entry), + want: new(logrus.Entry), + }, + { + failure: false, + name: "logger set to nil", + logger: nil, + want: nil, + }, + } + + // run tests + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + err := WithLogger(test.logger)(e) + + if test.failure { + if err == nil { + t.Errorf("WithLogger for %s should have returned err", test.name) + } + + return + } + + if err != nil { + t.Errorf("WithLogger returned err: %v", err) + } + + if !reflect.DeepEqual(e.logger, test.want) { + t.Errorf("WithLogger is %v, want %v", e.logger, test.want) + } + }) + } +} + +func TestSettings_EngineOpt_WithSkipCreation(t *testing.T) { + // setup types + e := &engine{config: new(config)} + + // setup tests + tests := []struct { + failure bool + name string + skipCreation bool + want bool + }{ + { + failure: false, + name: "skip creation set to true", + skipCreation: true, + want: true, + }, + { + failure: false, + name: "skip creation set to false", + skipCreation: false, + want: false, + }, + } + + // run tests + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + err := WithSkipCreation(test.skipCreation)(e) + + if test.failure { + if err == nil { + t.Errorf("WithSkipCreation for %s should have returned err", test.name) + } + + return + } + + if err != nil { + t.Errorf("WithSkipCreation returned err: %v", err) + } + + if !reflect.DeepEqual(e.config.SkipCreation, test.want) { + t.Errorf("WithSkipCreation is %v, want %v", e.config.SkipCreation, test.want) + } + }) + } +} + +func TestSettings_EngineOpt_WithContext(t *testing.T) { + // setup types + e := &engine{config: new(config)} + + // setup tests + tests := []struct { + failure bool + name string + ctx context.Context + want context.Context + }{ + { + failure: false, + name: "context set to TODO", + ctx: context.TODO(), + want: context.TODO(), + }, + { + failure: false, + name: "context set to nil", + ctx: nil, + want: nil, + }, + } + + // run tests + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + err := WithContext(test.ctx)(e) + + if test.failure { + if err == nil { + t.Errorf("WithContext for %s should have returned err", test.name) + } + + return + } + + if err != nil { + t.Errorf("WithContext returned err: %v", err) + } + + if !reflect.DeepEqual(e.ctx, test.want) { + t.Errorf("WithContext is %v, want %v", e.ctx, test.want) + } + }) + } +} diff --git a/database/settings/settings.go b/database/settings/settings.go new file mode 100644 index 000000000..a673ed49d --- /dev/null +++ b/database/settings/settings.go @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: Apache-2.0 + +package settings + +import ( + "context" + "fmt" + + "github.com/sirupsen/logrus" + "gorm.io/gorm" +) + +const ( + TableSettings = "settings" +) + +type ( + // config represents the settings required to create the engine that implements the SettingsInterface interface. + config struct { + // specifies to skip creating tables and indexes for the Settings engine + SkipCreation bool + } + + // engine represents the settings functionality that implements the SettingsInterface interface. + engine struct { + // engine configuration settings used in settings functions + config *config + + ctx context.Context + + // gorm.io/gorm database client used in settings functions + // + // https://pkg.go.dev/gorm.io/gorm#DB + client *gorm.DB + + // sirupsen/logrus logger used in settings functions + // + // https://pkg.go.dev/github.com/sirupsen/logrus#Entry + logger *logrus.Entry + } +) + +// New creates and returns a Vela service for integrating with settings in the database. +// +//nolint:revive // ignore returning unexported engine +func New(opts ...EngineOpt) (*engine, error) { + // create new Settings engine + e := new(engine) + + // create new fields + e.client = new(gorm.DB) + e.config = new(config) + e.logger = new(logrus.Entry) + + // apply all provided configuration options + for _, opt := range opts { + err := opt(e) + if err != nil { + return nil, err + } + } + + // check if we should skip creating database objects + if e.config.SkipCreation { + e.logger.Warning("skipping creation of settings table and indexes in the database") + + return e, nil + } + + // create the settings table + err := e.CreateSettingsTable(e.ctx, e.client.Config.Dialector.Name()) + if err != nil { + return nil, fmt.Errorf("unable to create %s table: %w", TableSettings, err) + } + + return e, nil +} diff --git a/database/settings/settings_test.go b/database/settings/settings_test.go new file mode 100644 index 000000000..0e1ac773f --- /dev/null +++ b/database/settings/settings_test.go @@ -0,0 +1,171 @@ +// SPDX-License-Identifier: Apache-2.0 + +package settings + +import ( + "reflect" + "testing" + + "github.com/DATA-DOG/go-sqlmock" + "github.com/sirupsen/logrus" + "gorm.io/driver/postgres" + "gorm.io/driver/sqlite" + "gorm.io/gorm" + + "github.com/go-vela/server/api/types/settings" +) + +func TestSettings_New(t *testing.T) { + // setup types + logger := logrus.NewEntry(logrus.StandardLogger()) + + _sql, _mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual)) + if err != nil { + t.Errorf("unable to create new SQL mock: %v", err) + } + defer _sql.Close() + + _mock.ExpectExec(CreatePostgresTable).WillReturnResult(sqlmock.NewResult(1, 1)) + + _config := &gorm.Config{SkipDefaultTransaction: true} + + _postgres, err := gorm.Open(postgres.New(postgres.Config{Conn: _sql}), _config) + if err != nil { + t.Errorf("unable to create new postgres database: %v", err) + } + + _sqlite, err := gorm.Open(sqlite.Open("file::memory:?cache=shared"), _config) + if err != nil { + t.Errorf("unable to create new sqlite database: %v", err) + } + + defer func() { _sql, _ := _sqlite.DB(); _sql.Close() }() + + // setup tests + tests := []struct { + failure bool + name string + client *gorm.DB + key string + logger *logrus.Entry + skipCreation bool + want *engine + }{ + { + failure: false, + name: "postgres", + client: _postgres, + logger: logger, + skipCreation: false, + want: &engine{ + client: _postgres, + config: &config{SkipCreation: false}, + logger: logger, + }, + }, + { + failure: false, + name: "sqlite3", + client: _sqlite, + logger: logger, + skipCreation: false, + want: &engine{ + client: _sqlite, + config: &config{SkipCreation: false}, + logger: logger, + }, + }, + } + + // run tests + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got, err := New( + WithClient(test.client), + WithLogger(test.logger), + WithSkipCreation(test.skipCreation), + ) + + if test.failure { + if err == nil { + t.Errorf("New for %s should have returned err", test.name) + } + + return + } + + if err != nil { + t.Errorf("New for %s returned err: %v", test.name, err) + } + + if !reflect.DeepEqual(got, test.want) { + t.Errorf("New for %s is %v, want %v", test.name, got, test.want) + } + }) + } +} + +// testPostgres is a helper function to create a Postgres engine for testing. +func testPostgres(t *testing.T) (*engine, sqlmock.Sqlmock) { + // create the new mock sql database + // + // https://pkg.go.dev/github.com/DATA-DOG/go-sqlmock#New + _sql, _mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual)) + if err != nil { + t.Errorf("unable to create new SQL mock: %v", err) + } + + _mock.ExpectExec(CreatePostgresTable).WillReturnResult(sqlmock.NewResult(1, 1)) + + // create the new mock Postgres database client + // + // https://pkg.go.dev/gorm.io/gorm#Open + _postgres, err := gorm.Open( + postgres.New(postgres.Config{Conn: _sql}), + &gorm.Config{SkipDefaultTransaction: true}, + ) + if err != nil { + t.Errorf("unable to create new postgres database: %v", err) + } + + _engine, err := New( + WithClient(_postgres), + WithLogger(logrus.NewEntry(logrus.StandardLogger())), + WithSkipCreation(false), + ) + if err != nil { + t.Errorf("unable to create new postgres settings engine: %v", err) + } + + return _engine, _mock +} + +// testSqlite is a helper function to create a Sqlite engine for testing. +func testSqlite(t *testing.T) *engine { + _sqlite, err := gorm.Open( + sqlite.Open("file::memory:?cache=shared"), + &gorm.Config{SkipDefaultTransaction: true}, + ) + if err != nil { + t.Errorf("unable to create new sqlite database: %v", err) + } + + _engine, err := New( + WithClient(_sqlite), + WithLogger(logrus.NewEntry(logrus.StandardLogger())), + WithSkipCreation(false), + ) + if err != nil { + t.Errorf("unable to create new sqlite settings engine: %v", err) + } + + return _engine +} + +// testSettings is a test helper function to create an api +// Platform type with all fields set to their zero values. +func testSettings() *settings.Platform { + s := settings.PlatformMockEmpty() + + return &s +} diff --git a/database/settings/table.go b/database/settings/table.go new file mode 100644 index 000000000..a7268bc76 --- /dev/null +++ b/database/settings/table.go @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: Apache-2.0 + +package settings + +import ( + "context" + + "github.com/go-vela/types/constants" +) + +const ( + // CreatePostgresTable represents a query to create the Postgres settings table. + CreatePostgresTable = ` +CREATE TABLE +IF NOT EXISTS +settings ( + id SERIAL PRIMARY KEY, + compiler JSON DEFAULT NULL, + queue JSON DEFAULT NULL, + repo_allowlist VARCHAR(1000), + schedule_allowlist VARCHAR(1000), + created_at INTEGER, + updated_at INTEGER, + updated_by VARCHAR(250) +); +` + + // CreateSqliteTable represents a query to create the Sqlite settings table. + CreateSqliteTable = ` +CREATE TABLE +IF NOT EXISTS +settings ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + compiler TEXT, + queue TEXT, + repo_allowlist VARCHAR(1000), + schedule_allowlist VARCHAR(1000), + created_at INTEGER, + updated_at INTEGER, + updated_by TEXT +); +` +) + +// CreateSettingsTable creates the settings table in the database. +func (e *engine) CreateSettingsTable(_ context.Context, driver string) error { + e.logger.Tracef("creating settings table in the database") + + // handle the driver provided to create the table + switch driver { + case constants.DriverPostgres: + // create the steps table for Postgres + return e.client.Exec(CreatePostgresTable).Error + case constants.DriverSqlite: + fallthrough + default: + // create the steps table for Sqlite + return e.client.Exec(CreateSqliteTable).Error + } +} diff --git a/database/settings/table_test.go b/database/settings/table_test.go new file mode 100644 index 000000000..13eaab42b --- /dev/null +++ b/database/settings/table_test.go @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: Apache-2.0 + +package settings + +import ( + "context" + "testing" + + "github.com/DATA-DOG/go-sqlmock" +) + +func TestSettings_Engine_CreateSettingsTable(t *testing.T) { + // setup types + _postgres, _mock := testPostgres(t) + defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() + + _mock.ExpectExec(CreatePostgresTable).WillReturnResult(sqlmock.NewResult(1, 1)) + + _sqlite := testSqlite(t) + defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() + + // setup tests + tests := []struct { + failure bool + name string + database *engine + }{ + { + failure: false, + name: "postgres", + database: _postgres, + }, + { + failure: false, + name: "sqlite3", + database: _sqlite, + }, + } + + // run tests + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + err := test.database.CreateSettingsTable(context.TODO(), test.name) + + if test.failure { + if err == nil { + t.Errorf("CreateSettingsTable for %s should have returned err", test.name) + } + + return + } + + if err != nil { + t.Errorf("CreateSettingsTable for %s returned err: %v", test.name, err) + } + }) + } +} diff --git a/database/settings/update.go b/database/settings/update.go new file mode 100644 index 000000000..b72b4d543 --- /dev/null +++ b/database/settings/update.go @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: Apache-2.0 + +package settings + +import ( + "context" + + "github.com/go-vela/server/api/types/settings" + "github.com/go-vela/server/database/types" +) + +// UpdateSettings updates a platform settings in the database. +func (e *engine) UpdateSettings(_ context.Context, s *settings.Platform) (*settings.Platform, error) { + e.logger.Trace("updating platform settings in the database") + + // cast the api type to database type + dbS := types.FromAPI(s) + + // validate the necessary fields are populated + err := dbS.Validate() + if err != nil { + return nil, err + } + + // send query to the database + err = e.client.Table(TableSettings).Save(dbS.Nullify()).Error + if err != nil { + return nil, err + } + + s = dbS.ToAPI() + + return s, nil +} diff --git a/database/settings/update_test.go b/database/settings/update_test.go new file mode 100644 index 000000000..7b9f31a38 --- /dev/null +++ b/database/settings/update_test.go @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: Apache-2.0 + +package settings + +import ( + "context" + "reflect" + "testing" + + "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" +) + +func TestSettings_Engine_UpdateSettings(t *testing.T) { + // setup types + _settings := testSettings() + _settings.SetID(1) + _settings.SetCloneImage("target/vela-git:latest") + _settings.SetTemplateDepth(10) + _settings.SetStarlarkExecLimit(100) + _settings.SetRoutes([]string{"vela", "large"}) + _settings.SetRepoAllowlist([]string{"octocat/hello-world"}) + _settings.SetScheduleAllowlist([]string{"*"}) + _settings.SetCreatedAt(1) + _settings.SetUpdatedAt(1) + _settings.SetUpdatedBy("octocat") + + _postgres, _mock := testPostgres(t) + defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() + + // ensure the mock expects the query + _mock.ExpectExec(`UPDATE "settings" SET "compiler"=$1,"queue"=$2,"repo_allowlist"=$3,"schedule_allowlist"=$4,"created_at"=$5,"updated_at"=$6,"updated_by"=$7 WHERE "id" = $8`). + WithArgs(`{"clone_image":{"String":"target/vela-git:latest","Valid":true},"template_depth":{"Int64":10,"Valid":true},"starlark_exec_limit":{"Int64":100,"Valid":true}}`, + `{"routes":["vela","large"]}`, `{"octocat/hello-world"}`, `{"*"}`, 1, testutils.AnyArgument{}, "octocat", 1). + WillReturnResult(sqlmock.NewResult(1, 1)) + + _sqlite := testSqlite(t) + defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() + + _, err := _sqlite.CreateSettings(context.TODO(), _settings) + if err != nil { + t.Errorf("unable to create test settings for sqlite: %v", err) + } + + // setup tests + tests := []struct { + failure bool + name string + database *engine + }{ + { + failure: false, + name: "postgres", + database: _postgres, + }, + { + failure: false, + name: "sqlite3", + database: _sqlite, + }, + } + + // run tests + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got, err := test.database.UpdateSettings(context.TODO(), _settings) + got.SetUpdatedAt(_settings.GetUpdatedAt()) + + if test.failure { + if err == nil { + t.Errorf("UpdateSettings for %s should have returned err", test.name) + } + + return + } + + if err != nil { + t.Errorf("UpdateSettings for %s returned err: %v", test.name, err) + } + + if !reflect.DeepEqual(got, _settings) { + t.Errorf("UpdateSettings for %s returned %s, want %s", test.name, got, _settings) + } + }) + } +} diff --git a/database/testutils/mock_args.go b/database/testutils/mock_args.go new file mode 100644 index 000000000..c2d8c562f --- /dev/null +++ b/database/testutils/mock_args.go @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: Apache-2.0 + +package testutils + +import ( + "database/sql/driver" + "time" +) + +// This will be used with the github.com/DATA-DOG/go-sqlmock library to compare values +// that are otherwise not easily compared. These typically would be values generated +// before adding or updating them in the database. +// +// https://github.com/DATA-DOG/go-sqlmock#matching-arguments-like-timetime +type AnyArgument struct{} + +// Match satisfies sqlmock.Argument interface. +func (a AnyArgument) Match(_ driver.Value) bool { + return true +} + +// NowTimestamp is used to test whether timestamps get updated correctly to the current time with lenience. +type NowTimestamp struct{} + +// Match satisfies sqlmock.Argument interface. +func (t NowTimestamp) Match(v driver.Value) bool { + ts, ok := v.(int64) + if !ok { + return false + } + + now := time.Now().Unix() + + return now-ts < 10 +} diff --git a/database/types/settings.go b/database/types/settings.go new file mode 100644 index 000000000..f17bac54b --- /dev/null +++ b/database/types/settings.go @@ -0,0 +1,218 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "database/sql" + "database/sql/driver" + "encoding/json" + "errors" + "fmt" + + "github.com/lib/pq" + + "github.com/go-vela/server/api/types/settings" + "github.com/go-vela/server/util" +) + +var ( + // ErrEmptyCloneImage defines the error type when a + // Settings type has an empty CloneImage field provided. + ErrEmptyCloneImage = errors.New("empty settings clone image provided") +) + +type ( + // Platform is the database representation of platform settings. + Platform struct { + ID sql.NullInt64 `sql:"id"` + Compiler + Queue + + RepoAllowlist pq.StringArray `json:"repo_allowlist" sql:"repo_allowlist" gorm:"type:varchar(1000)"` + ScheduleAllowlist pq.StringArray `json:"schedule_allowlist" sql:"schedule_allowlist" gorm:"type:varchar(1000)"` + + CreatedAt sql.NullInt64 `sql:"created_at"` + UpdatedAt sql.NullInt64 `sql:"updated_at"` + UpdatedBy sql.NullString `sql:"updated_by"` + } + + // Compiler is the database representation of compiler settings. + Compiler struct { + CloneImage sql.NullString `json:"clone_image" sql:"clone_image"` + TemplateDepth sql.NullInt64 `json:"template_depth" sql:"template_depth"` + StarlarkExecLimit sql.NullInt64 `json:"starlark_exec_limit" sql:"starlark_exec_limit"` + } + + // Queue is the database representation of queue settings. + Queue struct { + Routes pq.StringArray `json:"routes" sql:"routes" gorm:"type:varchar(1000)"` + } +) + +// Value - Implementation of valuer for database/sql for Compiler. +func (r Compiler) Value() (driver.Value, error) { + valueString, err := json.Marshal(r) + return string(valueString), err +} + +// Scan - Implement the database/sql scanner interface for Compiler. +func (r *Compiler) Scan(value interface{}) error { + switch v := value.(type) { + case []byte: + return json.Unmarshal(v, &r) + case string: + return json.Unmarshal([]byte(v), &r) + default: + return fmt.Errorf("wrong type for compiler: %T", v) + } +} + +// Value - Implementation of valuer for database/sql for Queue. +func (r Queue) Value() (driver.Value, error) { + valueString, err := json.Marshal(r) + return string(valueString), err +} + +// Scan - Implement the database/sql scanner interface for Queue. +func (r *Queue) Scan(value interface{}) error { + switch v := value.(type) { + case []byte: + return json.Unmarshal(v, &r) + case string: + return json.Unmarshal([]byte(v), &r) + default: + return fmt.Errorf("wrong type for queue: %T", v) + } +} + +// Nullify ensures the valid flag for +// the sql.Null types are properly set. +// +// When a field within the Settings type is the zero +// value for the field, the valid flag is set to +// false causing it to be NULL in the database. +func (ps *Platform) Nullify() *Platform { + if ps == nil { + return nil + } + + // check if the ID field should be false + if ps.ID.Int64 == 0 { + ps.ID.Valid = false + } + + // check if the CloneImage field should be false + if len(ps.CloneImage.String) == 0 { + ps.CloneImage.Valid = false + } + + // check if the CreatedAt field should be false + if ps.CreatedAt.Int64 < 0 { + ps.CreatedAt.Valid = false + } + + // check if the UpdatedAt field should be false + if ps.UpdatedAt.Int64 < 0 { + ps.UpdatedAt.Valid = false + } + + return ps +} + +// ToAPI converts the Settings type +// to an API Settings type. +func (ps *Platform) ToAPI() *settings.Platform { + psAPI := new(settings.Platform) + psAPI.SetID(ps.ID.Int64) + + psAPI.SetRepoAllowlist(ps.RepoAllowlist) + psAPI.SetScheduleAllowlist(ps.ScheduleAllowlist) + + psAPI.Compiler = &settings.Compiler{} + psAPI.SetCloneImage(ps.CloneImage.String) + psAPI.SetTemplateDepth(int(ps.TemplateDepth.Int64)) + psAPI.SetStarlarkExecLimit(uint64(ps.StarlarkExecLimit.Int64)) + + psAPI.Queue = &settings.Queue{} + psAPI.SetRoutes(ps.Routes) + + psAPI.SetCreatedAt(ps.CreatedAt.Int64) + psAPI.SetUpdatedAt(ps.UpdatedAt.Int64) + psAPI.SetUpdatedBy(ps.UpdatedBy.String) + + return psAPI +} + +// Validate verifies the necessary fields for +// the Settings type are populated correctly. +func (ps *Platform) Validate() error { + // verify the CloneImage field is populated + if len(ps.CloneImage.String) == 0 { + return ErrEmptyCloneImage + } + + // verify compiler settings are within limits + if ps.TemplateDepth.Int64 <= 0 { + return fmt.Errorf("template depth must be greater than zero, got: %d", ps.TemplateDepth.Int64) + } + + if ps.StarlarkExecLimit.Int64 <= 0 { + return fmt.Errorf("starlark exec limit must be greater than zero, got: %d", ps.StarlarkExecLimit.Int64) + } + + // ensure that all Settings string fields + // that can be returned as JSON are sanitized + // to avoid unsafe HTML content + ps.CloneImage = sql.NullString{String: util.Sanitize(ps.CloneImage.String), Valid: ps.CloneImage.Valid} + + // ensure that all Queue.Routes are sanitized + // to avoid unsafe HTML content + for i, v := range ps.Routes { + ps.Routes[i] = util.Sanitize(v) + } + + // ensure that all RepoAllowlist are sanitized + // to avoid unsafe HTML content + for i, v := range ps.RepoAllowlist { + ps.RepoAllowlist[i] = util.Sanitize(v) + } + + // ensure that all ScheduleAllowlist are sanitized + // to avoid unsafe HTML content + for i, v := range ps.ScheduleAllowlist { + ps.ScheduleAllowlist[i] = util.Sanitize(v) + } + + if ps.CreatedAt.Int64 < 0 { + return fmt.Errorf("created_at must be greater than zero, got: %d", ps.CreatedAt.Int64) + } + + if ps.UpdatedAt.Int64 < 0 { + return fmt.Errorf("updated_at must be greater than zero, got: %d", ps.UpdatedAt.Int64) + } + + return nil +} + +// FromAPI converts the API Settings type +// to a database Settings type. +func FromAPI(s *settings.Platform) *Platform { + settings := &Platform{ + ID: sql.NullInt64{Int64: s.GetID(), Valid: true}, + Compiler: Compiler{ + CloneImage: sql.NullString{String: s.GetCloneImage(), Valid: true}, + TemplateDepth: sql.NullInt64{Int64: int64(s.GetTemplateDepth()), Valid: true}, + StarlarkExecLimit: sql.NullInt64{Int64: int64(s.GetStarlarkExecLimit()), Valid: true}, + }, + Queue: Queue{ + Routes: pq.StringArray(s.GetRoutes()), + }, + RepoAllowlist: pq.StringArray(s.GetRepoAllowlist()), + ScheduleAllowlist: pq.StringArray(s.GetScheduleAllowlist()), + CreatedAt: sql.NullInt64{Int64: s.GetCreatedAt(), Valid: true}, + UpdatedAt: sql.NullInt64{Int64: s.GetUpdatedAt(), Valid: true}, + UpdatedBy: sql.NullString{String: s.GetUpdatedBy(), Valid: true}, + } + + return settings.Nullify() +} diff --git a/database/types/settings_test.go b/database/types/settings_test.go new file mode 100644 index 000000000..973e5d88d --- /dev/null +++ b/database/types/settings_test.go @@ -0,0 +1,195 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "database/sql" + "reflect" + "testing" + + api "github.com/go-vela/server/api/types/settings" +) + +func TestTypes_Platform_Nullify(t *testing.T) { + // setup types + var ps *Platform + + want := &Platform{ + ID: sql.NullInt64{Int64: 0, Valid: false}, + } + + // setup tests + tests := []struct { + repo *Platform + want *Platform + }{ + { + repo: testPlatform(), + want: testPlatform(), + }, + { + repo: ps, + want: nil, + }, + { + repo: new(Platform), + want: want, + }, + } + + // run tests + for _, test := range tests { + got := test.repo.Nullify() + + if !reflect.DeepEqual(got, test.want) { + t.Errorf("Nullify is %v, want %v", got, test.want) + } + } +} + +func TestTypes_Platform_ToAPI(t *testing.T) { + // setup types + want := new(api.Platform) + want.SetID(1) + want.SetRepoAllowlist([]string{"github/octocat"}) + want.SetScheduleAllowlist([]string{"*"}) + want.SetCreatedAt(0) + want.SetUpdatedAt(0) + want.SetUpdatedBy("") + + want.Compiler = new(api.Compiler) + want.SetCloneImage("target/vela-git:latest") + want.SetTemplateDepth(10) + want.SetStarlarkExecLimit(100) + + want.Queue = new(api.Queue) + want.SetRoutes([]string{"vela"}) + + // run test + got := testPlatform().ToAPI() + + if !reflect.DeepEqual(got, want) { + t.Errorf("ToAPI is %v, want %v", got, want) + } +} + +func TestTypes_Platform_Validate(t *testing.T) { + // setup tests + tests := []struct { + failure bool + settings *Platform + }{ + { + failure: false, + settings: testPlatform(), + }, + { // no CloneImage set for settings + failure: true, + settings: &Platform{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + Compiler: Compiler{ + TemplateDepth: sql.NullInt64{Int64: 10, Valid: true}, + StarlarkExecLimit: sql.NullInt64{Int64: 100, Valid: true}, + }, + }, + }, + { // no TemplateDepth set for settings + failure: true, + settings: &Platform{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + Compiler: Compiler{ + CloneImage: sql.NullString{String: "target/vela-git:latest", Valid: true}, + StarlarkExecLimit: sql.NullInt64{Int64: 100, Valid: true}, + }, + }, + }, + { // no StarlarkExecLimit set for settings + failure: true, + settings: &Platform{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + Compiler: Compiler{ + CloneImage: sql.NullString{String: "target/vela-git:latest", Valid: true}, + TemplateDepth: sql.NullInt64{Int64: 10, Valid: true}, + }, + }, + }, + { // no queue fields set for settings + failure: false, + settings: &Platform{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + Compiler: Compiler{ + CloneImage: sql.NullString{String: "target/vela-git:latest", Valid: true}, + TemplateDepth: sql.NullInt64{Int64: 10, Valid: true}, + StarlarkExecLimit: sql.NullInt64{Int64: 100, Valid: true}, + }, + Queue: Queue{}, + }, + }, + } + + // run tests + for _, test := range tests { + err := test.settings.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 TestTypes_Platform_PlatformFromAPI(t *testing.T) { + // setup types + s := new(api.Platform) + s.SetID(1) + s.SetRepoAllowlist([]string{"github/octocat"}) + s.SetScheduleAllowlist([]string{"*"}) + s.SetCreatedAt(0) + s.SetUpdatedAt(0) + s.SetUpdatedBy("") + + s.Compiler = new(api.Compiler) + s.SetCloneImage("target/vela-git:latest") + s.SetTemplateDepth(10) + s.SetStarlarkExecLimit(100) + + s.Queue = new(api.Queue) + s.SetRoutes([]string{"vela"}) + + want := testPlatform() + + // run test + got := FromAPI(s) + + if !reflect.DeepEqual(got, want) { + t.Errorf("PlatformFromAPI is %v, want %v", got, want) + } +} + +// testPlatform is a test helper function to create a Platform +// type with all fields set to a fake value. +func testPlatform() *Platform { + return &Platform{ + ID: sql.NullInt64{Int64: 1, Valid: true}, + Compiler: Compiler{ + CloneImage: sql.NullString{String: "target/vela-git:latest", Valid: true}, + TemplateDepth: sql.NullInt64{Int64: 10, Valid: true}, + StarlarkExecLimit: sql.NullInt64{Int64: 100, Valid: true}, + }, + Queue: Queue{ + Routes: []string{"vela"}, + }, + RepoAllowlist: []string{"github/octocat"}, + ScheduleAllowlist: []string{"*"}, + CreatedAt: sql.NullInt64{Int64: 0, Valid: true}, + UpdatedAt: sql.NullInt64{Int64: 0, Valid: true}, + UpdatedBy: sql.NullString{String: "", Valid: true}, + } +} diff --git a/go.mod b/go.mod index aefa64a29..4993597bb 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,7 @@ require ( github.com/alicebob/miniredis/v2 v2.32.1 github.com/aws/aws-sdk-go v1.51.0 github.com/buildkite/yaml v0.0.0-20181016232759-0caa5f0796e3 + github.com/distribution/reference v0.6.0 github.com/drone/envsubst v1.0.3 github.com/ghodss/yaml v1.0.0 github.com/gin-gonic/gin v1.9.1 @@ -99,6 +100,7 @@ require ( github.com/mitchellh/reflectwalk v1.0.1 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect github.com/pelletier/go-toml/v2 v2.0.8 // indirect github.com/prometheus/client_model v0.5.0 // indirect github.com/prometheus/common v0.48.0 // indirect diff --git a/go.sum b/go.sum index 3b30dd8ed..75bac3763 100644 --- a/go.sum +++ b/go.sum @@ -58,6 +58,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= +github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/drone/envsubst v1.0.3 h1:PCIBwNDYjs50AsLZPYdfhSATKaRg/FJmDc2D6+C2x8g= github.com/drone/envsubst v1.0.3/go.mod h1:N2jZmlMufstn1KEqvbHjw40h1KyTmnVzHcSc9bFiJ2g= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= @@ -213,6 +215,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= diff --git a/internal/image/doc.go b/internal/image/doc.go new file mode 100644 index 000000000..66d473d15 --- /dev/null +++ b/internal/image/doc.go @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: Apache-2.0 + +// Package image provides the ability for Vela to manage +// and manipulate images. +// +// Usage: +// +// import "github.com/go-vela/server/internal/image" +package image diff --git a/internal/image/image.go b/internal/image/image.go new file mode 100644 index 000000000..daa5b37bc --- /dev/null +++ b/internal/image/image.go @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: Apache-2.0 + +package image + +import ( + "github.com/distribution/reference" +) + +// ParseWithError digests the provided image into a +// fully qualified canonical reference. If an error +// occurs, it will return the last digested form of +// the image. +func ParseWithError(_image string) (string, error) { + // parse the image provided into a + // named, fully qualified reference + // + // https://pkg.go.dev/github.com/distribution/reference#ParseAnyReference + _reference, err := reference.ParseAnyReference(_image) + if err != nil { + return _image, err + } + + // ensure we have the canonical form of the named reference + // + // https://pkg.go.dev/github.com/distribution/reference#ParseNamed + _canonical, err := reference.ParseNamed(_reference.String()) + if err != nil { + return _reference.String(), err + } + + // ensure the canonical reference has a tag + // + // https://pkg.go.dev/github.com/distribution/reference#TagNameOnly + return reference.TagNameOnly(_canonical).String(), nil +} diff --git a/internal/image/image_test.go b/internal/image/image_test.go new file mode 100644 index 000000000..365fad2ff --- /dev/null +++ b/internal/image/image_test.go @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: Apache-2.0 + +package image + +import ( + "strings" + "testing" +) + +func TestImage_ParseWithError(t *testing.T) { + // setup tests + tests := []struct { + name string + failure bool + image string + want string + }{ + { + name: "image only", + failure: false, + image: "golang", + want: "docker.io/library/golang:latest", + }, + { + name: "image and tag", + failure: false, + image: "golang:latest", + want: "docker.io/library/golang:latest", + }, + { + name: "image and tag", + failure: false, + image: "golang:1.14", + want: "docker.io/library/golang:1.14", + }, + { + name: "fails with bad image", + failure: true, + image: "!@#$%^&*()", + want: "!@#$%^&*()", + }, + { + name: "fails with image sha", + failure: true, + image: "1a3f5e7d9c1b3a5f7e9d1c3b5a7f9e1d3c5b7a9f1e3d5d7c9b1a3f5e7d9c1b3a", + want: "sha256:1a3f5e7d9c1b3a5f7e9d1c3b5a7f9e1d3c5b7a9f1e3d5d7c9b1a3f5e7d9c1b3a", + }, + } + + // run tests + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got, err := ParseWithError(test.image) + + if test.failure { + if err == nil { + t.Errorf("ParseWithError should have returned err") + } + + if !strings.EqualFold(got, test.want) { + t.Errorf("ParseWithError is %s want %s", got, test.want) + } + + return // continue to next test + } + + if err != nil { + t.Errorf("ParseWithError returned err: %v", err) + } + + if !strings.EqualFold(got, test.want) { + t.Errorf("ParseWithError is %s want %s", got, test.want) + } + }) + } +} diff --git a/mock/server/server.go b/mock/server/server.go index fb6161ccd..9527cbc75 100644 --- a/mock/server/server.go +++ b/mock/server/server.go @@ -29,6 +29,9 @@ func FakeHandler() http.Handler { e.PUT("/api/v1/admin/user", updateUser) e.POST("/api/v1/admin/workers/:worker/register", registerToken) e.PUT("api/v1/admin/clean", cleanResoures) + e.GET("/api/v1/admin/settings", getSettings) + e.PUT("/api/v1/admin/settings", updateSettings) + e.DELETE("/api/v1/admin/settings", restoreSettings) // mock endpoints for build calls e.GET("/api/v1/repos/:org/:repo/builds/:build", getBuild) diff --git a/mock/server/settings.go b/mock/server/settings.go new file mode 100644 index 000000000..07e5c9419 --- /dev/null +++ b/mock/server/settings.go @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: Apache-2.0 + +package server + +import ( + "encoding/json" + "net/http" + + "github.com/gin-gonic/gin" + + "github.com/go-vela/server/api/types/settings" +) + +const ( + // SettingsResp represents a JSON return for a single settings. + SettingsResp = ` + { + "id": 1, + "compiler": { + "clone_image": "target/vela-git", + "template_depth": 3, + "starlark_exec_limit": 100 + }, + "queue": { + "routes": [ + "vela" + ] + }, + "repo_allowlist": [ + "*" + ], + "schedule_allowlist": [ + "octocat/hello-world" + ], + "created_at": 1, + "updated_at": 1, + "updated_by": "octocat" + }` + + // UpdateSettingsResp represents a JSON return for modifying a settings field. + UpdateSettingsResp = ` + { + "id": 1, + "compiler": { + "clone_image": "target/vela-git:latest", + "template_depth": 5, + "starlark_exec_limit": 123 + }, + "queue": { + "routes": [ + "vela", + "large" + ] + }, + "repo_allowlist": [], + "schedule_allowlist": [ + "octocat/hello-world", + "octocat/*" + ], + "created_at": 1, + "updated_at": 1, + "updated_by": "octocat" + }` + + // RestoreSettingsResp represents a JSON return for restoring the settings record to the defaults. + RestoreSettingsResp = ` + { + "id": 1, + "compiler": { + "clone_image": "target/vela-git:latest", + "template_depth": 5, + "starlark_exec_limit": 123 + }, + "queue": { + "routes": [ + "vela", + "large" + ] + }, + "repo_allowlist": [], + "schedule_allowlist": [ + "octocat/hello-world", + "octocat/*" + ], + "created_at": 1, + "updated_at": 1, + "updated_by": "octocat" + }` +) + +// getSettings has a param :settings returns mock JSON for a http GET. +func getSettings(c *gin.Context) { + data := []byte(SettingsResp) + + var body settings.Platform + _ = json.Unmarshal(data, &body) + + c.JSON(http.StatusOK, body) +} + +// updateSettings returns mock JSON for a http PUT. +func updateSettings(c *gin.Context) { + data := []byte(UpdateSettingsResp) + + var body settings.Platform + _ = json.Unmarshal(data, &body) + + c.JSON(http.StatusOK, body) +} + +// restoreSettings returns mock JSON for a http DELETE. +func restoreSettings(c *gin.Context) { + data := []byte(RestoreSettingsResp) + + var body settings.Platform + _ = json.Unmarshal(data, &body) + + c.JSON(http.StatusOK, body) +} diff --git a/mock/server/settings_test.go b/mock/server/settings_test.go new file mode 100644 index 000000000..d827cc756 --- /dev/null +++ b/mock/server/settings_test.go @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: Apache-2.0 + +package server + +import ( + "encoding/json" + "reflect" + "testing" + + "github.com/go-vela/server/api/types/settings" +) + +func TestSettings_GetResp(t *testing.T) { + testSettings := settings.Platform{} + + err := json.Unmarshal([]byte(SettingsResp), &testSettings) + if err != nil { + t.Errorf("error unmarshaling settings: %v", err) + } + + tSettings := reflect.TypeOf(testSettings) + + for i := 0; i < tSettings.NumField(); i++ { + f := reflect.ValueOf(testSettings).Field(i) + if f.IsNil() { + t.Errorf("SettingsResp missing field %s", tSettings.Field(i).Name) + } + } +} + +func TestSettings_UpdateResp(t *testing.T) { + testSettings := settings.Platform{} + + err := json.Unmarshal([]byte(UpdateSettingsResp), &testSettings) + if err != nil { + t.Errorf("error unmarshaling settings: %v", err) + } + + tSettings := reflect.TypeOf(testSettings) + + for i := 0; i < tSettings.NumField(); i++ { + f := reflect.ValueOf(testSettings).Field(i) + if f.IsNil() { + t.Errorf("UpdateSettingsResp missing field %s", tSettings.Field(i).Name) + } + } +} + +func TestSettings_RestoreResp(t *testing.T) { + testSettings := settings.Platform{} + + err := json.Unmarshal([]byte(RestoreSettingsResp), &testSettings) + if err != nil { + t.Errorf("error unmarshaling settings: %v", err) + } + + tSettings := reflect.TypeOf(testSettings) + + for i := 0; i < tSettings.NumField(); i++ { + f := reflect.ValueOf(testSettings).Field(i) + if f.IsNil() { + t.Errorf("RestoreSettingsResp missing field %s", tSettings.Field(i).Name) + } + } +} diff --git a/queue/queue.go b/queue/queue.go index fe2946f1b..181ed5899 100644 --- a/queue/queue.go +++ b/queue/queue.go @@ -6,10 +6,32 @@ import ( "fmt" "github.com/sirupsen/logrus" + "github.com/urfave/cli/v2" "github.com/go-vela/types/constants" ) +// FromCLIContext helper function to setup the queue from the CLI arguments. +func FromCLIContext(c *cli.Context) (Service, error) { + logrus.Debug("Creating queue client from CLI configuration") + + // queue configuration + _setup := &Setup{ + Driver: c.String("queue.driver"), + Address: c.String("queue.addr"), + Cluster: c.Bool("queue.cluster"), + Routes: c.StringSlice("queue.routes"), + Timeout: c.Duration("queue.pop.timeout"), + PrivateKey: c.String("queue.private-key"), + PublicKey: c.String("queue.public-key"), + } + + // setup the queue + // + // https://pkg.go.dev/github.com/go-vela/server/queue?tab=doc#New + return New(_setup) +} + // New creates and returns a Vela service capable of // integrating with the configured queue environment. // Currently, the following queues are supported: diff --git a/queue/redis/driver_test.go b/queue/redis/driver_test.go index 8ed67a3a5..52894f1ba 100644 --- a/queue/redis/driver_test.go +++ b/queue/redis/driver_test.go @@ -28,7 +28,7 @@ func TestRedis_Driver(t *testing.T) { _service, err := New( WithAddress(fmt.Sprintf("redis://%s", _redis.Addr())), - WithChannels("foo"), + WithRoutes("foo"), WithCluster(false), WithTimeout(5*time.Second), ) diff --git a/queue/redis/length.go b/queue/redis/length.go index c4d7bb7c3..7f5ed9b0b 100644 --- a/queue/redis/length.go +++ b/queue/redis/length.go @@ -6,13 +6,13 @@ import ( "context" ) -// Length tallies all items present in the configured channels in the queue. +// Length tallies all items present in the configured routes in the queue. func (c *client) Length(ctx context.Context) (int64, error) { - c.Logger.Tracef("reading length of all configured channels in queue") + c.Logger.Tracef("reading length of all configured routes in queue") total := int64(0) - for _, channel := range c.config.Channels { + for _, channel := range c.GetRoutes() { items, err := c.Redis.LLen(ctx, channel).Result() if err != nil { return 0, err diff --git a/queue/redis/length_test.go b/queue/redis/length_test.go index 545f9f54a..9656a8c20 100644 --- a/queue/redis/length_test.go +++ b/queue/redis/length_test.go @@ -33,26 +33,26 @@ func TestRedis_Length(t *testing.T) { // setup tests tests := []struct { - channels []string - want int64 + routes []string + want int64 }{ { - channels: []string{"vela"}, - want: 1, + routes: []string{"vela"}, + want: 1, }, { - channels: []string{"vela", "vela:second", "vela:third"}, - want: 4, + routes: []string{"vela", "vela:second", "vela:third"}, + want: 4, }, { - channels: []string{"vela", "vela:second", "phony"}, - want: 6, + routes: []string{"vela", "vela:second", "phony"}, + want: 6, }, } // run tests for _, test := range tests { - for _, channel := range test.channels { + for _, channel := range test.routes { err := _redis.Push(context.Background(), channel, bytes) if err != nil { t.Errorf("unable to push item to queue: %v", err) diff --git a/queue/redis/opts.go b/queue/redis/opts.go index 582994fea..f58dab06a 100644 --- a/queue/redis/opts.go +++ b/queue/redis/opts.go @@ -29,18 +29,18 @@ func WithAddress(address string) ClientOpt { } } -// WithChannels sets the channels in the queue client for Redis. -func WithChannels(channels ...string) ClientOpt { +// WithRoutes sets the routes in the queue client for Redis. +func WithRoutes(routes ...string) ClientOpt { return func(c *client) error { - c.Logger.Trace("configuring channels in redis queue client") + c.Logger.Trace("configuring routes in redis queue client") - // check if the channels provided are empty - if len(channels) == 0 { - return fmt.Errorf("no Redis queue channels provided") + // check if the routes provided are empty + if len(routes) == 0 { + return fmt.Errorf("no Redis queue routes provided") } - // set the queue channels in the redis client - c.config.Channels = channels + // set the queue routes in the redis client + c.SetRoutes(routes) return nil } diff --git a/queue/redis/opts_test.go b/queue/redis/opts_test.go index aa775c121..6e729ce52 100644 --- a/queue/redis/opts_test.go +++ b/queue/redis/opts_test.go @@ -64,7 +64,7 @@ func TestRedis_ClientOpt_WithAddress(t *testing.T) { } } -func TestRedis_ClientOpt_WithChannels(t *testing.T) { +func TestRedis_ClientOpt_WithRoutes(t *testing.T) { // setup tests // create a local fake redis instance // @@ -76,19 +76,19 @@ func TestRedis_ClientOpt_WithChannels(t *testing.T) { defer _redis.Close() tests := []struct { - failure bool - channels []string - want []string + failure bool + routes []string + want []string }{ { - failure: false, - channels: []string{"foo", "bar"}, - want: []string{"foo", "bar"}, + failure: false, + routes: []string{"foo", "bar"}, + want: []string{"foo", "bar"}, }, { - failure: true, - channels: []string{}, - want: []string{}, + failure: true, + routes: []string{}, + want: []string{}, }, } @@ -96,23 +96,23 @@ func TestRedis_ClientOpt_WithChannels(t *testing.T) { for _, test := range tests { _service, err := New( WithAddress(fmt.Sprintf("redis://%s", _redis.Addr())), - WithChannels(test.channels...), + WithRoutes(test.routes...), ) if test.failure { if err == nil { - t.Errorf("WithChannels should have returned err") + t.Errorf("WithRoutes should have returned err") } continue } if err != nil { - t.Errorf("WithChannels returned err: %v", err) + t.Errorf("WithRoutes returned err: %v", err) } - if !reflect.DeepEqual(_service.config.Channels, test.want) { - t.Errorf("WithChannels is %v, want %v", _service.config.Channels, test.want) + if !reflect.DeepEqual(_service.GetRoutes(), test.want) { + t.Errorf("WithRoutes is %v, want %v", _service.GetRoutes(), test.want) } } } diff --git a/queue/redis/ping_test.go b/queue/redis/ping_test.go index d069370f2..39fde9272 100644 --- a/queue/redis/ping_test.go +++ b/queue/redis/ping_test.go @@ -22,7 +22,7 @@ func TestRedis_Ping_Good(t *testing.T) { // setup redis mock goodRedis, err := New( WithAddress(fmt.Sprintf("redis://%s", _redis.Addr())), - WithChannels("foo"), + WithRoutes("foo"), WithCluster(false), WithTimeout(5*time.Second), ) @@ -49,7 +49,7 @@ func TestRedis_Ping_Bad(t *testing.T) { // setup redis mock badRedis, _ := New( WithAddress(fmt.Sprintf("redis://%s", _redis.Addr())), - WithChannels("foo"), + WithRoutes("foo"), WithCluster(false), WithTimeout(5*time.Second), ) diff --git a/queue/redis/pop.go b/queue/redis/pop.go index 4d1af3921..7c5658029 100644 --- a/queue/redis/pop.go +++ b/queue/redis/pop.go @@ -14,23 +14,23 @@ import ( ) // Pop grabs an item from the specified channel off the queue. -func (c *client) Pop(ctx context.Context, routes []string) (*models.Item, error) { - c.Logger.Tracef("popping item from queue %s", c.config.Channels) +func (c *client) Pop(ctx context.Context, inRoutes []string) (*models.Item, error) { + c.Logger.Tracef("popping item from queue %s", c.GetRoutes()) - // define channels to pop from - var channels []string + // define routes to pop from + var routes []string // if routes were supplied, use those if len(routes) > 0 { - channels = routes + routes = inRoutes } else { - channels = c.config.Channels + routes = c.GetRoutes() } // build a redis queue command to pop an item from queue // // https://pkg.go.dev/github.com/go-redis/redis?tab=doc#Client.BLPop - popCmd := c.Redis.BLPop(ctx, c.config.Timeout, channels...) + popCmd := c.Redis.BLPop(ctx, c.config.Timeout, routes...) // blocking call to pop item from queue // diff --git a/queue/redis/pop_test.go b/queue/redis/pop_test.go index b2ade0b40..190839f80 100644 --- a/queue/redis/pop_test.go +++ b/queue/redis/pop_test.go @@ -64,7 +64,7 @@ func TestRedis_Pop(t *testing.T) { t.Errorf("unable to create queue service: %v", err) } // overwrite channel to be invalid - badChannel.config.Channels = nil + badChannel.SetRoutes(nil) signed = sign.Sign(out, bytes, badChannel.config.PrivateKey) @@ -76,10 +76,10 @@ func TestRedis_Pop(t *testing.T) { // setup tests tests := []struct { - failure bool - redis *client - want *models.Item - channels []string + failure bool + redis *client + want *models.Item + routes []string }{ { failure: false, @@ -87,10 +87,10 @@ func TestRedis_Pop(t *testing.T) { want: _item, }, { - failure: false, - redis: _redis, - want: _item, - channels: []string{"custom"}, + failure: false, + redis: _redis, + want: _item, + routes: []string{"custom"}, }, { failure: false, @@ -106,7 +106,7 @@ func TestRedis_Pop(t *testing.T) { // run tests for _, test := range tests { - got, err := test.redis.Pop(context.Background(), test.channels) + got, err := test.redis.Pop(context.Background(), test.routes) if test.failure { if err == nil { diff --git a/queue/redis/redis.go b/queue/redis/redis.go index 5a789ed58..88b962c00 100644 --- a/queue/redis/redis.go +++ b/queue/redis/redis.go @@ -11,13 +11,13 @@ import ( "github.com/alicebob/miniredis/v2" "github.com/redis/go-redis/v9" "github.com/sirupsen/logrus" + + "github.com/go-vela/server/api/types/settings" ) type config struct { // specifies the address to use for the Redis client Address string - // specifies a list of channels for managing builds for the Redis client - Channels []string // enables the Redis client to integrate with a Redis cluster Cluster bool // specifies the timeout to use for the Redis client @@ -32,6 +32,9 @@ type client struct { config *config Redis *redis.Client Options *redis.Options + + settings.Queue + // https://pkg.go.dev/github.com/sirupsen/logrus#Entry Logger *logrus.Entry } @@ -174,7 +177,7 @@ func pingQueue(c *client) error { // This function is intended for running tests only. // //nolint:revive // ignore returning unexported client -func NewTest(signingPrivateKey, signingPublicKey string, channels ...string) (*client, error) { +func NewTest(signingPrivateKey, signingPublicKey string, routes ...string) (*client, error) { // create a local fake redis instance // // https://pkg.go.dev/github.com/alicebob/miniredis/v2#Run @@ -185,7 +188,7 @@ func NewTest(signingPrivateKey, signingPublicKey string, channels ...string) (*c return New( WithAddress(fmt.Sprintf("redis://%s", _redis.Addr())), - WithChannels(channels...), + WithRoutes(routes...), WithCluster(false), WithPrivateKey(signingPrivateKey), WithPublicKey(signingPublicKey), diff --git a/queue/redis/redis_test.go b/queue/redis/redis_test.go index 474d57de9..b08fda760 100644 --- a/queue/redis/redis_test.go +++ b/queue/redis/redis_test.go @@ -125,7 +125,7 @@ func TestRedis_New(t *testing.T) { for _, test := range tests { _, err := New( WithAddress(test.address), - WithChannels("foo"), + WithRoutes("foo"), WithCluster(false), WithTimeout(5*time.Second), ) diff --git a/queue/redis/route.go b/queue/redis/route.go index a25a537c6..e4fc0ae05 100644 --- a/queue/redis/route.go +++ b/queue/redis/route.go @@ -13,7 +13,7 @@ import ( // Route decides which route a build gets placed within the queue. func (c *client) Route(w *pipeline.Worker) (string, error) { - c.Logger.Tracef("deciding route from queue channels %s", c.config.Channels) + c.Logger.Tracef("deciding route from queue routes %s", c.GetRoutes()) // create buffer to store route buf := bytes.Buffer{} @@ -37,7 +37,7 @@ func (c *client) Route(w *pipeline.Worker) (string, error) { route := strings.TrimLeft(buf.String(), ":") - for _, r := range c.config.Channels { + for _, r := range c.GetRoutes() { if strings.EqualFold(route, r) { return route, nil } diff --git a/queue/redis/settings.go b/queue/redis/settings.go new file mode 100644 index 000000000..70747b6c3 --- /dev/null +++ b/queue/redis/settings.go @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: Apache-2.0 + +package redis + +import ( + "github.com/go-vela/server/api/types/settings" +) + +// GetSettings retrieves the api settings type in the Engine. +func (c *client) GetSettings() settings.Queue { + return c.Queue +} + +// SetSettings sets the api settings type in the Engine. +func (c *client) SetSettings(s *settings.Platform) { + if s != nil { + c.SetRoutes(s.GetRoutes()) + } +} diff --git a/queue/service.go b/queue/service.go index 3fdf27515..a976e7045 100644 --- a/queue/service.go +++ b/queue/service.go @@ -5,6 +5,7 @@ package queue import ( "context" + "github.com/go-vela/server/api/types/settings" "github.com/go-vela/server/queue/models" "github.com/go-vela/types/pipeline" ) @@ -37,4 +38,12 @@ type Service interface { // Route defines a function that decides which // channel a build gets placed within the queue. Route(*pipeline.Worker) (string, error) + + // GetSettings defines a function that returns + // queue settings. + GetSettings() settings.Queue + + // SetSettings defines a function that takes api settings + // and updates the compiler Engine. + SetSettings(*settings.Platform) } diff --git a/queue/setup.go b/queue/setup.go index cdac822ea..c554c9238 100644 --- a/queue/setup.go +++ b/queue/setup.go @@ -45,7 +45,7 @@ func (s *Setup) Redis() (Service, error) { // https://pkg.go.dev/github.com/go-vela/server/queue/redis?tab=doc#New return redis.New( redis.WithAddress(s.Address), - redis.WithChannels(s.Routes...), + redis.WithRoutes(s.Routes...), redis.WithCluster(s.Cluster), redis.WithTimeout(s.Timeout), redis.WithPrivateKey(s.PrivateKey), diff --git a/router/admin.go b/router/admin.go index c279445eb..22f83973e 100644 --- a/router/admin.go +++ b/router/admin.go @@ -12,18 +12,21 @@ import ( // AdminHandlers is a function that extends the provided base router group // with the API handlers for admin functionality. // -// GET /api/v1/admin/builds/queue -// GET /api/v1/admin/build/:id -// PUT /api/v1/admin/build -// PUT /api/v1/admin/clean -// PUT /api/v1/admin/deployment -// PUT /api/v1/admin/hook -// PUT /api/v1/admin/repo -// PUT /api/v1/admin/secret -// PUT /api/v1/admin/service -// PUT /api/v1/admin/step -// PUT /api/v1/admin/user -// POST /api/v1/admin/workers/:worker/register. +// GET /api/v1/admin/builds/queue +// GET /api/v1/admin/build/:id +// PUT /api/v1/admin/build +// PUT /api/v1/admin/clean +// PUT /api/v1/admin/deployment +// PUT /api/v1/admin/hook +// PUT /api/v1/admin/repo +// PUT /api/v1/admin/secret +// PUT /api/v1/admin/service +// PUT /api/v1/admin/step +// PUT /api/v1/admin/user +// POST /api/v1/admin/workers/:worker/register +// GET /api/v1/admin/settings +// PUT /api/v1/admin/settings +// DELETE /api/v1/admin/settings. func AdminHandlers(base *gin.RouterGroup) { // Admin endpoints _admin := base.Group("/admin", perm.MustPlatformAdmin()) @@ -60,5 +63,10 @@ func AdminHandlers(base *gin.RouterGroup) { // Admin worker endpoint _admin.POST("/workers/:worker/register", admin.RegisterToken) + + // Admin settings endpoints + _admin.GET("/settings", admin.GetSettings) + _admin.PUT("/settings", admin.UpdateSettings) + _admin.DELETE("/settings", admin.RestoreSettings) } // end of admin endpoints } diff --git a/router/middleware/allowlist.go b/router/middleware/allowlist.go deleted file mode 100644 index edfe5feb2..000000000 --- a/router/middleware/allowlist.go +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - -package middleware - -import ( - "github.com/gin-gonic/gin" -) - -// Allowlist is a middleware function that attaches the allowlist used -// to limit which repos can be activated within the system. -func Allowlist(allowlist []string) gin.HandlerFunc { - return func(c *gin.Context) { - c.Set("allowlist", allowlist) - c.Next() - } -} diff --git a/router/middleware/allowlist_schedule.go b/router/middleware/allowlist_schedule.go deleted file mode 100644 index d22a7aa20..000000000 --- a/router/middleware/allowlist_schedule.go +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - -package middleware - -import ( - "github.com/gin-gonic/gin" -) - -// AllowlistSchedule is a middleware function that attaches the allowlistschedule used -// to limit which repos can utilize the schedule feature within the system. -func AllowlistSchedule(allowlistschedule []string) gin.HandlerFunc { - return func(c *gin.Context) { - c.Set("allowlistschedule", allowlistschedule) - c.Next() - } -} diff --git a/router/middleware/cli.go b/router/middleware/cli.go new file mode 100644 index 000000000..acc1972eb --- /dev/null +++ b/router/middleware/cli.go @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: Apache-2.0 + +package middleware + +import ( + "github.com/gin-gonic/gin" + "github.com/urfave/cli/v2" + + cliMiddleware "github.com/go-vela/server/router/middleware/cli" +) + +// CLI is a middleware function that attaches the cli client +// to the context of every http.Request. +func CLI(cliCtx *cli.Context) gin.HandlerFunc { + return func(c *gin.Context) { + cliMiddleware.ToContext(c, cliCtx) + + c.Next() + } +} diff --git a/router/middleware/cli/context.go b/router/middleware/cli/context.go new file mode 100644 index 000000000..13952ddc2 --- /dev/null +++ b/router/middleware/cli/context.go @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: Apache-2.0 + +package cli + +import ( + "context" + + "github.com/urfave/cli/v2" +) + +const key = "cli" + +// Setter defines a context that enables setting values. +type Setter interface { + Set(string, interface{}) +} + +// FromContext returns the cli context associated with this context. +func FromContext(c context.Context) *cli.Context { + value := c.Value(key) + if value == nil { + return nil + } + + s, ok := value.(*cli.Context) + if !ok { + return nil + } + + return s +} + +// ToContext adds the cli context to this context if it supports +// the Setter interface. +func ToContext(c Setter, s *cli.Context) { + c.Set(key, s) +} diff --git a/router/middleware/cli/context_test.go b/router/middleware/cli/context_test.go new file mode 100644 index 000000000..4269f3c06 --- /dev/null +++ b/router/middleware/cli/context_test.go @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: Apache-2.0 + +package cli + +import ( + "testing" + + "github.com/gin-gonic/gin" + "github.com/urfave/cli/v2" +) + +func TestSettings_FromContext(t *testing.T) { + // setup types + want := &cli.Context{} + + // setup context + gin.SetMode(gin.TestMode) + context, _ := gin.CreateTestContext(nil) + context.Set(key, want) + + // run test + got := FromContext(context) + + if got != want { + t.Errorf("FromContext is %v, want %v", got, want) + } +} + +func TestSettings_FromContext_Bad(t *testing.T) { + // setup context + gin.SetMode(gin.TestMode) + context, _ := gin.CreateTestContext(nil) + context.Set(key, nil) + + // run test + got := FromContext(context) + + if got != nil { + t.Errorf("FromContext is %v, want nil", got) + } +} + +func TestSettings_FromContext_WrongType(t *testing.T) { + // setup context + gin.SetMode(gin.TestMode) + context, _ := gin.CreateTestContext(nil) + context.Set(key, 1) + + // run test + got := FromContext(context) + + if got != nil { + t.Errorf("FromContext is %v, want nil", got) + } +} + +func TestSettings_FromContext_Empty(t *testing.T) { + // setup context + gin.SetMode(gin.TestMode) + context, _ := gin.CreateTestContext(nil) + + // run test + got := FromContext(context) + + if got != nil { + t.Errorf("FromContext is %v, want nil", got) + } +} + +func TestSettings_ToContext(t *testing.T) { + // setup types + want := &cli.Context{} + + // setup context + gin.SetMode(gin.TestMode) + context, _ := gin.CreateTestContext(nil) + ToContext(context, want) + + // run test + got := context.Value(key) + + if got != want { + t.Errorf("ToContext is %v, want %v", got, want) + } +} diff --git a/router/middleware/cli/doc.go b/router/middleware/cli/doc.go new file mode 100644 index 000000000..3bdc404c6 --- /dev/null +++ b/router/middleware/cli/doc.go @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: Apache-2.0 + +// Package cli provides the ability for inserting +// Vela cli resources into or extracting Vela cli +// resources from the middleware chain for the API. +// +// Usage: +// +// import "github.com/go-vela/server/router/middleware/cli" +package cli diff --git a/router/middleware/allowlist_schedule_test.go b/router/middleware/cli_test.go similarity index 65% rename from router/middleware/allowlist_schedule_test.go rename to router/middleware/cli_test.go index 1461b8719..d94e68c75 100644 --- a/router/middleware/allowlist_schedule_test.go +++ b/router/middleware/cli_test.go @@ -9,12 +9,18 @@ import ( "testing" "github.com/gin-gonic/gin" + "github.com/urfave/cli/v2" ) -func TestMiddleware_AllowlistSchedule(t *testing.T) { +func TestMiddleware_CLI(t *testing.T) { // setup types - got := []string{""} - want := []string{"foobar"} + want := &cli.Context{ + App: &cli.App{ + Name: "foo", + }, + } + + got := &cli.Context{} // setup context gin.SetMode(gin.TestMode) @@ -24,9 +30,9 @@ func TestMiddleware_AllowlistSchedule(t *testing.T) { context.Request, _ = http.NewRequest(http.MethodGet, "/health", nil) // setup mock server - engine.Use(AllowlistSchedule(want)) + engine.Use(CLI(want)) engine.GET("/health", func(c *gin.Context) { - got = c.Value("allowlistschedule").([]string) + got = c.Value("cli").(*cli.Context) c.Status(http.StatusOK) }) @@ -35,10 +41,10 @@ func TestMiddleware_AllowlistSchedule(t *testing.T) { engine.ServeHTTP(context.Writer, context.Request) if resp.Code != http.StatusOK { - t.Errorf("AllowlistSchedule returned %v, want %v", resp.Code, http.StatusOK) + t.Errorf("CLI returned %v, want %v", resp.Code, http.StatusOK) } if !reflect.DeepEqual(got, want) { - t.Errorf("AllowlistSchedule is %v, want %v", got, want) + t.Errorf("CLI is %v, want %v", got, want) } } diff --git a/router/middleware/compiler.go b/router/middleware/compiler.go index be25a9992..fbd382a4d 100644 --- a/router/middleware/compiler.go +++ b/router/middleware/compiler.go @@ -6,13 +6,18 @@ import ( "github.com/gin-gonic/gin" "github.com/go-vela/server/compiler" + "github.com/go-vela/server/router/middleware/settings" ) // Compiler is a middleware function that initializes the compiler and // attaches to the context of every http.Request. -func Compiler(cli compiler.Engine) gin.HandlerFunc { +func Compiler(comp compiler.Engine) gin.HandlerFunc { return func(c *gin.Context) { - compiler.WithGinContext(c, cli) + s := settings.FromContext(c) + comp.SetSettings(s) + + compiler.WithGinContext(c, comp) + c.Next() } } diff --git a/router/middleware/compiler_test.go b/router/middleware/compiler_test.go index 517de8881..d018b06a9 100644 --- a/router/middleware/compiler_test.go +++ b/router/middleware/compiler_test.go @@ -12,25 +12,50 @@ import ( "github.com/gin-gonic/gin" "github.com/urfave/cli/v2" + "github.com/go-vela/server/api/types/settings" "github.com/go-vela/server/compiler" "github.com/go-vela/server/compiler/native" + sMiddleware "github.com/go-vela/server/router/middleware/settings" ) func TestMiddleware_CompilerNative(t *testing.T) { // setup types - var got compiler.Engine + defaultCloneImage := "target/vela-git" + wantCloneImage := "target/vela-git:latest" + + set := flag.NewFlagSet("", flag.ExitOnError) + set.String("clone-image", defaultCloneImage, "doc") - want, _ := native.New(cli.NewContext(nil, flag.NewFlagSet("test", 0), nil)) + want, _ := native.FromCLIContext(cli.NewContext(nil, set, nil)) + want.SetCloneImage(wantCloneImage) + + var got compiler.Engine + got, _ = native.FromCLIContext(cli.NewContext(nil, set, nil)) // setup context gin.SetMode(gin.TestMode) resp := httptest.NewRecorder() context, engine := gin.CreateTestContext(resp) + + engine.Use(func() gin.HandlerFunc { + return func(c *gin.Context) { + s := settings.Platform{ + Compiler: &settings.Compiler{}, + } + s.SetCloneImage(wantCloneImage) + + sMiddleware.ToContext(c, &s) + + c.Next() + } + }(), + ) + + engine.Use(Compiler(got)) + context.Request, _ = http.NewRequest(http.MethodGet, "/health", nil) - // setup mock server - engine.Use(Compiler(want)) engine.GET("/health", func(c *gin.Context) { got = compiler.FromContext(c) diff --git a/router/middleware/pipeline/pipeline_test.go b/router/middleware/pipeline/pipeline_test.go index 489025859..d7af22303 100644 --- a/router/middleware/pipeline/pipeline_test.go +++ b/router/middleware/pipeline/pipeline_test.go @@ -285,7 +285,7 @@ func TestPipeline_Establish_NoPipeline(t *testing.T) { set := flag.NewFlagSet("test", 0) set.String("clone-image", "target/vela-git:latest", "doc") - comp, err := native.New(cli.NewContext(nil, set, nil)) + comp, err := native.FromCLIContext(cli.NewContext(nil, set, nil)) if err != nil { t.Errorf("unable to create compiler: %v", err) } diff --git a/router/middleware/queue.go b/router/middleware/queue.go index 7f157ccb3..eff077aa0 100644 --- a/router/middleware/queue.go +++ b/router/middleware/queue.go @@ -6,13 +6,18 @@ import ( "github.com/gin-gonic/gin" "github.com/go-vela/server/queue" + "github.com/go-vela/server/router/middleware/settings" ) // Queue is a middleware function that initializes the queue and // attaches to the context of every http.Request. func Queue(q queue.Service) gin.HandlerFunc { return func(c *gin.Context) { + s := settings.FromContext(c) + q.SetSettings(s) + queue.WithGinContext(c, q) + c.Next() } } diff --git a/router/middleware/settings.go b/router/middleware/settings.go new file mode 100644 index 000000000..1e985bf73 --- /dev/null +++ b/router/middleware/settings.go @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: Apache-2.0 + +package middleware + +import ( + "github.com/gin-gonic/gin" + + "github.com/go-vela/server/api/types/settings" + sMiddleware "github.com/go-vela/server/router/middleware/settings" +) + +// Settings is a middleware function that attaches settings +// to the context of every http.Request. +func Settings(s *settings.Platform) gin.HandlerFunc { + return func(c *gin.Context) { + sMiddleware.ToContext(c, s) + + c.Next() + } +} diff --git a/router/middleware/settings/context.go b/router/middleware/settings/context.go new file mode 100644 index 000000000..f5aa5fb62 --- /dev/null +++ b/router/middleware/settings/context.go @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: Apache-2.0 + +package settings + +import ( + "context" + + "github.com/go-vela/server/api/types/settings" +) + +const key = "settings" + +// Setter defines a context that enables setting values. +type Setter interface { + Set(string, interface{}) +} + +// FromContext returns the Settings associated with this context. +func FromContext(c context.Context) *settings.Platform { + value := c.Value(key) + if value == nil { + return nil + } + + s, ok := value.(*settings.Platform) + if !ok { + return nil + } + + return s +} + +// ToContext adds the Settings to this context if it supports +// the Setter interface. +func ToContext(c Setter, s *settings.Platform) { + c.Set(key, s) +} diff --git a/router/middleware/settings/context_test.go b/router/middleware/settings/context_test.go new file mode 100644 index 000000000..0c17b4297 --- /dev/null +++ b/router/middleware/settings/context_test.go @@ -0,0 +1,106 @@ +// SPDX-License-Identifier: Apache-2.0 + +package settings + +import ( + "testing" + + "github.com/gin-gonic/gin" + + "github.com/go-vela/server/api/types/settings" +) + +func TestSettings_FromContext(t *testing.T) { + // setup types + num := int64(1) + cloneImage := "target/vela-git" + + cs := settings.Compiler{ + CloneImage: &cloneImage, + } + + want := &settings.Platform{ + ID: &num, + Compiler: &cs, + } + + // setup context + gin.SetMode(gin.TestMode) + context, _ := gin.CreateTestContext(nil) + context.Set(key, want) + + // run test + got := FromContext(context) + + if got != want { + t.Errorf("FromContext is %v, want %v", got, want) + } +} + +func TestSettings_FromContext_Bad(t *testing.T) { + // setup context + gin.SetMode(gin.TestMode) + context, _ := gin.CreateTestContext(nil) + context.Set(key, nil) + + // run test + got := FromContext(context) + + if got != nil { + t.Errorf("FromContext is %v, want nil", got) + } +} + +func TestSettings_FromContext_WrongType(t *testing.T) { + // setup context + gin.SetMode(gin.TestMode) + context, _ := gin.CreateTestContext(nil) + context.Set(key, 1) + + // run test + got := FromContext(context) + + if got != nil { + t.Errorf("FromContext is %v, want nil", got) + } +} + +func TestSettings_FromContext_Empty(t *testing.T) { + // setup context + gin.SetMode(gin.TestMode) + context, _ := gin.CreateTestContext(nil) + + // run test + got := FromContext(context) + + if got != nil { + t.Errorf("FromContext is %v, want nil", got) + } +} + +func TestSettings_ToContext(t *testing.T) { + // setup types + num := int64(1) + cloneImage := "target/vela-git" + + cs := settings.Compiler{ + CloneImage: &cloneImage, + } + + want := &settings.Platform{ + ID: &num, + Compiler: &cs, + } + + // setup context + gin.SetMode(gin.TestMode) + context, _ := gin.CreateTestContext(nil) + ToContext(context, want) + + // run test + got := context.Value(key) + + if got != want { + t.Errorf("ToContext is %v, want %v", got, want) + } +} diff --git a/router/middleware/settings/doc.go b/router/middleware/settings/doc.go new file mode 100644 index 000000000..2c83d65fc --- /dev/null +++ b/router/middleware/settings/doc.go @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: Apache-2.0 + +// Package settings provides the ability for inserting +// Vela settings resources into or extracting Vela settings +// resources from the middleware chain for the API. +// +// Usage: +// +// import "github.com/go-vela/server/router/middleware/settings" +package settings diff --git a/router/middleware/allowlist_test.go b/router/middleware/settings_test.go similarity index 60% rename from router/middleware/allowlist_test.go rename to router/middleware/settings_test.go index 2bc59623d..d0b5d2b58 100644 --- a/router/middleware/allowlist_test.go +++ b/router/middleware/settings_test.go @@ -9,12 +9,16 @@ import ( "testing" "github.com/gin-gonic/gin" + + "github.com/go-vela/server/api/types/settings" ) -func TestMiddleware_Allowlist(t *testing.T) { +func TestMiddleware_Settings(t *testing.T) { // setup types - got := []string{""} - want := []string{"foobar"} + want := settings.PlatformMockEmpty() + want.SetCloneImage("target/vela-git") + + got := settings.PlatformMockEmpty() // setup context gin.SetMode(gin.TestMode) @@ -24,9 +28,9 @@ func TestMiddleware_Allowlist(t *testing.T) { context.Request, _ = http.NewRequest(http.MethodGet, "/health", nil) // setup mock server - engine.Use(Allowlist(want)) + engine.Use(Settings(&want)) engine.GET("/health", func(c *gin.Context) { - got = c.Value("allowlist").([]string) + got = *c.Value("settings").(*settings.Platform) c.Status(http.StatusOK) }) @@ -35,10 +39,10 @@ func TestMiddleware_Allowlist(t *testing.T) { engine.ServeHTTP(context.Writer, context.Request) if resp.Code != http.StatusOK { - t.Errorf("Secret returned %v, want %v", resp.Code, http.StatusOK) + t.Errorf("Settings returned %v, want %v", resp.Code, http.StatusOK) } if !reflect.DeepEqual(got, want) { - t.Errorf("Secret is %v, want %v", got, want) + t.Errorf("Settings is %v, want %v", got, want) } } diff --git a/router/middleware/worker_test.go b/router/middleware/worker_test.go index 7717d03c5..5f01dc8a4 100644 --- a/router/middleware/worker_test.go +++ b/router/middleware/worker_test.go @@ -37,10 +37,10 @@ func TestMiddleware_Worker(t *testing.T) { engine.ServeHTTP(context.Writer, context.Request) if resp.Code != http.StatusOK { - t.Errorf("Secret returned %v, want %v", resp.Code, http.StatusOK) + t.Errorf("Worker returned %v, want %v", resp.Code, http.StatusOK) } if !reflect.DeepEqual(got, want) { - t.Errorf("Secret is %v, want %v", got, want) + t.Errorf("Worker is %v, want %v", got, want) } } From 6a9e5098ff3648f58cd2cf9a9538c8e7a5430af4 Mon Sep 17 00:00:00 2001 From: Taylor Mapes Date: Mon, 13 May 2024 09:19:49 -0500 Subject: [PATCH 51/71] chore: Correct the register worker token swagger path (#1128) --- api/admin/worker.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/admin/worker.go b/api/admin/worker.go index e09d0b046..82d7e9b5c 100644 --- a/api/admin/worker.go +++ b/api/admin/worker.go @@ -16,7 +16,7 @@ import ( "github.com/go-vela/types/library" ) -// swagger:operation POST /api/v1/admin/workers/{worker}/register-token admin RegisterToken +// swagger:operation POST /api/v1/admin/workers/{worker}/register admin RegisterToken // // Get a worker registration token // From 93571138ad3f66fc12149b645b0ba78b2efb12d7 Mon Sep 17 00:00:00 2001 From: dave vader <48764154+plyr4@users.noreply.github.com> Date: Mon, 13 May 2024 09:34:05 -0500 Subject: [PATCH 52/71] chore: rename settings FromAPI constructor (#1126) Co-authored-by: Easton Crupper <65553218+ecrupper@users.noreply.github.com> --- database/settings/create.go | 2 +- database/settings/update.go | 2 +- database/types/settings.go | 4 ++-- database/types/settings_test.go | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/database/settings/create.go b/database/settings/create.go index 0e86f7fbc..7775fb4c9 100644 --- a/database/settings/create.go +++ b/database/settings/create.go @@ -14,7 +14,7 @@ func (e *engine) CreateSettings(_ context.Context, s *settings.Platform) (*setti e.logger.Tracef("creating platform settings in the database with %v", s.String()) // cast the api type to database type - settings := types.FromAPI(s) + settings := types.SettingsFromAPI(s) // validate the necessary fields are populated err := settings.Validate() diff --git a/database/settings/update.go b/database/settings/update.go index b72b4d543..c8a3e1679 100644 --- a/database/settings/update.go +++ b/database/settings/update.go @@ -14,7 +14,7 @@ func (e *engine) UpdateSettings(_ context.Context, s *settings.Platform) (*setti e.logger.Trace("updating platform settings in the database") // cast the api type to database type - dbS := types.FromAPI(s) + dbS := types.SettingsFromAPI(s) // validate the necessary fields are populated err := dbS.Validate() diff --git a/database/types/settings.go b/database/types/settings.go index f17bac54b..ea0d47a2a 100644 --- a/database/types/settings.go +++ b/database/types/settings.go @@ -194,9 +194,9 @@ func (ps *Platform) Validate() error { return nil } -// FromAPI converts the API Settings type +// SettingsFromAPI converts the API Settings type // to a database Settings type. -func FromAPI(s *settings.Platform) *Platform { +func SettingsFromAPI(s *settings.Platform) *Platform { settings := &Platform{ ID: sql.NullInt64{Int64: s.GetID(), Valid: true}, Compiler: Compiler{ diff --git a/database/types/settings_test.go b/database/types/settings_test.go index 973e5d88d..40285eb34 100644 --- a/database/types/settings_test.go +++ b/database/types/settings_test.go @@ -166,7 +166,7 @@ func TestTypes_Platform_PlatformFromAPI(t *testing.T) { want := testPlatform() // run test - got := FromAPI(s) + got := SettingsFromAPI(s) if !reflect.DeepEqual(got, want) { t.Errorf("PlatformFromAPI is %v, want %v", got, want) From 927dc715e59f0e14704b0a04117c3d04fb656d68 Mon Sep 17 00:00:00 2001 From: dave vader <48764154+plyr4@users.noreply.github.com> Date: Mon, 13 May 2024 16:39:26 -0500 Subject: [PATCH 53/71] fix: platform settings yaml tags (#1129) --- api/types/settings/compiler.go | 6 +++--- api/types/settings/platform.go | 14 +++++++------- api/types/settings/queue.go | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/api/types/settings/compiler.go b/api/types/settings/compiler.go index a18a31401..147cade94 100644 --- a/api/types/settings/compiler.go +++ b/api/types/settings/compiler.go @@ -5,9 +5,9 @@ package settings import "fmt" type Compiler struct { - CloneImage *string `json:"clone_image,omitempty"` - TemplateDepth *int `json:"template_depth,omitempty"` - StarlarkExecLimit *uint64 `json:"starlark_exec_limit,omitempty"` + CloneImage *string `json:"clone_image,omitempty" yaml:"clone_image,omitempty"` + TemplateDepth *int `json:"template_depth,omitempty" yaml:"template_depth,omitempty"` + StarlarkExecLimit *uint64 `json:"starlark_exec_limit,omitempty" yaml:"starlark_exec_limit,omitempty"` } // GetCloneImage returns the CloneImage field. diff --git a/api/types/settings/platform.go b/api/types/settings/platform.go index f72698b66..b494c8faa 100644 --- a/api/types/settings/platform.go +++ b/api/types/settings/platform.go @@ -11,13 +11,13 @@ import ( // swagger:model Platform type Platform struct { ID *int64 `json:"id"` - *Queue `json:"queue"` - *Compiler `json:"compiler"` - RepoAllowlist *[]string `json:"repo_allowlist"` - ScheduleAllowlist *[]string `json:"schedule_allowlist"` - CreatedAt *int64 `json:"created_at,omitempty"` - UpdatedAt *int64 `json:"updated_at,omitempty"` - UpdatedBy *string `json:"updated_by,omitempty"` + *Compiler `json:"compiler,omitempty" yaml:"compiler,omitempty"` + *Queue `json:"queue,omitempty" yaml:"queue,omitempty"` + RepoAllowlist *[]string `json:"repo_allowlist,omitempty" yaml:"repo_allowlist,omitempty"` + ScheduleAllowlist *[]string `json:"schedule_allowlist,omitempty" yaml:"schedule_allowlist,omitempty"` + CreatedAt *int64 `json:"created_at,omitempty" yaml:"created_at,omitempty"` + UpdatedAt *int64 `json:"updated_at,omitempty" yaml:"updated_at,omitempty"` + UpdatedBy *string `json:"updated_by,omitempty" yaml:"updated_by,omitempty"` } // GetID returns the ID field. diff --git a/api/types/settings/queue.go b/api/types/settings/queue.go index 9bf54dfd1..e813b18ae 100644 --- a/api/types/settings/queue.go +++ b/api/types/settings/queue.go @@ -5,7 +5,7 @@ package settings import "fmt" type Queue struct { - Routes *[]string `json:"routes,omitempty"` + Routes *[]string `json:"routes,omitempty" yaml:"routes,omitempty"` } // GetRoutes returns the Routes field. From 4a31c1e4ca8779a8298e488235b5a8a5929d5493 Mon Sep 17 00:00:00 2001 From: dave vader <48764154+plyr4@users.noreply.github.com> Date: Thu, 16 May 2024 10:17:32 -0500 Subject: [PATCH 54/71] fix(settings): missing fields in api conversion and func renames (#1130) --- api/admin/settings.go | 15 ++++++++----- api/types/settings/platform.go | 35 ++++++++++++++++++++++------- api/types/settings/platform_test.go | 2 +- cmd/vela-server/server.go | 10 ++------- 4 files changed, 39 insertions(+), 23 deletions(-) diff --git a/api/admin/settings.go b/api/admin/settings.go index 0b067372b..f567c4263 100644 --- a/api/admin/settings.go +++ b/api/admin/settings.go @@ -119,7 +119,7 @@ func UpdateSettings(c *gin.Context) { // duplicate settings to not alter the shared pointer _s := new(settings.Platform) - _s.Update(s) + _s.FromSettings(s) // ensure we update the singleton record _s.SetID(1) @@ -254,18 +254,21 @@ func RestoreSettings(c *gin.Context) { return } - s.SetUpdatedAt(time.Now().UTC().Unix()) - s.SetUpdatedBy(u.GetName()) + // initialize a new settings record + _s := settings.FromCLIContext(cliCtx) + + _s.SetUpdatedAt(time.Now().UTC().Unix()) + _s.SetUpdatedBy(u.GetName()) // read in defaults supplied from the cli runtime compilerSettings := compiler.GetSettings() - s.SetCompiler(compilerSettings) + _s.SetCompiler(compilerSettings) queueSettings := queue.GetSettings() - s.SetQueue(queueSettings) + _s.SetQueue(queueSettings) // send API call to update the settings - s, err = database.FromContext(c).UpdateSettings(ctx, s) + s, err = database.FromContext(c).UpdateSettings(ctx, _s) if err != nil { retErr := fmt.Errorf("unable to update (restore) settings: %w", err) diff --git a/api/types/settings/platform.go b/api/types/settings/platform.go index b494c8faa..ff7c58ef3 100644 --- a/api/types/settings/platform.go +++ b/api/types/settings/platform.go @@ -4,6 +4,8 @@ package settings import ( "fmt" + + "github.com/urfave/cli/v2" ) // Platform is the API representation of platform settingps. @@ -20,6 +22,19 @@ type Platform struct { UpdatedBy *string `json:"updated_by,omitempty" yaml:"updated_by,omitempty"` } +// FromCLIContext returns a new Platform record from a cli context. +func FromCLIContext(c *cli.Context) *Platform { + ps := new(Platform) + + // set repos permitted to be added + ps.SetRepoAllowlist(c.StringSlice("vela-repo-allowlist")) + + // set repos permitted to use schedules + ps.SetScheduleAllowlist(c.StringSlice("vela-schedule-allowlist")) + + return ps +} + // GetID returns the ID field. // // When the provided Platform type is nil, or the field within @@ -228,21 +243,25 @@ func (ps *Platform) SetUpdatedBy(v string) { ps.UpdatedBy = &v } -// Update takes another settings record and updates the internal fields, intended -// to be used when the refreshing settings record shared across the server. -func (ps *Platform) Update(newSettingps *Platform) { +// FromSettings takes another settings record and updates the internal fields, +// used when the updating settings and refreshing the record shared across the server. +func (ps *Platform) FromSettings(_ps *Platform) { if ps == nil { return } - if newSettingps == nil { + if _ps == nil { return } - ps.SetCompiler(newSettingps.GetCompiler()) - ps.SetQueue(newSettingps.GetQueue()) - ps.SetRepoAllowlist(newSettingps.GetRepoAllowlist()) - ps.SetScheduleAllowlist(newSettingps.GetScheduleAllowlist()) + ps.SetCompiler(_ps.GetCompiler()) + ps.SetQueue(_ps.GetQueue()) + ps.SetRepoAllowlist(_ps.GetRepoAllowlist()) + ps.SetScheduleAllowlist(_ps.GetScheduleAllowlist()) + + ps.SetCreatedAt(_ps.GetCreatedAt()) + ps.SetUpdatedAt(_ps.GetUpdatedAt()) + ps.SetUpdatedBy(_ps.GetUpdatedBy()) } // String implements the Stringer interface for the Platform type. diff --git a/api/types/settings/platform_test.go b/api/types/settings/platform_test.go index 56c9cec7b..059c7b574 100644 --- a/api/types/settings/platform_test.go +++ b/api/types/settings/platform_test.go @@ -121,7 +121,7 @@ func TestTypes_Platform_Update(t *testing.T) { // run tests for _, test := range tests { - test.platform.Update(test.want) + test.platform.FromSettings(test.want) if diff := cmp.Diff(test.want, test.platform); diff != "" { t.Errorf("(Update: -want +got):\n%s", diff) diff --git a/cmd/vela-server/server.go b/cmd/vela-server/server.go index bae9ec326..dd5b6d6c6 100644 --- a/cmd/vela-server/server.go +++ b/cmd/vela-server/server.go @@ -119,7 +119,7 @@ func server(c *cli.Context) error { logrus.Info("creating initial platform settings") // create initial settings record - ps = new(settings.Platform) + ps = settings.FromCLIContext(c) // singleton record ID should always be 1 ps.SetID(1) @@ -135,12 +135,6 @@ func server(c *cli.Context) error { queueSettings := queue.GetSettings() ps.SetQueue(queueSettings) - // set repos permitted to be added - ps.SetRepoAllowlist(c.StringSlice("vela-repo-allowlist")) - - // set repos permitted to use schedules - ps.SetScheduleAllowlist(c.StringSlice("vela-schedule-allowlist")) - // create the settings record in the database _, err = database.CreateSettings(context.Background(), ps) if err != nil { @@ -252,7 +246,7 @@ func server(c *cli.Context) error { } // update the internal fields for the shared settings record - ps.Update(newSettings) + ps.FromSettings(newSettings) } }) From 178e678a82130df48e2bd1c5a86050e35972a12b Mon Sep 17 00:00:00 2001 From: dave vader <48764154+plyr4@users.noreply.github.com> Date: Thu, 16 May 2024 10:52:23 -0500 Subject: [PATCH 55/71] fix(settings): swagger missing 401 responses (#1132) --- api/admin/settings.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/api/admin/settings.go b/api/admin/settings.go index f567c4263..f04109680 100644 --- a/api/admin/settings.go +++ b/api/admin/settings.go @@ -36,6 +36,10 @@ import ( // type: json // schema: // "$ref": "#/definitions/Platform" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" // '404': // description: Unable to retrieve settings // schema: @@ -88,6 +92,10 @@ func GetSettings(c *gin.Context) { // description: Unable to update settings — bad request // schema: // "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" // '404': // description: Unable to retrieve platform settings to update // schema: @@ -206,6 +214,10 @@ func UpdateSettings(c *gin.Context) { // type: json // schema: // "$ref": "#/definitions/Platform" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" // '404': // description: Unable to retrieve settings to restore // schema: From c35d01e017d10a96af292c08d5617a1cdefac492 Mon Sep 17 00:00:00 2001 From: Win San Date: Fri, 17 May 2024 15:02:32 -0500 Subject: [PATCH 56/71] enhance(schedule): add next run field to schedule (#1131) * Add next run field to Schedule * Lint code * Update integration test * Populate next run field in ToAPI * Handle err from gronx NextTickAfter * Fix conditional --- api/types/schedule.go | 29 ++++++++++++++++++++++++++ api/types/schedule_test.go | 12 +++++++++++ database/integration_test.go | 9 ++++++++ database/schedule/count_active_test.go | 10 +++++++++ database/schedule/count_repo_test.go | 10 +++++++++ database/schedule/count_test.go | 10 +++++++++ database/schedule/create_test.go | 6 ++++++ database/schedule/delete_test.go | 6 ++++++ database/schedule/get_repo_test.go | 6 ++++++ database/schedule/get_test.go | 6 ++++++ database/schedule/list_active_test.go | 10 +++++++++ database/schedule/list_repo_test.go | 10 +++++++++ database/schedule/list_test.go | 10 +++++++++ database/schedule/update.go | 2 +- database/schedule/update_test.go | 10 +++++++++ database/types/schedule.go | 10 +++++++++ database/types/schedule_test.go | 6 ++++++ mock/server/schedule.go | 9 +++++--- 18 files changed, 167 insertions(+), 4 deletions(-) diff --git a/api/types/schedule.go b/api/types/schedule.go index c21568a27..2fb174779 100644 --- a/api/types/schedule.go +++ b/api/types/schedule.go @@ -22,6 +22,7 @@ type Schedule struct { ScheduledAt *int64 `json:"scheduled_at,omitempty"` Branch *string `json:"branch,omitempty"` Error *string `json:"error,omitempty"` + NextRun *int64 `json:"next_run,omitempty"` } // GetID returns the ID field. @@ -180,6 +181,19 @@ func (s *Schedule) GetError() string { return *s.Error } +// GetNextRun returns the NextRun field. +// +// When the provided Schedule type is nil, or the field within +// the type is nil, it returns the zero value for the field. +func (s *Schedule) GetNextRun() int64 { + // return zero value if Schedule type or NextRun field is nil + if s == nil || s.NextRun == nil { + return 0 + } + + return *s.NextRun +} + // SetID sets the ID field. // // When the provided Schedule type is nil, it @@ -336,6 +350,19 @@ func (s *Schedule) SetError(err string) { s.Error = &err } +// SetNextRun sets the NextRun field. +// +// When the provided Schedule type is nil, it +// will set nothing and immediately return. +func (s *Schedule) SetNextRun(nextRun int64) { + // return if Schedule type is nil + if s == nil { + return + } + + s.NextRun = &nextRun +} + // String implements the Stringer interface for the Schedule type. func (s *Schedule) String() string { return fmt.Sprintf(`{ @@ -351,6 +378,7 @@ func (s *Schedule) String() string { UpdatedBy: %s, Branch: %s, Error: %s, + NextRun: %d, }`, s.GetActive(), s.GetCreatedAt(), @@ -364,5 +392,6 @@ func (s *Schedule) String() string { s.GetUpdatedBy(), s.GetBranch(), s.GetError(), + s.GetNextRun(), ) } diff --git a/api/types/schedule_test.go b/api/types/schedule_test.go index ca5bb09db..4d6becdbf 100644 --- a/api/types/schedule_test.go +++ b/api/types/schedule_test.go @@ -81,6 +81,10 @@ func TestTypes_Schedule_Getters(t *testing.T) { if test.schedule.GetError() != test.want.GetError() { t.Errorf("GetError is %v, want %v", test.schedule.GetError(), test.want.GetError()) } + + if test.schedule.GetNextRun() != test.want.GetNextRun() { + t.Errorf("GetNextRun is %v, want %v", test.schedule.GetNextRun(), test.want.GetNextRun()) + } }) } } @@ -123,6 +127,7 @@ func TestTypes_Schedule_Setters(t *testing.T) { test.schedule.SetScheduledAt(test.want.GetScheduledAt()) test.schedule.SetBranch(test.want.GetBranch()) test.schedule.SetError(test.want.GetError()) + test.schedule.SetNextRun(test.want.GetNextRun()) if test.schedule.GetID() != test.want.GetID() { t.Errorf("SetID is %v, want %v", test.schedule.GetID(), test.want.GetID()) @@ -171,6 +176,10 @@ func TestTypes_Schedule_Setters(t *testing.T) { if test.schedule.GetError() != test.want.GetError() { t.Errorf("SetError is %v, want %v", test.schedule.GetError(), test.want.GetError()) } + + if test.schedule.GetNextRun() != test.want.GetNextRun() { + t.Errorf("SetNextRun is %v, want %v", test.schedule.GetNextRun(), test.want.GetNextRun()) + } }) } } @@ -191,6 +200,7 @@ func TestTypes_Schedule_String(t *testing.T) { UpdatedBy: %s, Branch: %s, Error: %s, + NextRun: %d, }`, s.GetActive(), s.GetCreatedAt(), @@ -204,6 +214,7 @@ func TestTypes_Schedule_String(t *testing.T) { s.GetUpdatedBy(), s.GetBranch(), s.GetError(), + s.GetNextRun(), ) got := s.String() @@ -227,6 +238,7 @@ func testSchedule() *Schedule { s.SetScheduledAt(time.Now().Add(time.Hour * 2).UTC().Unix()) s.SetBranch("main") s.SetError("unable to trigger build for schedule nightly: unknown character") + s.SetNextRun(time.Now().Add((time.Hour * 2) + 24).UTC().Unix()) return s } diff --git a/database/integration_test.go b/database/integration_test.go index db70091b3..e1bdcffd3 100644 --- a/database/integration_test.go +++ b/database/integration_test.go @@ -10,6 +10,7 @@ import ( "testing" "time" + "github.com/adhocore/gronx" "github.com/google/go-cmp/cmp" api "github.com/go-vela/server/api/types" @@ -2547,6 +2548,9 @@ func newResources() *Resources { pipelineTwo.SetTemplates(false) pipelineTwo.SetData([]byte("version: 1")) + currTime := time.Now().UTC() + nextTime, _ := gronx.NextTickAfter("0 0 * * *", currTime, false) + scheduleOne := new(api.Schedule) scheduleOne.SetID(1) scheduleOne.SetRepo(repoOne) @@ -2560,6 +2564,10 @@ func newResources() *Resources { scheduleOne.SetScheduledAt(time.Now().Add(time.Hour * 2).UTC().Unix()) scheduleOne.SetBranch("main") scheduleOne.SetError("no version: YAML property provided") + scheduleOne.SetNextRun(nextTime.Unix()) + + currTime = time.Now().UTC() + nextTime, _ = gronx.NextTickAfter("0 * * * *", currTime, false) scheduleTwo := new(api.Schedule) scheduleTwo.SetID(2) @@ -2574,6 +2582,7 @@ func newResources() *Resources { scheduleTwo.SetScheduledAt(time.Now().Add(time.Hour * 2).UTC().Unix()) scheduleTwo.SetBranch("main") scheduleTwo.SetError("no version: YAML property provided") + scheduleTwo.SetNextRun(nextTime.Unix()) secretOrg := new(library.Secret) secretOrg.SetID(1) diff --git a/database/schedule/count_active_test.go b/database/schedule/count_active_test.go index 6c496965f..a94af19c6 100644 --- a/database/schedule/count_active_test.go +++ b/database/schedule/count_active_test.go @@ -5,8 +5,10 @@ package schedule import ( "context" "testing" + "time" "github.com/DATA-DOG/go-sqlmock" + "github.com/adhocore/gronx" "github.com/google/go-cmp/cmp" api "github.com/go-vela/server/api/types" @@ -49,6 +51,9 @@ func TestSchedule_Engine_CountActiveSchedules(t *testing.T) { _repo.SetPreviousName("") _repo.SetApproveBuild(constants.ApproveNever) + currTime := time.Now().UTC() + nextTime, _ := gronx.NextTickAfter("0 0 * * *", currTime, false) + _scheduleOne := testutils.APISchedule() _scheduleOne.SetID(1) _scheduleOne.SetRepo(_repo) @@ -62,6 +67,10 @@ func TestSchedule_Engine_CountActiveSchedules(t *testing.T) { _scheduleOne.SetScheduledAt(2013476291) _scheduleOne.SetBranch("main") _scheduleOne.SetError("no version: YAML property provided") + _scheduleOne.SetNextRun(nextTime.Unix()) + + currTime = time.Now().UTC() + nextTime, _ = gronx.NextTickAfter("0 * * * *", currTime, false) _scheduleTwo := testutils.APISchedule() _scheduleTwo.SetID(2) @@ -76,6 +85,7 @@ func TestSchedule_Engine_CountActiveSchedules(t *testing.T) { _scheduleTwo.SetScheduledAt(2013476291) _scheduleTwo.SetBranch("main") _scheduleTwo.SetError("no version: YAML property provided") + _scheduleTwo.SetNextRun(nextTime.Unix()) _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() diff --git a/database/schedule/count_repo_test.go b/database/schedule/count_repo_test.go index 360894fc1..2b95abd10 100644 --- a/database/schedule/count_repo_test.go +++ b/database/schedule/count_repo_test.go @@ -5,8 +5,10 @@ package schedule import ( "context" "testing" + "time" "github.com/DATA-DOG/go-sqlmock" + "github.com/adhocore/gronx" "github.com/google/go-cmp/cmp" api "github.com/go-vela/server/api/types" @@ -49,6 +51,9 @@ func TestSchedule_Engine_CountSchedulesForRepo(t *testing.T) { _repo.SetPreviousName("") _repo.SetApproveBuild(constants.ApproveNever) + currTime := time.Now().UTC() + nextTime, _ := gronx.NextTickAfter("0 0 * * *", currTime, false) + _scheduleOne := testutils.APISchedule() _scheduleOne.SetID(1) _scheduleOne.SetRepo(_repo) @@ -62,6 +67,10 @@ func TestSchedule_Engine_CountSchedulesForRepo(t *testing.T) { _scheduleOne.SetScheduledAt(2013476291) _scheduleOne.SetBranch("main") _scheduleOne.SetError("no version: YAML property provided") + _scheduleOne.SetNextRun(nextTime.Unix()) + + currTime = time.Now().UTC() + nextTime, _ = gronx.NextTickAfter("0 * * * *", currTime, false) _scheduleTwo := testutils.APISchedule() _scheduleTwo.SetID(2) @@ -76,6 +85,7 @@ func TestSchedule_Engine_CountSchedulesForRepo(t *testing.T) { _scheduleTwo.SetScheduledAt(2013476291) _scheduleTwo.SetBranch("main") _scheduleTwo.SetError("no version: YAML property provided") + _scheduleTwo.SetNextRun(nextTime.Unix()) _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() diff --git a/database/schedule/count_test.go b/database/schedule/count_test.go index 0338ff7fb..13be42a30 100644 --- a/database/schedule/count_test.go +++ b/database/schedule/count_test.go @@ -5,8 +5,10 @@ package schedule import ( "context" "testing" + "time" "github.com/DATA-DOG/go-sqlmock" + "github.com/adhocore/gronx" "github.com/google/go-cmp/cmp" api "github.com/go-vela/server/api/types" @@ -49,6 +51,9 @@ func TestSchedule_Engine_CountSchedules(t *testing.T) { _repo.SetPreviousName("") _repo.SetApproveBuild(constants.ApproveNever) + currTime := time.Now().UTC() + nextTime, _ := gronx.NextTickAfter("0 0 * * *", currTime, false) + _scheduleOne := testutils.APISchedule() _scheduleOne.SetID(1) _scheduleOne.SetRepo(_repo) @@ -62,6 +67,10 @@ func TestSchedule_Engine_CountSchedules(t *testing.T) { _scheduleOne.SetScheduledAt(2013476291) _scheduleOne.SetBranch("main") _scheduleOne.SetError("no version: YAML property provided") + _scheduleOne.SetNextRun(nextTime.Unix()) + + currTime = time.Now().UTC() + nextTime, _ = gronx.NextTickAfter("0 * * * *", currTime, false) _scheduleTwo := testutils.APISchedule() _scheduleTwo.SetID(2) @@ -76,6 +85,7 @@ func TestSchedule_Engine_CountSchedules(t *testing.T) { _scheduleTwo.SetScheduledAt(2013476291) _scheduleTwo.SetBranch("main") _scheduleTwo.SetError("no version: YAML property provided") + _scheduleTwo.SetNextRun(nextTime.Unix()) _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() diff --git a/database/schedule/create_test.go b/database/schedule/create_test.go index 7858d4014..ac028099e 100644 --- a/database/schedule/create_test.go +++ b/database/schedule/create_test.go @@ -5,8 +5,10 @@ package schedule import ( "context" "testing" + "time" "github.com/DATA-DOG/go-sqlmock" + "github.com/adhocore/gronx" "github.com/google/go-cmp/cmp" api "github.com/go-vela/server/api/types" @@ -49,6 +51,9 @@ func TestSchedule_Engine_CreateSchedule(t *testing.T) { _repo.SetPreviousName("") _repo.SetApproveBuild(constants.ApproveNever) + currTime := time.Now().UTC() + nextTime, _ := gronx.NextTickAfter("0 0 * * *", currTime, false) + _schedule := testutils.APISchedule() _schedule.SetID(1) _schedule.SetRepo(_repo) @@ -62,6 +67,7 @@ func TestSchedule_Engine_CreateSchedule(t *testing.T) { _schedule.SetScheduledAt(2013476291) _schedule.SetBranch("main") _schedule.SetError("no version: YAML property provided") + _schedule.SetNextRun(nextTime.Unix()) _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() diff --git a/database/schedule/delete_test.go b/database/schedule/delete_test.go index d633bf38e..971377d92 100644 --- a/database/schedule/delete_test.go +++ b/database/schedule/delete_test.go @@ -5,8 +5,10 @@ package schedule import ( "context" "testing" + "time" "github.com/DATA-DOG/go-sqlmock" + "github.com/adhocore/gronx" api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database/testutils" @@ -48,6 +50,9 @@ func TestSchedule_Engine_DeleteSchedule(t *testing.T) { _repo.SetPreviousName("") _repo.SetApproveBuild(constants.ApproveNever) + currTime := time.Now().UTC() + nextTime, _ := gronx.NextTickAfter("0 0 * * *", currTime, false) + _schedule := testutils.APISchedule() _schedule.SetID(1) _schedule.SetRepo(_repo) @@ -61,6 +66,7 @@ func TestSchedule_Engine_DeleteSchedule(t *testing.T) { _schedule.SetScheduledAt(2013476291) _schedule.SetBranch("main") _schedule.SetError("no version: YAML property provided") + _schedule.SetNextRun(nextTime.Unix()) _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() diff --git a/database/schedule/get_repo_test.go b/database/schedule/get_repo_test.go index 40a92a761..704443112 100644 --- a/database/schedule/get_repo_test.go +++ b/database/schedule/get_repo_test.go @@ -5,8 +5,10 @@ package schedule import ( "context" "testing" + "time" "github.com/DATA-DOG/go-sqlmock" + "github.com/adhocore/gronx" "github.com/google/go-cmp/cmp" api "github.com/go-vela/server/api/types" @@ -50,6 +52,9 @@ func TestSchedule_Engine_GetScheduleForRepo(t *testing.T) { _repo.SetPreviousName("") _repo.SetApproveBuild(constants.ApproveNever) + currTime := time.Now().UTC() + nextTime, _ := gronx.NextTickAfter("0 0 * * *", currTime, false) + _schedule := testutils.APISchedule() _schedule.SetID(1) _schedule.SetRepo(_repo) @@ -63,6 +68,7 @@ func TestSchedule_Engine_GetScheduleForRepo(t *testing.T) { _schedule.SetScheduledAt(2013476291) _schedule.SetBranch("main") _schedule.SetError("no version: YAML property provided") + _schedule.SetNextRun(nextTime.Unix()) _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() diff --git a/database/schedule/get_test.go b/database/schedule/get_test.go index 2f5b81952..5d6f44fca 100644 --- a/database/schedule/get_test.go +++ b/database/schedule/get_test.go @@ -5,8 +5,10 @@ package schedule import ( "context" "testing" + "time" "github.com/DATA-DOG/go-sqlmock" + "github.com/adhocore/gronx" "github.com/google/go-cmp/cmp" api "github.com/go-vela/server/api/types" @@ -50,6 +52,9 @@ func TestSchedule_Engine_GetSchedule(t *testing.T) { _repo.SetPreviousName("") _repo.SetApproveBuild(constants.ApproveNever) + currTime := time.Now().UTC() + nextTime, _ := gronx.NextTickAfter("0 0 * * *", currTime, false) + _schedule := testutils.APISchedule() _schedule.SetID(1) _schedule.SetRepo(_repo) @@ -63,6 +68,7 @@ func TestSchedule_Engine_GetSchedule(t *testing.T) { _schedule.SetScheduledAt(2013476291) _schedule.SetBranch("main") _schedule.SetError("no version: YAML property provided") + _schedule.SetNextRun(nextTime.Unix()) _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() diff --git a/database/schedule/list_active_test.go b/database/schedule/list_active_test.go index e3179e020..385cdf595 100644 --- a/database/schedule/list_active_test.go +++ b/database/schedule/list_active_test.go @@ -5,8 +5,10 @@ package schedule import ( "context" "testing" + "time" "github.com/DATA-DOG/go-sqlmock" + "github.com/adhocore/gronx" "github.com/google/go-cmp/cmp" api "github.com/go-vela/server/api/types" @@ -50,6 +52,9 @@ func TestSchedule_Engine_ListActiveSchedules(t *testing.T) { _repo.SetPreviousName("") _repo.SetApproveBuild(constants.ApproveNever) + currTime := time.Now().UTC() + nextTime, _ := gronx.NextTickAfter("0 0 * * *", currTime, false) + _scheduleOne := testutils.APISchedule() _scheduleOne.SetID(1) _scheduleOne.SetRepo(_repo) @@ -63,6 +68,10 @@ func TestSchedule_Engine_ListActiveSchedules(t *testing.T) { _scheduleOne.SetScheduledAt(2013476291) _scheduleOne.SetBranch("main") _scheduleOne.SetError("no version: YAML property provided") + _scheduleOne.SetNextRun(nextTime.Unix()) + + currTime = time.Now().UTC() + nextTime, _ = gronx.NextTickAfter("0 * * * *", currTime, false) _scheduleTwo := testutils.APISchedule() _scheduleTwo.SetID(2) @@ -77,6 +86,7 @@ func TestSchedule_Engine_ListActiveSchedules(t *testing.T) { _scheduleTwo.SetScheduledAt(2013476291) _scheduleTwo.SetBranch("main") _scheduleTwo.SetError("no version: YAML property provided") + _scheduleTwo.SetNextRun(nextTime.Unix()) _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() diff --git a/database/schedule/list_repo_test.go b/database/schedule/list_repo_test.go index 43b1fcf58..0719e6b68 100644 --- a/database/schedule/list_repo_test.go +++ b/database/schedule/list_repo_test.go @@ -5,8 +5,10 @@ package schedule import ( "context" "testing" + "time" "github.com/DATA-DOG/go-sqlmock" + "github.com/adhocore/gronx" "github.com/google/go-cmp/cmp" api "github.com/go-vela/server/api/types" @@ -50,6 +52,9 @@ func TestSchedule_Engine_ListSchedulesForRepo(t *testing.T) { _repo.SetPreviousName("") _repo.SetApproveBuild(constants.ApproveNever) + currTime := time.Now().UTC() + nextTime, _ := gronx.NextTickAfter("0 0 * * *", currTime, false) + _scheduleOne := testutils.APISchedule() _scheduleOne.SetID(1) _scheduleOne.SetRepo(_repo) @@ -63,6 +68,10 @@ func TestSchedule_Engine_ListSchedulesForRepo(t *testing.T) { _scheduleOne.SetScheduledAt(2013476291) _scheduleOne.SetBranch("main") _scheduleOne.SetError("no version: YAML property provided") + _scheduleOne.SetNextRun(nextTime.Unix()) + + currTime = time.Now().UTC() + nextTime, _ = gronx.NextTickAfter("0 * * * *", currTime, false) _scheduleTwo := testutils.APISchedule() _scheduleTwo.SetID(2) @@ -77,6 +86,7 @@ func TestSchedule_Engine_ListSchedulesForRepo(t *testing.T) { _scheduleTwo.SetScheduledAt(2013476291) _scheduleTwo.SetBranch("main") _scheduleTwo.SetError("no version: YAML property provided") + _scheduleTwo.SetNextRun(nextTime.Unix()) _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() diff --git a/database/schedule/list_test.go b/database/schedule/list_test.go index 8338c5dc1..b699a12c4 100644 --- a/database/schedule/list_test.go +++ b/database/schedule/list_test.go @@ -5,8 +5,10 @@ package schedule import ( "context" "testing" + "time" "github.com/DATA-DOG/go-sqlmock" + "github.com/adhocore/gronx" "github.com/google/go-cmp/cmp" api "github.com/go-vela/server/api/types" @@ -50,6 +52,9 @@ func TestSchedule_Engine_ListSchedules(t *testing.T) { _repo.SetPreviousName("") _repo.SetApproveBuild(constants.ApproveNever) + currTime := time.Now().UTC() + nextTime, _ := gronx.NextTickAfter("0 0 * * *", currTime, false) + _scheduleOne := testutils.APISchedule() _scheduleOne.SetID(1) _scheduleOne.SetRepo(_repo) @@ -63,6 +68,10 @@ func TestSchedule_Engine_ListSchedules(t *testing.T) { _scheduleOne.SetScheduledAt(2013476291) _scheduleOne.SetBranch("main") _scheduleOne.SetError("no version: YAML property provided") + _scheduleOne.SetNextRun(nextTime.Unix()) + + currTime = time.Now().UTC() + nextTime, _ = gronx.NextTickAfter("0 * * * *", currTime, false) _scheduleTwo := testutils.APISchedule() _scheduleTwo.SetID(2) @@ -77,6 +86,7 @@ func TestSchedule_Engine_ListSchedules(t *testing.T) { _scheduleTwo.SetScheduledAt(2013476291) _scheduleTwo.SetBranch("main") _scheduleTwo.SetError("no version: YAML property provided") + _scheduleTwo.SetNextRun(nextTime.Unix()) _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() diff --git a/database/schedule/update.go b/database/schedule/update.go index 790ef89f3..7dcc1256d 100644 --- a/database/schedule/update.go +++ b/database/schedule/update.go @@ -41,7 +41,7 @@ func (e *engine) UpdateSchedule(ctx context.Context, s *api.Schedule, fields boo return nil, err } - // set repo to provided repo if creation successful + // set repo to provided repo if update successful result := schedule.ToAPI() result.SetRepo(s.GetRepo()) diff --git a/database/schedule/update_test.go b/database/schedule/update_test.go index f0b1ea2c0..c936b2ab1 100644 --- a/database/schedule/update_test.go +++ b/database/schedule/update_test.go @@ -5,8 +5,10 @@ package schedule import ( "context" "testing" + "time" "github.com/DATA-DOG/go-sqlmock" + "github.com/adhocore/gronx" "github.com/google/go-cmp/cmp" api "github.com/go-vela/server/api/types" @@ -49,6 +51,9 @@ func TestSchedule_Engine_UpdateSchedule_Config(t *testing.T) { _repo.SetPreviousName("") _repo.SetApproveBuild(constants.ApproveNever) + currTime := time.Now().UTC() + nextTime, _ := gronx.NextTickAfter("0 0 * * *", currTime, false) + _schedule := testutils.APISchedule() _schedule.SetID(1) _schedule.SetRepo(_repo) @@ -62,6 +67,7 @@ func TestSchedule_Engine_UpdateSchedule_Config(t *testing.T) { _schedule.SetScheduledAt(2013476291) _schedule.SetBranch("main") _schedule.SetError("no version: YAML property provided") + _schedule.SetNextRun(nextTime.Unix()) _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() @@ -159,6 +165,9 @@ func TestSchedule_Engine_UpdateSchedule_NotConfig(t *testing.T) { _repo.SetPreviousName("") _repo.SetApproveBuild(constants.ApproveNever) + currTime := time.Now().UTC() + nextTime, _ := gronx.NextTickAfter("0 0 * * *", currTime, false) + _schedule := testutils.APISchedule() _schedule.SetID(1) _schedule.SetRepo(_repo) @@ -172,6 +181,7 @@ func TestSchedule_Engine_UpdateSchedule_NotConfig(t *testing.T) { _schedule.SetScheduledAt(2013476291) _schedule.SetBranch("main") _schedule.SetError("no version: YAML property provided") + _schedule.SetNextRun(nextTime.Unix()) _postgres, _mock := testPostgres(t) defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() diff --git a/database/types/schedule.go b/database/types/schedule.go index 6d2ada21c..ecd578b48 100644 --- a/database/types/schedule.go +++ b/database/types/schedule.go @@ -5,6 +5,7 @@ package types import ( "database/sql" "errors" + "time" "github.com/adhocore/gronx" @@ -87,6 +88,9 @@ func (s *Schedule) Nullify() *Schedule { func (s *Schedule) ToAPI() *api.Schedule { schedule := new(api.Schedule) + t := time.Now().UTC() + nextTime, err := gronx.NextTickAfter(s.Entry.String, t, false) + schedule.SetID(s.ID.Int64) schedule.SetRepo(s.Repo.ToAPI()) schedule.SetActive(s.Active.Bool) @@ -100,6 +104,12 @@ func (s *Schedule) ToAPI() *api.Schedule { schedule.SetBranch(s.Branch.String) schedule.SetError(s.Error.String) + if err == nil { + schedule.SetNextRun(nextTime.Unix()) + } else { + schedule.SetNextRun(0) + } + return schedule } diff --git a/database/types/schedule_test.go b/database/types/schedule_test.go index dcf056218..aa7ad21be 100644 --- a/database/types/schedule_test.go +++ b/database/types/schedule_test.go @@ -8,6 +8,8 @@ import ( "testing" "time" + "github.com/adhocore/gronx" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database/testutils" "github.com/go-vela/types/constants" @@ -93,6 +95,9 @@ func TestTypes_Schedule_ToAPI(t *testing.T) { repo.SetPreviousName("oldName") repo.SetApproveBuild(constants.ApproveNever) + currTime := time.Now().UTC() + nextTime, _ := gronx.NextTickAfter("0 0 * * *", currTime, false) + want := testutils.APISchedule() want.SetID(1) want.SetActive(true) @@ -106,6 +111,7 @@ func TestTypes_Schedule_ToAPI(t *testing.T) { want.SetScheduledAt(time.Now().Add(time.Hour * 2).UTC().Unix()) want.SetBranch("main") want.SetError("unable to trigger build for schedule nightly: unknown character") + want.SetNextRun(nextTime.Unix()) // run test got := testSchedule().ToAPI() diff --git a/mock/server/schedule.go b/mock/server/schedule.go index 390aa6b4a..73882e4af 100644 --- a/mock/server/schedule.go +++ b/mock/server/schedule.go @@ -73,7 +73,8 @@ const ( "updated_by": "octocat", "scheduled_at": 0, "branch": "main", - "error": "error message" + "error": "error message", + "next_run": 0 }` SchedulesResp = `[ { @@ -133,7 +134,8 @@ const ( "updated_by": "octocat", "scheduled_at": 0, "branch": "main", - "error": "error message" + "error": "error message", + "next_run": 0 }, { "id": 1, @@ -193,7 +195,8 @@ const ( "scheduled_at": 0, "repo_id": 1, "branch": "main", - "error": "error message" + "error": "error message", + "next_run": 0 }]` ) From 4f81558023247b297c3b154e03feb2a8816bc7c5 Mon Sep 17 00:00:00 2001 From: dave vader <48764154+plyr4@users.noreply.github.com> Date: Tue, 4 Jun 2024 11:38:18 -0500 Subject: [PATCH 57/71] enhance: add scm user id to build obj (#1133) --- api/build/restart.go | 19 +- api/types/build.go | 84 ++-- api/types/build_test.go | 214 ++++----- api/webhook/post.go | 19 + cmd/vela-server/schedule.go | 9 + compiler/native/environment_test.go | 625 +++++++++++++------------- database/build/create_test.go | 6 +- database/build/list_dashboard_test.go | 6 +- database/build/table.go | 2 + database/build/update_test.go | 6 +- database/integration_test.go | 2 + database/testutils/api_resources.go | 1 + database/types/build.go | 9 + database/types/build_test.go | 3 + mock/server/build.go | 1 + router/middleware/build/build_test.go | 1 + scm/github/user.go | 28 ++ scm/github/webhook.go | 14 +- scm/github/webhook_test.go | 19 +- scm/service.go | 6 + 20 files changed, 617 insertions(+), 457 deletions(-) create mode 100644 scm/github/user.go diff --git a/api/build/restart.go b/api/build/restart.go index 2569a4915..f8798fbb6 100644 --- a/api/build/restart.go +++ b/api/build/restart.go @@ -89,6 +89,7 @@ func RestartBuild(c *gin.Context) { o := org.Retrieve(c) r := repo.Retrieve(c) u := user.Retrieve(c) + scm := scm.FromContext(c) ctx := c.Request.Context() entry := fmt.Sprintf("%s/%d", r.GetFullName(), b.GetNumber()) @@ -112,8 +113,22 @@ func RestartBuild(c *gin.Context) { return } - // set sender to the user who initiated the restart and parent to the previous build + // set sender to the user who initiated the restart b.SetSender(cl.Subject) + + // fetch scm user id + senderID, err := scm.GetUserID(ctx, u.GetName(), r.GetOwner().GetToken()) + if err != nil { + retErr := fmt.Errorf("unable to get SCM user id for %s: %w", u.GetName(), err) + + util.HandleError(c, http.StatusInternalServerError, retErr) + + return + } + + b.SetSenderSCMID(senderID) + + // parent to the previous build b.SetParent(b.GetNumber()) logger.Debugf("Generating queue items for build %s", entry) @@ -132,7 +147,7 @@ func RestartBuild(c *gin.Context) { c, config, database.FromContext(c), - scm.FromContext(c), + scm, compiler.FromContext(c), queue.FromContext(c), ) diff --git a/api/types/build.go b/api/types/build.go index 231e8b80b..e44c7e21f 100644 --- a/api/types/build.go +++ b/api/types/build.go @@ -38,6 +38,7 @@ type Build struct { Message *string `json:"message,omitempty"` Commit *string `json:"commit,omitempty"` Sender *string `json:"sender,omitempty"` + SenderSCMID *string `json:"sender_scm_id,omitempty"` Author *string `json:"author,omitempty"` Email *string `json:"email,omitempty"` Link *string `json:"link,omitempty"` @@ -86,33 +87,34 @@ func (b *Build) Duration() string { // provided from the fields of the Build type. func (b *Build) Environment(workspace, channel string) map[string]string { envs := map[string]string{ - "VELA_BUILD_APPROVED_AT": ToString(b.GetApprovedAt()), - "VELA_BUILD_APPROVED_BY": ToString(b.GetApprovedBy()), - "VELA_BUILD_AUTHOR": ToString(b.GetAuthor()), - "VELA_BUILD_AUTHOR_EMAIL": ToString(b.GetEmail()), - "VELA_BUILD_BASE_REF": ToString(b.GetBaseRef()), - "VELA_BUILD_BRANCH": ToString(b.GetBranch()), - "VELA_BUILD_CHANNEL": ToString(channel), - "VELA_BUILD_CLONE": ToString(b.GetClone()), - "VELA_BUILD_COMMIT": ToString(b.GetCommit()), - "VELA_BUILD_CREATED": ToString(b.GetCreated()), - "VELA_BUILD_DISTRIBUTION": ToString(b.GetDistribution()), - "VELA_BUILD_ENQUEUED": ToString(b.GetEnqueued()), - "VELA_BUILD_EVENT": ToString(b.GetEvent()), - "VELA_BUILD_EVENT_ACTION": ToString(b.GetEventAction()), - "VELA_BUILD_HOST": ToString(b.GetHost()), - "VELA_BUILD_LINK": ToString(b.GetLink()), - "VELA_BUILD_MESSAGE": ToString(b.GetMessage()), - "VELA_BUILD_NUMBER": ToString(b.GetNumber()), - "VELA_BUILD_PARENT": ToString(b.GetParent()), - "VELA_BUILD_REF": ToString(b.GetRef()), - "VELA_BUILD_RUNTIME": ToString(b.GetRuntime()), - "VELA_BUILD_SENDER": ToString(b.GetSender()), - "VELA_BUILD_STARTED": ToString(b.GetStarted()), - "VELA_BUILD_SOURCE": ToString(b.GetSource()), - "VELA_BUILD_STATUS": ToString(b.GetStatus()), - "VELA_BUILD_TITLE": ToString(b.GetTitle()), - "VELA_BUILD_WORKSPACE": ToString(workspace), + "VELA_BUILD_APPROVED_AT": ToString(b.GetApprovedAt()), + "VELA_BUILD_APPROVED_BY": ToString(b.GetApprovedBy()), + "VELA_BUILD_AUTHOR": ToString(b.GetAuthor()), + "VELA_BUILD_AUTHOR_EMAIL": ToString(b.GetEmail()), + "VELA_BUILD_BASE_REF": ToString(b.GetBaseRef()), + "VELA_BUILD_BRANCH": ToString(b.GetBranch()), + "VELA_BUILD_CHANNEL": ToString(channel), + "VELA_BUILD_CLONE": ToString(b.GetClone()), + "VELA_BUILD_COMMIT": ToString(b.GetCommit()), + "VELA_BUILD_CREATED": ToString(b.GetCreated()), + "VELA_BUILD_DISTRIBUTION": ToString(b.GetDistribution()), + "VELA_BUILD_ENQUEUED": ToString(b.GetEnqueued()), + "VELA_BUILD_EVENT": ToString(b.GetEvent()), + "VELA_BUILD_EVENT_ACTION": ToString(b.GetEventAction()), + "VELA_BUILD_HOST": ToString(b.GetHost()), + "VELA_BUILD_LINK": ToString(b.GetLink()), + "VELA_BUILD_MESSAGE": ToString(b.GetMessage()), + "VELA_BUILD_NUMBER": ToString(b.GetNumber()), + "VELA_BUILD_PARENT": ToString(b.GetParent()), + "VELA_BUILD_REF": ToString(b.GetRef()), + "VELA_BUILD_RUNTIME": ToString(b.GetRuntime()), + "VELA_BUILD_SENDER": ToString(b.GetSender()), + "VELA_BUILD_SENDER_SCM_ID": ToString(b.GetSenderSCMID()), + "VELA_BUILD_STARTED": ToString(b.GetStarted()), + "VELA_BUILD_SOURCE": ToString(b.GetSource()), + "VELA_BUILD_STATUS": ToString(b.GetStatus()), + "VELA_BUILD_TITLE": ToString(b.GetTitle()), + "VELA_BUILD_WORKSPACE": ToString(workspace), // deprecated environment variables "BUILD_AUTHOR": ToString(b.GetAuthor()), @@ -502,6 +504,19 @@ func (b *Build) GetSender() string { return *b.Sender } +// GetSenderSCMID returns the SenderSCMID 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) GetSenderSCMID() string { + // return zero value if Build type or SenderSCMID field is nil + if b == nil || b.SenderSCMID == nil { + return "" + } + + return *b.SenderSCMID +} + // GetAuthor returns the Author field. // // When the provided Build type is nil, or the field within @@ -944,6 +959,19 @@ func (b *Build) SetSender(v string) { b.Sender = &v } +// SetSenderSCMID sets the SenderSCMID field. +// +// When the provided Build type is nil, it +// will set nothing and immediately return. +func (b *Build) SetSenderSCMID(v string) { + // return if Build type is nil + if b == nil { + return + } + + b.SenderSCMID = &v +} + // SetAuthor sets the Author field. // // When the provided Build type is nil, it @@ -1135,6 +1163,7 @@ func (b *Build) String() string { Repo: %s, Runtime: %s, Sender: %s, + SenderSCMID: %s, Source: %s, Started: %d, Status: %s, @@ -1170,6 +1199,7 @@ func (b *Build) String() string { b.GetRepo().GetFullName(), b.GetRuntime(), b.GetSender(), + b.GetSenderSCMID(), b.GetSource(), b.GetStarted(), b.GetStatus(), diff --git a/api/types/build_test.go b/api/types/build_test.go index d70853bda..dd6d70483 100644 --- a/api/types/build_test.go +++ b/api/types/build_test.go @@ -92,55 +92,56 @@ func TestTypes_Build_Environment(t *testing.T) { { build: testBuild(), want: map[string]string{ - "VELA_BUILD_APPROVED_AT": "1563474076", - "VELA_BUILD_APPROVED_BY": "OctoCat", - "VELA_BUILD_AUTHOR": "OctoKitty", - "VELA_BUILD_AUTHOR_EMAIL": "OctoKitty@github.com", - "VELA_BUILD_BASE_REF": "", - "VELA_BUILD_BRANCH": "main", - "VELA_BUILD_CHANNEL": "TODO", - "VELA_BUILD_CLONE": "https://github.com/github/octocat.git", - "VELA_BUILD_COMMIT": "48afb5bdc41ad69bf22588491333f7cf71135163", - "VELA_BUILD_CREATED": "1563474076", - "VELA_BUILD_DISTRIBUTION": "linux", - "VELA_BUILD_ENQUEUED": "1563474077", - "VELA_BUILD_EVENT": "push", - "VELA_BUILD_EVENT_ACTION": "", - "VELA_BUILD_HOST": "example.company.com", - "VELA_BUILD_LINK": "https://example.company.com/github/octocat/1", - "VELA_BUILD_MESSAGE": "First commit...", - "VELA_BUILD_NUMBER": "1", - "VELA_BUILD_PARENT": "1", - "VELA_BUILD_REF": "refs/heads/main", - "VELA_BUILD_RUNTIME": "docker", - "VELA_BUILD_SENDER": "OctoKitty", - "VELA_BUILD_STARTED": "1563474078", - "VELA_BUILD_SOURCE": "https://github.com/github/octocat/48afb5bdc41ad69bf22588491333f7cf71135163", - "VELA_BUILD_STATUS": "running", - "VELA_BUILD_TITLE": "push received from https://github.com/github/octocat", - "VELA_BUILD_WORKSPACE": "TODO", - "BUILD_AUTHOR": "OctoKitty", - "BUILD_AUTHOR_EMAIL": "OctoKitty@github.com", - "BUILD_BASE_REF": "", - "BUILD_BRANCH": "main", - "BUILD_CHANNEL": "TODO", - "BUILD_CLONE": "https://github.com/github/octocat.git", - "BUILD_COMMIT": "48afb5bdc41ad69bf22588491333f7cf71135163", - "BUILD_CREATED": "1563474076", - "BUILD_ENQUEUED": "1563474077", - "BUILD_EVENT": "push", - "BUILD_HOST": "example.company.com", - "BUILD_LINK": "https://example.company.com/github/octocat/1", - "BUILD_MESSAGE": "First commit...", - "BUILD_NUMBER": "1", - "BUILD_PARENT": "1", - "BUILD_REF": "refs/heads/main", - "BUILD_SENDER": "OctoKitty", - "BUILD_STARTED": "1563474078", - "BUILD_SOURCE": "https://github.com/github/octocat/48afb5bdc41ad69bf22588491333f7cf71135163", - "BUILD_STATUS": "running", - "BUILD_TITLE": "push received from https://github.com/github/octocat", - "BUILD_WORKSPACE": "TODO", + "VELA_BUILD_APPROVED_AT": "1563474076", + "VELA_BUILD_APPROVED_BY": "OctoCat", + "VELA_BUILD_AUTHOR": "OctoKitty", + "VELA_BUILD_AUTHOR_EMAIL": "OctoKitty@github.com", + "VELA_BUILD_BASE_REF": "", + "VELA_BUILD_BRANCH": "main", + "VELA_BUILD_CHANNEL": "TODO", + "VELA_BUILD_CLONE": "https://github.com/github/octocat.git", + "VELA_BUILD_COMMIT": "48afb5bdc41ad69bf22588491333f7cf71135163", + "VELA_BUILD_CREATED": "1563474076", + "VELA_BUILD_DISTRIBUTION": "linux", + "VELA_BUILD_ENQUEUED": "1563474077", + "VELA_BUILD_EVENT": "push", + "VELA_BUILD_EVENT_ACTION": "", + "VELA_BUILD_HOST": "example.company.com", + "VELA_BUILD_LINK": "https://example.company.com/github/octocat/1", + "VELA_BUILD_MESSAGE": "First commit...", + "VELA_BUILD_NUMBER": "1", + "VELA_BUILD_PARENT": "1", + "VELA_BUILD_REF": "refs/heads/main", + "VELA_BUILD_RUNTIME": "docker", + "VELA_BUILD_SENDER": "OctoKitty", + "VELA_BUILD_SENDER_SCM_ID": "123", + "VELA_BUILD_STARTED": "1563474078", + "VELA_BUILD_SOURCE": "https://github.com/github/octocat/48afb5bdc41ad69bf22588491333f7cf71135163", + "VELA_BUILD_STATUS": "running", + "VELA_BUILD_TITLE": "push received from https://github.com/github/octocat", + "VELA_BUILD_WORKSPACE": "TODO", + "BUILD_AUTHOR": "OctoKitty", + "BUILD_AUTHOR_EMAIL": "OctoKitty@github.com", + "BUILD_BASE_REF": "", + "BUILD_BRANCH": "main", + "BUILD_CHANNEL": "TODO", + "BUILD_CLONE": "https://github.com/github/octocat.git", + "BUILD_COMMIT": "48afb5bdc41ad69bf22588491333f7cf71135163", + "BUILD_CREATED": "1563474076", + "BUILD_ENQUEUED": "1563474077", + "BUILD_EVENT": "push", + "BUILD_HOST": "example.company.com", + "BUILD_LINK": "https://example.company.com/github/octocat/1", + "BUILD_MESSAGE": "First commit...", + "BUILD_NUMBER": "1", + "BUILD_PARENT": "1", + "BUILD_REF": "refs/heads/main", + "BUILD_SENDER": "OctoKitty", + "BUILD_STARTED": "1563474078", + "BUILD_SOURCE": "https://github.com/github/octocat/48afb5bdc41ad69bf22588491333f7cf71135163", + "BUILD_STATUS": "running", + "BUILD_TITLE": "push received from https://github.com/github/octocat", + "BUILD_WORKSPACE": "TODO", }, }, { @@ -169,6 +170,7 @@ func TestTypes_Build_Environment(t *testing.T) { "VELA_BUILD_REF": "refs/pulls/1/head", "VELA_BUILD_RUNTIME": "docker", "VELA_BUILD_SENDER": "OctoKitty", + "VELA_BUILD_SENDER_SCM_ID": "123", "VELA_BUILD_STARTED": "1563474078", "VELA_BUILD_SOURCE": "https://github.com/github/octocat/48afb5bdc41ad69bf22588491333f7cf71135163", "VELA_BUILD_STATUS": "running", @@ -227,6 +229,7 @@ func TestTypes_Build_Environment(t *testing.T) { "VELA_BUILD_REF": "refs/heads/main", "VELA_BUILD_RUNTIME": "docker", "VELA_BUILD_SENDER": "OctoKitty", + "VELA_BUILD_SENDER_SCM_ID": "123", "VELA_BUILD_STARTED": "1563474078", "VELA_BUILD_SOURCE": "https://github.com/github/octocat/48afb5bdc41ad69bf22588491333f7cf71135163", "VELA_BUILD_STATUS": "running", @@ -287,6 +290,7 @@ func TestTypes_Build_Environment(t *testing.T) { "VELA_BUILD_REF": "refs/tags/v0.1.0", "VELA_BUILD_RUNTIME": "docker", "VELA_BUILD_SENDER": "OctoKitty", + "VELA_BUILD_SENDER_SCM_ID": "123", "VELA_BUILD_STARTED": "1563474078", "VELA_BUILD_SOURCE": "https://github.com/github/octocat/48afb5bdc41ad69bf22588491333f7cf71135163", "VELA_BUILD_STATUS": "running", @@ -350,6 +354,7 @@ func TestTypes_Build_Environment(t *testing.T) { "VELA_BUILD_REF": "refs/pulls/1/head", "VELA_BUILD_RUNTIME": "docker", "VELA_BUILD_SENDER": "OctoKitty", + "VELA_BUILD_SENDER_SCM_ID": "123", "VELA_BUILD_STARTED": "1563474078", "VELA_BUILD_SOURCE": "https://github.com/github/octocat/48afb5bdc41ad69bf22588491333f7cf71135163", "VELA_BUILD_STATUS": "running", @@ -386,57 +391,58 @@ func TestTypes_Build_Environment(t *testing.T) { { build: _tag, want: map[string]string{ - "VELA_BUILD_APPROVED_AT": "1563474076", - "VELA_BUILD_APPROVED_BY": "OctoCat", - "VELA_BUILD_AUTHOR": "OctoKitty", - "VELA_BUILD_AUTHOR_EMAIL": "OctoKitty@github.com", - "VELA_BUILD_BASE_REF": "", - "VELA_BUILD_BRANCH": "main", - "VELA_BUILD_CHANNEL": "TODO", - "VELA_BUILD_CLONE": "https://github.com/github/octocat.git", - "VELA_BUILD_COMMIT": "48afb5bdc41ad69bf22588491333f7cf71135163", - "VELA_BUILD_CREATED": "1563474076", - "VELA_BUILD_DISTRIBUTION": "linux", - "VELA_BUILD_ENQUEUED": "1563474077", - "VELA_BUILD_EVENT": "tag", - "VELA_BUILD_EVENT_ACTION": "", - "VELA_BUILD_HOST": "example.company.com", - "VELA_BUILD_LINK": "https://example.company.com/github/octocat/1", - "VELA_BUILD_MESSAGE": "First commit...", - "VELA_BUILD_NUMBER": "1", - "VELA_BUILD_PARENT": "1", - "VELA_BUILD_REF": "refs/tags/v0.1.0", - "VELA_BUILD_RUNTIME": "docker", - "VELA_BUILD_SENDER": "OctoKitty", - "VELA_BUILD_STARTED": "1563474078", - "VELA_BUILD_SOURCE": "https://github.com/github/octocat/48afb5bdc41ad69bf22588491333f7cf71135163", - "VELA_BUILD_STATUS": "running", - "VELA_BUILD_TAG": "v0.1.0", - "VELA_BUILD_TITLE": "push received from https://github.com/github/octocat", - "VELA_BUILD_WORKSPACE": "TODO", - "BUILD_AUTHOR": "OctoKitty", - "BUILD_AUTHOR_EMAIL": "OctoKitty@github.com", - "BUILD_BASE_REF": "", - "BUILD_BRANCH": "main", - "BUILD_CHANNEL": "TODO", - "BUILD_CLONE": "https://github.com/github/octocat.git", - "BUILD_COMMIT": "48afb5bdc41ad69bf22588491333f7cf71135163", - "BUILD_CREATED": "1563474076", - "BUILD_ENQUEUED": "1563474077", - "BUILD_EVENT": "tag", - "BUILD_HOST": "example.company.com", - "BUILD_LINK": "https://example.company.com/github/octocat/1", - "BUILD_MESSAGE": "First commit...", - "BUILD_NUMBER": "1", - "BUILD_PARENT": "1", - "BUILD_REF": "refs/tags/v0.1.0", - "BUILD_SENDER": "OctoKitty", - "BUILD_STARTED": "1563474078", - "BUILD_SOURCE": "https://github.com/github/octocat/48afb5bdc41ad69bf22588491333f7cf71135163", - "BUILD_STATUS": "running", - "BUILD_TAG": "v0.1.0", - "BUILD_TITLE": "push received from https://github.com/github/octocat", - "BUILD_WORKSPACE": "TODO", + "VELA_BUILD_APPROVED_AT": "1563474076", + "VELA_BUILD_APPROVED_BY": "OctoCat", + "VELA_BUILD_AUTHOR": "OctoKitty", + "VELA_BUILD_AUTHOR_EMAIL": "OctoKitty@github.com", + "VELA_BUILD_BASE_REF": "", + "VELA_BUILD_BRANCH": "main", + "VELA_BUILD_CHANNEL": "TODO", + "VELA_BUILD_CLONE": "https://github.com/github/octocat.git", + "VELA_BUILD_COMMIT": "48afb5bdc41ad69bf22588491333f7cf71135163", + "VELA_BUILD_CREATED": "1563474076", + "VELA_BUILD_DISTRIBUTION": "linux", + "VELA_BUILD_ENQUEUED": "1563474077", + "VELA_BUILD_EVENT": "tag", + "VELA_BUILD_EVENT_ACTION": "", + "VELA_BUILD_HOST": "example.company.com", + "VELA_BUILD_LINK": "https://example.company.com/github/octocat/1", + "VELA_BUILD_MESSAGE": "First commit...", + "VELA_BUILD_NUMBER": "1", + "VELA_BUILD_PARENT": "1", + "VELA_BUILD_REF": "refs/tags/v0.1.0", + "VELA_BUILD_RUNTIME": "docker", + "VELA_BUILD_SENDER": "OctoKitty", + "VELA_BUILD_SENDER_SCM_ID": "123", + "VELA_BUILD_STARTED": "1563474078", + "VELA_BUILD_SOURCE": "https://github.com/github/octocat/48afb5bdc41ad69bf22588491333f7cf71135163", + "VELA_BUILD_STATUS": "running", + "VELA_BUILD_TAG": "v0.1.0", + "VELA_BUILD_TITLE": "push received from https://github.com/github/octocat", + "VELA_BUILD_WORKSPACE": "TODO", + "BUILD_AUTHOR": "OctoKitty", + "BUILD_AUTHOR_EMAIL": "OctoKitty@github.com", + "BUILD_BASE_REF": "", + "BUILD_BRANCH": "main", + "BUILD_CHANNEL": "TODO", + "BUILD_CLONE": "https://github.com/github/octocat.git", + "BUILD_COMMIT": "48afb5bdc41ad69bf22588491333f7cf71135163", + "BUILD_CREATED": "1563474076", + "BUILD_ENQUEUED": "1563474077", + "BUILD_EVENT": "tag", + "BUILD_HOST": "example.company.com", + "BUILD_LINK": "https://example.company.com/github/octocat/1", + "BUILD_MESSAGE": "First commit...", + "BUILD_NUMBER": "1", + "BUILD_PARENT": "1", + "BUILD_REF": "refs/tags/v0.1.0", + "BUILD_SENDER": "OctoKitty", + "BUILD_STARTED": "1563474078", + "BUILD_SOURCE": "https://github.com/github/octocat/48afb5bdc41ad69bf22588491333f7cf71135163", + "BUILD_STATUS": "running", + "BUILD_TAG": "v0.1.0", + "BUILD_TITLE": "push received from https://github.com/github/octocat", + "BUILD_WORKSPACE": "TODO", }, }, } @@ -650,6 +656,7 @@ func TestTypes_Build_Setters(t *testing.T) { test.build.SetMessage(test.want.GetMessage()) test.build.SetCommit(test.want.GetCommit()) test.build.SetSender(test.want.GetSender()) + test.build.SetSenderSCMID(test.want.GetSenderSCMID()) test.build.SetAuthor(test.want.GetAuthor()) test.build.SetEmail(test.want.GetEmail()) test.build.SetLink(test.want.GetLink()) @@ -751,6 +758,10 @@ func TestTypes_Build_Setters(t *testing.T) { t.Errorf("SetSender is %v, want %v", test.build.GetSender(), test.want.GetSender()) } + if test.build.GetSenderSCMID() != test.want.GetSenderSCMID() { + t.Errorf("SetSenderSCMID is %v, want %v", test.build.GetSenderSCMID(), test.want.GetSenderSCMID()) + } + if test.build.GetAuthor() != test.want.GetAuthor() { t.Errorf("SetAuthor is %v, want %v", test.build.GetAuthor(), test.want.GetAuthor()) } @@ -836,6 +847,7 @@ func TestTypes_Build_String(t *testing.T) { Repo: %s, Runtime: %s, Sender: %s, + SenderSCMID: %s, Source: %s, Started: %d, Status: %s, @@ -871,6 +883,7 @@ func TestTypes_Build_String(t *testing.T) { b.GetRepo().GetFullName(), b.GetRuntime(), b.GetSender(), + b.GetSenderSCMID(), b.GetSource(), b.GetStarted(), b.GetStatus(), @@ -911,6 +924,7 @@ func testBuild() *Build { b.SetMessage("First commit...") b.SetCommit("48afb5bdc41ad69bf22588491333f7cf71135163") b.SetSender("OctoKitty") + b.SetSenderSCMID("123") b.SetAuthor("OctoKitty") b.SetEmail("OctoKitty@github.com") b.SetLink("https://example.company.com/github/octocat/1") diff --git a/api/webhook/post.go b/api/webhook/post.go index 20600d525..50d69d315 100644 --- a/api/webhook/post.go +++ b/api/webhook/post.go @@ -207,6 +207,25 @@ func PostWebhook(c *gin.Context) { return } + // attach a sender SCM id if the webhook payload from the SCM has no sender id + // the code in ProcessWebhook implies that the sender may not always be present + // fallbacks like pusher/commit_author do not have an id + if len(b.GetSenderSCMID()) == 0 || b.GetSenderSCMID() == "0" { + // fetch scm user id for pusher + senderID, err := scm.FromContext(c).GetUserID(ctx, b.GetSender(), repo.GetOwner().GetToken()) + if err != nil { + retErr := fmt.Errorf("unable to assign sender SCM id: %w", err) + util.HandleError(c, http.StatusBadRequest, retErr) + + h.SetStatus(constants.StatusFailure) + h.SetError(retErr.Error()) + + return + } + + b.SetSenderSCMID(senderID) + } + // set the RepoID fields b.SetRepo(repo) h.SetRepoID(repo.GetID()) diff --git a/cmd/vela-server/schedule.go b/cmd/vela-server/schedule.go index f2832935e..3709df9a8 100644 --- a/cmd/vela-server/schedule.go +++ b/cmd/vela-server/schedule.go @@ -179,6 +179,15 @@ func processSchedule(ctx context.Context, s *api.Schedule, settings *settings.Pl b.SetRef(fmt.Sprintf("refs/heads/%s", b.GetBranch())) b.SetRepo(r) b.SetSender(s.GetUpdatedBy()) + + // fetch scm user id + senderID, err := scm.GetUserID(ctx, s.GetUpdatedBy(), r.GetOwner().GetToken()) + if err != nil { + return fmt.Errorf("unable to get SCM user id for %s: %w", s.GetUpdatedBy(), err) + } + + b.SetSenderSCMID(senderID) + b.SetSource(fmt.Sprintf("%s/tree/%s", url, b.GetBranch())) b.SetStatus(constants.StatusPending) b.SetTitle(fmt.Sprintf("%s received from %s", constants.EventSchedule, url)) diff --git a/compiler/native/environment_test.go b/compiler/native/environment_test.go index 9c55ed41d..6d920021a 100644 --- a/compiler/native/environment_test.go +++ b/compiler/native/environment_test.go @@ -104,104 +104,105 @@ func TestNative_EnvironmentSteps(t *testing.T) { Name: str, Pull: "always", Environment: raw.StringSliceMap{ - "BUILD_AUTHOR": "", - "BUILD_AUTHOR_EMAIL": "", - "BUILD_BASE_REF": "", - "BUILD_BRANCH": "", - "BUILD_CHANNEL": "TODO", - "BUILD_CLONE": "", - "BUILD_COMMIT": "", - "BUILD_CREATED": "0", - "BUILD_ENQUEUED": "0", - "BUILD_EVENT": "", - "BUILD_HOST": "", - "BUILD_LINK": "", - "BUILD_MESSAGE": "", - "BUILD_NUMBER": "0", - "BUILD_PARENT": "0", - "BUILD_REF": "", - "BUILD_SENDER": "", - "BUILD_SOURCE": "", - "BUILD_STARTED": "0", - "BUILD_STATUS": "", - "BUILD_TITLE": "", - "BUILD_WORKSPACE": "/vela/src", - "CI": "true", - "REPOSITORY_ACTIVE": "false", - "REPOSITORY_ALLOW_EVENTS": "", - "REPOSITORY_BRANCH": "", - "REPOSITORY_CLONE": "", - "REPOSITORY_FULL_NAME": "", - "REPOSITORY_LINK": "", - "REPOSITORY_NAME": "", - "REPOSITORY_ORG": "", - "REPOSITORY_PRIVATE": "false", - "REPOSITORY_TIMEOUT": "0", - "REPOSITORY_TRUSTED": "false", - "REPOSITORY_VISIBILITY": "", - "VELA": "true", - "VELA_ADDR": "TODO", - "VELA_BUILD_APPROVED_AT": "0", - "VELA_BUILD_APPROVED_BY": "", - "VELA_BUILD_AUTHOR": "", - "VELA_BUILD_AUTHOR_EMAIL": "", - "VELA_BUILD_BASE_REF": "", - "VELA_BUILD_BRANCH": "", - "VELA_BUILD_CHANNEL": "TODO", - "VELA_BUILD_CLONE": "", - "VELA_BUILD_COMMIT": "", - "VELA_BUILD_CREATED": "0", - "VELA_BUILD_DISTRIBUTION": "", - "VELA_BUILD_ENQUEUED": "0", - "VELA_BUILD_EVENT": "", - "VELA_BUILD_EVENT_ACTION": "", - "VELA_BUILD_HOST": "", - "VELA_BUILD_LINK": "", - "VELA_BUILD_MESSAGE": "", - "VELA_BUILD_NUMBER": "0", - "VELA_BUILD_PARENT": "0", - "VELA_BUILD_REF": "", - "VELA_BUILD_RUNTIME": "", - "VELA_BUILD_SENDER": "", - "VELA_BUILD_SOURCE": "", - "VELA_BUILD_STARTED": "0", - "VELA_BUILD_STATUS": "", - "VELA_BUILD_TITLE": "", - "VELA_BUILD_WORKSPACE": "/vela/src", - "VELA_CHANNEL": "TODO", - "VELA_DATABASE": "TODO", - "VELA_DISTRIBUTION": "TODO", - "VELA_HOST": "TODO", - "VELA_NETRC_MACHINE": "TODO", - "VELA_NETRC_PASSWORD": "", - "VELA_NETRC_USERNAME": "x-oauth-basic", - "VELA_QUEUE": "TODO", - "VELA_REPO_ACTIVE": "false", - "VELA_REPO_ALLOW_EVENTS": "", - "VELA_REPO_APPROVE_BUILD": "", - "VELA_REPO_BRANCH": "", - "VELA_REPO_TOPICS": "", - "VELA_REPO_BUILD_LIMIT": "0", - "VELA_REPO_CLONE": "", - "VELA_REPO_FULL_NAME": "", - "VELA_REPO_LINK": "", - "VELA_REPO_NAME": "", - "VELA_REPO_ORG": "", - "VELA_REPO_OWNER": "", - "VELA_REPO_PIPELINE_TYPE": "", - "VELA_REPO_PRIVATE": "false", - "VELA_REPO_TIMEOUT": "0", - "VELA_REPO_TRUSTED": "false", - "VELA_REPO_VISIBILITY": "", - "VELA_RUNTIME": "TODO", - "VELA_SOURCE": "TODO", - "VELA_USER_ACTIVE": "false", - "VELA_USER_ADMIN": "false", - "VELA_USER_FAVORITES": "[]", - "VELA_USER_NAME": "", - "VELA_VERSION": "TODO", - "VELA_WORKSPACE": "/vela/src", - "HELLO": "Hello, Stage Message", + "BUILD_AUTHOR": "", + "BUILD_AUTHOR_EMAIL": "", + "BUILD_BASE_REF": "", + "BUILD_BRANCH": "", + "BUILD_CHANNEL": "TODO", + "BUILD_CLONE": "", + "BUILD_COMMIT": "", + "BUILD_CREATED": "0", + "BUILD_ENQUEUED": "0", + "BUILD_EVENT": "", + "BUILD_HOST": "", + "BUILD_LINK": "", + "BUILD_MESSAGE": "", + "BUILD_NUMBER": "0", + "BUILD_PARENT": "0", + "BUILD_REF": "", + "BUILD_SENDER": "", + "BUILD_SOURCE": "", + "BUILD_STARTED": "0", + "BUILD_STATUS": "", + "BUILD_TITLE": "", + "BUILD_WORKSPACE": "/vela/src", + "CI": "true", + "REPOSITORY_ACTIVE": "false", + "REPOSITORY_ALLOW_EVENTS": "", + "REPOSITORY_BRANCH": "", + "REPOSITORY_CLONE": "", + "REPOSITORY_FULL_NAME": "", + "REPOSITORY_LINK": "", + "REPOSITORY_NAME": "", + "REPOSITORY_ORG": "", + "REPOSITORY_PRIVATE": "false", + "REPOSITORY_TIMEOUT": "0", + "REPOSITORY_TRUSTED": "false", + "REPOSITORY_VISIBILITY": "", + "VELA": "true", + "VELA_ADDR": "TODO", + "VELA_BUILD_APPROVED_AT": "0", + "VELA_BUILD_APPROVED_BY": "", + "VELA_BUILD_AUTHOR": "", + "VELA_BUILD_AUTHOR_EMAIL": "", + "VELA_BUILD_BASE_REF": "", + "VELA_BUILD_BRANCH": "", + "VELA_BUILD_CHANNEL": "TODO", + "VELA_BUILD_CLONE": "", + "VELA_BUILD_COMMIT": "", + "VELA_BUILD_CREATED": "0", + "VELA_BUILD_DISTRIBUTION": "", + "VELA_BUILD_ENQUEUED": "0", + "VELA_BUILD_EVENT": "", + "VELA_BUILD_EVENT_ACTION": "", + "VELA_BUILD_HOST": "", + "VELA_BUILD_LINK": "", + "VELA_BUILD_MESSAGE": "", + "VELA_BUILD_NUMBER": "0", + "VELA_BUILD_PARENT": "0", + "VELA_BUILD_REF": "", + "VELA_BUILD_RUNTIME": "", + "VELA_BUILD_SENDER": "", + "VELA_BUILD_SENDER_SCM_ID": "", + "VELA_BUILD_SOURCE": "", + "VELA_BUILD_STARTED": "0", + "VELA_BUILD_STATUS": "", + "VELA_BUILD_TITLE": "", + "VELA_BUILD_WORKSPACE": "/vela/src", + "VELA_CHANNEL": "TODO", + "VELA_DATABASE": "TODO", + "VELA_DISTRIBUTION": "TODO", + "VELA_HOST": "TODO", + "VELA_NETRC_MACHINE": "TODO", + "VELA_NETRC_PASSWORD": "", + "VELA_NETRC_USERNAME": "x-oauth-basic", + "VELA_QUEUE": "TODO", + "VELA_REPO_ACTIVE": "false", + "VELA_REPO_ALLOW_EVENTS": "", + "VELA_REPO_APPROVE_BUILD": "", + "VELA_REPO_BRANCH": "", + "VELA_REPO_TOPICS": "", + "VELA_REPO_BUILD_LIMIT": "0", + "VELA_REPO_CLONE": "", + "VELA_REPO_FULL_NAME": "", + "VELA_REPO_LINK": "", + "VELA_REPO_NAME": "", + "VELA_REPO_ORG": "", + "VELA_REPO_OWNER": "", + "VELA_REPO_PIPELINE_TYPE": "", + "VELA_REPO_PRIVATE": "false", + "VELA_REPO_TIMEOUT": "0", + "VELA_REPO_TRUSTED": "false", + "VELA_REPO_VISIBILITY": "", + "VELA_RUNTIME": "TODO", + "VELA_SOURCE": "TODO", + "VELA_USER_ACTIVE": "false", + "VELA_USER_ADMIN": "false", + "VELA_USER_FAVORITES": "[]", + "VELA_USER_NAME": "", + "VELA_VERSION": "TODO", + "VELA_WORKSPACE": "/vela/src", + "HELLO": "Hello, Stage Message", }, }, } @@ -280,104 +281,105 @@ func TestNative_EnvironmentServices(t *testing.T) { Name: str, Pull: "always", Environment: raw.StringSliceMap{ - "BUILD_AUTHOR": "", - "BUILD_AUTHOR_EMAIL": "", - "BUILD_BASE_REF": "", - "BUILD_BRANCH": "", - "BUILD_CHANNEL": "TODO", - "BUILD_CLONE": "", - "BUILD_COMMIT": "", - "BUILD_CREATED": "0", - "BUILD_ENQUEUED": "0", - "BUILD_EVENT": "", - "BUILD_HOST": "", - "BUILD_LINK": "", - "BUILD_MESSAGE": "", - "BUILD_NUMBER": "0", - "BUILD_PARENT": "0", - "BUILD_REF": "", - "BUILD_SENDER": "", - "BUILD_SOURCE": "", - "BUILD_STARTED": "0", - "BUILD_STATUS": "", - "BUILD_TITLE": "", - "BUILD_WORKSPACE": "/vela/src", - "CI": "true", - "REPOSITORY_ACTIVE": "false", - "REPOSITORY_ALLOW_EVENTS": "", - "REPOSITORY_BRANCH": "", - "REPOSITORY_CLONE": "", - "REPOSITORY_FULL_NAME": "", - "REPOSITORY_LINK": "", - "REPOSITORY_NAME": "", - "REPOSITORY_ORG": "", - "REPOSITORY_PRIVATE": "false", - "REPOSITORY_TIMEOUT": "0", - "REPOSITORY_TRUSTED": "false", - "REPOSITORY_VISIBILITY": "", - "VELA": "true", - "VELA_ADDR": "TODO", - "VELA_BUILD_APPROVED_AT": "0", - "VELA_BUILD_APPROVED_BY": "", - "VELA_BUILD_AUTHOR": "", - "VELA_BUILD_AUTHOR_EMAIL": "", - "VELA_BUILD_BASE_REF": "", - "VELA_BUILD_BRANCH": "", - "VELA_BUILD_CHANNEL": "TODO", - "VELA_BUILD_CLONE": "", - "VELA_BUILD_COMMIT": "", - "VELA_BUILD_CREATED": "0", - "VELA_BUILD_DISTRIBUTION": "", - "VELA_BUILD_ENQUEUED": "0", - "VELA_BUILD_EVENT": "", - "VELA_BUILD_EVENT_ACTION": "", - "VELA_BUILD_HOST": "", - "VELA_BUILD_LINK": "", - "VELA_BUILD_MESSAGE": "", - "VELA_BUILD_NUMBER": "0", - "VELA_BUILD_PARENT": "0", - "VELA_BUILD_REF": "", - "VELA_BUILD_RUNTIME": "", - "VELA_BUILD_SENDER": "", - "VELA_BUILD_SOURCE": "", - "VELA_BUILD_STARTED": "0", - "VELA_BUILD_STATUS": "", - "VELA_BUILD_TITLE": "", - "VELA_BUILD_WORKSPACE": "/vela/src", - "VELA_CHANNEL": "TODO", - "VELA_DATABASE": "TODO", - "VELA_DISTRIBUTION": "TODO", - "VELA_HOST": "TODO", - "VELA_NETRC_MACHINE": "TODO", - "VELA_NETRC_PASSWORD": "", - "VELA_NETRC_USERNAME": "x-oauth-basic", - "VELA_QUEUE": "TODO", - "VELA_REPO_ACTIVE": "false", - "VELA_REPO_ALLOW_EVENTS": "", - "VELA_REPO_APPROVE_BUILD": "", - "VELA_REPO_BRANCH": "", - "VELA_REPO_TOPICS": "", - "VELA_REPO_BUILD_LIMIT": "0", - "VELA_REPO_CLONE": "", - "VELA_REPO_FULL_NAME": "", - "VELA_REPO_LINK": "", - "VELA_REPO_NAME": "", - "VELA_REPO_ORG": "", - "VELA_REPO_OWNER": "", - "VELA_REPO_PIPELINE_TYPE": "", - "VELA_REPO_PRIVATE": "false", - "VELA_REPO_TIMEOUT": "0", - "VELA_REPO_TRUSTED": "false", - "VELA_REPO_VISIBILITY": "", - "VELA_RUNTIME": "TODO", - "VELA_SOURCE": "TODO", - "VELA_USER_ACTIVE": "false", - "VELA_USER_ADMIN": "false", - "VELA_USER_FAVORITES": "[]", - "VELA_USER_NAME": "", - "VELA_VERSION": "TODO", - "VELA_WORKSPACE": "/vela/src", - "HELLO": "Hello, Global Message", + "BUILD_AUTHOR": "", + "BUILD_AUTHOR_EMAIL": "", + "BUILD_BASE_REF": "", + "BUILD_BRANCH": "", + "BUILD_CHANNEL": "TODO", + "BUILD_CLONE": "", + "BUILD_COMMIT": "", + "BUILD_CREATED": "0", + "BUILD_ENQUEUED": "0", + "BUILD_EVENT": "", + "BUILD_HOST": "", + "BUILD_LINK": "", + "BUILD_MESSAGE": "", + "BUILD_NUMBER": "0", + "BUILD_PARENT": "0", + "BUILD_REF": "", + "BUILD_SENDER": "", + "BUILD_SOURCE": "", + "BUILD_STARTED": "0", + "BUILD_STATUS": "", + "BUILD_TITLE": "", + "BUILD_WORKSPACE": "/vela/src", + "CI": "true", + "REPOSITORY_ACTIVE": "false", + "REPOSITORY_ALLOW_EVENTS": "", + "REPOSITORY_BRANCH": "", + "REPOSITORY_CLONE": "", + "REPOSITORY_FULL_NAME": "", + "REPOSITORY_LINK": "", + "REPOSITORY_NAME": "", + "REPOSITORY_ORG": "", + "REPOSITORY_PRIVATE": "false", + "REPOSITORY_TIMEOUT": "0", + "REPOSITORY_TRUSTED": "false", + "REPOSITORY_VISIBILITY": "", + "VELA": "true", + "VELA_ADDR": "TODO", + "VELA_BUILD_APPROVED_AT": "0", + "VELA_BUILD_APPROVED_BY": "", + "VELA_BUILD_AUTHOR": "", + "VELA_BUILD_AUTHOR_EMAIL": "", + "VELA_BUILD_BASE_REF": "", + "VELA_BUILD_BRANCH": "", + "VELA_BUILD_CHANNEL": "TODO", + "VELA_BUILD_CLONE": "", + "VELA_BUILD_COMMIT": "", + "VELA_BUILD_CREATED": "0", + "VELA_BUILD_DISTRIBUTION": "", + "VELA_BUILD_ENQUEUED": "0", + "VELA_BUILD_EVENT": "", + "VELA_BUILD_EVENT_ACTION": "", + "VELA_BUILD_HOST": "", + "VELA_BUILD_LINK": "", + "VELA_BUILD_MESSAGE": "", + "VELA_BUILD_NUMBER": "0", + "VELA_BUILD_PARENT": "0", + "VELA_BUILD_REF": "", + "VELA_BUILD_RUNTIME": "", + "VELA_BUILD_SENDER": "", + "VELA_BUILD_SENDER_SCM_ID": "", + "VELA_BUILD_SOURCE": "", + "VELA_BUILD_STARTED": "0", + "VELA_BUILD_STATUS": "", + "VELA_BUILD_TITLE": "", + "VELA_BUILD_WORKSPACE": "/vela/src", + "VELA_CHANNEL": "TODO", + "VELA_DATABASE": "TODO", + "VELA_DISTRIBUTION": "TODO", + "VELA_HOST": "TODO", + "VELA_NETRC_MACHINE": "TODO", + "VELA_NETRC_PASSWORD": "", + "VELA_NETRC_USERNAME": "x-oauth-basic", + "VELA_QUEUE": "TODO", + "VELA_REPO_ACTIVE": "false", + "VELA_REPO_ALLOW_EVENTS": "", + "VELA_REPO_APPROVE_BUILD": "", + "VELA_REPO_BRANCH": "", + "VELA_REPO_TOPICS": "", + "VELA_REPO_BUILD_LIMIT": "0", + "VELA_REPO_CLONE": "", + "VELA_REPO_FULL_NAME": "", + "VELA_REPO_LINK": "", + "VELA_REPO_NAME": "", + "VELA_REPO_ORG": "", + "VELA_REPO_OWNER": "", + "VELA_REPO_PIPELINE_TYPE": "", + "VELA_REPO_PRIVATE": "false", + "VELA_REPO_TIMEOUT": "0", + "VELA_REPO_TRUSTED": "false", + "VELA_REPO_VISIBILITY": "", + "VELA_RUNTIME": "TODO", + "VELA_SOURCE": "TODO", + "VELA_USER_ACTIVE": "false", + "VELA_USER_ADMIN": "false", + "VELA_USER_FAVORITES": "[]", + "VELA_USER_NAME": "", + "VELA_VERSION": "TODO", + "VELA_WORKSPACE": "/vela/src", + "HELLO": "Hello, Global Message", }, }, } @@ -437,105 +439,106 @@ func TestNative_EnvironmentSecrets(t *testing.T) { "foo": "bar", }, Environment: raw.StringSliceMap{ - "BUILD_AUTHOR": "", - "BUILD_AUTHOR_EMAIL": "", - "BUILD_BASE_REF": "", - "BUILD_BRANCH": "", - "BUILD_CHANNEL": "TODO", - "BUILD_CLONE": "", - "BUILD_COMMIT": "", - "BUILD_CREATED": "0", - "BUILD_ENQUEUED": "0", - "BUILD_EVENT": "", - "BUILD_HOST": "", - "BUILD_LINK": "", - "BUILD_MESSAGE": "", - "BUILD_NUMBER": "0", - "BUILD_PARENT": "0", - "BUILD_REF": "", - "BUILD_SENDER": "", - "BUILD_SOURCE": "", - "BUILD_STARTED": "0", - "BUILD_STATUS": "", - "BUILD_TITLE": "", - "BUILD_WORKSPACE": "/vela/src", - "CI": "true", - "PARAMETER_FOO": "bar", - "REPOSITORY_ACTIVE": "false", - "REPOSITORY_ALLOW_EVENTS": "", - "REPOSITORY_BRANCH": "", - "REPOSITORY_CLONE": "", - "REPOSITORY_FULL_NAME": "", - "REPOSITORY_LINK": "", - "REPOSITORY_NAME": "", - "REPOSITORY_ORG": "", - "REPOSITORY_PRIVATE": "false", - "REPOSITORY_TIMEOUT": "0", - "REPOSITORY_TRUSTED": "false", - "REPOSITORY_VISIBILITY": "", - "VELA": "true", - "VELA_ADDR": "TODO", - "VELA_BUILD_APPROVED_AT": "0", - "VELA_BUILD_APPROVED_BY": "", - "VELA_BUILD_AUTHOR": "", - "VELA_BUILD_AUTHOR_EMAIL": "", - "VELA_BUILD_BASE_REF": "", - "VELA_BUILD_BRANCH": "", - "VELA_BUILD_CHANNEL": "TODO", - "VELA_BUILD_CLONE": "", - "VELA_BUILD_COMMIT": "", - "VELA_BUILD_CREATED": "0", - "VELA_BUILD_DISTRIBUTION": "", - "VELA_BUILD_ENQUEUED": "0", - "VELA_BUILD_EVENT": "", - "VELA_BUILD_EVENT_ACTION": "", - "VELA_BUILD_HOST": "", - "VELA_BUILD_LINK": "", - "VELA_BUILD_MESSAGE": "", - "VELA_BUILD_NUMBER": "0", - "VELA_BUILD_PARENT": "0", - "VELA_BUILD_REF": "", - "VELA_BUILD_RUNTIME": "", - "VELA_BUILD_SENDER": "", - "VELA_BUILD_SOURCE": "", - "VELA_BUILD_STARTED": "0", - "VELA_BUILD_STATUS": "", - "VELA_BUILD_TITLE": "", - "VELA_BUILD_WORKSPACE": "/vela/src", - "VELA_CHANNEL": "TODO", - "VELA_DATABASE": "TODO", - "VELA_DISTRIBUTION": "TODO", - "VELA_HOST": "TODO", - "VELA_NETRC_MACHINE": "TODO", - "VELA_NETRC_PASSWORD": "", - "VELA_NETRC_USERNAME": "x-oauth-basic", - "VELA_QUEUE": "TODO", - "VELA_REPO_ACTIVE": "false", - "VELA_REPO_ALLOW_EVENTS": "", - "VELA_REPO_APPROVE_BUILD": "", - "VELA_REPO_BRANCH": "", - "VELA_REPO_TOPICS": "", - "VELA_REPO_BUILD_LIMIT": "0", - "VELA_REPO_CLONE": "", - "VELA_REPO_FULL_NAME": "", - "VELA_REPO_LINK": "", - "VELA_REPO_NAME": "", - "VELA_REPO_ORG": "", - "VELA_REPO_OWNER": "", - "VELA_REPO_PIPELINE_TYPE": "", - "VELA_REPO_PRIVATE": "false", - "VELA_REPO_TIMEOUT": "0", - "VELA_REPO_TRUSTED": "false", - "VELA_REPO_VISIBILITY": "", - "VELA_RUNTIME": "TODO", - "VELA_SOURCE": "TODO", - "VELA_USER_ACTIVE": "false", - "VELA_USER_ADMIN": "false", - "VELA_USER_FAVORITES": "[]", - "VELA_USER_NAME": "", - "VELA_VERSION": "TODO", - "VELA_WORKSPACE": "/vela/src", - "HELLO": "Hello, Global Message", + "BUILD_AUTHOR": "", + "BUILD_AUTHOR_EMAIL": "", + "BUILD_BASE_REF": "", + "BUILD_BRANCH": "", + "BUILD_CHANNEL": "TODO", + "BUILD_CLONE": "", + "BUILD_COMMIT": "", + "BUILD_CREATED": "0", + "BUILD_ENQUEUED": "0", + "BUILD_EVENT": "", + "BUILD_HOST": "", + "BUILD_LINK": "", + "BUILD_MESSAGE": "", + "BUILD_NUMBER": "0", + "BUILD_PARENT": "0", + "BUILD_REF": "", + "BUILD_SENDER": "", + "BUILD_SOURCE": "", + "BUILD_STARTED": "0", + "BUILD_STATUS": "", + "BUILD_TITLE": "", + "BUILD_WORKSPACE": "/vela/src", + "CI": "true", + "PARAMETER_FOO": "bar", + "REPOSITORY_ACTIVE": "false", + "REPOSITORY_ALLOW_EVENTS": "", + "REPOSITORY_BRANCH": "", + "REPOSITORY_CLONE": "", + "REPOSITORY_FULL_NAME": "", + "REPOSITORY_LINK": "", + "REPOSITORY_NAME": "", + "REPOSITORY_ORG": "", + "REPOSITORY_PRIVATE": "false", + "REPOSITORY_TIMEOUT": "0", + "REPOSITORY_TRUSTED": "false", + "REPOSITORY_VISIBILITY": "", + "VELA": "true", + "VELA_ADDR": "TODO", + "VELA_BUILD_APPROVED_AT": "0", + "VELA_BUILD_APPROVED_BY": "", + "VELA_BUILD_AUTHOR": "", + "VELA_BUILD_AUTHOR_EMAIL": "", + "VELA_BUILD_BASE_REF": "", + "VELA_BUILD_BRANCH": "", + "VELA_BUILD_CHANNEL": "TODO", + "VELA_BUILD_CLONE": "", + "VELA_BUILD_COMMIT": "", + "VELA_BUILD_CREATED": "0", + "VELA_BUILD_DISTRIBUTION": "", + "VELA_BUILD_ENQUEUED": "0", + "VELA_BUILD_EVENT": "", + "VELA_BUILD_EVENT_ACTION": "", + "VELA_BUILD_HOST": "", + "VELA_BUILD_LINK": "", + "VELA_BUILD_MESSAGE": "", + "VELA_BUILD_NUMBER": "0", + "VELA_BUILD_PARENT": "0", + "VELA_BUILD_REF": "", + "VELA_BUILD_RUNTIME": "", + "VELA_BUILD_SENDER": "", + "VELA_BUILD_SENDER_SCM_ID": "", + "VELA_BUILD_SOURCE": "", + "VELA_BUILD_STARTED": "0", + "VELA_BUILD_STATUS": "", + "VELA_BUILD_TITLE": "", + "VELA_BUILD_WORKSPACE": "/vela/src", + "VELA_CHANNEL": "TODO", + "VELA_DATABASE": "TODO", + "VELA_DISTRIBUTION": "TODO", + "VELA_HOST": "TODO", + "VELA_NETRC_MACHINE": "TODO", + "VELA_NETRC_PASSWORD": "", + "VELA_NETRC_USERNAME": "x-oauth-basic", + "VELA_QUEUE": "TODO", + "VELA_REPO_ACTIVE": "false", + "VELA_REPO_ALLOW_EVENTS": "", + "VELA_REPO_APPROVE_BUILD": "", + "VELA_REPO_BRANCH": "", + "VELA_REPO_TOPICS": "", + "VELA_REPO_BUILD_LIMIT": "0", + "VELA_REPO_CLONE": "", + "VELA_REPO_FULL_NAME": "", + "VELA_REPO_LINK": "", + "VELA_REPO_NAME": "", + "VELA_REPO_ORG": "", + "VELA_REPO_OWNER": "", + "VELA_REPO_PIPELINE_TYPE": "", + "VELA_REPO_PRIVATE": "false", + "VELA_REPO_TIMEOUT": "0", + "VELA_REPO_TRUSTED": "false", + "VELA_REPO_VISIBILITY": "", + "VELA_RUNTIME": "TODO", + "VELA_SOURCE": "TODO", + "VELA_USER_ACTIVE": "false", + "VELA_USER_ADMIN": "false", + "VELA_USER_FAVORITES": "[]", + "VELA_USER_NAME": "", + "VELA_VERSION": "TODO", + "VELA_WORKSPACE": "/vela/src", + "HELLO": "Hello, Global Message", }, }, }, @@ -589,38 +592,38 @@ func TestNative_environment(t *testing.T) { // push { w: workspace, - b: &api.Build{ID: &num64, Repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, Number: &num, Parent: &num, Event: &push, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &str, BaseRef: &str}, + b: &api.Build{ID: &num64, Repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, Number: &num, Parent: &num, Event: &push, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, SenderSCMID: &str, Author: &str, Branch: &str, Ref: &str, BaseRef: &str}, m: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, r: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, u: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, - want: map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "push", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "foo", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "push", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "foo", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_OWNER": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, + want: map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "push", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "foo", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "push", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "foo", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SENDER_SCM_ID": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_OWNER": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, }, // tag { w: workspace, - b: &api.Build{ID: &num64, Repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, Number: &num, Parent: &num, Event: &tag, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &tagref, BaseRef: &str}, + b: &api.Build{ID: &num64, Repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, Number: &num, Parent: &num, Event: &tag, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, SenderSCMID: &str, Author: &str, Branch: &str, Ref: &tagref, BaseRef: &str}, m: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, r: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, u: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, - want: map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "tag", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "refs/tags/1", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TAG": "1", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "tag", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "refs/tags/1", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TAG": "1", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_OWNER": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, + want: map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "tag", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "refs/tags/1", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TAG": "1", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "tag", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "refs/tags/1", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SENDER_SCM_ID": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TAG": "1", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_OWNER": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, }, // pull_request { w: workspace, - b: &api.Build{ID: &num64, Repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, Number: &num, Parent: &num, Event: &pull, EventAction: &pullact, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &pullref, BaseRef: &str}, + b: &api.Build{ID: &num64, Repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, Number: &num, Parent: &num, Event: &pull, EventAction: &pullact, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, SenderSCMID: &str, Author: &str, Branch: &str, Ref: &pullref, BaseRef: &str}, m: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, r: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, u: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, - want: map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "pull_request", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_PULL_REQUEST_NUMBER": "1", "BUILD_REF": "refs/pull/1/head", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "pull_request", "VELA_BUILD_EVENT_ACTION": "opened", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_PULL_REQUEST": "1", "VELA_BUILD_REF": "refs/pull/1/head", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_PULL_REQUEST": "1", "VELA_PULL_REQUEST_SOURCE": "", "VELA_PULL_REQUEST_TARGET": "foo", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_OWNER": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, + want: map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "pull_request", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_PULL_REQUEST_NUMBER": "1", "BUILD_REF": "refs/pull/1/head", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "pull_request", "VELA_BUILD_EVENT_ACTION": "opened", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_PULL_REQUEST": "1", "VELA_BUILD_REF": "refs/pull/1/head", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SENDER_SCM_ID": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_PULL_REQUEST": "1", "VELA_PULL_REQUEST_SOURCE": "", "VELA_PULL_REQUEST_TARGET": "foo", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_OWNER": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, }, // deployment { w: workspace, - b: &api.Build{ID: &num64, Repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, Number: &num, Parent: &num, Event: &deploy, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &target, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &pullref, BaseRef: &str}, + b: &api.Build{ID: &num64, Repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, Number: &num, Parent: &num, Event: &deploy, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &target, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, SenderSCMID: &str, Author: &str, Branch: &str, Ref: &pullref, BaseRef: &str}, m: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, r: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, u: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, - want: map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "deployment", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "refs/pull/1/head", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TARGET": "production", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "deployment", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "refs/pull/1/head", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TARGET": "production", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DEPLOYMENT": "production", "VELA_DEPLOYMENT_NUMBER": "0", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_OWNER": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, + want: map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "deployment", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "refs/pull/1/head", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TARGET": "production", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "deployment", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "refs/pull/1/head", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SENDER_SCM_ID": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TARGET": "production", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DEPLOYMENT": "production", "VELA_DEPLOYMENT_NUMBER": "0", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_OWNER": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, }, } @@ -705,31 +708,31 @@ func Test_client_EnvironmentBuild(t *testing.T) { want map[string]string }{ {"push", fields{ - build: &api.Build{ID: &num64, Repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, Number: &num, Parent: &num, Event: &push, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &str, BaseRef: &str}, + build: &api.Build{ID: &num64, Repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, Number: &num, Parent: &num, Event: &push, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, SenderSCMID: &str, Author: &str, Branch: &str, Ref: &str, BaseRef: &str}, metadata: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, user: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, - }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "push", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "foo", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "push", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "foo", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_OWNER": "foo", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}}, + }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "push", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "foo", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "push", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "foo", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SENDER_SCM_ID": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_OWNER": "foo", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}}, {"tag", fields{ - build: &api.Build{ID: &num64, Repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, Number: &num, Parent: &num, Event: &tag, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &tagref, BaseRef: &str}, + build: &api.Build{ID: &num64, Repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, Number: &num, Parent: &num, Event: &tag, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, SenderSCMID: &str, Author: &str, Branch: &str, Ref: &tagref, BaseRef: &str}, metadata: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, user: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, - }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "tag", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "refs/tags/1", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TAG": "1", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "tag", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "refs/tags/1", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TAG": "1", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_OWNER": "foo", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, + }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "tag", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "refs/tags/1", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TAG": "1", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "tag", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "refs/tags/1", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SENDER_SCM_ID": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TAG": "1", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_OWNER": "foo", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, }, {"pull_request", fields{ - build: &api.Build{ID: &num64, Repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, Number: &num, Parent: &num, Event: &pull, EventAction: &pullact, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &pullref, BaseRef: &str}, + build: &api.Build{ID: &num64, Repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, Number: &num, Parent: &num, Event: &pull, EventAction: &pullact, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, SenderSCMID: &str, Author: &str, Branch: &str, Ref: &pullref, BaseRef: &str}, metadata: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, user: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, - }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "pull_request", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_PULL_REQUEST_NUMBER": "1", "BUILD_REF": "refs/pull/1/head", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "pull_request", "VELA_BUILD_EVENT_ACTION": "opened", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_PULL_REQUEST": "1", "VELA_BUILD_REF": "refs/pull/1/head", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_PULL_REQUEST": "1", "VELA_PULL_REQUEST_SOURCE": "", "VELA_PULL_REQUEST_TARGET": "foo", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_OWNER": "foo", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, + }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "pull_request", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_PULL_REQUEST_NUMBER": "1", "BUILD_REF": "refs/pull/1/head", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "pull_request", "VELA_BUILD_EVENT_ACTION": "opened", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_PULL_REQUEST": "1", "VELA_BUILD_REF": "refs/pull/1/head", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SENDER_SCM_ID": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_PULL_REQUEST": "1", "VELA_PULL_REQUEST_SOURCE": "", "VELA_PULL_REQUEST_TARGET": "foo", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_OWNER": "foo", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, }, {"deployment", fields{ - build: &api.Build{ID: &num64, Repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, Number: &num, Parent: &num, Event: &deploy, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &target, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, Author: &str, Branch: &str, Ref: &pullref, BaseRef: &str}, + build: &api.Build{ID: &num64, Repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, Number: &num, Parent: &num, Event: &deploy, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &target, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, SenderSCMID: &str, Author: &str, Branch: &str, Ref: &pullref, BaseRef: &str}, metadata: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, user: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, - }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "deployment", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "refs/pull/1/head", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TARGET": "production", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "deployment", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "refs/pull/1/head", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TARGET": "production", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DEPLOYMENT": "production", "VELA_DEPLOYMENT_NUMBER": "0", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_OWNER": "foo", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, + }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "deployment", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "refs/pull/1/head", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TARGET": "production", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "deployment", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "refs/pull/1/head", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SENDER_SCM_ID": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TARGET": "production", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DEPLOYMENT": "production", "VELA_DEPLOYMENT_NUMBER": "0", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_OWNER": "foo", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, }, } for _, tt := range tests { diff --git a/database/build/create_test.go b/database/build/create_test.go index 83b6f5a2c..9f9d72399 100644 --- a/database/build/create_test.go +++ b/database/build/create_test.go @@ -42,9 +42,9 @@ func TestBuild_Engine_CreateBuild(t *testing.T) { // ensure the mock expects the query _mock.ExpectQuery(`INSERT INTO "builds" -("repo_id","pipeline_id","number","parent","event","event_action","status","error","enqueued","created","started","finished","deploy","deploy_number","deploy_payload","clone","source","title","message","commit","sender","author","email","link","branch","ref","base_ref","head_ref","host","runtime","distribution","approved_at","approved_by","id") -VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$30,$31,$32,$33,$34) RETURNING "id"`). - WithArgs(1, nil, 1, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, AnyArgument{}, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 1). +("repo_id","pipeline_id","number","parent","event","event_action","status","error","enqueued","created","started","finished","deploy","deploy_number","deploy_payload","clone","source","title","message","commit","sender","sender_scm_id","author","email","link","branch","ref","base_ref","head_ref","host","runtime","distribution","approved_at","approved_by","id") +VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$30,$31,$32,$33,$34,$35) RETURNING "id"`). + WithArgs(1, nil, 1, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, AnyArgument{}, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 1). WillReturnRows(_rows) _sqlite := testSqlite(t) diff --git a/database/build/list_dashboard_test.go b/database/build/list_dashboard_test.go index 81a042296..803c19db2 100644 --- a/database/build/list_dashboard_test.go +++ b/database/build/list_dashboard_test.go @@ -50,9 +50,9 @@ func TestBuild_Engine_ListBuildsForDashboardRepo(t *testing.T) { // create expected query result in mock _rows := sqlmock.NewRows( - []string{"id", "repo_id", "pipeline_id", "number", "parent", "event", "event_action", "status", "error", "enqueued", "created", "started", "finished", "deploy", "deploy_payload", "clone", "source", "title", "message", "commit", "sender", "author", "email", "link", "branch", "ref", "base_ref", "head_ref", "host", "runtime", "distribution", "approved_at", "approved_by", "timestamp"}). - AddRow(2, 1, nil, 2, 0, "pull_request", "", "", "", 0, 2, 0, 0, "", nil, "", "", "", "", "", "", "", "", "", "main", "", "", "", "", "", "", 0, "", 0). - AddRow(1, 1, nil, 1, 0, "push", "", "", "", 0, 1, 0, 0, "", nil, "", "", "", "", "", "", "", "", "", "main", "", "", "", "", "", "", 0, "", 0) + []string{"id", "repo_id", "pipeline_id", "number", "parent", "event", "event_action", "status", "error", "enqueued", "created", "started", "finished", "deploy", "deploy_payload", "clone", "source", "title", "message", "commit", "sender", "sender_scm_id", "author", "email", "link", "branch", "ref", "base_ref", "head_ref", "host", "runtime", "distribution", "approved_at", "approved_by", "timestamp"}). + AddRow(2, 1, nil, 2, 0, "pull_request", "", "", "", 0, 2, 0, 0, "", nil, "", "", "", "", "", "", "", "", "", "", "main", "", "", "", "", "", "", 0, "", 0). + AddRow(1, 1, nil, 1, 0, "push", "", "", "", 0, 1, 0, 0, "", nil, "", "", "", "", "", "", "", "", "", "", "main", "", "", "", "", "", "", 0, "", 0) // ensure the mock expects the query _mock.ExpectQuery(`SELECT * FROM "builds" WHERE repo_id = $1 AND branch IN ($2) AND event IN ($3,$4) ORDER BY number DESC LIMIT $5`).WithArgs(1, "main", "push", "pull_request", 5).WillReturnRows(_rows) diff --git a/database/build/table.go b/database/build/table.go index fde722a17..8d1ca461e 100644 --- a/database/build/table.go +++ b/database/build/table.go @@ -36,6 +36,7 @@ builds ( message VARCHAR(2000), commit VARCHAR(500), sender VARCHAR(250), + sender_scm_id VARCHAR(250), author VARCHAR(250), email VARCHAR(500), link VARCHAR(1000), @@ -80,6 +81,7 @@ builds ( message TEXT, 'commit' TEXT, sender TEXT, + sender_scm_id TEXT, author TEXT, email TEXT, link TEXT, diff --git a/database/build/update_test.go b/database/build/update_test.go index 149779780..4c0c1137e 100644 --- a/database/build/update_test.go +++ b/database/build/update_test.go @@ -41,9 +41,9 @@ func TestBuild_Engine_UpdateBuild(t *testing.T) { // ensure the mock expects the query _mock.ExpectExec(`UPDATE "builds" -SET "repo_id"=$1,"pipeline_id"=$2,"number"=$3,"parent"=$4,"event"=$5,"event_action"=$6,"status"=$7,"error"=$8,"enqueued"=$9,"created"=$10,"started"=$11,"finished"=$12,"deploy"=$13,"deploy_number"=$14,"deploy_payload"=$15,"clone"=$16,"source"=$17,"title"=$18,"message"=$19,"commit"=$20,"sender"=$21,"author"=$22,"email"=$23,"link"=$24,"branch"=$25,"ref"=$26,"base_ref"=$27,"head_ref"=$28,"host"=$29,"runtime"=$30,"distribution"=$31,"approved_at"=$32,"approved_by"=$33 -WHERE "id" = $34`). - WithArgs(1, nil, 1, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, AnyArgument{}, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 1). +SET "repo_id"=$1,"pipeline_id"=$2,"number"=$3,"parent"=$4,"event"=$5,"event_action"=$6,"status"=$7,"error"=$8,"enqueued"=$9,"created"=$10,"started"=$11,"finished"=$12,"deploy"=$13,"deploy_number"=$14,"deploy_payload"=$15,"clone"=$16,"source"=$17,"title"=$18,"message"=$19,"commit"=$20,"sender"=$21,"sender_scm_id"=$22,"author"=$23,"email"=$24,"link"=$25,"branch"=$26,"ref"=$27,"base_ref"=$28,"head_ref"=$29,"host"=$30,"runtime"=$31,"distribution"=$32,"approved_at"=$33,"approved_by"=$34 +WHERE "id" = $35`). + WithArgs(1, nil, 1, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, AnyArgument{}, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 1). WillReturnResult(sqlmock.NewResult(1, 1)) _sqlite := testSqlite(t) diff --git a/database/integration_test.go b/database/integration_test.go index e1bdcffd3..8996ca9fe 100644 --- a/database/integration_test.go +++ b/database/integration_test.go @@ -2311,6 +2311,7 @@ func newResources() *Resources { buildOne.SetMessage("First commit...") buildOne.SetCommit("48afb5bdc41ad69bf22588491333f7cf71135163") buildOne.SetSender("OctoKitty") + buildOne.SetSenderSCMID("123") buildOne.SetAuthor("OctoKitty") buildOne.SetEmail("OctoKitty@github.com") buildOne.SetLink("https://example.company.com/github/octocat/1") @@ -2347,6 +2348,7 @@ func newResources() *Resources { buildTwo.SetMessage("Second commit...") buildTwo.SetCommit("48afb5bdc41ad69bf22588491333f7cf71135164") buildTwo.SetSender("OctoKitty") + buildTwo.SetSenderSCMID("123") buildTwo.SetAuthor("OctoKitty") buildTwo.SetEmail("OctoKitty@github.com") buildTwo.SetLink("https://example.company.com/github/octocat/2") diff --git a/database/testutils/api_resources.go b/database/testutils/api_resources.go index 06b34eba8..a418ee363 100644 --- a/database/testutils/api_resources.go +++ b/database/testutils/api_resources.go @@ -36,6 +36,7 @@ func APIBuild() *api.Build { Message: new(string), Commit: new(string), Sender: new(string), + SenderSCMID: new(string), Author: new(string), Email: new(string), Link: new(string), diff --git a/database/types/build.go b/database/types/build.go index 4023836e6..66157607e 100644 --- a/database/types/build.go +++ b/database/types/build.go @@ -54,6 +54,7 @@ type Build struct { Message sql.NullString `sql:"message"` Commit sql.NullString `sql:"commit"` Sender sql.NullString `sql:"sender"` + SenderSCMID sql.NullString `sql:"sender_scm_id"` Author sql.NullString `sql:"author"` Email sql.NullString `sql:"email"` Link sql.NullString `sql:"link"` @@ -209,6 +210,11 @@ func (b *Build) Nullify() *Build { b.Sender.Valid = false } + // check if the SenderSCMID field should be false + if len(b.SenderSCMID.String) == 0 { + b.SenderSCMID.Valid = false + } + // check if the Author field should be false if len(b.Author.String) == 0 { b.Author.Valid = false @@ -299,6 +305,7 @@ func (b *Build) ToAPI() *api.Build { build.SetMessage(b.Message.String) build.SetCommit(b.Commit.String) build.SetSender(b.Sender.String) + build.SetSenderSCMID(b.SenderSCMID.String) build.SetAuthor(b.Author.String) build.SetEmail(b.Email.String) build.SetLink(b.Link.String) @@ -342,6 +349,7 @@ func (b *Build) Validate() error { b.Message = sql.NullString{String: util.Sanitize(b.Message.String), Valid: b.Message.Valid} b.Commit = sql.NullString{String: util.Sanitize(b.Commit.String), Valid: b.Commit.Valid} b.Sender = sql.NullString{String: util.Sanitize(b.Sender.String), Valid: b.Sender.Valid} + b.SenderSCMID = sql.NullString{String: util.Sanitize(b.SenderSCMID.String), Valid: b.SenderSCMID.Valid} b.Author = sql.NullString{String: util.Sanitize(b.Author.String), Valid: b.Author.Valid} b.Email = sql.NullString{String: util.Sanitize(b.Email.String), Valid: b.Email.Valid} b.Link = sql.NullString{String: util.Sanitize(b.Link.String), Valid: b.Link.Valid} @@ -383,6 +391,7 @@ func BuildFromAPI(b *api.Build) *Build { Message: sql.NullString{String: b.GetMessage(), Valid: true}, Commit: sql.NullString{String: b.GetCommit(), Valid: true}, Sender: sql.NullString{String: b.GetSender(), Valid: true}, + SenderSCMID: sql.NullString{String: b.GetSenderSCMID(), Valid: true}, Author: sql.NullString{String: b.GetAuthor(), Valid: true}, Email: sql.NullString{String: b.GetEmail(), Valid: true}, Link: sql.NullString{String: b.GetLink(), Valid: true}, diff --git a/database/types/build_test.go b/database/types/build_test.go index 04a88d923..3eb12f142 100644 --- a/database/types/build_test.go +++ b/database/types/build_test.go @@ -133,6 +133,7 @@ func TestTypes_Build_ToAPI(t *testing.T) { want.SetMessage("First commit...") want.SetCommit("48afb5bdc41ad69bf22588491333f7cf71135163") want.SetSender("OctoKitty") + want.SetSenderSCMID("123") want.SetAuthor("OctoKitty") want.SetEmail("OctoKitty@github.com") want.SetLink("https://example.company.com/github/octocat/1") @@ -228,6 +229,7 @@ func TestTypes_Build_BuildFromAPI(t *testing.T) { b.SetMessage("First commit...") b.SetCommit("48afb5bdc41ad69bf22588491333f7cf71135163") b.SetSender("OctoKitty") + b.SetSenderSCMID("123") b.SetAuthor("OctoKitty") b.SetEmail("OctoKitty@github.com") b.SetLink("https://example.company.com/github/octocat/1") @@ -291,6 +293,7 @@ func testBuild() *Build { Message: sql.NullString{String: "First commit...", Valid: true}, Commit: sql.NullString{String: "48afb5bdc41ad69bf22588491333f7cf71135163", Valid: true}, Sender: sql.NullString{String: "OctoKitty", Valid: true}, + SenderSCMID: sql.NullString{String: "123", Valid: true}, Author: sql.NullString{String: "OctoKitty", Valid: true}, Email: sql.NullString{String: "OctoKitty@github.com", Valid: true}, Link: sql.NullString{String: "https://example.company.com/github/octocat/1", Valid: true}, diff --git a/mock/server/build.go b/mock/server/build.go index 37466b910..36e9234d2 100644 --- a/mock/server/build.go +++ b/mock/server/build.go @@ -85,6 +85,7 @@ const ( "message": "First commit...", "commit": "48afb5bdc41ad69bf22588491333f7cf71135163", "sender": "OctoKitty", + "sender_scm_id": "0", "author": "OctoKitty", "email": "octokitty@github.com", "link": "https://vela.example.company.com/github/octocat/1", diff --git a/router/middleware/build/build_test.go b/router/middleware/build/build_test.go index d6d600b30..e95036c54 100644 --- a/router/middleware/build/build_test.go +++ b/router/middleware/build/build_test.go @@ -75,6 +75,7 @@ func TestBuild_Establish(t *testing.T) { want.SetMessage("") want.SetCommit("") want.SetSender("") + want.SetSenderSCMID("") want.SetAuthor("") want.SetEmail("") want.SetLink("") diff --git a/scm/github/user.go b/scm/github/user.go new file mode 100644 index 000000000..e50cc19ff --- /dev/null +++ b/scm/github/user.go @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: Apache-2.0 + +package github + +import ( + "context" + "fmt" + + "github.com/sirupsen/logrus" +) + +// GetUserID captures the user's scm id. +func (c *client) GetUserID(ctx context.Context, name string, token string) (string, error) { + c.Logger.WithFields(logrus.Fields{ + "user": name, + }).Tracef("capturing SCM user id for %s", name) + + // create GitHub OAuth client with user's token + client := c.newClientToken(token) + + // send API call to capture user + user, _, err := client.Users.Get(ctx, name) + if err != nil { + return "", err + } + + return fmt.Sprint(user.GetID()), nil +} diff --git a/scm/github/webhook.go b/scm/github/webhook.go index 0d0f1fb50..3092ae63e 100644 --- a/scm/github/webhook.go +++ b/scm/github/webhook.go @@ -69,7 +69,7 @@ func (c *client) ProcessWebhook(ctx context.Context, request *http.Request) (*in // process the event from the webhook switch event := event.(type) { case *github.PushEvent: - return c.processPushEvent(h, event) + return c.processPushEvent(ctx, h, event) case *github.PullRequestEvent: return c.processPREvent(h, event) case *github.DeploymentEvent: @@ -128,7 +128,7 @@ func (c *client) RedeliverWebhook(ctx context.Context, u *api.User, r *api.Repo, } // processPushEvent is a helper function to process the push event. -func (c *client) processPushEvent(h *library.Hook, payload *github.PushEvent) (*internal.Webhook, error) { +func (c *client) processPushEvent(ctx context.Context, h *library.Hook, payload *github.PushEvent) (*internal.Webhook, error) { c.Logger.WithFields(logrus.Fields{ "org": payload.GetRepo().GetOwner().GetLogin(), "repo": payload.GetRepo().GetName(), @@ -156,6 +156,7 @@ func (c *client) processPushEvent(h *library.Hook, payload *github.PushEvent) (* b.SetMessage(payload.GetHeadCommit().GetMessage()) b.SetCommit(payload.GetHeadCommit().GetID()) b.SetSender(payload.GetSender().GetLogin()) + b.SetSenderSCMID(fmt.Sprint(payload.GetSender().GetID())) b.SetAuthor(payload.GetHeadCommit().GetAuthor().GetLogin()) b.SetEmail(payload.GetHeadCommit().GetAuthor().GetEmail()) b.SetBranch(strings.TrimPrefix(payload.GetRef(), "refs/heads/")) @@ -275,7 +276,7 @@ func (c *client) processPREvent(h *library.Hook, payload *github.PullRequestEven r.SetPrivate(repo.GetPrivate()) r.SetTopics(repo.Topics) - // convert payload to library build + // convert payload to api build b := new(api.Build) b.SetEvent(constants.EventPull) b.SetEventAction(payload.GetAction()) @@ -285,6 +286,7 @@ func (c *client) processPREvent(h *library.Hook, payload *github.PullRequestEven b.SetMessage(payload.GetPullRequest().GetTitle()) b.SetCommit(payload.GetPullRequest().GetHead().GetSHA()) b.SetSender(payload.GetSender().GetLogin()) + b.SetSenderSCMID(fmt.Sprint(payload.GetSender().GetID())) b.SetAuthor(payload.GetPullRequest().GetUser().GetLogin()) b.SetEmail(payload.GetPullRequest().GetUser().GetEmail()) b.SetBranch(payload.GetPullRequest().GetBase().GetRef()) @@ -305,6 +307,7 @@ func (c *client) processPREvent(h *library.Hook, payload *github.PullRequestEven // ensure the build sender is set if len(b.GetSender()) == 0 { b.SetSender(payload.GetPullRequest().GetUser().GetLogin()) + b.SetSenderSCMID(fmt.Sprint(payload.GetPullRequest().GetUser().GetID())) } // ensure the build email is set @@ -360,7 +363,7 @@ func (c *client) processDeploymentEvent(h *library.Hook, payload *github.Deploym r.SetPrivate(repo.GetPrivate()) r.SetTopics(repo.Topics) - // convert payload to library build + // convert payload to api build b := new(api.Build) b.SetEvent(constants.EventDeploy) b.SetEventAction(constants.ActionCreated) @@ -372,6 +375,8 @@ func (c *client) processDeploymentEvent(h *library.Hook, payload *github.Deploym b.SetMessage(payload.GetDeployment().GetDescription()) b.SetCommit(payload.GetDeployment().GetSHA()) b.SetSender(payload.GetSender().GetLogin()) + b.SetSenderSCMID(fmt.Sprint(payload.GetSender().GetID())) + b.SetAuthor(payload.GetDeployment().GetCreator().GetLogin()) b.SetEmail(payload.GetDeployment().GetCreator().GetEmail()) b.SetBranch(payload.GetDeployment().GetRef()) @@ -485,6 +490,7 @@ func (c *client) processIssueCommentEvent(h *library.Hook, payload *github.Issue b.SetTitle(fmt.Sprintf("%s received from %s", constants.EventComment, repo.GetHTMLURL())) b.SetMessage(payload.Issue.GetTitle()) b.SetSender(payload.GetSender().GetLogin()) + b.SetSenderSCMID(fmt.Sprint(payload.GetSender().GetID())) b.SetAuthor(payload.GetIssue().GetUser().GetLogin()) b.SetEmail(payload.GetIssue().GetUser().GetEmail()) b.SetRef(fmt.Sprintf("refs/pull/%d/head", payload.GetIssue().GetNumber())) diff --git a/scm/github/webhook_test.go b/scm/github/webhook_test.go index baf8bf722..b2f8f5e98 100644 --- a/scm/github/webhook_test.go +++ b/scm/github/webhook_test.go @@ -75,6 +75,7 @@ func TestGithub_ProcessWebhook_Push(t *testing.T) { wantBuild.SetMessage("Update README.md") wantBuild.SetCommit("9c93babf58917cd6f6f6772b5df2b098f507ff95") wantBuild.SetSender("Codertocat") + wantBuild.SetSenderSCMID("21031067") wantBuild.SetAuthor("Codertocat") wantBuild.SetEmail("21031067+Codertocat@users.noreply.github.com") wantBuild.SetBranch("main") @@ -153,6 +154,7 @@ func TestGithub_ProcessWebhook_Push_NoSender(t *testing.T) { wantBuild.SetMessage("Update README.md") wantBuild.SetCommit("9c93babf58917cd6f6f6772b5df2b098f507ff95") wantBuild.SetSender("Codertocat") + wantBuild.SetSenderSCMID("0") wantBuild.SetAuthor("Codertocat") wantBuild.SetEmail("21031067+Codertocat@users.noreply.github.com") wantBuild.SetBranch("main") @@ -171,8 +173,8 @@ func TestGithub_ProcessWebhook_Push_NoSender(t *testing.T) { t.Errorf("ProcessWebhook returned err: %v", err) } - if !reflect.DeepEqual(got, want) { - t.Errorf("ProcessWebhook is %v, want %v", got, want) + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("ProcessWebhook() mismatch (-want +got):\n%s", diff) } } @@ -230,6 +232,7 @@ func TestGithub_ProcessWebhook_Push_Branch_Delete(t *testing.T) { wantBuild.SetMessage("main branch deleted") wantBuild.SetCommit("d3d9188fc87a6977343e922c128f162a86018d76") wantBuild.SetSender("Codertocat") + wantBuild.SetSenderSCMID("21031067") wantBuild.SetAuthor("Codertocat") wantBuild.SetEmail("21031067+Codertocat@users.noreply.github.com") wantBuild.SetBranch("main") @@ -307,6 +310,7 @@ func TestGithub_ProcessWebhook_Push_Tag_Delete(t *testing.T) { wantBuild.SetMessage("v0.1 tag deleted") wantBuild.SetCommit("d3d9188fc87a6977343e922c128f162a86018d76") wantBuild.SetSender("Codertocat") + wantBuild.SetSenderSCMID("21031067") wantBuild.SetAuthor("Codertocat") wantBuild.SetEmail("21031067+Codertocat@users.noreply.github.com") wantBuild.SetBranch("v0.1") @@ -366,6 +370,7 @@ func TestGithub_ProcessWebhook_PullRequest(t *testing.T) { wantBuild.SetMessage("Update the README with new information") wantBuild.SetCommit("34c5c7793cb3b279e22454cb6750c80560547b3a") wantBuild.SetSender("Codertocat") + wantBuild.SetSenderSCMID("21031067") wantBuild.SetAuthor("Codertocat") wantBuild.SetEmail("") wantBuild.SetBranch("main") @@ -382,6 +387,7 @@ func TestGithub_ProcessWebhook_PullRequest(t *testing.T) { wantBuild2.SetMessage("Update the README with new information") wantBuild2.SetCommit("34c5c7793cb3b279e22454cb6750c80560547b3a") wantBuild2.SetSender("Codertocat") + wantBuild2.SetSenderSCMID("21031067") wantBuild2.SetAuthor("Codertocat") wantBuild2.SetEmail("") wantBuild2.SetBranch("main") @@ -398,6 +404,7 @@ func TestGithub_ProcessWebhook_PullRequest(t *testing.T) { wantBuild3.SetMessage("Update the README with new information") wantBuild3.SetCommit("34c5c7793cb3b279e22454cb6750c80560547b3a") wantBuild3.SetSender("Codertocat") + wantBuild3.SetSenderSCMID("21031067") wantBuild3.SetAuthor("Codertocat") wantBuild3.SetEmail("") wantBuild3.SetBranch("main") @@ -414,6 +421,7 @@ func TestGithub_ProcessWebhook_PullRequest(t *testing.T) { wantBuild4.SetMessage("Update the README with new information") wantBuild4.SetCommit("34c5c7793cb3b279e22454cb6750c80560547b3a") wantBuild4.SetSender("Codertocat") + wantBuild4.SetSenderSCMID("21031067") wantBuild4.SetAuthor("Codertocat") wantBuild4.SetEmail("") wantBuild4.SetBranch("main") @@ -599,6 +607,7 @@ func TestGithub_ProcessWebhook_Deployment(t *testing.T) { wantBuild.SetMessage("") wantBuild.SetCommit("f95f852bd8fca8fcc58a9a2d6c842781e32a215e") wantBuild.SetSender("Codertocat") + wantBuild.SetSenderSCMID("21031067") wantBuild.SetAuthor("Codertocat") wantBuild.SetEmail("") wantBuild.SetBranch("main") @@ -734,6 +743,7 @@ func TestGithub_ProcessWebhook_Deployment_Commit(t *testing.T) { wantBuild.SetMessage("") wantBuild.SetCommit("f95f852bd8fca8fcc58a9a2d6c842781e32a215e") wantBuild.SetSender("Codertocat") + wantBuild.SetSenderSCMID("21031067") wantBuild.SetAuthor("Codertocat") wantBuild.SetEmail("") wantBuild.SetBranch("main") @@ -1002,6 +1012,7 @@ func TestGithub_ProcessWebhook_IssueComment_PR(t *testing.T) { wantBuild.SetTitle("comment received from https://github.com/Codertocat/Hello-World") wantBuild.SetMessage("Update the README with new information") wantBuild.SetSender("Codertocat") + wantBuild.SetSenderSCMID("2172") wantBuild.SetAuthor("Codertocat") wantBuild.SetEmail("") wantBuild.SetRef("refs/pull/1/head") @@ -1022,8 +1033,8 @@ func TestGithub_ProcessWebhook_IssueComment_PR(t *testing.T) { t.Errorf("ProcessWebhook returned err: %v", err) } - if !reflect.DeepEqual(got, want) { - t.Errorf("ProcessWebhook is %v, want %v", got, want) + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("ProcessWebhook() mismatch (-want +got):\n%s", diff) } } diff --git a/scm/service.go b/scm/service.go index b65a529eb..88bb5ecf3 100644 --- a/scm/service.go +++ b/scm/service.go @@ -41,6 +41,12 @@ type Service interface { // the OAuth workflow for the session. Login(context.Context, http.ResponseWriter, *http.Request) (string, error) + // User SCM Interface Functions + + // GetUserID defines a function that captures + // the scm user id attached to the username. + GetUserID(context.Context, string, string) (string, error) + // Access SCM Interface Functions // OrgAccess defines a function that captures From a0b14ae60d76c6511f75a9f8344419658c1e268e Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Wed, 5 Jun 2024 09:59:32 -0500 Subject: [PATCH 58/71] feat!: Vela OIDC provider (#1120) * init commit * some renaming and comment fixing * tests and renaming things here and there, plus pull in types * update subject * integration test * pull in types and add event to subject * address lint review feedback * fix tests * more integration test fixes * bytes buffer for exponent * correct issuer and add commands claim * sender to actor * use lestrrat jwx lib for jwks * fixes * more fixes * use wrapper for swagger jwk set * address feedback * enhance: add build_id and actor_id to claims * enhance: complete adding build_id and actor_id to claims * enhance: complete adding build_id and actor_id to claims * fix: apply context to GenerateRSA * fix: add err check to ParseBool * enhance: audience validation * enhance: better audience validation * enhance: add query parameter input validation * tweak: order of operations, move sanitize lower * enhance: add scm user id to build obj * enhance: add GetUserID to scm interface * fix: apply missing scm id using scm client lookups * chore: verbose comment on fallback user fetch * chore: comment typo * enhance: use repo owner token in schedule processing * enhance: use repo owner token in restart build * enhance: change claims actor_id to actor_scm_id --------- Co-authored-by: davidvader --- api/admin/rotate_keys.go | 53 +++ api/build/id_request_token.go | 152 ++++++++ api/build/id_token.go | 138 +++++++ api/build/token.go | 2 +- api/jwks.go | 47 +++ api/oi_config.go | 63 ++++ api/types/oidc.go | 43 +++ cmd/vela-server/main.go | 6 + cmd/vela-server/server.go | 7 +- cmd/vela-server/token.go | 19 +- compiler/native/environment.go | 1 + compiler/native/environment_test.go | 16 +- constants/secret.go | 33 ++ constants/status.go | 33 ++ constants/table.go | 3 + constants/token.go | 33 ++ constants/visibility.go | 16 + database/database.go | 2 + database/integration_test.go | 96 +++++ database/interface.go | 4 + database/jwk/create.go | 27 ++ database/jwk/create_test.go | 72 ++++ database/jwk/get.go | 33 ++ database/jwk/get_test.go | 87 +++++ database/jwk/interface.go | 33 ++ database/jwk/jwk.go | 77 ++++ database/jwk/jwk_test.go | 163 +++++++++ database/jwk/list.go | 40 +++ database/jwk/list_test.go | 103 ++++++ database/jwk/opts.go | 52 +++ database/jwk/opts_test.go | 208 +++++++++++ database/jwk/rotate.go | 40 +++ database/jwk/rotate_test.go | 125 +++++++ database/jwk/table.go | 50 +++ database/jwk/table_test.go | 58 +++ database/resource.go | 12 + database/resource_test.go | 3 + database/testutils/api_resources.go | 26 ++ database/testutils/mock_args.go | 27 ++ database/types/jwk.go | 77 ++++ database/types/jwk_test.go | 106 ++++++ go.mod | 12 +- go.sum | 27 +- internal/token/compose_test.go | 5 +- internal/token/generate_rsa.go | 57 +++ internal/token/manager.go | 22 +- internal/token/mint.go | 127 ++++++- internal/token/parse.go | 2 +- internal/token/parse_test.go | 29 +- internal/token/refresh_test.go | 7 +- mock/server/authentication.go | 59 +++ mock/server/build.go | 54 +++ mock/server/server.go | 6 + router/admin.go | 3 + router/build.go | 2 + router/middleware/claims/claims_test.go | 16 +- router/middleware/perm/perm.go | 44 ++- router/middleware/perm/perm_test.go | 378 ++++++++++++++++---- router/middleware/pipeline/pipeline_test.go | 4 +- router/middleware/token_manager_test.go | 2 +- router/middleware/user/user_test.go | 16 +- router/router.go | 4 + 62 files changed, 2919 insertions(+), 143 deletions(-) create mode 100644 api/admin/rotate_keys.go create mode 100644 api/build/id_request_token.go create mode 100644 api/build/id_token.go create mode 100644 api/jwks.go create mode 100644 api/oi_config.go create mode 100644 api/types/oidc.go create mode 100644 constants/secret.go create mode 100644 constants/status.go create mode 100644 constants/token.go create mode 100644 constants/visibility.go create mode 100644 database/jwk/create.go create mode 100644 database/jwk/create_test.go create mode 100644 database/jwk/get.go create mode 100644 database/jwk/get_test.go create mode 100644 database/jwk/interface.go create mode 100644 database/jwk/jwk.go create mode 100644 database/jwk/jwk_test.go create mode 100644 database/jwk/list.go create mode 100644 database/jwk/list_test.go create mode 100644 database/jwk/opts.go create mode 100644 database/jwk/opts_test.go create mode 100644 database/jwk/rotate.go create mode 100644 database/jwk/rotate_test.go create mode 100644 database/jwk/table.go create mode 100644 database/jwk/table_test.go create mode 100644 database/types/jwk.go create mode 100644 database/types/jwk_test.go create mode 100644 internal/token/generate_rsa.go diff --git a/api/admin/rotate_keys.go b/api/admin/rotate_keys.go new file mode 100644 index 000000000..56681a60c --- /dev/null +++ b/api/admin/rotate_keys.go @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: Apache-2.0 + +package admin + +import ( + "fmt" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + + "github.com/go-vela/server/database" + "github.com/go-vela/server/util" +) + +// swagger:operation POST /api/v1/admin/rotate_oidc_keys admin AdminRotateOIDCKeys +// +// Rotate RSA Keys +// +// --- +// produces: +// - application/json +// parameters: +// security: +// - ApiKeyAuth: [] +// responses: +// '200': +// description: Successfully rotated OIDC provider keys +// schema: +// type: string +// '500': +// description: Error unable to rotate OIDC provider keys +// schema: +// "$ref": "#/definitions/Error" + +// RotateOIDCKeys represents the API handler to +// rotate RSA keys in OIDC provider service. +func RotateOIDCKeys(c *gin.Context) { + logrus.Info("Admin: rotating keys for OIDC provider") + + // capture middleware values + ctx := c.Request.Context() + + err := database.FromContext(c).RotateKeys(ctx) + if err != nil { + retErr := fmt.Errorf("unable to rotate keys: %w", err) + util.HandleError(c, http.StatusInternalServerError, retErr) + + return + } + + c.JSON(http.StatusOK, "keys rotated successfully") +} diff --git a/api/build/id_request_token.go b/api/build/id_request_token.go new file mode 100644 index 000000000..f5e3c9f93 --- /dev/null +++ b/api/build/id_request_token.go @@ -0,0 +1,152 @@ +// SPDX-License-Identifier: Apache-2.0 + +package build + +import ( + "errors" + "fmt" + "net/http" + "strconv" + "time" + + "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + + "github.com/go-vela/server/constants" + "github.com/go-vela/server/internal/token" + "github.com/go-vela/server/router/middleware/build" + "github.com/go-vela/server/router/middleware/claims" + "github.com/go-vela/server/util" + "github.com/go-vela/types/library" +) + +// swagger:operation GET /api/v1/repos/{org}/{repo}/builds/{build}/id_request_token builds GetIDRequestToken +// +// Get a Vela OIDC request token associated with a build +// +// --- +// produces: +// - application/json +// parameters: +// - in: path +// name: repo +// description: Name of the repo +// required: true +// type: string +// - in: path +// name: org +// description: Name of the org +// required: true +// type: string +// - in: path +// name: build +// description: Build number +// required: true +// type: integer +// - in: query +// name: image +// description: Add image to token claims +// type: string +// - in: query +// name: request +// description: Add request input to token claims +// type: string +// - in: query +// name: commands +// description: Add commands input to token claims +// type: boolean +// security: +// - ApiKeyAuth: [] +// responses: +// '200': +// description: Successfully retrieved ID Request token +// schema: +// "$ref": "#/definitions/Token" +// '400': +// description: Bad request +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized request +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Unable to find build +// schema: +// "$ref": "#/definitions/Error" +// '500': +// description: Unable to generate ID request token +// schema: +// "$ref": "#/definitions/Error" + +// GetIDRequestToken represents the API handler to generate and return an ID request token. +func GetIDRequestToken(c *gin.Context) { + // capture middleware values + b := build.Retrieve(c) + cl := claims.Retrieve(c) + + // update engine logger with API metadata + // + // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields + logrus.WithFields(logrus.Fields{ + "build": b.GetNumber(), + "org": b.GetRepo().GetOrg(), + "repo": b.GetRepo().GetName(), + "user": cl.Subject, + }).Infof("generating ID request token for build %s/%d", b.GetRepo().GetFullName(), b.GetNumber()) + + image := c.Query("image") + if len(image) == 0 { + retErr := errors.New("no step 'image' provided in query parameters") + + util.HandleError(c, http.StatusBadRequest, retErr) + + return + } + + request := c.Query("request") + if len(request) == 0 { + retErr := errors.New("no 'request' provided in query parameters") + + util.HandleError(c, http.StatusBadRequest, retErr) + + return + } + + commands, err := strconv.ParseBool(c.Query("commands")) + if err != nil { + retErr := fmt.Errorf("unable to parse 'commands' query parameter as boolean %s: %w", c.Query("commands"), err) + + util.HandleError(c, http.StatusBadRequest, retErr) + + return + } + + // retrieve token manager from context + tm := c.MustGet("token-manager").(*token.Manager) + + exp := (time.Duration(b.GetRepo().GetTimeout()) * time.Minute) + tm.BuildTokenBufferDuration + + // set mint token options + idmto := &token.MintTokenOpts{ + Build: b, + Repo: b.GetRepo().GetFullName(), + TokenType: constants.IDRequestTokenType, + TokenDuration: exp, + Image: util.Sanitize(image), + Request: util.Sanitize(request), + Commands: commands, + } + + // mint token + idrt, err := tm.MintToken(idmto) + if err != nil { + retErr := fmt.Errorf("unable to generate ID request token: %w", err) + + util.HandleError(c, http.StatusInternalServerError, retErr) + + return + } + + c.JSON(http.StatusOK, library.Token{Token: &idrt}) +} diff --git a/api/build/id_token.go b/api/build/id_token.go new file mode 100644 index 000000000..a2b7fdab7 --- /dev/null +++ b/api/build/id_token.go @@ -0,0 +1,138 @@ +// SPDX-License-Identifier: Apache-2.0 + +package build + +import ( + "fmt" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + + "github.com/go-vela/server/constants" + "github.com/go-vela/server/database" + "github.com/go-vela/server/internal/token" + "github.com/go-vela/server/router/middleware/build" + "github.com/go-vela/server/router/middleware/claims" + "github.com/go-vela/server/util" + "github.com/go-vela/types/library" +) + +// swagger:operation GET /api/v1/repos/{org}/{repo}/builds/{build}/id_token builds GetIDToken +// +// Get a Vela OIDC token associated with a build +// +// --- +// produces: +// - application/json +// parameters: +// - in: path +// name: repo +// description: Name of the repo +// required: true +// type: string +// - in: path +// name: org +// description: Name of the org +// required: true +// type: string +// - in: path +// name: build +// description: Build number +// required: true +// type: integer +// - in: query +// name: audience +// description: Add audience to token claims +// type: array +// items: +// type: string +// collectionFormat: multi +// security: +// - ApiKeyAuth: [] +// responses: +// '200': +// description: Successfully retrieved ID token +// schema: +// "$ref": "#/definitions/Token" +// '400': +// description: Bad request +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized request +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Unable to find build +// schema: +// "$ref": "#/definitions/Error" +// '500': +// description: Unable to generate id token +// schema: +// "$ref": "#/definitions/Error" + +// GetIDToken represents the API handler to generate a id token. +func GetIDToken(c *gin.Context) { + // capture middleware values + b := build.Retrieve(c) + cl := claims.Retrieve(c) + ctx := c.Request.Context() + + // update engine logger with API metadata + // + // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields + logrus.WithFields(logrus.Fields{ + "build": b.GetNumber(), + "org": b.GetRepo().GetOrg(), + "repo": b.GetRepo().GetName(), + "subject": cl.Subject, + }).Infof("generating ID token for build %s/%d", b.GetRepo().GetFullName(), b.GetNumber()) + + // retrieve token manager from context + tm := c.MustGet("token-manager").(*token.Manager) + + // set mint token options + idmto := &token.MintTokenOpts{ + Build: b, + Repo: b.GetRepo().GetFullName(), + TokenType: constants.IDTokenType, + TokenDuration: tm.IDTokenDuration, + Image: cl.Image, + Request: cl.Request, + Commands: cl.Commands, + } + + // if audience is provided, include that in claims + audience := []string{} + + if len(c.QueryArray("audience")) > 0 { + for _, a := range c.QueryArray("audience") { + if len(a) > 0 { + audience = append(audience, util.Sanitize(a)) + } + } + } + + if len(audience) == 0 { + retErr := fmt.Errorf("unable to generate ID token: %s", "no audience provided") + + util.HandleError(c, http.StatusBadRequest, retErr) + + return + } + + idmto.Audience = audience + + // mint token + idt, err := tm.MintIDToken(ctx, idmto, database.FromContext(c)) + if err != nil { + retErr := fmt.Errorf("unable to generate ID token: %w", err) + + util.HandleError(c, http.StatusInternalServerError, retErr) + + return + } + + c.JSON(http.StatusOK, library.Token{Token: &idt}) +} diff --git a/api/build/token.go b/api/build/token.go index 4c6de18ec..fd0664684 100644 --- a/api/build/token.go +++ b/api/build/token.go @@ -99,7 +99,7 @@ func GetBuildToken(c *gin.Context) { // set mint token options bmto := &token.MintTokenOpts{ Hostname: cl.Subject, - BuildID: b.GetID(), + Build: b, Repo: r.GetFullName(), TokenType: constants.WorkerBuildTokenType, TokenDuration: exp, diff --git a/api/jwks.go b/api/jwks.go new file mode 100644 index 000000000..3d124f77d --- /dev/null +++ b/api/jwks.go @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: Apache-2.0 + +package api + +import ( + "fmt" + "net/http" + + "github.com/gin-gonic/gin" + + "github.com/go-vela/server/database" + "github.com/go-vela/server/util" +) + +// swagger:operation GET /_services/token/.well-known/jwks token GetJWKS +// +// Get the JWKS for the Vela OIDC service +// +// --- +// produces: +// - application/json +// parameters: +// security: +// - ApiKeyAuth: [] +// responses: +// '200': +// description: Successfully retrieved the Vela JWKS +// schema: +// "$ref": "#/definitions/JWKSet" +// '500': +// description: Unable to get the Vela JWKS +// schema: +// "$ref": "#/definitions/Error" + +// GetJWKS represents the API handler for requests to public keys in the Vela OpenID service. +func GetJWKS(c *gin.Context) { + // retrieve JWKs from the database + keys, err := database.FromContext(c).ListJWKs(c) + if err != nil { + retErr := fmt.Errorf("unable to get key set: %w", err) + util.HandleError(c, http.StatusInternalServerError, retErr) + + return + } + + c.JSON(http.StatusOK, keys) +} diff --git a/api/oi_config.go b/api/oi_config.go new file mode 100644 index 000000000..02edeb939 --- /dev/null +++ b/api/oi_config.go @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: Apache-2.0 + +package api + +import ( + "fmt" + "net/http" + + "github.com/gin-gonic/gin" + "github.com/golang-jwt/jwt/v5" + + "github.com/go-vela/server/api/types" + "github.com/go-vela/server/internal" +) + +// swagger:operation GET /_services/token/.well-known/openid-configuration token GetOpenIDConfig +// +// Get the OpenID configuration for the Vela OIDC service +// +// --- +// produces: +// - application/json +// parameters: +// security: +// - ApiKeyAuth: [] +// responses: +// '200': +// description: Successfully retrieved the Vela OpenID Configuration +// schema: +// "$ref": "#/definitions/OpenIDConfig" + +// GetOpenIDConfig represents the API handler for requests for configurations in the Vela OpenID service. +func GetOpenIDConfig(c *gin.Context) { + m := c.MustGet("metadata").(*internal.Metadata) + config := types.OpenIDConfig{ + Issuer: fmt.Sprintf("%s/_services/token", m.Vela.Address), + JWKSAddress: fmt.Sprintf("%s/%s", m.Vela.Address, "_services/token/.well-known/jwks"), + SupportedClaims: []string{ + "sub", + "exp", + "iat", + "iss", + "aud", + "build_number", + "build_id", + "repo", + "token_type", + "actor", + "actor_scm_id", + "commands", + "image", + "request", + "event", + "sha", + "ref", + }, + Algorithms: []string{ + jwt.SigningMethodRS256.Name, + }, + } + + c.JSON(http.StatusOK, config) +} diff --git a/api/types/oidc.go b/api/types/oidc.go new file mode 100644 index 000000000..7598351f6 --- /dev/null +++ b/api/types/oidc.go @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "github.com/golang-jwt/jwt/v5" + "github.com/lestrrat-go/jwx/jwk" +) + +// OpenIDConfig is a struct that represents the OpenID Connect configuration. +// +// swagger:model OpenIDConfig +type OpenIDConfig struct { + Issuer string `json:"issuer"` + JWKSAddress string `json:"jwks_uri"` + SupportedClaims []string `json:"supported_claims"` + Algorithms []string `json:"id_token_signing_alg_values_supported"` +} + +// OpenIDClaims struct is an extension of the JWT standard claims. It +// includes information relevant to OIDC services. +type OpenIDClaims struct { + BuildNumber int `json:"build_number,omitempty"` + BuildID int64 `json:"build_id,omitempty"` + Actor string `json:"actor,omitempty"` + ActorSCMID string `json:"actor_scm_id,omitempty"` + Repo string `json:"repo,omitempty"` + TokenType string `json:"token_type,omitempty"` + Image string `json:"image,omitempty"` + Request string `json:"request,omitempty"` + Commands bool `json:"commands,omitempty"` + Event string `json:"event,omitempty"` + Ref string `json:"ref,omitempty"` + SHA string `json:"sha,omitempty"` + jwt.RegisteredClaims +} + +// JWKSet is a wrapper of lestrrat-go/jwx/jwk.Set for API Swagger gen. +// +// swagger:model JWKSet +type JWKSet struct { + jwk.Set +} diff --git a/cmd/vela-server/main.go b/cmd/vela-server/main.go index 7fa51ca27..7dd589f07 100644 --- a/cmd/vela-server/main.go +++ b/cmd/vela-server/main.go @@ -181,6 +181,12 @@ func main() { Usage: "sets the duration of the worker register token", Value: 1 * time.Minute, }, + &cli.DurationFlag{ + EnvVars: []string{"VELA_OPEN_ID_TOKEN_DURATION", "OPEN_ID_TOKEN_DURATION"}, + Name: "id-token-duration", + Usage: "sets the duration of an OpenID token requested during a build (should be short)", + Value: 5 * time.Minute, + }, // Compiler Flags &cli.BoolFlag{ EnvVars: []string{"VELA_COMPILER_GITHUB", "COMPILER_GITHUB"}, diff --git a/cmd/vela-server/server.go b/cmd/vela-server/server.go index dd5b6d6c6..9472e9c54 100644 --- a/cmd/vela-server/server.go +++ b/cmd/vela-server/server.go @@ -103,6 +103,11 @@ func server(c *cli.Context) error { return err } + tm, err := setupTokenManager(c, database) + if err != nil { + return err + } + jitter := wait.Jitter(5*time.Second, 2.0) logrus.Infof("retrieving initial platform settings after %v delay", jitter) @@ -154,7 +159,7 @@ func server(c *cli.Context) error { middleware.Database(database), middleware.Logger(logrus.StandardLogger(), time.RFC3339), middleware.Metadata(metadata), - middleware.TokenManager(setupTokenManager(c)), + middleware.TokenManager(tm), middleware.Queue(queue), middleware.RequestVersion, middleware.Secret(c.String("vela-secret")), diff --git a/cmd/vela-server/token.go b/cmd/vela-server/token.go index 04a756fca..525ce1518 100644 --- a/cmd/vela-server/token.go +++ b/cmd/vela-server/token.go @@ -3,26 +3,35 @@ package main import ( - "github.com/golang-jwt/jwt/v5" + "fmt" + "github.com/sirupsen/logrus" "github.com/urfave/cli/v2" + "github.com/go-vela/server/database" "github.com/go-vela/server/internal/token" ) // helper function to setup the tokenmanager from the CLI arguments. -func setupTokenManager(c *cli.Context) *token.Manager { +func setupTokenManager(c *cli.Context, db database.Interface) (*token.Manager, error) { logrus.Debug("Creating token manager from CLI configuration") tm := &token.Manager{ - PrivateKey: c.String("vela-server-private-key"), - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: c.String("vela-server-private-key"), UserAccessTokenDuration: c.Duration("user-access-token-duration"), UserRefreshTokenDuration: c.Duration("user-refresh-token-duration"), BuildTokenBufferDuration: c.Duration("build-token-buffer-duration"), WorkerAuthTokenDuration: c.Duration("worker-auth-token-duration"), WorkerRegisterTokenDuration: c.Duration("worker-register-token-duration"), + IDTokenDuration: c.Duration("id-token-duration"), + Issuer: fmt.Sprintf("%s/_services/token", c.String("server-addr")), + } + + // generate a new RSA key pair + err := tm.GenerateRSA(c.Context, db) + if err != nil { + return nil, err } - return tm + return tm, nil } diff --git a/compiler/native/environment.go b/compiler/native/environment.go index 1d0666e43..a2542fb3f 100644 --- a/compiler/native/environment.go +++ b/compiler/native/environment.go @@ -315,6 +315,7 @@ func environment(b *api.Build, m *internal.Metadata, r *api.Repo, u *api.User) m env["VELA_NETRC_MACHINE"] = m.Source.Host env["VELA_QUEUE"] = m.Queue.Driver env["VELA_SOURCE"] = m.Source.Driver + env["VELA_ID_TOKEN_REQUEST_URL"] = fmt.Sprintf("%s/api/v1/repos/%s/builds/%d/id_token", m.Vela.Address, r.GetFullName(), b.GetNumber()) channel = m.Queue.Channel workspace = fmt.Sprintf("%s/%s/%s/%s", workspace, m.Source.Host, r.GetOrg(), r.GetName()) } diff --git a/compiler/native/environment_test.go b/compiler/native/environment_test.go index 6d920021a..cb78fbd99 100644 --- a/compiler/native/environment_test.go +++ b/compiler/native/environment_test.go @@ -596,7 +596,7 @@ func TestNative_environment(t *testing.T) { m: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, r: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, u: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, - want: map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "push", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "foo", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "push", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "foo", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SENDER_SCM_ID": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_OWNER": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, + want: map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "push", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "foo", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "push", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "foo", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SENDER_SCM_ID": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_OWNER": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_ID_TOKEN_REQUEST_URL": "foo/api/v1/repos/foo/builds/1/id_token"}, }, // tag { @@ -605,7 +605,7 @@ func TestNative_environment(t *testing.T) { m: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, r: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, u: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, - want: map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "tag", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "refs/tags/1", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TAG": "1", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "tag", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "refs/tags/1", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SENDER_SCM_ID": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TAG": "1", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_OWNER": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, + want: map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "tag", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "refs/tags/1", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TAG": "1", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "tag", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "refs/tags/1", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SENDER_SCM_ID": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TAG": "1", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_OWNER": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_ID_TOKEN_REQUEST_URL": "foo/api/v1/repos/foo/builds/1/id_token"}, }, // pull_request { @@ -614,7 +614,7 @@ func TestNative_environment(t *testing.T) { m: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, r: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, u: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, - want: map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "pull_request", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_PULL_REQUEST_NUMBER": "1", "BUILD_REF": "refs/pull/1/head", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "pull_request", "VELA_BUILD_EVENT_ACTION": "opened", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_PULL_REQUEST": "1", "VELA_BUILD_REF": "refs/pull/1/head", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SENDER_SCM_ID": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_PULL_REQUEST": "1", "VELA_PULL_REQUEST_SOURCE": "", "VELA_PULL_REQUEST_TARGET": "foo", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_OWNER": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, + want: map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "pull_request", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_PULL_REQUEST_NUMBER": "1", "BUILD_REF": "refs/pull/1/head", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "pull_request", "VELA_BUILD_EVENT_ACTION": "opened", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_PULL_REQUEST": "1", "VELA_BUILD_REF": "refs/pull/1/head", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SENDER_SCM_ID": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_PULL_REQUEST": "1", "VELA_PULL_REQUEST_SOURCE": "", "VELA_PULL_REQUEST_TARGET": "foo", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_OWNER": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_ID_TOKEN_REQUEST_URL": "foo/api/v1/repos/foo/builds/1/id_token"}, }, // deployment { @@ -623,7 +623,7 @@ func TestNative_environment(t *testing.T) { m: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, r: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, u: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, - want: map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "deployment", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "refs/pull/1/head", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TARGET": "production", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "deployment", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "refs/pull/1/head", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SENDER_SCM_ID": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TARGET": "production", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DEPLOYMENT": "production", "VELA_DEPLOYMENT_NUMBER": "0", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_OWNER": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, + want: map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "deployment", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "refs/pull/1/head", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TARGET": "production", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "deployment", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "refs/pull/1/head", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SENDER_SCM_ID": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TARGET": "production", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DEPLOYMENT": "production", "VELA_DEPLOYMENT_NUMBER": "0", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_BRANCH": "foo", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_OWNER": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_ID_TOKEN_REQUEST_URL": "foo/api/v1/repos/foo/builds/1/id_token"}, }, } @@ -712,27 +712,27 @@ func Test_client_EnvironmentBuild(t *testing.T) { metadata: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, user: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, - }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "push", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "foo", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "push", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "foo", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SENDER_SCM_ID": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_OWNER": "foo", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}}, + }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "push", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "foo", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "push", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "foo", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SENDER_SCM_ID": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_OWNER": "foo", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_ID_TOKEN_REQUEST_URL": "foo/api/v1/repos/foo/builds/1/id_token"}}, {"tag", fields{ build: &api.Build{ID: &num64, Repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, Number: &num, Parent: &num, Event: &tag, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, SenderSCMID: &str, Author: &str, Branch: &str, Ref: &tagref, BaseRef: &str}, metadata: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, user: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, - }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "tag", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "refs/tags/1", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TAG": "1", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "tag", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "refs/tags/1", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SENDER_SCM_ID": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TAG": "1", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_OWNER": "foo", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, + }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "tag", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "refs/tags/1", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TAG": "1", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "tag", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "refs/tags/1", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SENDER_SCM_ID": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TAG": "1", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_OWNER": "foo", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_ID_TOKEN_REQUEST_URL": "foo/api/v1/repos/foo/builds/1/id_token"}, }, {"pull_request", fields{ build: &api.Build{ID: &num64, Repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, Number: &num, Parent: &num, Event: &pull, EventAction: &pullact, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &str, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, SenderSCMID: &str, Author: &str, Branch: &str, Ref: &pullref, BaseRef: &str}, metadata: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, user: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, - }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "pull_request", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_PULL_REQUEST_NUMBER": "1", "BUILD_REF": "refs/pull/1/head", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "pull_request", "VELA_BUILD_EVENT_ACTION": "opened", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_PULL_REQUEST": "1", "VELA_BUILD_REF": "refs/pull/1/head", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SENDER_SCM_ID": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_PULL_REQUEST": "1", "VELA_PULL_REQUEST_SOURCE": "", "VELA_PULL_REQUEST_TARGET": "foo", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_OWNER": "foo", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, + }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "pull_request", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_PULL_REQUEST_NUMBER": "1", "BUILD_REF": "refs/pull/1/head", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "pull_request", "VELA_BUILD_EVENT_ACTION": "opened", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_PULL_REQUEST": "1", "VELA_BUILD_REF": "refs/pull/1/head", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SENDER_SCM_ID": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_PULL_REQUEST": "1", "VELA_PULL_REQUEST_SOURCE": "", "VELA_PULL_REQUEST_TARGET": "foo", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_OWNER": "foo", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_ID_TOKEN_REQUEST_URL": "foo/api/v1/repos/foo/builds/1/id_token"}, }, {"deployment", fields{ build: &api.Build{ID: &num64, Repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, Number: &num, Parent: &num, Event: &deploy, Status: &str, Error: &str, Enqueued: &num64, Created: &num64, Started: &num64, Finished: &num64, Deploy: &target, Clone: &str, Source: &str, Title: &str, Message: &str, Commit: &str, Sender: &str, SenderSCMID: &str, Author: &str, Branch: &str, Ref: &pullref, BaseRef: &str}, metadata: &internal.Metadata{Database: &internal.Database{Driver: str, Host: str}, Queue: &internal.Queue{Channel: str, Driver: str, Host: str}, Source: &internal.Source{Driver: str, Host: str}, Vela: &internal.Vela{Address: str, WebAddress: str}}, repo: &api.Repo{ID: &num64, Owner: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, Org: &str, Name: &str, FullName: &str, Link: &str, Clone: &str, Branch: &str, Topics: &topics, BuildLimit: &num64, Timeout: &num64, Visibility: &str, Private: &booL, Trusted: &booL, Active: &booL}, user: &api.User{ID: &num64, Name: &str, Token: &str, Active: &booL, Admin: &booL}, - }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "deployment", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "refs/pull/1/head", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TARGET": "production", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "deployment", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "refs/pull/1/head", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SENDER_SCM_ID": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TARGET": "production", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DEPLOYMENT": "production", "VELA_DEPLOYMENT_NUMBER": "0", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_OWNER": "foo", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo"}, + }, map[string]string{"BUILD_AUTHOR": "foo", "BUILD_AUTHOR_EMAIL": "", "BUILD_BASE_REF": "foo", "BUILD_BRANCH": "foo", "BUILD_CHANNEL": "foo", "BUILD_CLONE": "foo", "BUILD_COMMIT": "foo", "BUILD_CREATED": "1", "BUILD_ENQUEUED": "1", "BUILD_EVENT": "deployment", "BUILD_HOST": "", "BUILD_LINK": "", "BUILD_MESSAGE": "foo", "BUILD_NUMBER": "1", "BUILD_PARENT": "1", "BUILD_REF": "refs/pull/1/head", "BUILD_SENDER": "foo", "BUILD_SOURCE": "foo", "BUILD_STARTED": "1", "BUILD_STATUS": "foo", "BUILD_TARGET": "production", "BUILD_TITLE": "foo", "BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "CI": "true", "REPOSITORY_ACTIVE": "false", "REPOSITORY_ALLOW_EVENTS": "", "REPOSITORY_BRANCH": "foo", "REPOSITORY_CLONE": "foo", "REPOSITORY_FULL_NAME": "foo", "REPOSITORY_LINK": "foo", "REPOSITORY_NAME": "foo", "REPOSITORY_ORG": "foo", "REPOSITORY_PRIVATE": "false", "REPOSITORY_TIMEOUT": "1", "REPOSITORY_TRUSTED": "false", "REPOSITORY_VISIBILITY": "foo", "VELA": "true", "VELA_ADDR": "foo", "VELA_BUILD_APPROVED_AT": "0", "VELA_BUILD_APPROVED_BY": "", "VELA_BUILD_AUTHOR": "foo", "VELA_BUILD_AUTHOR_EMAIL": "", "VELA_BUILD_BASE_REF": "foo", "VELA_BUILD_BRANCH": "foo", "VELA_BUILD_CHANNEL": "foo", "VELA_BUILD_CLONE": "foo", "VELA_BUILD_COMMIT": "foo", "VELA_BUILD_CREATED": "1", "VELA_BUILD_DISTRIBUTION": "", "VELA_BUILD_ENQUEUED": "1", "VELA_BUILD_EVENT": "deployment", "VELA_BUILD_EVENT_ACTION": "", "VELA_BUILD_HOST": "", "VELA_BUILD_LINK": "", "VELA_BUILD_MESSAGE": "foo", "VELA_BUILD_NUMBER": "1", "VELA_BUILD_PARENT": "1", "VELA_BUILD_REF": "refs/pull/1/head", "VELA_BUILD_RUNTIME": "", "VELA_BUILD_SENDER": "foo", "VELA_BUILD_SENDER_SCM_ID": "foo", "VELA_BUILD_SOURCE": "foo", "VELA_BUILD_STARTED": "1", "VELA_BUILD_STATUS": "foo", "VELA_BUILD_TARGET": "production", "VELA_BUILD_TITLE": "foo", "VELA_BUILD_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_CHANNEL": "foo", "VELA_DATABASE": "foo", "VELA_DEPLOYMENT": "production", "VELA_DEPLOYMENT_NUMBER": "0", "VELA_DISTRIBUTION": "TODO", "VELA_HOST": "foo", "VELA_NETRC_MACHINE": "foo", "VELA_NETRC_PASSWORD": "foo", "VELA_NETRC_USERNAME": "x-oauth-basic", "VELA_QUEUE": "foo", "VELA_REPO_ACTIVE": "false", "VELA_REPO_ALLOW_EVENTS": "", "VELA_REPO_APPROVE_BUILD": "", "VELA_REPO_OWNER": "foo", "VELA_REPO_BRANCH": "foo", "VELA_REPO_BUILD_LIMIT": "1", "VELA_REPO_CLONE": "foo", "VELA_REPO_FULL_NAME": "foo", "VELA_REPO_LINK": "foo", "VELA_REPO_NAME": "foo", "VELA_REPO_ORG": "foo", "VELA_REPO_PIPELINE_TYPE": "", "VELA_REPO_PRIVATE": "false", "VELA_REPO_TIMEOUT": "1", "VELA_REPO_TOPICS": "cloud,security", "VELA_REPO_TRUSTED": "false", "VELA_REPO_VISIBILITY": "foo", "VELA_RUNTIME": "TODO", "VELA_SOURCE": "foo", "VELA_USER_ACTIVE": "false", "VELA_USER_ADMIN": "false", "VELA_USER_FAVORITES": "[]", "VELA_USER_NAME": "foo", "VELA_VERSION": "TODO", "VELA_WORKSPACE": "/vela/src/foo/foo/foo", "VELA_ID_TOKEN_REQUEST_URL": "foo/api/v1/repos/foo/builds/1/id_token"}, }, } for _, tt := range tests { diff --git a/constants/secret.go b/constants/secret.go new file mode 100644 index 000000000..bb794f025 --- /dev/null +++ b/constants/secret.go @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: Apache-2.0 + +package constants + +// Secret types. +const ( + // SecretPullBuild defines the pull policy type for a secret. + SecretPullBuild = "build_start" + + // SecretPullStep defines the pull policy type for a secret. + SecretPullStep = "step_start" + + // SecretOrg defines the secret type for a secret scoped to a specific org. + SecretOrg = "org" + + // SecretRepo defines the secret type for a secret scoped to a specific repo. + SecretRepo = "repo" + + // SecretShared defines the secret type for a secret shared across the installation. + SecretShared = "shared" + + // SecretMask defines the secret mask to be used in place of secret values returned to users. + SecretMask = "[secure]" + + // SecretLogMask defines the secret mask to be used when distributing logs that contain secrets. + SecretLogMask = "***" + + // SecretRestrictedCharacters defines the set of characters that a secret name cannot contain. + // This matches the following characters: + // Equal Sign = + // Null Character \x00 + SecretRestrictedCharacters = "=\x00" +) diff --git a/constants/status.go b/constants/status.go new file mode 100644 index 000000000..489f4a7df --- /dev/null +++ b/constants/status.go @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: Apache-2.0 + +package constants + +// Build and step statuses. +const ( + // StatusError defines the status type for build and step error statuses. + StatusError = "error" + + // StatusFailure defines the status type for build and step failure statuses. + StatusFailure = "failure" + + // StatusKilled defines the status type for build and step killed statuses. + StatusKilled = "killed" + + // StatusCanceled defines the status type for build and step canceled statuses. + StatusCanceled = "canceled" + + // StatusPending defines the status type for build and step pending statuses. + StatusPending = "pending" + + // StatusPendingApproval defines the status type for a build waiting to be approved to run. + StatusPendingApproval = "pending approval" + + // StatusRunning defines the status type for build and step running statuses. + StatusRunning = "running" + + // StatusSuccess defines the status type for build and step success statuses. + StatusSuccess = "success" + + // StatusSkipped defines the status type for build and step skipped statuses. + StatusSkipped = "skipped" +) diff --git a/constants/table.go b/constants/table.go index 6d9ff76e8..736335482 100644 --- a/constants/table.go +++ b/constants/table.go @@ -5,4 +5,7 @@ package constants const ( // TableDashboard defines the table type for the database dashboards table. TableDashboard = "dashboards" + + // TableJWK defines the table type for the database jwks table. + TableJWK = "jwks" ) diff --git a/constants/token.go b/constants/token.go new file mode 100644 index 000000000..793b1f7c7 --- /dev/null +++ b/constants/token.go @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: Apache-2.0 + +package constants + +// Constants for tokens. +const ( + // RefreshTokenName is the name associated with the refresh token. + RefreshTokenName = "vela_refresh_token" + + // UserAccessTokenType is the name associated with the user access token type. + UserAccessTokenType = "UserAccess" + + // UserRefreshTokenType is the name associated with the user refresh token type. + UserRefreshTokenType = "UserRefresh" + + // WorkerAuthTokenType is the name associated with the worker authentication token type. + WorkerAuthTokenType = "WorkerAuth" + + // WorkerRegisterTokenType is the name associated with the worker registration token type. + WorkerRegisterTokenType = "WorkerRegister" + + // WorkerBuildTokenType is the name associated with the worker build token type. + WorkerBuildTokenType = "WorkerBuild" + + // ServerWorkerTokenType is the name associated with the server-worker symmetric token. + ServerWorkerTokenType = "ServerWorker" + + // IDRequestTokenType is the name associated with the id request token type. + IDRequestTokenType = "IDRequest" + + // IDTokenType is the name associated with the id token type. + IDTokenType = "ID" +) diff --git a/constants/visibility.go b/constants/visibility.go new file mode 100644 index 000000000..af2f35b04 --- /dev/null +++ b/constants/visibility.go @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: Apache-2.0 + +package constants + +// Repo visibility types. +const ( + // VisibilityPublic defines the visibility type for allowing any + // users in Vela to access their repo regardless of the access + // defined in the source control system. + VisibilityPublic = "public" + + // VisibilityPrivate defines the visibility type for only allowing + // users in Vela with pre-defined access in the source control + // system to access their repo. + VisibilityPrivate = "private" +) diff --git a/database/database.go b/database/database.go index 5a9e982b2..9ff3a2855 100644 --- a/database/database.go +++ b/database/database.go @@ -17,6 +17,7 @@ import ( "github.com/go-vela/server/database/deployment" "github.com/go-vela/server/database/executable" "github.com/go-vela/server/database/hook" + "github.com/go-vela/server/database/jwk" "github.com/go-vela/server/database/log" "github.com/go-vela/server/database/pipeline" "github.com/go-vela/server/database/repo" @@ -68,6 +69,7 @@ type ( executable.BuildExecutableInterface deployment.DeploymentInterface hook.HookInterface + jwk.JWKInterface log.LogInterface pipeline.PipelineInterface repo.RepoInterface diff --git a/database/integration_test.go b/database/integration_test.go index 8996ca9fe..9d70d53d2 100644 --- a/database/integration_test.go +++ b/database/integration_test.go @@ -12,6 +12,7 @@ import ( "github.com/adhocore/gronx" "github.com/google/go-cmp/cmp" + "github.com/lestrrat-go/jwx/jwk" api "github.com/go-vela/server/api/types" "github.com/go-vela/server/api/types/settings" @@ -20,6 +21,7 @@ import ( "github.com/go-vela/server/database/deployment" "github.com/go-vela/server/database/executable" "github.com/go-vela/server/database/hook" + dbJWK "github.com/go-vela/server/database/jwk" "github.com/go-vela/server/database/log" "github.com/go-vela/server/database/pipeline" "github.com/go-vela/server/database/repo" @@ -43,6 +45,7 @@ type Resources struct { Deployments []*library.Deployment Executables []*library.BuildExecutable Hooks []*library.Hook + JWKs jwk.Set Logs []*library.Log Pipelines []*library.Pipeline Repos []*api.Repo @@ -136,6 +139,8 @@ func TestDatabase_Integration(t *testing.T) { t.Run("test_hooks", func(t *testing.T) { testHooks(t, db, resources) }) + t.Run("test_jwks", func(t *testing.T) { testJWKs(t, db, resources) }) + t.Run("test_logs", func(t *testing.T) { testLogs(t, db, resources) }) t.Run("test_pipelines", func(t *testing.T) { testPipelines(t, db, resources) }) @@ -855,6 +860,89 @@ func testHooks(t *testing.T, db Interface, resources *Resources) { } } +func testJWKs(t *testing.T, db Interface, resources *Resources) { + // create a variable to track the number of methods called for jwks + methods := make(map[string]bool) + // capture the element type of the jwk interface + element := reflect.TypeOf(new(dbJWK.JWKInterface)).Elem() + // iterate through all methods found in the jwk interface + for i := 0; i < element.NumMethod(); i++ { + // skip tracking the methods to create indexes and tables for jwks + // since those are already called when the database engine starts + if strings.Contains(element.Method(i).Name, "Table") { + continue + } + + // add the method name to the list of functions + methods[element.Method(i).Name] = false + } + + for i := 0; i < resources.JWKs.Len(); i++ { + jk, _ := resources.JWKs.Get(i) + + jkPub, _ := jk.(jwk.RSAPublicKey) + + err := db.CreateJWK(context.TODO(), jkPub) + if err != nil { + t.Errorf("unable to create jwk %s: %v", jkPub.KeyID(), err) + } + } + methods["CreateJWK"] = true + + list, err := db.ListJWKs(context.TODO()) + if err != nil { + t.Errorf("unable to list jwks: %v", err) + } + + if !reflect.DeepEqual(resources.JWKs, list) { + t.Errorf("ListJWKs() mismatch, want %v, got %v", resources.JWKs, list) + } + + methods["ListJWKs"] = true + + for i := 0; i < resources.JWKs.Len(); i++ { + jk, _ := resources.JWKs.Get(i) + + jkPub, _ := jk.(jwk.RSAPublicKey) + + got, err := db.GetActiveJWK(context.TODO(), jkPub.KeyID()) + if err != nil { + t.Errorf("unable to get jwk %s: %v", jkPub.KeyID(), err) + } + + if !cmp.Equal(jkPub, got, testutils.JwkKeyOpts) { + t.Errorf("GetJWK() is %v, want %v", got, jkPub) + } + } + + methods["GetActiveJWK"] = true + + err = db.RotateKeys(context.TODO()) + if err != nil { + t.Errorf("unable to rotate keys: %v", err) + } + + for i := 0; i < resources.JWKs.Len(); i++ { + jk, _ := resources.JWKs.Get(i) + + jkPub, _ := jk.(jwk.RSAPublicKey) + + _, err := db.GetActiveJWK(context.TODO(), jkPub.KeyID()) + if err == nil { + t.Errorf("GetActiveJWK() should return err after rotation") + } + } + + methods["RotateKeys"] = true + + // ensure we called all the methods we expected to + for method, called := range methods { + if !called { + t.Errorf("method %s was not called for jwks", method) + } + } +} + func testLogs(t *testing.T, db Interface, resources *Resources) { // create a variable to track the number of methods called for logs methods := make(map[string]bool) @@ -2484,6 +2572,13 @@ func newResources() *Resources { hookThree.SetLink("https://github.com/github/octocat/settings/hooks/1") hookThree.SetWebhookID(78910) + jwkOne := testutils.JWK() + jwkTwo := testutils.JWK() + + jwkSet := jwk.NewSet() + jwkSet.Add(jwkOne) + jwkSet.Add(jwkTwo) + logServiceOne := new(library.Log) logServiceOne.SetID(1) logServiceOne.SetBuildID(1) @@ -2749,6 +2844,7 @@ func newResources() *Resources { Deployments: []*library.Deployment{deploymentOne, deploymentTwo}, Executables: []*library.BuildExecutable{executableOne, executableTwo}, Hooks: []*library.Hook{hookOne, hookTwo, hookThree}, + JWKs: jwkSet, Logs: []*library.Log{logServiceOne, logServiceTwo, logStepOne, logStepTwo}, Pipelines: []*library.Pipeline{pipelineOne, pipelineTwo}, Repos: []*api.Repo{repoOne, repoTwo}, diff --git a/database/interface.go b/database/interface.go index 0d82da099..b054d4329 100644 --- a/database/interface.go +++ b/database/interface.go @@ -8,6 +8,7 @@ import ( "github.com/go-vela/server/database/deployment" "github.com/go-vela/server/database/executable" "github.com/go-vela/server/database/hook" + "github.com/go-vela/server/database/jwk" "github.com/go-vela/server/database/log" "github.com/go-vela/server/database/pipeline" "github.com/go-vela/server/database/repo" @@ -53,6 +54,9 @@ type Interface interface { // HookInterface defines the interface for hooks stored in the database. hook.HookInterface + // JWKInterface defines the interface for JWKs stored in the database. + jwk.JWKInterface + // LogInterface defines the interface for logs stored in the database. log.LogInterface diff --git a/database/jwk/create.go b/database/jwk/create.go new file mode 100644 index 000000000..3f5896e41 --- /dev/null +++ b/database/jwk/create.go @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: Apache-2.0 + +package jwk + +import ( + "context" + "database/sql" + + "github.com/lestrrat-go/jwx/jwk" + "github.com/sirupsen/logrus" + + "github.com/go-vela/server/constants" + "github.com/go-vela/server/database/types" +) + +// CreateJWK creates a new JWK in the database. +func (e *engine) CreateJWK(_ context.Context, j jwk.RSAPublicKey) error { + e.logger.WithFields(logrus.Fields{ + "jwk": j.KeyID(), + }).Tracef("creating key %s in the database", j.KeyID()) + + key := types.JWKFromAPI(j) + key.Active = sql.NullBool{Bool: true, Valid: true} + + // send query to the database + return e.client.Table(constants.TableJWK).Create(key).Error +} diff --git a/database/jwk/create_test.go b/database/jwk/create_test.go new file mode 100644 index 000000000..2275a4c4e --- /dev/null +++ b/database/jwk/create_test.go @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: Apache-2.0 + +package jwk + +import ( + "context" + "encoding/json" + "testing" + + "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" +) + +func TestJWK_Engine_CreateJWK(t *testing.T) { + // setup types + _jwk := testutils.JWK() + _jwkBytes, err := json.Marshal(_jwk) + if err != nil { + t.Errorf("unable to marshal JWK: %v", err) + } + + _postgres, _mock := testPostgres(t) + defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() + + // ensure the mock expects the query + _mock.ExpectExec(`INSERT INTO "jwks" +("id","active","key") +VALUES ($1,$2,$3)`). + WithArgs(_jwk.KeyID(), true, _jwkBytes). + WillReturnResult(sqlmock.NewResult(1, 1)) + + _sqlite := testSqlite(t) + defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() + + // setup tests + tests := []struct { + failure bool + name string + database *engine + }{ + { + failure: false, + name: "postgres", + database: _postgres, + }, + { + failure: false, + name: "sqlite3", + database: _sqlite, + }, + } + + // run tests + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + err := test.database.CreateJWK(context.TODO(), _jwk) + + if test.failure { + if err == nil { + t.Errorf("CreateDashboard for %s should have returned err", test.name) + } + + return + } + + if err != nil { + t.Errorf("CreateDashboard for %s returned err: %v", test.name, err) + } + }) + } +} diff --git a/database/jwk/get.go b/database/jwk/get.go new file mode 100644 index 000000000..187753df8 --- /dev/null +++ b/database/jwk/get.go @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: Apache-2.0 + +package jwk + +import ( + "context" + + "github.com/lestrrat-go/jwx/jwk" + + "github.com/go-vela/server/constants" + "github.com/go-vela/server/database/types" +) + +// GetActiveJWK gets a JWK by UUID (kid) from the database if active. +func (e *engine) GetActiveJWK(_ context.Context, id string) (jwk.RSAPublicKey, error) { + e.logger.Tracef("getting key %s from the database", id) + + // variable to store query results + j := new(types.JWK) + + // send query to the database and store result in variable + err := e.client. + Table(constants.TableJWK). + Where("id = ?", id). + Where("active = ?", true). + Take(j). + Error + if err != nil { + return j.ToAPI(), err + } + + return j.ToAPI(), nil +} diff --git a/database/jwk/get_test.go b/database/jwk/get_test.go new file mode 100644 index 000000000..2cb131bae --- /dev/null +++ b/database/jwk/get_test.go @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: Apache-2.0 + +package jwk + +import ( + "context" + "encoding/json" + "testing" + + "github.com/DATA-DOG/go-sqlmock" + "github.com/google/go-cmp/cmp" + "github.com/lestrrat-go/jwx/jwk" + + "github.com/go-vela/server/database/testutils" +) + +func TestJWK_Engine_GetJWK(t *testing.T) { + // setup types + _jwk := testutils.JWK() + _jwkBytes, err := json.Marshal(_jwk) + if err != nil { + t.Errorf("unable to marshal JWK: %v", err) + } + + _postgres, _mock := testPostgres(t) + defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() + + // create expected result in mock + _rows := sqlmock.NewRows( + []string{"id", "active", "key"}, + ).AddRow(_jwk.KeyID(), true, _jwkBytes) + + // ensure the mock expects the query + _mock.ExpectQuery(`SELECT * FROM "jwks" WHERE id = $1 AND active = $2 LIMIT $3`).WithArgs(_jwk.KeyID(), true, 1).WillReturnRows(_rows) + + _sqlite := testSqlite(t) + defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() + + err = _sqlite.CreateJWK(context.TODO(), _jwk) + if err != nil { + t.Errorf("unable to create test repo for sqlite: %v", err) + } + + // setup tests + tests := []struct { + failure bool + name string + database *engine + want jwk.RSAPublicKey + }{ + { + failure: false, + name: "postgres", + database: _postgres, + want: _jwk, + }, + { + failure: false, + name: "sqlite3", + database: _sqlite, + want: _jwk, + }, + } + + // run tests + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got, err := test.database.GetActiveJWK(context.TODO(), _jwk.KeyID()) + + if test.failure { + if err == nil { + t.Errorf("GetActiveJWK for %s should have returned err", test.name) + } + + return + } + + if err != nil { + t.Errorf("GetActiveJWK for %s returned err: %v", test.name, err) + } + + if diff := cmp.Diff(test.want, got, testutils.JwkKeyOpts); diff != "" { + t.Errorf("GetActiveJWK mismatch (-want +got):\n%s", diff) + } + }) + } +} diff --git a/database/jwk/interface.go b/database/jwk/interface.go new file mode 100644 index 000000000..a83b1b300 --- /dev/null +++ b/database/jwk/interface.go @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: Apache-2.0 + +package jwk + +import ( + "context" + + "github.com/lestrrat-go/jwx/jwk" +) + +// JWKInterface represents the Vela interface for JWK +// functions with the supported Database backends. +// +//nolint:revive // ignore name stutter +type JWKInterface interface { + // JWK Data Definition Language Functions + // + // https://en.wikipedia.org/wiki/Data_definition_language + CreateJWKTable(context.Context, string) error + + // JWK Data Manipulation Language Functions + // + // https://en.wikipedia.org/wiki/Data_manipulation_language + + // CreateJWK defines a function that creates a JWK. + CreateJWK(context.Context, jwk.RSAPublicKey) error + // RotateKeys defines a function that rotates JWKs. + RotateKeys(context.Context) error + // ListJWKs defines a function that lists all JWKs configured. + ListJWKs(context.Context) (jwk.Set, error) + // GetJWK defines a function that gets a JWK by the provided key ID. + GetActiveJWK(context.Context, string) (jwk.RSAPublicKey, error) +} diff --git a/database/jwk/jwk.go b/database/jwk/jwk.go new file mode 100644 index 000000000..6b3acc33f --- /dev/null +++ b/database/jwk/jwk.go @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: Apache-2.0 + +package jwk + +import ( + "context" + "fmt" + + "github.com/sirupsen/logrus" + "gorm.io/gorm" + + "github.com/go-vela/server/constants" +) + +type ( + // config represents the settings required to create the engine that implements the JWKService interface. + config struct { + // specifies to skip creating tables and indexes for the JWK engine + SkipCreation bool + // specifies the driver for proper popping query + Driver string + } + + // engine represents the key set functionality that implements the JWKService interface. + engine struct { + // engine configuration settings used in key set functions + config *config + + ctx context.Context + + // gorm.io/gorm database client used in key set functions + // + // https://pkg.go.dev/gorm.io/gorm#DB + client *gorm.DB + + // sirupsen/logrus logger used in key set functions + // + // https://pkg.go.dev/github.com/sirupsen/logrus#Entry + logger *logrus.Entry + } +) + +// New creates and returns a Vela service for integrating with key sets in the database. +// +//nolint:revive // ignore returning unexported engine +func New(opts ...EngineOpt) (*engine, error) { + // create new JWK engine + e := new(engine) + + // create new fields + e.client = new(gorm.DB) + e.config = new(config) + e.logger = new(logrus.Entry) + + // apply all provided configuration options + for _, opt := range opts { + err := opt(e) + if err != nil { + return nil, err + } + } + + // check if we should skip creating key set database objects + if e.config.SkipCreation { + e.logger.Warning("skipping creation of key sets table and indexes in the database") + + return e, nil + } + + // create the JWK table + err := e.CreateJWKTable(e.ctx, e.client.Config.Dialector.Name()) + if err != nil { + return nil, fmt.Errorf("unable to create %s table: %w", constants.TableJWK, err) + } + + return e, nil +} diff --git a/database/jwk/jwk_test.go b/database/jwk/jwk_test.go new file mode 100644 index 000000000..95ff9a463 --- /dev/null +++ b/database/jwk/jwk_test.go @@ -0,0 +1,163 @@ +// SPDX-License-Identifier: Apache-2.0 + +package jwk + +import ( + "reflect" + "testing" + + "github.com/DATA-DOG/go-sqlmock" + "github.com/sirupsen/logrus" + "gorm.io/driver/postgres" + "gorm.io/driver/sqlite" + "gorm.io/gorm" +) + +func TestJWK_New(t *testing.T) { + // setup types + logger := logrus.NewEntry(logrus.StandardLogger()) + + _sql, _mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual)) + if err != nil { + t.Errorf("unable to create new SQL mock: %v", err) + } + defer _sql.Close() + + _mock.ExpectExec(CreatePostgresTable).WillReturnResult(sqlmock.NewResult(1, 1)) + + _config := &gorm.Config{SkipDefaultTransaction: true} + + _postgres, err := gorm.Open(postgres.New(postgres.Config{Conn: _sql}), _config) + if err != nil { + t.Errorf("unable to create new postgres database: %v", err) + } + + _sqlite, err := gorm.Open(sqlite.Open("file::memory:?cache=shared"), _config) + if err != nil { + t.Errorf("unable to create new sqlite database: %v", err) + } + + defer func() { _sql, _ := _sqlite.DB(); _sql.Close() }() + + // setup tests + tests := []struct { + failure bool + name string + client *gorm.DB + key string + logger *logrus.Entry + skipCreation bool + want *engine + }{ + { + failure: false, + name: "postgres", + client: _postgres, + key: "A1B2C3D4E5G6H7I8J9K0LMNOPQRSTUVW", + logger: logger, + skipCreation: false, + want: &engine{ + client: _postgres, + config: &config{SkipCreation: false}, + logger: logger, + }, + }, + { + failure: false, + name: "sqlite3", + client: _sqlite, + key: "A1B2C3D4E5G6H7I8J9K0LMNOPQRSTUVW", + logger: logger, + skipCreation: false, + want: &engine{ + client: _sqlite, + config: &config{SkipCreation: false}, + logger: logger, + }, + }, + } + + // run tests + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got, err := New( + WithClient(test.client), + WithLogger(test.logger), + WithSkipCreation(test.skipCreation), + ) + + if test.failure { + if err == nil { + t.Errorf("New for %s should have returned err", test.name) + } + + return + } + + if err != nil { + t.Errorf("New for %s returned err: %v", test.name, err) + } + + if !reflect.DeepEqual(got, test.want) { + t.Errorf("New for %s is %v, want %v", test.name, got, test.want) + } + }) + } +} + +// testPostgres is a helper function to create a Postgres engine for testing. +func testPostgres(t *testing.T) (*engine, sqlmock.Sqlmock) { + // create the new mock sql database + // + // https://pkg.go.dev/github.com/DATA-DOG/go-sqlmock#New + _sql, _mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual)) + if err != nil { + t.Errorf("unable to create new SQL mock: %v", err) + } + + _mock.ExpectExec(CreatePostgresTable).WillReturnResult(sqlmock.NewResult(1, 1)) + + // create the new mock Postgres database client + // + // https://pkg.go.dev/gorm.io/gorm#Open + _postgres, err := gorm.Open( + postgres.New(postgres.Config{Conn: _sql}), + &gorm.Config{SkipDefaultTransaction: true}, + ) + if err != nil { + t.Errorf("unable to create new postgres database: %v", err) + } + + _engine, err := New( + WithClient(_postgres), + WithLogger(logrus.NewEntry(logrus.StandardLogger())), + WithSkipCreation(false), + ) + if err != nil { + t.Errorf("unable to create new postgres dashboard engine: %v", err) + } + + return _engine, _mock +} + +// testSqlite is a helper function to create a Sqlite engine for testing. +func testSqlite(t *testing.T) *engine { + _sqlite, err := gorm.Open( + sqlite.Open("file::memory:?cache=shared"), + &gorm.Config{SkipDefaultTransaction: true}, + ) + if err != nil { + t.Errorf("unable to create new sqlite database: %v", err) + } + + _engine, err := New( + WithClient(_sqlite), + WithLogger(logrus.NewEntry(logrus.StandardLogger())), + WithSkipCreation(false), + ) + if err != nil { + t.Errorf("unable to create new sqlite dashboard engine: %v", err) + } + + return _engine +} diff --git a/database/jwk/list.go b/database/jwk/list.go new file mode 100644 index 000000000..7c83b48b1 --- /dev/null +++ b/database/jwk/list.go @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: Apache-2.0 + +package jwk + +import ( + "context" + + "github.com/lestrrat-go/jwx/jwk" + + "github.com/go-vela/server/constants" + "github.com/go-vela/server/database/types" +) + +// ListJWKs gets a list of all configured JWKs from the database. +func (e *engine) ListJWKs(_ context.Context) (jwk.Set, error) { + e.logger.Trace("listing all jwks from the database") + + k := new([]types.JWK) + keySet := jwk.NewSet() + + // send query to the database and store result in variable + err := e.client. + Table(constants.TableJWK). + Find(&k). + Error + if err != nil { + return nil, err + } + + // iterate through all query results + for _, key := range *k { + // https://golang.org/doc/faq#closures_and_goroutines + tmp := key + + // convert query result to API type + keySet.Add(tmp.ToAPI()) + } + + return keySet, nil +} diff --git a/database/jwk/list_test.go b/database/jwk/list_test.go new file mode 100644 index 000000000..f4d54dcc2 --- /dev/null +++ b/database/jwk/list_test.go @@ -0,0 +1,103 @@ +// SPDX-License-Identifier: Apache-2.0 + +package jwk + +import ( + "context" + "encoding/json" + "reflect" + "testing" + + "github.com/DATA-DOG/go-sqlmock" + "github.com/lestrrat-go/jwx/jwk" + + "github.com/go-vela/server/database/testutils" +) + +func TestJWK_Engine_ListJWKs(t *testing.T) { + // setup types + _jwkOne := testutils.JWK() + _jwkOneBytes, err := json.Marshal(_jwkOne) + if err != nil { + t.Errorf("unable to marshal JWK: %v", err) + } + + _jwkTwo := testutils.JWK() + _jwkTwoBytes, err := json.Marshal(_jwkTwo) + if err != nil { + t.Errorf("unable to marshal JWK: %v", err) + } + + _postgres, _mock := testPostgres(t) + defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() + + // create expected result in mock + _rows := sqlmock.NewRows( + []string{"id", "active", "key"}). + AddRow(_jwkOne.KeyID(), true, _jwkOneBytes). + AddRow(_jwkTwo.KeyID(), true, _jwkTwoBytes) + + // ensure the mock expects the query + _mock.ExpectQuery(`SELECT * FROM "jwks"`).WillReturnRows(_rows) + + _sqlite := testSqlite(t) + defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() + + err = _sqlite.CreateJWK(context.TODO(), _jwkOne) + if err != nil { + t.Errorf("unable to create test jwk for sqlite: %v", err) + } + + err = _sqlite.CreateJWK(context.TODO(), _jwkTwo) + if err != nil { + t.Errorf("unable to create test jwk for sqlite: %v", err) + } + + wantSet := jwk.NewSet() + wantSet.Add(_jwkOne) + wantSet.Add(_jwkTwo) + + // setup tests + tests := []struct { + failure bool + name string + database *engine + want jwk.Set + }{ + { + failure: false, + name: "postgres", + database: _postgres, + want: wantSet, + }, + { + failure: false, + name: "sqlite3", + database: _sqlite, + want: wantSet, + }, + } + + // run tests + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got, err := test.database.ListJWKs(context.TODO()) + + if test.failure { + if err == nil { + t.Errorf("ListJWKs for %s should have returned err", test.name) + } + + return + } + + if err != nil { + t.Errorf("ListJWKs for %s returned err: %v", test.name, err) + } + + if !reflect.DeepEqual(got, test.want) { + t.Errorf("ListJWKs for %s is %v, want %v", test.name, got, test.want) + } + }) + } +} diff --git a/database/jwk/opts.go b/database/jwk/opts.go new file mode 100644 index 000000000..b26329135 --- /dev/null +++ b/database/jwk/opts.go @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: Apache-2.0 + +package jwk + +import ( + "context" + + "github.com/sirupsen/logrus" + "gorm.io/gorm" +) + +// EngineOpt represents a configuration option to initialize the database engine for key sets. +type EngineOpt func(*engine) error + +// WithClient sets the gorm.io/gorm client in the database engine for key sets. +func WithClient(client *gorm.DB) EngineOpt { + return func(e *engine) error { + // set the gorm.io/gorm client in the key set engine + e.client = client + + return nil + } +} + +// WithLogger sets the github.com/sirupsen/logrus logger in the database engine for key sets. +func WithLogger(logger *logrus.Entry) EngineOpt { + return func(e *engine) error { + // set the github.com/sirupsen/logrus logger in the key set engine + e.logger = logger + + return nil + } +} + +// WithSkipCreation sets the skip creation logic in the database engine for key sets. +func WithSkipCreation(skipCreation bool) EngineOpt { + return func(e *engine) error { + // set to skip creating tables and indexes in the key set engine + e.config.SkipCreation = skipCreation + + return nil + } +} + +// WithContext sets the context in the database engine for key sets. +func WithContext(ctx context.Context) EngineOpt { + return func(e *engine) error { + e.ctx = ctx + + return nil + } +} diff --git a/database/jwk/opts_test.go b/database/jwk/opts_test.go new file mode 100644 index 000000000..8a7192111 --- /dev/null +++ b/database/jwk/opts_test.go @@ -0,0 +1,208 @@ +// SPDX-License-Identifier: Apache-2.0 + +package jwk + +import ( + "context" + "reflect" + "testing" + + "github.com/sirupsen/logrus" + "gorm.io/gorm" +) + +func TestHook_EngineOpt_WithClient(t *testing.T) { + // setup types + e := &engine{client: new(gorm.DB)} + + // setup tests + tests := []struct { + failure bool + name string + client *gorm.DB + want *gorm.DB + }{ + { + failure: false, + name: "client set to new database", + client: new(gorm.DB), + want: new(gorm.DB), + }, + { + failure: false, + name: "client set to nil", + client: nil, + want: nil, + }, + } + + // run tests + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + err := WithClient(test.client)(e) + + if test.failure { + if err == nil { + t.Errorf("WithClient for %s should have returned err", test.name) + } + + return + } + + if err != nil { + t.Errorf("WithClient returned err: %v", err) + } + + if !reflect.DeepEqual(e.client, test.want) { + t.Errorf("WithClient is %v, want %v", e.client, test.want) + } + }) + } +} + +func TestHook_EngineOpt_WithLogger(t *testing.T) { + // setup types + e := &engine{logger: new(logrus.Entry)} + + // setup tests + tests := []struct { + failure bool + name string + logger *logrus.Entry + want *logrus.Entry + }{ + { + failure: false, + name: "logger set to new entry", + logger: new(logrus.Entry), + want: new(logrus.Entry), + }, + { + failure: false, + name: "logger set to nil", + logger: nil, + want: nil, + }, + } + + // run tests + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + err := WithLogger(test.logger)(e) + + if test.failure { + if err == nil { + t.Errorf("WithLogger for %s should have returned err", test.name) + } + + return + } + + if err != nil { + t.Errorf("WithLogger returned err: %v", err) + } + + if !reflect.DeepEqual(e.logger, test.want) { + t.Errorf("WithLogger is %v, want %v", e.logger, test.want) + } + }) + } +} + +func TestHook_EngineOpt_WithSkipCreation(t *testing.T) { + // setup types + e := &engine{config: new(config)} + + // setup tests + tests := []struct { + failure bool + name string + skipCreation bool + want bool + }{ + { + failure: false, + name: "skip creation set to true", + skipCreation: true, + want: true, + }, + { + failure: false, + name: "skip creation set to false", + skipCreation: false, + want: false, + }, + } + + // run tests + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + err := WithSkipCreation(test.skipCreation)(e) + + if test.failure { + if err == nil { + t.Errorf("WithSkipCreation for %s should have returned err", test.name) + } + + return + } + + if err != nil { + t.Errorf("WithSkipCreation returned err: %v", err) + } + + if !reflect.DeepEqual(e.config.SkipCreation, test.want) { + t.Errorf("WithSkipCreation is %v, want %v", e.config.SkipCreation, test.want) + } + }) + } +} + +func TestHook_EngineOpt_WithContext(t *testing.T) { + // setup types + e := &engine{config: new(config)} + + // setup tests + tests := []struct { + failure bool + name string + ctx context.Context + want context.Context + }{ + { + failure: false, + name: "context set to TODO", + ctx: context.TODO(), + want: context.TODO(), + }, + { + failure: false, + name: "context set to nil", + ctx: nil, + want: nil, + }, + } + + // run tests + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + err := WithContext(test.ctx)(e) + + if test.failure { + if err == nil { + t.Errorf("WithContext for %s should have returned err", test.name) + } + + return + } + + if err != nil { + t.Errorf("WithContext returned err: %v", err) + } + + if !reflect.DeepEqual(e.ctx, test.want) { + t.Errorf("WithContext is %v, want %v", e.ctx, test.want) + } + }) + } +} diff --git a/database/jwk/rotate.go b/database/jwk/rotate.go new file mode 100644 index 000000000..82ff1c422 --- /dev/null +++ b/database/jwk/rotate.go @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: Apache-2.0 + +package jwk + +import ( + "context" + "database/sql" + + "github.com/go-vela/server/constants" + "github.com/go-vela/server/database/types" +) + +// RotateKeys removes all inactive keys and sets active keys to inactive. +func (e *engine) RotateKeys(_ context.Context) error { + e.logger.Trace("rotating jwks in the database") + + k := types.JWK{} + + // remove inactive keys + err := e.client. + Table(constants.TableJWK). + Where("active = ?", false). + Delete(&k). + Error + if err != nil { + return err + } + + // set active keys to inactive + err = e.client. + Table(constants.TableJWK). + Where("active = ?", true). + Update("active", sql.NullBool{Bool: false, Valid: true}). + Error + if err != nil { + return err + } + + return nil +} diff --git a/database/jwk/rotate_test.go b/database/jwk/rotate_test.go new file mode 100644 index 000000000..cd4acbb72 --- /dev/null +++ b/database/jwk/rotate_test.go @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: Apache-2.0 + +package jwk + +import ( + "context" + "encoding/json" + "testing" + + "github.com/DATA-DOG/go-sqlmock" + + "github.com/go-vela/server/database/testutils" +) + +func TestJWK_Engine_RotateKeys(t *testing.T) { + // setup types + _jwkOne := testutils.JWK() + _jwkOneBytes, err := json.Marshal(_jwkOne) + if err != nil { + t.Errorf("unable to marshal JWK: %v", err) + } + + _jwkTwo := testutils.JWK() + _jwkTwoBytes, err := json.Marshal(_jwkTwo) + if err != nil { + t.Errorf("unable to marshal JWK: %v", err) + } + + _postgres, _mock := testPostgres(t) + defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() + + // create expected result in mock + _rows := sqlmock.NewRows( + []string{"id", "active", "key"}, + ).AddRow(_jwkOne.KeyID(), true, _jwkOneBytes) + + // ensure the mock expects the query + _mock.ExpectQuery(`SELECT * FROM "jwks" WHERE id = $1 AND active = $2 LIMIT $3`).WithArgs(_jwkOne.KeyID(), true, 1).WillReturnRows(_rows) + + // create expected result in mock + _rows = sqlmock.NewRows( + []string{"id", "active", "key"}, + ).AddRow(_jwkTwo.KeyID(), true, _jwkTwoBytes) + + // ensure the mock expects the query + _mock.ExpectQuery(`SELECT * FROM "jwks" WHERE id = $1 AND active = $2 LIMIT $3`).WithArgs(_jwkTwo.KeyID(), true, 1).WillReturnRows(_rows) + + _mock.ExpectExec(`DELETE FROM "jwks" WHERE active = $1`). + WithArgs(false). + WillReturnResult(sqlmock.NewResult(1, 1)) + + _mock.ExpectExec(`UPDATE "jwks" SET "active"=$1 WHERE active = $2`). + WithArgs(false, true). + WillReturnResult(sqlmock.NewResult(1, 1)) + + _sqlite := testSqlite(t) + defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() + + err = _sqlite.CreateJWK(context.TODO(), _jwkOne) + if err != nil { + t.Errorf("unable to create test jwk for sqlite: %v", err) + } + + err = _sqlite.CreateJWK(context.TODO(), _jwkTwo) + if err != nil { + t.Errorf("unable to create test jwk for sqlite: %v", err) + } + + // setup tests + tests := []struct { + failure bool + name string + database *engine + }{ + { + failure: false, + name: "postgres", + database: _postgres, + }, + { + failure: false, + name: "sqlite3", + database: _sqlite, + }, + } + + // run tests + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + _, err := test.database.GetActiveJWK(context.TODO(), _jwkOne.KeyID()) + if err != nil { + t.Errorf("GetActiveJWK for %s returned err: %v", test.name, err) + } + + _, err = test.database.GetActiveJWK(context.TODO(), _jwkTwo.KeyID()) + if err != nil { + t.Errorf("GetActiveJWK for %s returned err: %v", test.name, err) + } + + err = test.database.RotateKeys(context.TODO()) + + if test.failure { + if err == nil { + t.Errorf("RotateKeys for %s should have returned err", test.name) + } + + return + } + + if err != nil { + t.Errorf("RotateKeys for %s returned err: %v", test.name, err) + } + + _, err = test.database.GetActiveJWK(context.TODO(), _jwkOne.KeyID()) + if err == nil { + t.Errorf("GetActiveJWK for %s should have returned err", test.name) + } + + _, err = test.database.GetActiveJWK(context.TODO(), _jwkTwo.KeyID()) + if err == nil { + t.Errorf("GetActiveJWK for %s should have returned err", test.name) + } + }) + } +} diff --git a/database/jwk/table.go b/database/jwk/table.go new file mode 100644 index 000000000..6e2108de9 --- /dev/null +++ b/database/jwk/table.go @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: Apache-2.0 + +package jwk + +import ( + "context" + + "github.com/go-vela/types/constants" +) + +const ( + // CreatePostgresTable represents a query to create the Postgres jwks table. + CreatePostgresTable = ` +CREATE TABLE +IF NOT EXISTS +jwks ( + id UUID PRIMARY KEY, + active BOOLEAN, + key JSON DEFAULT NULL +); +` + + // CreateSqliteTable represents a query to create the Sqlite jwks table. + CreateSqliteTable = ` +CREATE TABLE +IF NOT EXISTS +jwks ( + id TEXT PRIMARY KEY, + active BOOLEAN, + key TEXT +); +` +) + +// CreateJWKTable creates the jwks table in the database. +func (e *engine) CreateJWKTable(ctx context.Context, driver string) error { + e.logger.Tracef("creating jwks table in the database") + + // handle the driver provided to create the table + switch driver { + case constants.DriverPostgres: + // create the jwks table for Postgres + return e.client.Exec(CreatePostgresTable).Error + case constants.DriverSqlite: + fallthrough + default: + // create the jwks table for Sqlite + return e.client.Exec(CreateSqliteTable).Error + } +} diff --git a/database/jwk/table_test.go b/database/jwk/table_test.go new file mode 100644 index 000000000..ec8626677 --- /dev/null +++ b/database/jwk/table_test.go @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: Apache-2.0 + +package jwk + +import ( + "context" + "testing" + + "github.com/DATA-DOG/go-sqlmock" +) + +func TestJWK_Engine_CreateJWKTable(t *testing.T) { + // setup types + _postgres, _mock := testPostgres(t) + defer func() { _sql, _ := _postgres.client.DB(); _sql.Close() }() + + _mock.ExpectExec(CreatePostgresTable).WillReturnResult(sqlmock.NewResult(1, 1)) + + _sqlite := testSqlite(t) + defer func() { _sql, _ := _sqlite.client.DB(); _sql.Close() }() + + // setup tests + tests := []struct { + failure bool + name string + database *engine + }{ + { + failure: false, + name: "postgres", + database: _postgres, + }, + { + failure: false, + name: "sqlite3", + database: _sqlite, + }, + } + + // run tests + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + err := test.database.CreateJWKTable(context.TODO(), test.name) + + if test.failure { + if err == nil { + t.Errorf("CreateJWKTable for %s should have returned err", test.name) + } + + return + } + + if err != nil { + t.Errorf("CreateJWKTable for %s returned err: %v", test.name, err) + } + }) + } +} diff --git a/database/resource.go b/database/resource.go index 486d2a137..c11341c64 100644 --- a/database/resource.go +++ b/database/resource.go @@ -10,6 +10,7 @@ import ( "github.com/go-vela/server/database/deployment" "github.com/go-vela/server/database/executable" "github.com/go-vela/server/database/hook" + "github.com/go-vela/server/database/jwk" "github.com/go-vela/server/database/log" "github.com/go-vela/server/database/pipeline" "github.com/go-vela/server/database/repo" @@ -96,6 +97,17 @@ func (e *engine) NewResources(ctx context.Context) error { return err } + // create the database agnostic engine for JWKs + e.JWKInterface, err = jwk.New( + jwk.WithContext(e.ctx), + jwk.WithClient(e.client), + jwk.WithLogger(e.logger), + jwk.WithSkipCreation(e.config.SkipCreation), + ) + if err != nil { + return err + } + // create the database agnostic engine for logs e.LogInterface, err = log.New( log.WithContext(e.ctx), diff --git a/database/resource_test.go b/database/resource_test.go index a1371108b..cdc5dbaa3 100644 --- a/database/resource_test.go +++ b/database/resource_test.go @@ -13,6 +13,7 @@ import ( "github.com/go-vela/server/database/deployment" "github.com/go-vela/server/database/executable" "github.com/go-vela/server/database/hook" + "github.com/go-vela/server/database/jwk" "github.com/go-vela/server/database/log" "github.com/go-vela/server/database/pipeline" "github.com/go-vela/server/database/repo" @@ -47,6 +48,8 @@ func TestDatabase_Engine_NewResources(t *testing.T) { // ensure the mock expects the hook queries _mock.ExpectExec(hook.CreatePostgresTable).WillReturnResult(sqlmock.NewResult(1, 1)) _mock.ExpectExec(hook.CreateRepoIDIndex).WillReturnResult(sqlmock.NewResult(1, 1)) + // ensure the mock expects the jwk queries + _mock.ExpectExec(jwk.CreatePostgresTable).WillReturnResult(sqlmock.NewResult(1, 1)) // ensure the mock expects the log queries _mock.ExpectExec(log.CreatePostgresTable).WillReturnResult(sqlmock.NewResult(1, 1)) _mock.ExpectExec(log.CreateBuildIDIndex).WillReturnResult(sqlmock.NewResult(1, 1)) diff --git a/database/testutils/api_resources.go b/database/testutils/api_resources.go index a418ee363..83a3d5c3c 100644 --- a/database/testutils/api_resources.go +++ b/database/testutils/api_resources.go @@ -3,6 +3,12 @@ package testutils import ( + "crypto/rand" + "crypto/rsa" + + "github.com/google/uuid" + "github.com/lestrrat-go/jwx/jwk" + api "github.com/go-vela/server/api/types" "github.com/go-vela/server/api/types/actions" "github.com/go-vela/types/library" @@ -269,3 +275,23 @@ func APIDashboardRepo() *api.DashboardRepo { Events: new([]string), } } + +func JWK() jwk.RSAPublicKey { + privateRSAKey, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + return nil + } + + // assign KID to key pair + kid, err := uuid.NewV7() + if err != nil { + return nil + } + + j := jwk.NewRSAPublicKey() + _ = j.FromRaw(&privateRSAKey.PublicKey) + + _ = j.Set(jwk.KeyIDKey, kid.String()) + + return j +} diff --git a/database/testutils/mock_args.go b/database/testutils/mock_args.go index c2d8c562f..e6d8a9324 100644 --- a/database/testutils/mock_args.go +++ b/database/testutils/mock_args.go @@ -4,7 +4,11 @@ package testutils import ( "database/sql/driver" + "reflect" "time" + + "github.com/google/go-cmp/cmp" + "github.com/lestrrat-go/jwx/jwk" ) // This will be used with the github.com/DATA-DOG/go-sqlmock library to compare values @@ -33,3 +37,26 @@ func (t NowTimestamp) Match(v driver.Value) bool { return now-ts < 10 } + +var JwkKeyOpts = cmp.Options{ + cmp.FilterValues(func(x, y interface{}) bool { + _, xOk := x.(jwk.RSAPublicKey) + _, yOk := y.(jwk.RSAPublicKey) + return xOk && yOk + }, cmp.Comparer(func(x, y interface{}) bool { + xJWK := x.(jwk.RSAPublicKey) + yJWK := y.(jwk.RSAPublicKey) + + var rawXKey, rawYKey interface{} + + if err := xJWK.Raw(&rawXKey); err != nil { + return false + } + + if err := yJWK.Raw(&rawYKey); err != nil { + return false + } + + return reflect.DeepEqual(rawXKey, rawYKey) && xJWK.KeyID() == yJWK.KeyID() + })), +} diff --git a/database/types/jwk.go b/database/types/jwk.go new file mode 100644 index 000000000..486512da1 --- /dev/null +++ b/database/types/jwk.go @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "database/sql" + "encoding/json" + "errors" + + "github.com/google/uuid" + "github.com/lestrrat-go/jwx/jwk" +) + +var ( + // ErrInvalidKID defines the error type when a + // JWK type has an invalid ID field provided. + ErrInvalidKID = errors.New("invalid key identifier provided") +) + +type ( + // JWK is the database representation of a jwk. + JWK struct { + ID uuid.UUID `gorm:"type:uuid"` + Active sql.NullBool `sql:"active"` + Key []byte `sql:"key"` + } +) + +// Nullify ensures the valid flag for +// the sql.Null types are properly set. +// +// When a field within the JWK type is the zero +// value for the field, the valid flag is set to +// false causing it to be NULL in the database. +func (j *JWK) Nullify() *JWK { + if j == nil { + return nil + } + + return j +} + +// ToAPI converts the JWK type +// to an API JWK type. +func (j *JWK) ToAPI() jwk.RSAPublicKey { + parsedKey, _ := jwk.ParseKey(j.Key) + + switch jwk := parsedKey.(type) { + case jwk.RSAPublicKey: + return jwk + default: + return nil + } +} + +// JWKFromAPI converts the API JWK type +// to a database JWK type. +func JWKFromAPI(j jwk.RSAPublicKey) *JWK { + var ( + id uuid.UUID + err error + ) + + id, err = uuid.Parse(j.KeyID()) + if err != nil { + return nil + } + + bytesKey, _ := json.Marshal(j) + + jwk := &JWK{ + ID: id, + Key: bytesKey, + } + + return jwk.Nullify() +} diff --git a/database/types/jwk_test.go b/database/types/jwk_test.go new file mode 100644 index 000000000..01fbf6ddc --- /dev/null +++ b/database/types/jwk_test.go @@ -0,0 +1,106 @@ +// SPDX-License-Identifier: Apache-2.0 + +package types + +import ( + "database/sql" + "encoding/json" + "reflect" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/uuid" + + "github.com/go-vela/server/database/testutils" +) + +func TestTypes_JWK_Nullify(t *testing.T) { + // setup tests + var j *JWK + + tests := []struct { + JWK *JWK + want *JWK + }{ + { + JWK: testJWK(), + want: testJWK(), + }, + { + JWK: j, + want: nil, + }, + } + + // run tests + for _, test := range tests { + got := test.JWK.Nullify() + + if !reflect.DeepEqual(got, test.want) { + t.Errorf("Nullify is %v, want %v", got, test.want) + } + } +} + +func TestTypes_JWK_ToAPI(t *testing.T) { + // setup types + want := testutils.JWK() + + wantBytes, err := json.Marshal(want) + if err != nil { + t.Errorf("unable to marshal JWK: %v", err) + } + + uuid, _ := uuid.Parse(want.KeyID()) + h := &JWK{ + ID: uuid, + Active: sql.NullBool{Bool: true, Valid: true}, + Key: wantBytes, + } + + // run test + got := h.ToAPI() + + if !reflect.DeepEqual(got, want) { + t.Errorf("ToAPI is %v, want %v", got, want) + } +} + +func TestTypes_JWKFromAPI(t *testing.T) { + j := testutils.JWK() + + jBytes, err := json.Marshal(j) + if err != nil { + t.Errorf("unable to marshal JWK: %v", err) + } + + uuid, err := uuid.Parse(j.KeyID()) + if err != nil { + t.Errorf("unable to parse JWK key id: %v", err) + } + + // setup types + want := &JWK{ + ID: uuid, + Active: sql.NullBool{Bool: false, Valid: false}, + Key: jBytes, + } + + // run test + got := JWKFromAPI(j) + + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("JWKFromAPI() mismatch (-want +got):\n%s", diff) + } +} + +// testJWK is a test helper function to create a JWK +// type with all fields set to a fake value. +func testJWK() *JWK { + uuid, _ := uuid.Parse("c8da1302-07d6-11ea-882f-4893bca275b8") + + return &JWK{ + ID: uuid, + Active: sql.NullBool{Bool: true, Valid: true}, + } +} diff --git a/go.mod b/go.mod index 4993597bb..f9837b3eb 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/ghodss/yaml v1.0.0 github.com/gin-gonic/gin v1.9.1 github.com/go-playground/assert/v2 v2.2.0 - github.com/go-vela/types v0.23.4-0.20240417135026-fb4a95c30338 + github.com/go-vela/types v0.23.4-0.20240516161114-57d6b8f77b10 github.com/golang-jwt/jwt/v5 v5.2.1 github.com/google/go-cmp v0.6.0 github.com/google/go-github/v61 v61.0.0 @@ -46,6 +46,15 @@ require ( k8s.io/apimachinery v0.29.2 ) +require ( + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect + github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect + github.com/lestrrat-go/blackmagic v1.0.2 // indirect + github.com/lestrrat-go/httpcc v1.0.1 // indirect + github.com/lestrrat-go/iter v1.0.2 // indirect + github.com/lestrrat-go/option v1.0.1 // indirect +) + require ( github.com/Masterminds/goutils v1.1.1 // indirect github.com/PuerkitoBio/purell v1.1.1 // indirect @@ -92,6 +101,7 @@ require ( github.com/klauspost/cpuid/v2 v2.2.4 // indirect github.com/kr/text v0.2.0 // indirect github.com/leodido/go-urn v1.2.4 // indirect + github.com/lestrrat-go/jwx v1.2.29 github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-sqlite3 v1.14.17 // indirect github.com/mitchellh/copystructure v1.0.0 // indirect diff --git a/go.sum b/go.sum index 75bac3763..0f39a0a81 100644 --- a/go.sum +++ b/go.sum @@ -56,6 +56,9 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= @@ -87,8 +90,8 @@ github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw= github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= -github.com/go-vela/types v0.23.4-0.20240417135026-fb4a95c30338 h1:I0v47dOdAvjX7lOFN4s28uONChmluD6TNgFL1hpav60= -github.com/go-vela/types v0.23.4-0.20240417135026-fb4a95c30338/go.mod h1:vISsYDdjz9RPEK6qZ+MxtrdZEjTVU4K30NomB3826u8= +github.com/go-vela/types v0.23.4-0.20240516161114-57d6b8f77b10 h1:VQxIqxpJKIOzRnMi4z/d+EOo7jc5PXCnlUvZZl5ajzA= +github.com/go-vela/types v0.23.4-0.20240516161114-57d6b8f77b10/go.mod h1:vISsYDdjz9RPEK6qZ+MxtrdZEjTVU4K30NomB3826u8= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= @@ -184,6 +187,19 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= +github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A= +github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y= +github.com/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N+AkAr5k= +github.com/lestrrat-go/blackmagic v1.0.2/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU= +github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE= +github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E= +github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI= +github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4= +github.com/lestrrat-go/jwx v1.2.29 h1:QT0utmUJ4/12rmsVQrJ3u55bycPkKqGYuGT4tyRhxSQ= +github.com/lestrrat-go/jwx v1.2.29/go.mod h1:hU8k2l6WF0ncx20uQdOmik/Gjg6E3/wIRtXSNFeZuB8= +github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= +github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= +github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A= @@ -252,17 +268,20 @@ github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= @@ -306,6 +325,7 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= @@ -341,6 +361,7 @@ golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= diff --git a/internal/token/compose_test.go b/internal/token/compose_test.go index 0cbce444c..c6efd58ce 100644 --- a/internal/token/compose_test.go +++ b/internal/token/compose_test.go @@ -24,8 +24,7 @@ func TestToken_Compose(t *testing.T) { u.SetToken("bar") tm := &Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } @@ -47,7 +46,7 @@ func TestToken_Compose(t *testing.T) { tkn := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) - want, err := tkn.SignedString([]byte(tm.PrivateKey)) + want, err := tkn.SignedString([]byte(tm.PrivateKeyHMAC)) if err != nil { t.Errorf("Unable to create test token: %v", err) } diff --git a/internal/token/generate_rsa.go b/internal/token/generate_rsa.go new file mode 100644 index 000000000..350ab8ea9 --- /dev/null +++ b/internal/token/generate_rsa.go @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: Apache-2.0 + +package token + +import ( + "context" + "crypto/rand" + "crypto/rsa" + + "github.com/google/uuid" + "github.com/lestrrat-go/jwx/jwk" + + "github.com/go-vela/server/database" +) + +// GenerateRSA creates an RSA key pair and sets it in the token manager and saves the JWK in the database. +func (tm *Manager) GenerateRSA(ctx context.Context, db database.Interface) error { + // generate key pair + privateRSAKey, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + return err + } + + // assign KID to key pair + kid, err := uuid.NewV7() + if err != nil { + return err + } + + j := jwk.NewRSAPublicKey() + + err = j.FromRaw(&privateRSAKey.PublicKey) + if err != nil { + return err + } + + err = j.Set(jwk.KeyIDKey, kid.String()) + if err != nil { + return err + } + + // create the JWK in the database + err = db.CreateJWK(context.TODO(), j) + if err != nil { + return err + } + + // create the RSA key set for token manager + keySet := RSAKeySet{ + PrivateKey: privateRSAKey, + KID: kid.String(), + } + + tm.RSAKeySet = keySet + + return nil +} diff --git a/internal/token/manager.go b/internal/token/manager.go index c02484b87..8094bd131 100644 --- a/internal/token/manager.go +++ b/internal/token/manager.go @@ -3,17 +3,21 @@ package token import ( + "crypto/rsa" "time" - - "github.com/golang-jwt/jwt/v5" ) +type RSAKeySet struct { + PrivateKey *rsa.PrivateKey + KID string +} + type Manager struct { - // PrivateKey key used to sign tokens - PrivateKey string + // PrivateKeyHMAC is the private key used to sign and validate closed-system tokens + PrivateKeyHMAC string - // SignMethod method to sign tokens - SignMethod jwt.SigningMethod + // RSAKeySet is the private key used to sign and validate open-system tokens (OIDC) + RSAKeySet RSAKeySet // UserAccessTokenDuration specifies the token duration to use for users UserAccessTokenDuration time.Duration @@ -29,4 +33,10 @@ type Manager struct { // WorkerRegisterTokenDuration specifies the token duration for worker register WorkerRegisterTokenDuration time.Duration + + // IDTokenDuration specifies the token duration for ID tokens + IDTokenDuration time.Duration + + // Issuer specifies the issuer of the token + Issuer string } diff --git a/internal/token/mint.go b/internal/token/mint.go index f4a4338a7..1cbb65663 100644 --- a/internal/token/mint.go +++ b/internal/token/mint.go @@ -3,36 +3,48 @@ package token import ( + "context" "errors" "fmt" "time" "github.com/golang-jwt/jwt/v5" + "gorm.io/gorm" api "github.com/go-vela/server/api/types" - "github.com/go-vela/types/constants" + "github.com/go-vela/server/constants" + "github.com/go-vela/server/database" ) // Claims struct is an extension of the JWT standard claims. It // includes information about the user. type Claims struct { - BuildID int64 `json:"build_id"` - IsActive bool `json:"is_active"` - IsAdmin bool `json:"is_admin"` - Repo string `json:"repo"` - TokenType string `json:"token_type"` + BuildID int64 `json:"build_id,omitempty"` + BuildNumber int `json:"build_number,omitempty"` + Actor string `json:"actor,omitempty"` + IsActive bool `json:"is_active,omitempty"` + IsAdmin bool `json:"is_admin,omitempty"` + Repo string `json:"repo,omitempty"` + TokenType string `json:"token_type,omitempty"` + Image string `json:"image,omitempty"` + Request string `json:"request,omitempty"` + Commands bool `json:"commands,omitempty"` jwt.RegisteredClaims } // MintTokenOpts is a type to inform the token minter how to construct // the token. type MintTokenOpts struct { - BuildID int64 + Build *api.Build Hostname string Repo string TokenDuration time.Duration TokenType string User *api.User + Audience []string + Image string + Request string + Commands bool } // MintToken mints a Vela JWT Token given a set of options. @@ -52,7 +64,7 @@ func (tm *Manager) MintToken(mto *MintTokenOpts) (string, error) { claims.Subject = mto.User.GetName() case constants.WorkerBuildTokenType: - if mto.BuildID == 0 { + if mto.Build.GetID() == 0 { return "", errors.New("missing build id for build token") } @@ -64,7 +76,7 @@ func (tm *Manager) MintToken(mto *MintTokenOpts) (string, error) { return "", errors.New("missing host name for build token") } - claims.BuildID = mto.BuildID + claims.BuildID = mto.Build.GetID() claims.Repo = mto.Repo claims.Subject = mto.Hostname @@ -75,6 +87,28 @@ func (tm *Manager) MintToken(mto *MintTokenOpts) (string, error) { claims.Subject = mto.Hostname + case constants.IDRequestTokenType: + if len(mto.Repo) == 0 { + return "", errors.New("missing repo for ID request token") + } + + if mto.Build == nil { + return "", errors.New("missing build for ID request token") + } + + if mto.Build.GetID() == 0 { + return "", errors.New("missing build id for ID request token") + } + + claims.Repo = mto.Repo + claims.Subject = fmt.Sprintf("repo:%s:ref:%s:event:%s", mto.Repo, mto.Build.GetRef(), mto.Build.GetEvent()) + claims.BuildID = mto.Build.GetID() + claims.BuildNumber = mto.Build.GetNumber() + claims.Actor = mto.Build.GetSender() + claims.Image = mto.Image + claims.Request = mto.Request + claims.Commands = mto.Commands + default: return "", errors.New("invalid token type") } @@ -83,10 +117,81 @@ func (tm *Manager) MintToken(mto *MintTokenOpts) (string, error) { claims.ExpiresAt = jwt.NewNumericDate(time.Now().Add(mto.TokenDuration)) claims.TokenType = mto.TokenType - tk := jwt.NewWithClaims(tm.SignMethod, claims) + tk := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) + + //sign token with configured private signing key + token, err := tk.SignedString([]byte(tm.PrivateKeyHMAC)) + if err != nil { + return "", fmt.Errorf("unable to sign token: %w", err) + } + + return token, nil +} + +// MintIDToken mints a Vela JWT ID Token for a build. +func (tm *Manager) MintIDToken(ctx context.Context, mto *MintTokenOpts, db database.Interface) (string, error) { + // initialize claims struct + var claims = new(api.OpenIDClaims) + + // validate provided claims + if len(mto.Repo) == 0 { + return "", errors.New("missing repo for ID token") + } + + if mto.Build == nil { + return "", errors.New("missing build for ID token") + } + + if mto.Build.GetNumber() == 0 { + return "", errors.New("missing build id for ID token") + } + + if len(mto.Build.GetSender()) == 0 { + return "", errors.New("missing build sender for ID token") + } + + // set claims based on input + claims.Actor = mto.Build.GetSender() + claims.ActorSCMID = mto.Build.GetSenderSCMID() + claims.BuildNumber = mto.Build.GetNumber() + claims.BuildID = mto.Build.GetID() + claims.Repo = mto.Repo + claims.Event = fmt.Sprintf("%s:%s", mto.Build.GetEvent(), mto.Build.GetEventAction()) + claims.SHA = mto.Build.GetCommit() + claims.Ref = mto.Build.GetRef() + claims.Subject = fmt.Sprintf("repo:%s:ref:%s:event:%s", mto.Repo, mto.Build.GetRef(), mto.Build.GetEvent()) + claims.Audience = mto.Audience + claims.TokenType = mto.TokenType + claims.Image = mto.Image + claims.Request = mto.Request + claims.Commands = mto.Commands + + // set standard claims + claims.IssuedAt = jwt.NewNumericDate(time.Now()) + claims.ExpiresAt = jwt.NewNumericDate(time.Now().Add(mto.TokenDuration)) + claims.Issuer = tm.Issuer + + tk := jwt.NewWithClaims(jwt.SigningMethodRS256, claims) + + // verify key is active in the database before signing + _, err := db.GetActiveJWK(ctx, tm.RSAKeySet.KID) + if err != nil { + if !errors.Is(err, gorm.ErrRecordNotFound) { + return "", fmt.Errorf("unable to get active public key: %w", err) + } + + // generate a new RSA key pair if previous key is inactive (rotated) + err = tm.GenerateRSA(ctx, db) + if err != nil { + return "", fmt.Errorf("unable to generate RSA key pair: %w", err) + } + } + + // set KID header + tk.Header["kid"] = tm.RSAKeySet.KID //sign token with configured private signing key - token, err := tk.SignedString([]byte(tm.PrivateKey)) + token, err := tk.SignedString(tm.RSAKeySet.PrivateKey) if err != nil { return "", fmt.Errorf("unable to sign token: %w", err) } diff --git a/internal/token/parse.go b/internal/token/parse.go index c42d90686..d5db3041e 100644 --- a/internal/token/parse.go +++ b/internal/token/parse.go @@ -42,7 +42,7 @@ func (tm *Manager) ParseToken(token string) (*Claims, error) { return nil, errors.New("token has no expiration") } - return []byte(tm.PrivateKey), err + return []byte(tm.PrivateKeyHMAC), err }) if err != nil { diff --git a/internal/token/parse_test.go b/internal/token/parse_test.go index a3efd14ea..600efe35e 100644 --- a/internal/token/parse_test.go +++ b/internal/token/parse_test.go @@ -21,9 +21,13 @@ func TestTokenManager_ParseToken(t *testing.T) { u.SetName("foo") u.SetToken("bar") + b := new(api.Build) + b.SetID(1) + b.SetNumber(1) + b.SetSender("octocat") + tm := &Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } @@ -74,7 +78,7 @@ func TestTokenManager_ParseToken(t *testing.T) { { TokenType: constants.WorkerBuildTokenType, Mto: &MintTokenOpts{ - BuildID: 1, + Build: b, Repo: "foo/bar", Hostname: "worker", TokenType: constants.WorkerBuildTokenType, @@ -122,8 +126,7 @@ func TestTokenManager_ParseToken_Error_NoParse(t *testing.T) { u.SetToken("bar") tm := &Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } @@ -147,8 +150,7 @@ func TestTokenManager_ParseToken_Expired(t *testing.T) { u.SetToken("bar") tm := &Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } @@ -179,8 +181,7 @@ func TestTokenManager_ParseToken_NoSubject(t *testing.T) { u.SetToken("bar") tm := &Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } @@ -195,7 +196,7 @@ func TestTokenManager_ParseToken_NoSubject(t *testing.T) { } tkn := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) - token, err := tkn.SignedString([]byte(tm.PrivateKey)) + token, err := tkn.SignedString([]byte(tm.PrivateKeyHMAC)) if err != nil { t.Errorf("Unable to create test token: %v", err) } @@ -219,8 +220,7 @@ func TestTokenManager_ParseToken_Error_InvalidSignature(t *testing.T) { u.SetToken("bar") tm := &Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } @@ -236,7 +236,7 @@ func TestTokenManager_ParseToken_Error_InvalidSignature(t *testing.T) { } tkn := jwt.NewWithClaims(jwt.SigningMethodHS512, claims) - token, err := tkn.SignedString([]byte(tm.PrivateKey)) + token, err := tkn.SignedString([]byte(tm.PrivateKeyHMAC)) if err != nil { t.Errorf("Unable to create test token: %v", err) } @@ -260,8 +260,7 @@ func TestToken_Parse_AccessToken_NoExpiration(t *testing.T) { u.SetToken("bar") tm := &Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } diff --git a/internal/token/refresh_test.go b/internal/token/refresh_test.go index 139bb6634..49c809eb6 100644 --- a/internal/token/refresh_test.go +++ b/internal/token/refresh_test.go @@ -10,7 +10,6 @@ import ( "time" "github.com/gin-gonic/gin" - "github.com/golang-jwt/jwt/v5" api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" @@ -25,8 +24,7 @@ func TestTokenManager_Refresh(t *testing.T) { u.SetToken("bar") tm := &Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } @@ -85,8 +83,7 @@ func TestTokenManager_Refresh_Expired(t *testing.T) { u.SetToken("bar") tm := &Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } diff --git a/mock/server/authentication.go b/mock/server/authentication.go index 094915768..6e9f4512b 100644 --- a/mock/server/authentication.go +++ b/mock/server/authentication.go @@ -7,7 +7,9 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/lestrrat-go/jwx/jwk" + api "github.com/go-vela/server/api/types" "github.com/go-vela/types" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" @@ -19,6 +21,43 @@ const ( TokenRefreshResp = `{ "token": "header.payload.signature" }` + + // OpenIDConfigResp represents a JSON return for an OpenID configuration. + OpenIDConfigResp = `{ + "issuer": "https://vela.com/_services/token", + "jwks_uri": "https://vela.com/_services/token/.well-known/jwks", + "supported_claims": [ + "sub", + "exp", + "iat", + "iss", + "aud", + "build_number", + "build_id", + "repo", + "token_type", + "actor", + "actor_scm_id", + "commands", + "image", + "request" + ], + "id_token_signing_alg_values_supported": [ + "RS256" + ] +}` + + // JWKSResp represents a JSON return for the JWKS. + JWKSResp = `{ + "keys": [ + { + "e": "AQAB", + "kid": "f7ec4ab7-c9a2-440e-bfb3-83b6599479ea", + "kty": "RSA", + "n": "weh9G_J6yZEugOFo6MQ057t_ExafteA_zVRS3CEPWiOgBLLRymh-KS6aCW-kHVuyBsnWNrCcc5cRJ6ISFnQMtkJtbpV_72qbw0zhFLiYomZDh5nb5dqCoiWIVNG8_a_My9jhXAIghs8MLbG-_Tj9jZb3K3n3Ies-Cg1E5SWO3YX8I1_X7ZlgqhEbktoy2RvR_crQA_fi1jRW5Q6PldIJmu4FIeXN_ny_sgg6ZQtTImFderUy1aUxUnpjilU-yv13eJejYQnJ7rExJVsDqq3B_CnYD2ioJC6b7aoEPvCpZ_1VgTTnQt6nedmr2Hih3GHgDNsM-BFr63aG3qZ5v9bVRw" + } + ] +` ) // getTokenRefresh returns mock JSON for a http GET. @@ -100,3 +139,23 @@ func validateOAuthToken(c *gin.Context) { c.JSON(http.StatusOK, "oauth token was created by vela") } + +// openIDConfig returns a mock response for a http GET. +func openIDConfig(c *gin.Context) { + data := []byte(OpenIDConfigResp) + + var body api.OpenIDConfig + _ = json.Unmarshal(data, &body) + + c.JSON(http.StatusOK, body) +} + +// getJWKS returns a mock response for a http GET. +func getJWKS(c *gin.Context) { + data := []byte(JWKSResp) + + var body jwk.RSAPublicKey + _ = json.Unmarshal(data, &body) + + c.JSON(http.StatusOK, body) +} diff --git a/mock/server/build.go b/mock/server/build.go index 36e9234d2..ebbe44b88 100644 --- a/mock/server/build.go +++ b/mock/server/build.go @@ -203,6 +203,20 @@ const ( "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJidWlsZF9pZCI6MSwicmVwbyI6ImZvby9iYXIiLCJzdWIiOiJPY3RvY2F0IiwiaWF0IjoxNTE2MjM5MDIyfQ.hD7gXpaf9acnLBdOBa4GOEa5KZxdzd0ZvK6fGwaN4bc" }` + // IDTokenResp represents a JSON return for requesting an ID token. + // + //nolint:gosec // not actual credentials + IDTokenResp = `{ + "token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImY3ZWM0YWI3LWM5YTItNDQwZS1iZmIzLTgzYjY1OTk0NzllYSJ9.eyJidWlsZF9udW1iZXIiOjEsImFjdG9yIjoiT2N0b2NhdCIsInJlcG8iOiJPY3RvY2F0L3Rlc3QiLCJ0b2tlbl90eXBlIjoiSUQiLCJpbWFnZSI6ImFscGluZTpsYXRlc3QiLCJjb21tYW5kcyI6dHJ1ZSwicmVxdWVzdCI6IndyaXRlIiwiaXNzIjoiaHR0cHM6Ly92ZWxhLmNvbS9fc2VydmljZXMvdG9rZW4iLCJzdWIiOiJyZXBvOk9jdG9jYXQvdGVzdDpyZWY6cmVmcy9oZWFkcy9tYWluOmV2ZW50OnB1c2giLCJleHAiOjE3MTQ0OTU4MjMsImlhdCI6MTcxNDQ5NTUyMywiYXVkIjpbInRlc3QiLCJleGFtcGxlIl19.nCniV3r0TjJT0JGRtcubhhJnffo_uBUcYvFRlqSOHEOjRQo5cSwNfiePVicfWQYNbLYeJ_7HmxT2C27jCa2MjaYNXFXoVVAP9Cl-LIMqkpiIG85gHlsJaJILT_a8a1F6an0gK1st-iPB6h7casMXR479zdWnVX30WEE7Ed34T-ee6MOxYZ6-VDsVvxVLYe8dYMxvJkBWDI31djqzYfdWWWyYTPqfLCyRaojZeiCzKMt7m5GDRiOLXooYorv3ybizFoupr4md3Kk9MlArgMn7PYNGnmZuzJ01JrIUk6FTVty638yUmEIgiW7sdLzZG9HJ3E3hS6WJleXj--E95wmyyw" + }` + + // IDTokenRequestTokenResp represents a JSON return for requesting an IDTokenRequestToken. + // + //nolint:gosec // not actual credentials + IDTokenRequestTokenResp = `{ + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImY3ZWM0YWI3LWM5YTItNDQwZS1iZmIzLTgzYjY1OTk0NzllYSJ9.eyJidWlsZF9pZCI6MSwiYnVpbGRfbnVtYmVyIjoxLCJhY3RvciI6Ik9jdG9jYXQiLCJyZXBvIjoiT2N0b2NhdC90ZXN0IiwidG9rZW5fdHlwZSI6IklEUmVxdWVzdCIsImltYWdlIjoiYWxwaW5lOmxhdGVzdCIsImNvbW1hbmRzIjp0cnVlLCJyZXF1ZXN0Ijoid3JpdGUiLCJpc3MiOiJodHRwczovL3ZlbGEuY29tL19zZXJ2aWNlcy90b2tlbiIsInN1YiI6InJlcG86T2N0b2NhdC90ZXN0OnJlZjpyZWZzL2hlYWRzL21haW46ZXZlbnQ6cHVzaCIsImV4cCI6MTcxNDQ5NTgyMywiaWF0IjoxNzE0NDk1NTIzfQ.l7ulJ7g5iTWGrR_IOBC2borJj2yixRAMZpsZEeaMvUw" + }` + // BuildExecutableResp represents a JSON return for requesting a build executable. BuildExecutableResp = `{ "id": 1 @@ -420,6 +434,46 @@ func buildToken(c *gin.Context) { c.JSON(http.StatusOK, body) } +// idToken has a param :build returns mock JSON for a http GET. +// +// Pass "0" to :build to test receiving a http 400 response. +func idToken(c *gin.Context) { + b := c.Param("build") + + if strings.EqualFold(b, "0") { + c.AbortWithStatusJSON(http.StatusBadRequest, "") + + return + } + + data := []byte(IDTokenResp) + + var body library.Token + _ = json.Unmarshal(data, &body) + + c.JSON(http.StatusOK, body) +} + +// idTokenRequestToken has a param :build returns mock JSON for a http GET. +// +// Pass "0" to :build to test receiving a http 400 response. +func idTokenRequestToken(c *gin.Context) { + b := c.Param("build") + + if strings.EqualFold(b, "0") { + c.AbortWithStatusJSON(http.StatusBadRequest, "") + + return + } + + data := []byte(IDTokenRequestTokenResp) + + var body library.Token + _ = json.Unmarshal(data, &body) + + c.JSON(http.StatusOK, body) +} + // buildExecutable has a param :build returns mock JSON for a http GET. // // Pass "0" to :build to test receiving a http 500 response. diff --git a/mock/server/server.go b/mock/server/server.go index 9527cbc75..4b249cec3 100644 --- a/mock/server/server.go +++ b/mock/server/server.go @@ -45,6 +45,8 @@ func FakeHandler() http.Handler { e.DELETE("/api/v1/repos/:org/:repo/builds/:build", removeBuild) e.GET("/api/v1/repos/:org/:repo/builds/:build/token", buildToken) e.GET("/api/v1/repos/:org/:repo/builds/:build/executable", buildExecutable) + e.GET("/api/v1/repos/:org/:repo/builds/:build/id_token", idToken) + e.GET("/api/v1/repos/:org/:repo/builds/:build/id_request_token", idTokenRequestToken) // mock endpoints for dashboard calls e.GET("/api/v1/dashboards/:dashboard", getDashboard) @@ -146,6 +148,10 @@ func FakeHandler() http.Handler { e.GET("/validate-token", validateToken) e.GET("/validate-oauth", validateOAuthToken) + // mock endpoints for oidc calls + e.GET("/_services/token/.well-known/openid-configuration", openIDConfig) + e.GET("/_services/token/.well-known/jwks", getJWKS) + // mock endpoint for queue credentials e.GET("/api/v1/queue/info", getQueueCreds) diff --git a/router/admin.go b/router/admin.go index 22f83973e..d349fd7b0 100644 --- a/router/admin.go +++ b/router/admin.go @@ -49,6 +49,9 @@ func AdminHandlers(base *gin.RouterGroup) { // Admin repo endpoint _admin.PUT("/repo", admin.UpdateRepo) + // Admin rotate keys endpoint + _admin.POST("/rotate_oidc_keys", admin.RotateOIDCKeys) + // Admin secret endpoint _admin.PUT("/secret", admin.UpdateSecret) diff --git a/router/build.go b/router/build.go index 44091b1f0..924576763 100644 --- a/router/build.go +++ b/router/build.go @@ -63,6 +63,8 @@ func BuildHandlers(base *gin.RouterGroup) { b.DELETE("/cancel", executors.Establish(), perm.MustWrite(), build.CancelBuild) b.GET("/logs", perm.MustRead(), log.ListLogsForBuild) b.GET("/token", perm.MustWorkerAuthToken(), build.GetBuildToken) + b.GET("/id_token", perm.MustIDRequestToken(), build.GetIDToken) + b.GET("/id_request_token", perm.MustBuildAccess(), build.GetIDRequestToken) b.GET("/graph", perm.MustRead(), build.GetBuildGraph) b.GET("/executable", perm.MustBuildAccess(), build.GetBuildExecutable) diff --git a/router/middleware/claims/claims_test.go b/router/middleware/claims/claims_test.go index 4ef838a3d..fa61c773f 100644 --- a/router/middleware/claims/claims_test.go +++ b/router/middleware/claims/claims_test.go @@ -60,9 +60,13 @@ func TestClaims_Establish(t *testing.T) { user.SetAdmin(false) user.SetFavorites([]string{}) + build := new(api.Build) + build.SetID(1) + build.SetNumber(1) + build.SetSender("octocat") + tm := &token.Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, WorkerAuthTokenDuration: time.Minute * 20, @@ -112,7 +116,7 @@ func TestClaims_Establish(t *testing.T) { }, Mto: &token.MintTokenOpts{ Hostname: "host", - BuildID: 1, + Build: build, Repo: "foo/bar", TokenDuration: time.Minute * 35, TokenType: constants.WorkerBuildTokenType, @@ -223,8 +227,7 @@ func TestClaims_Establish(t *testing.T) { func TestClaims_Establish_NoToken(t *testing.T) { // setup types tm := &token.Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } @@ -249,8 +252,7 @@ func TestClaims_Establish_NoToken(t *testing.T) { func TestClaims_Establish_BadToken(t *testing.T) { // setup types tm := &token.Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } diff --git a/router/middleware/perm/perm.go b/router/middleware/perm/perm.go index f32d34dea..e0f11979d 100644 --- a/router/middleware/perm/perm.go +++ b/router/middleware/perm/perm.go @@ -10,6 +10,7 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" + "github.com/go-vela/server/constants" "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/claims" "github.com/go-vela/server/router/middleware/org" @@ -17,7 +18,6 @@ import ( "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" "github.com/go-vela/server/util" - "github.com/go-vela/types/constants" ) // MustPlatformAdmin ensures the user has admin access to the platform. @@ -173,6 +173,48 @@ func MustBuildAccess() gin.HandlerFunc { } } +// MustIDRequestToken ensures the token is a valid ID request token for the appropriate build. +func MustIDRequestToken() gin.HandlerFunc { + return func(c *gin.Context) { + cl := claims.Retrieve(c) + b := build.Retrieve(c) + + // update engine logger with API metadata + // + // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields + logrus.WithFields(logrus.Fields{ + "repo": cl.Subject, + }).Debugf("verifying worker %s has a valid build token", cl.Subject) + + // verify expected type + if !strings.EqualFold(cl.TokenType, constants.IDRequestTokenType) { + retErr := fmt.Errorf("invalid token: must provide a valid request ID token") + util.HandleError(c, http.StatusUnauthorized, retErr) + + return + } + + // if build is not in a running state, then an ID token should not be needed + if !strings.EqualFold(b.GetStatus(), constants.StatusRunning) { + util.HandleError(c, http.StatusBadRequest, fmt.Errorf("invalid request")) + + return + } + + // verify expected build id + if b.GetID() != cl.BuildID { + logrus.WithFields(logrus.Fields{ + "user": cl.Subject, + "repo": cl.Repo, + "build": cl.BuildID, + }).Warnf("request ID token for build %d attempted to be used for %s build %d by %s", cl.BuildID, b.GetStatus(), b.GetID(), cl.Subject) + + retErr := fmt.Errorf("invalid token") + util.HandleError(c, http.StatusUnauthorized, retErr) + } + } +} + // MustSecretAdmin ensures the user has admin access to the org, repo or team. // //nolint:funlen // ignore function length diff --git a/router/middleware/perm/perm_test.go b/router/middleware/perm/perm_test.go index 8ca690b50..772aecf14 100644 --- a/router/middleware/perm/perm_test.go +++ b/router/middleware/perm/perm_test.go @@ -11,9 +11,9 @@ import ( "time" "github.com/gin-gonic/gin" - "github.com/golang-jwt/jwt/v5" api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/constants" "github.com/go-vela/server/database" "github.com/go-vela/server/internal/token" "github.com/go-vela/server/router/middleware/build" @@ -23,7 +23,6 @@ import ( "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" "github.com/go-vela/server/scm/github" - "github.com/go-vela/types/constants" ) func TestPerm_MustPlatformAdmin(t *testing.T) { @@ -31,8 +30,7 @@ func TestPerm_MustPlatformAdmin(t *testing.T) { secret := "superSecret" tm := &token.Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } @@ -112,8 +110,7 @@ func TestPerm_MustPlatformAdmin_NotAdmin(t *testing.T) { secret := "superSecret" tm := &token.Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } @@ -191,8 +188,7 @@ func TestPerm_MustPlatformAdmin_NotAdmin(t *testing.T) { func TestPerm_MustWorkerRegisterToken(t *testing.T) { // setup types tm := &token.Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, WorkerRegisterTokenDuration: time.Minute * 1, @@ -238,8 +234,7 @@ func TestPerm_MustWorkerRegisterToken(t *testing.T) { func TestPerm_MustWorkerRegisterToken_PlatAdmin(t *testing.T) { tm := &token.Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } @@ -304,8 +299,7 @@ func TestPerm_MustWorkerRegisterToken_PlatAdmin(t *testing.T) { func TestPerm_MustWorkerAuthToken(t *testing.T) { // setup types tm := &token.Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, WorkerRegisterTokenDuration: time.Minute * 1, @@ -353,8 +347,7 @@ func TestPerm_MustWorkerAuth_ServerWorkerToken(t *testing.T) { // setup types secret := "superSecret" tm := &token.Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, WorkerRegisterTokenDuration: time.Minute * 1, @@ -413,15 +406,14 @@ func TestPerm_MustBuildAccess(t *testing.T) { b.SetNumber(1) tm := &token.Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } mto := &token.MintTokenOpts{ Hostname: "worker", - BuildID: 1, + Build: b, Repo: "foo/bar", TokenDuration: time.Minute * 30, TokenType: constants.WorkerBuildTokenType, @@ -508,8 +500,7 @@ func TestPerm_MustBuildAccess_PlatAdmin(t *testing.T) { u.SetAdmin(true) tm := &token.Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } @@ -596,16 +587,18 @@ func TestPerm_MustBuildToken_WrongBuild(t *testing.T) { b.SetRepo(r) b.SetNumber(1) + wB := new(api.Build) + wB.SetID(2) + tm := &token.Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } mto := &token.MintTokenOpts{ Hostname: "worker", - BuildID: 2, + Build: wB, Repo: "foo/bar", TokenDuration: time.Minute * 30, TokenType: constants.WorkerBuildTokenType, @@ -664,6 +657,288 @@ func TestPerm_MustBuildToken_WrongBuild(t *testing.T) { } } +func TestPerm_MustIDRequestToken(t *testing.T) { + // setup types + secret := "superSecret" + + owner := new(api.User) + owner.SetID(1) + + r := new(api.Repo) + r.SetID(1) + r.SetOwner(owner) + r.SetHash("baz") + r.SetOrg("foo") + r.SetName("bar") + r.SetFullName("foo/bar") + r.SetVisibility("public") + + b := new(api.Build) + b.SetID(1) + b.SetRepo(r) + b.SetNumber(1) + b.SetStatus(constants.StatusRunning) + b.SetCommit("456def") + + tm := &token.Manager{ + PrivateKeyHMAC: "123abc", + UserAccessTokenDuration: time.Minute * 5, + UserRefreshTokenDuration: time.Minute * 30, + } + + mto := &token.MintTokenOpts{ + Hostname: "foo/bar/456def", + Build: b, + Repo: r.GetFullName(), + TokenDuration: time.Minute * 30, + TokenType: constants.IDRequestTokenType, + } + + tok, err := tm.MintToken(mto) + if err != nil { + t.Errorf("unable to mint token: %v", err) + } + + // setup context + gin.SetMode(gin.TestMode) + + resp := httptest.NewRecorder() + context, engine := gin.CreateTestContext(resp) + + // setup database + db, err := database.NewTest() + if err != nil { + t.Errorf("unable to create test database engine: %v", err) + } + + ctx := _context.TODO() + + defer func() { + _ = db.DeleteBuild(ctx, b) + _ = db.DeleteRepo(_context.TODO(), r) + db.Close() + }() + + _, _ = db.CreateRepo(_context.TODO(), r) + _, _ = db.CreateBuild(ctx, b) + + context.Request, _ = http.NewRequest(http.MethodGet, "/test/foo/bar/builds/1", nil) + context.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", tok)) + + // setup vela mock server + engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) + engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) + engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) + engine.Use(claims.Establish()) + engine.Use(user.Establish()) + engine.Use(org.Establish()) + engine.Use(repo.Establish()) + engine.Use(build.Establish()) + engine.Use(MustIDRequestToken()) + engine.GET("/test/:org/:repo/builds/:build", func(c *gin.Context) { + c.Status(http.StatusOK) + }) + + s1 := httptest.NewServer(engine) + defer s1.Close() + + // run test + engine.ServeHTTP(context.Writer, context.Request) + + if resp.Code != http.StatusOK { + t.Errorf("MustIDRequestToken returned %v, want %v: %v", resp.Code, http.StatusOK, resp.Body.String()) + } +} + +func TestPerm_MustIDRequestToken_NotRunning(t *testing.T) { + // setup types + secret := "superSecret" + + owner := new(api.User) + owner.SetID(1) + + r := new(api.Repo) + r.SetID(1) + r.SetOwner(owner) + r.SetHash("baz") + r.SetOrg("foo") + r.SetName("bar") + r.SetFullName("foo/bar") + r.SetVisibility("public") + + b := new(api.Build) + b.SetID(1) + b.SetRepo(r) + b.SetNumber(1) + b.SetStatus(constants.StatusSuccess) + b.SetCommit("456def") + + u := new(api.User) + u.SetID(1) + u.SetName("admin") + u.SetToken("bar") + u.SetAdmin(true) + + tm := &token.Manager{ + PrivateKeyHMAC: "123abc", + UserAccessTokenDuration: time.Minute * 5, + UserRefreshTokenDuration: time.Minute * 30, + } + + mto := &token.MintTokenOpts{ + Hostname: "foo/bar/456def", + Build: b, + Repo: "foo/bar", + TokenDuration: time.Minute * 30, + TokenType: constants.IDRequestTokenType, + } + + tok, _ := tm.MintToken(mto) + + // setup context + gin.SetMode(gin.TestMode) + + resp := httptest.NewRecorder() + context, engine := gin.CreateTestContext(resp) + + ctx := _context.TODO() + + // setup database + db, err := database.NewTest() + if err != nil { + t.Errorf("unable to create test database engine: %v", err) + } + + defer func() { + _ = db.DeleteBuild(ctx, b) + _ = db.DeleteRepo(_context.TODO(), r) + _ = db.DeleteUser(_context.TODO(), u) + db.Close() + }() + + _, _ = db.CreateRepo(_context.TODO(), r) + _, _ = db.CreateBuild(ctx, b) + _, _ = db.CreateUser(_context.TODO(), u) + + context.Request, _ = http.NewRequest(http.MethodGet, "/test/foo/bar/builds/1", nil) + context.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", tok)) + + // setup vela mock server + engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) + engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) + engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) + engine.Use(claims.Establish()) + engine.Use(user.Establish()) + engine.Use(org.Establish()) + engine.Use(repo.Establish()) + engine.Use(build.Establish()) + engine.Use(MustIDRequestToken()) + engine.GET("/test/:org/:repo/builds/:build", func(c *gin.Context) { + c.Status(http.StatusOK) + }) + + s1 := httptest.NewServer(engine) + defer s1.Close() + + // run test + engine.ServeHTTP(context.Writer, context.Request) + + if resp.Code != http.StatusBadRequest { + t.Errorf("MustIDRequestToken returned %v, want %v", resp.Code, http.StatusOK) + } +} + +func TestPerm_MustIDRequestToken_WrongBuild(t *testing.T) { + // setup types + secret := "superSecret" + + owner := new(api.User) + owner.SetID(1) + + r := new(api.Repo) + r.SetID(1) + r.SetOwner(owner) + r.SetHash("baz") + r.SetOrg("foo") + r.SetName("bar") + r.SetFullName("foo/bar") + r.SetVisibility("public") + + b := new(api.Build) + b.SetID(1) + b.SetRepo(r) + b.SetNumber(1) + + wB := new(api.Build) + wB.SetID(2) + + tm := &token.Manager{ + PrivateKeyHMAC: "123abc", + UserAccessTokenDuration: time.Minute * 5, + UserRefreshTokenDuration: time.Minute * 30, + } + + mto := &token.MintTokenOpts{ + Hostname: "foo/bar/456def", + Build: wB, + Repo: "foo/bar", + TokenDuration: time.Minute * 30, + TokenType: constants.IDRequestTokenType, + } + + tok, _ := tm.MintToken(mto) + + // setup context + gin.SetMode(gin.TestMode) + + resp := httptest.NewRecorder() + context, engine := gin.CreateTestContext(resp) + + ctx := _context.TODO() + + // setup database + db, err := database.NewTest() + if err != nil { + t.Errorf("unable to create test database engine: %v", err) + } + + defer func() { + _ = db.DeleteBuild(ctx, b) + _ = db.DeleteRepo(_context.TODO(), r) + db.Close() + }() + + _, _ = db.CreateRepo(_context.TODO(), r) + _, _ = db.CreateBuild(ctx, b) + + context.Request, _ = http.NewRequest(http.MethodGet, "/test/foo/bar/builds/1", nil) + context.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", tok)) + + // setup vela mock server + engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) + engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) + engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) + engine.Use(claims.Establish()) + engine.Use(user.Establish()) + engine.Use(org.Establish()) + engine.Use(repo.Establish()) + engine.Use(build.Establish()) + engine.Use(MustIDRequestToken()) + engine.GET("/test/:org/:repo/builds/:build", func(c *gin.Context) { + c.Status(http.StatusOK) + }) + + s1 := httptest.NewServer(engine) + defer s1.Close() + + // run test + engine.ServeHTTP(context.Writer, context.Request) + + if resp.Code != http.StatusBadRequest { + t.Errorf("MustBuildAccess returned %v, want %v", resp.Code, http.StatusBadRequest) + } +} + func TestPerm_MustSecretAdmin_BuildToken_Repo(t *testing.T) { // setup types secret := "superSecret" @@ -686,15 +961,14 @@ func TestPerm_MustSecretAdmin_BuildToken_Repo(t *testing.T) { b.SetNumber(1) tm := &token.Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } mto := &token.MintTokenOpts{ Hostname: "worker", - BuildID: 1, + Build: b, Repo: "foo/bar", TokenDuration: time.Minute * 30, TokenType: constants.WorkerBuildTokenType, @@ -772,15 +1046,14 @@ func TestPerm_MustSecretAdmin_BuildToken_Org(t *testing.T) { b.SetNumber(1) tm := &token.Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } mto := &token.MintTokenOpts{ Hostname: "worker", - BuildID: 1, + Build: b, Repo: "foo/bar", TokenDuration: time.Minute * 30, TokenType: constants.WorkerBuildTokenType, @@ -858,15 +1131,14 @@ func TestPerm_MustSecretAdmin_BuildToken_Shared(t *testing.T) { b.SetNumber(1) tm := &token.Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } mto := &token.MintTokenOpts{ Hostname: "worker", - BuildID: 1, + Build: b, Repo: "foo/bar", TokenDuration: time.Minute * 30, TokenType: constants.WorkerBuildTokenType, @@ -927,8 +1199,7 @@ func TestPerm_MustAdmin(t *testing.T) { secret := "superSecret" tm := &token.Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } @@ -1027,8 +1298,7 @@ func TestPerm_MustAdmin_PlatAdmin(t *testing.T) { secret := "superSecret" tm := &token.Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } @@ -1127,8 +1397,7 @@ func TestPerm_MustAdmin_NotAdmin(t *testing.T) { secret := "superSecret" tm := &token.Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } @@ -1227,8 +1496,7 @@ func TestPerm_MustWrite(t *testing.T) { secret := "superSecret" tm := &token.Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } @@ -1327,8 +1595,7 @@ func TestPerm_MustWrite_PlatAdmin(t *testing.T) { secret := "superSecret" tm := &token.Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } @@ -1427,8 +1694,7 @@ func TestPerm_MustWrite_RepoAdmin(t *testing.T) { secret := "superSecret" tm := &token.Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } @@ -1527,8 +1793,7 @@ func TestPerm_MustWrite_NotWrite(t *testing.T) { secret := "superSecret" tm := &token.Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } @@ -1627,8 +1892,7 @@ func TestPerm_MustRead(t *testing.T) { secret := "superSecret" tm := &token.Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } @@ -1727,8 +1991,7 @@ func TestPerm_MustRead_PlatAdmin(t *testing.T) { secret := "superSecret" tm := &token.Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } @@ -1827,8 +2090,7 @@ func TestPerm_MustRead_WorkerBuildToken(t *testing.T) { secret := "superSecret" tm := &token.Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } @@ -1854,7 +2116,7 @@ func TestPerm_MustRead_WorkerBuildToken(t *testing.T) { Hostname: "worker", TokenDuration: time.Minute * 35, TokenType: constants.WorkerBuildTokenType, - BuildID: 1, + Build: b, Repo: "foo/bar", } @@ -1916,8 +2178,7 @@ func TestPerm_MustRead_RepoAdmin(t *testing.T) { secret := "superSecret" tm := &token.Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } @@ -2016,8 +2277,7 @@ func TestPerm_MustRead_RepoWrite(t *testing.T) { secret := "superSecret" tm := &token.Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } @@ -2116,8 +2376,7 @@ func TestPerm_MustRead_RepoPublic(t *testing.T) { secret := "superSecret" tm := &token.Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } @@ -2216,8 +2475,7 @@ func TestPerm_MustRead_NotRead(t *testing.T) { secret := "superSecret" tm := &token.Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } diff --git a/router/middleware/pipeline/pipeline_test.go b/router/middleware/pipeline/pipeline_test.go index d7af22303..5a8c6d608 100644 --- a/router/middleware/pipeline/pipeline_test.go +++ b/router/middleware/pipeline/pipeline_test.go @@ -13,7 +13,6 @@ import ( "time" "github.com/gin-gonic/gin" - "github.com/golang-jwt/jwt/v5" "github.com/urfave/cli/v2" api "github.com/go-vela/server/api/types" @@ -227,8 +226,7 @@ func TestPipeline_Establish_NoPipeline(t *testing.T) { secret := "superSecret" tm := &token.Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } diff --git a/router/middleware/token_manager_test.go b/router/middleware/token_manager_test.go index 8f8bb4fa2..6daee4e88 100644 --- a/router/middleware/token_manager_test.go +++ b/router/middleware/token_manager_test.go @@ -21,7 +21,7 @@ func TestMiddleware_TokenManager(t *testing.T) { var got *token.Manager want := new(token.Manager) - want.PrivateKey = "123abc" + want.PrivateKeyHMAC = "123abc" // setup context gin.SetMode(gin.TestMode) diff --git a/router/middleware/user/user_test.go b/router/middleware/user/user_test.go index a6809c334..8e15f80f7 100644 --- a/router/middleware/user/user_test.go +++ b/router/middleware/user/user_test.go @@ -12,7 +12,6 @@ import ( "time" "github.com/gin-gonic/gin" - "github.com/golang-jwt/jwt/v5" api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" @@ -47,8 +46,7 @@ func TestUser_Establish(t *testing.T) { secret := "superSecret" tm := &token.Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } @@ -144,8 +142,7 @@ func TestUser_Establish_NoToken(t *testing.T) { // setup types secret := "superSecret" tm := &token.Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } @@ -183,8 +180,7 @@ func TestUser_Establish_DiffTokenType(t *testing.T) { secret := "superSecret" tm := &token.Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } @@ -232,8 +228,7 @@ func TestUser_Establish_NoAuthorizeUser(t *testing.T) { secret := "superSecret" tm := &token.Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } @@ -274,8 +269,7 @@ func TestUser_Establish_NoAuthorizeUser(t *testing.T) { func TestUser_Establish_NoUser(t *testing.T) { // setup types tm := &token.Manager{ - PrivateKey: "123abc", - SignMethod: jwt.SigningMethodHS256, + PrivateKeyHMAC: "123abc", UserAccessTokenDuration: time.Minute * 5, UserRefreshTokenDuration: time.Minute * 30, } diff --git a/router/router.go b/router/router.go index 49d8f6012..2e7aebbb2 100644 --- a/router/router.go +++ b/router/router.go @@ -89,6 +89,10 @@ func Load(options ...gin.HandlerFunc) *gin.Engine { // Webhook endpoint r.POST("/webhook", webhook.PostWebhook) + // JWKS endpoints + r.GET("/_services/token/.well-known/openid-configuration", api.GetOpenIDConfig) + r.GET("/_services/token/.well-known/jwks", api.GetJWKS) + // Authentication endpoints authenticate := r.Group("/authenticate") { From 5ac9c0e3b226e0e4783492f39f47c396c2082251 Mon Sep 17 00:00:00 2001 From: david may <1301201+wass3r@users.noreply.github.com> Date: Wed, 5 Jun 2024 13:06:26 -0500 Subject: [PATCH 59/71] feat(db/log): use logrus as logger for db (#1135) * use logrus for gorm * use witherror * add knobs for db logging * false is default * show normal set of logrus levels * extend test struct with new fields * update test function with new fields --- database/context.go | 4 + database/database.go | 61 ++++++++++++- database/database_test.go | 28 ++++++ database/flags.go | 27 ++++++ database/logger.go | 79 +++++++++++++++++ database/logger_test.go | 51 +++++++++++ database/opts.go | 40 +++++++++ database/opts_test.go | 176 ++++++++++++++++++++++++++++++++++++++ 8 files changed, 462 insertions(+), 4 deletions(-) create mode 100644 database/logger.go create mode 100644 database/logger_test.go diff --git a/database/context.go b/database/context.go index fd4cae217..a11863e7d 100644 --- a/database/context.go +++ b/database/context.go @@ -49,6 +49,10 @@ func FromCLIContext(c *cli.Context) (Interface, error) { WithConnectionOpen(c.Int("database.connection.open")), WithDriver(c.String("database.driver")), WithEncryptionKey(c.String("database.encryption.key")), + WithLogLevel(c.String("database.log.level")), + WithLogSkipNotFound(c.Bool("database.log.skip_notfound")), + WithLogSlowThreshold(c.Duration("database.log.slow_threshold")), + WithLogShowSQL(c.Bool("database.log.show_sql")), WithSkipCreation(c.Bool("database.skip_creation")), ) } diff --git a/database/database.go b/database/database.go index 9ff3a2855..f9e2658ed 100644 --- a/database/database.go +++ b/database/database.go @@ -48,6 +48,14 @@ type ( Driver string // specifies the encryption key to use for the database engine EncryptionKey string + // specifies the database engine specific log level + LogLevel string + // specifies to skip logging when a record is not found + LogSkipNotFound bool + // specifies the threshold for slow queries in the database engine + LogSlowThreshold time.Duration + // specifies whether to log SQL queries in the database engine + LogShowSQL bool // specifies to skip creating tables and indexes for the database engine SkipCreation bool } @@ -113,21 +121,62 @@ func New(opts ...EngineOpt) (Interface, error) { return nil, err } - // update the logger with additional metadata + // by default use the global logger with additional metadata e.logger = logrus.NewEntry(logrus.StandardLogger()).WithField("database", e.Driver()) + // translate the log level to logrus level for the database engine + var dbLogLevel logrus.Level + + switch e.config.LogLevel { + case "t", "trace", "Trace", "TRACE": + dbLogLevel = logrus.TraceLevel + case "d", "debug", "Debug", "DEBUG": + dbLogLevel = logrus.DebugLevel + case "i", "info", "Info", "INFO": + dbLogLevel = logrus.InfoLevel + case "w", "warn", "Warn", "WARN": + dbLogLevel = logrus.WarnLevel + case "e", "error", "Error", "ERROR": + dbLogLevel = logrus.ErrorLevel + case "f", "fatal", "Fatal", "FATAL": + dbLogLevel = logrus.FatalLevel + case "p", "panic", "Panic", "PANIC": + dbLogLevel = logrus.PanicLevel + } + + // if the log level for the database engine is different than + // the global log level, create a new logrus instance + if dbLogLevel != logrus.GetLevel() { + log := logrus.New() + + // set the custom log level + log.Level = dbLogLevel + + // copy the formatter from the global logger to + // retain the same format for the database engine + log.Formatter = logrus.StandardLogger().Formatter + + // update the logger with additional metadata + e.logger = logrus.NewEntry(log).WithField("database", e.Driver()) + } + e.logger.Trace("creating database engine from configuration") - // process the database driver being provided + + // configure gorm to use logrus as internal logger + gormConfig := &gorm.Config{ + Logger: NewGormLogger(e.logger, e.config.LogSlowThreshold, e.config.LogSkipNotFound, e.config.LogShowSQL), + } + switch e.config.Driver { case constants.DriverPostgres: // create the new Postgres database client - e.client, err = gorm.Open(postgres.Open(e.config.Address), &gorm.Config{}) + e.client, err = gorm.Open(postgres.Open(e.config.Address), gormConfig) if err != nil { return nil, err } case constants.DriverSqlite: // create the new Sqlite database client - e.client, err = gorm.Open(sqlite.Open(e.config.Address), &gorm.Config{}) + e.client, err = gorm.Open(sqlite.Open(e.config.Address), gormConfig) if err != nil { return nil, err } @@ -177,5 +226,9 @@ func NewTest() (Interface, error) { WithDriver("sqlite3"), WithEncryptionKey("A1B2C3D4E5G6H7I8J9K0LMNOPQRSTUVW"), WithSkipCreation(false), + WithLogLevel("warn"), + WithLogShowSQL(false), + WithLogSkipNotFound(true), + WithLogSlowThreshold(200*time.Millisecond), ) } diff --git a/database/database_test.go b/database/database_test.go index 26ea7e471..a8b70111a 100644 --- a/database/database_test.go +++ b/database/database_test.go @@ -32,6 +32,10 @@ func TestDatabase_New(t *testing.T) { ConnectionOpen: 20, EncryptionKey: "A1B2C3D4E5G6H7I8J9K0LMNOPQRSTUVW", SkipCreation: false, + LogLevel: "info", + LogSkipNotFound: true, + LogSlowThreshold: 100 * time.Millisecond, + LogShowSQL: false, }, }, { @@ -46,6 +50,10 @@ func TestDatabase_New(t *testing.T) { ConnectionOpen: 20, EncryptionKey: "A1B2C3D4E5G6H7I8J9K0LMNOPQRSTUVW", SkipCreation: false, + LogLevel: "info", + LogSkipNotFound: true, + LogSlowThreshold: 100 * time.Millisecond, + LogShowSQL: false, }, }, { @@ -60,6 +68,10 @@ func TestDatabase_New(t *testing.T) { ConnectionOpen: 20, EncryptionKey: "A1B2C3D4E5G6H7I8J9K0LMNOPQRSTUVW", SkipCreation: false, + LogLevel: "info", + LogSkipNotFound: true, + LogSlowThreshold: 100 * time.Millisecond, + LogShowSQL: false, }, }, { @@ -74,6 +86,10 @@ func TestDatabase_New(t *testing.T) { ConnectionOpen: 20, EncryptionKey: "A1B2C3D4E5G6H7I8J9K0LMNOPQRSTUVW", SkipCreation: false, + LogLevel: "info", + LogSkipNotFound: true, + LogSlowThreshold: 100 * time.Millisecond, + LogShowSQL: false, }, }, } @@ -88,6 +104,10 @@ func TestDatabase_New(t *testing.T) { WithConnectionIdle(test.config.ConnectionIdle), WithConnectionOpen(test.config.ConnectionOpen), WithDriver(test.config.Driver), + WithLogLevel(test.config.LogLevel), + WithLogShowSQL(test.config.LogShowSQL), + WithLogSkipNotFound(test.config.LogSkipNotFound), + WithLogSlowThreshold(test.config.LogSlowThreshold), WithEncryptionKey(test.config.EncryptionKey), WithSkipCreation(test.config.SkipCreation), ) @@ -119,6 +139,10 @@ func testPostgres(t *testing.T) (*engine, sqlmock.Sqlmock) { Driver: "postgres", EncryptionKey: "A1B2C3D4E5G6H7I8J9K0LMNOPQRSTUVW", SkipCreation: false, + LogLevel: "info", + LogSkipNotFound: true, + LogSlowThreshold: 100 * time.Millisecond, + LogShowSQL: false, }, logger: logrus.NewEntry(logrus.StandardLogger()), } @@ -161,6 +185,10 @@ func testSqlite(t *testing.T) *engine { Driver: "sqlite3", EncryptionKey: "A1B2C3D4E5G6H7I8J9K0LMNOPQRSTUVW", SkipCreation: false, + LogLevel: "info", + LogSkipNotFound: true, + LogSlowThreshold: 100 * time.Millisecond, + LogShowSQL: false, }, logger: logrus.NewEntry(logrus.StandardLogger()), } diff --git a/database/flags.go b/database/flags.go index 8655c1808..129143655 100644 --- a/database/flags.go +++ b/database/flags.go @@ -60,6 +60,33 @@ var Flags = []cli.Flag{ Name: "database.encryption.key", Usage: "AES-256 key for encrypting and decrypting values in the database", }, + &cli.StringFlag{ + EnvVars: []string{"VELA_DATABASE_LOG_LEVEL", "DATABASE_LOG_LEVEL"}, + FilePath: "/vela/database/log_level", + Name: "database.log.level", + Usage: "set log level - options: (trace|debug|info|warn|error|fatal|panic)", + Value: "warn", + }, + &cli.BoolFlag{ + EnvVars: []string{"VELA_DATABASE_LOG_SHOW_SQL", "DATABASE_LOG_SHOW_SQL"}, + FilePath: "/vela/database/log_show_sql", + Name: "database.log.show_sql", + Usage: "show the SQL query in the logs", + }, + &cli.BoolFlag{ + EnvVars: []string{"VELA_DATABASE_LOG_SKIP_NOTFOUND", "DATABASE_LOG_SKIP_NOTFOUND"}, + FilePath: "/vela/database/log_skip_notfound", + Name: "database.log.skip_notfound", + Usage: "skip logging when a resource is not found in the database", + Value: true, + }, + &cli.DurationFlag{ + EnvVars: []string{"VELA_DATABASE_LOG_SLOW_THRESHOLD", "DATABASE_LOG_SLOW_THRESHOLD"}, + FilePath: "/vela/database/log_slow_threshold", + Name: "database.log.slow_threshold", + Usage: "queries that take longer than this threshold are considered slow and will be logged", + Value: 200 * time.Millisecond, + }, &cli.BoolFlag{ EnvVars: []string{"VELA_DATABASE_SKIP_CREATION", "DATABASE_SKIP_CREATION"}, FilePath: "/vela/database/skip_creation", diff --git a/database/logger.go b/database/logger.go new file mode 100644 index 000000000..819574704 --- /dev/null +++ b/database/logger.go @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: Apache-2.0 + +package database + +import ( + "context" + "errors" + "time" + + "github.com/sirupsen/logrus" + "gorm.io/gorm" + "gorm.io/gorm/logger" + "gorm.io/gorm/utils" +) + +// GormLogger is a custom logger for Gorm. +type GormLogger struct { + slowThreshold time.Duration + skipErrRecordNotFound bool + showSQL bool + entry *logrus.Entry +} + +// NewGormLogger creates a new Gorm logger. +func NewGormLogger(logger *logrus.Entry, slowThreshold time.Duration, skipNotFound, showSQL bool) *GormLogger { + return &GormLogger{ + skipErrRecordNotFound: skipNotFound, + slowThreshold: slowThreshold, + showSQL: showSQL, + entry: logger, + } +} + +// LogMode sets the log mode for the logger. +func (l *GormLogger) LogMode(logger.LogLevel) logger.Interface { + return l +} + +// Info implements the logger.Interface. +func (l *GormLogger) Info(ctx context.Context, msg string, args ...interface{}) { + l.entry.WithContext(ctx).Info(msg, args) +} + +// Warn implements the logger.Interface. +func (l *GormLogger) Warn(ctx context.Context, msg string, args ...interface{}) { + l.entry.WithContext(ctx).Warn(msg, args) +} + +// Error implements the logger.Interface. +func (l *GormLogger) Error(ctx context.Context, msg string, args ...interface{}) { + l.entry.WithContext(ctx).Error(msg, args) +} + +// Trace implements the logger.Interface. +func (l *GormLogger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) { + elapsed := time.Since(begin) + sql, rows := fc() + fields := logrus.Fields{ + "rows": rows, + "elapsed": elapsed, + "source": utils.FileWithLineNum(), + } + + if l.showSQL { + fields["sql"] = sql + } + + if err != nil && (!errors.Is(err, gorm.ErrRecordNotFound) || !l.skipErrRecordNotFound) { + l.entry.WithContext(ctx).WithError(err).WithFields(fields).Error("gorm error") + return + } + + if l.slowThreshold != 0 && elapsed > l.slowThreshold { + l.entry.WithContext(ctx).WithFields(fields).Warnf("gorm warn SLOW QUERY >= %s, took %s", l.slowThreshold, elapsed) + return + } + + l.entry.WithContext(ctx).WithFields(fields).Infof("gorm info") +} diff --git a/database/logger_test.go b/database/logger_test.go new file mode 100644 index 000000000..ce64513bf --- /dev/null +++ b/database/logger_test.go @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: Apache-2.0 + +package database + +import ( + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/sirupsen/logrus" +) + +func TestNewGormLogger(t *testing.T) { + logger := logrus.NewEntry(logrus.New()) + + type args struct { + logger *logrus.Entry + slowThreshold time.Duration + skipNotFound bool + showSQL bool + } + tests := []struct { + name string + args args + want *GormLogger + }{ + { + name: "logger set", + args: args{ + logger: logger, + slowThreshold: time.Second, + skipNotFound: false, + showSQL: true, + }, + want: &GormLogger{ + slowThreshold: time.Second, + skipErrRecordNotFound: false, + showSQL: true, + entry: logger, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if diff := cmp.Diff(NewGormLogger(tt.args.logger, tt.args.slowThreshold, tt.args.skipNotFound, tt.args.showSQL), tt.want, cmpopts.EquateComparable(GormLogger{})); diff != "" { + t.Errorf("NewGormLogger() mismatch (-got +want):\n%s", diff) + } + }) + } +} diff --git a/database/opts.go b/database/opts.go index 2e758d802..3a35d751e 100644 --- a/database/opts.go +++ b/database/opts.go @@ -80,6 +80,46 @@ func WithEncryptionKey(encryptionKey string) EngineOpt { } } +// WithLogLevel sets the log level in the database engine. +func WithLogLevel(logLevel string) EngineOpt { + return func(e *engine) error { + // set the log level for the database engine + e.config.LogLevel = logLevel + + return nil + } +} + +// WithLogSkipNotFound sets the log skip not found option in the database engine. +func WithLogSkipNotFound(logSkipNotFound bool) EngineOpt { + return func(e *engine) error { + // set the log skip not found option for the database engine + e.config.LogSkipNotFound = logSkipNotFound + + return nil + } +} + +// WithLogSlowThreshold sets the log slow query threshold in the database engine. +func WithLogSlowThreshold(logSlowThreshold time.Duration) EngineOpt { + return func(e *engine) error { + // set the slow query threshold for the database engine + e.config.LogSlowThreshold = logSlowThreshold + + return nil + } +} + +// WithLogShowSQL sets the log show SQL option in the database engine. +func WithLogShowSQL(logShowSQL bool) EngineOpt { + return func(e *engine) error { + // set the log show SQL option for the database engine + e.config.LogShowSQL = logShowSQL + + return nil + } +} + // WithSkipCreation sets the skip creation logic in the database engine. func WithSkipCreation(skipCreation bool) EngineOpt { return func(e *engine) error { diff --git a/database/opts_test.go b/database/opts_test.go index 7089d9271..abd65ad94 100644 --- a/database/opts_test.go +++ b/database/opts_test.go @@ -405,3 +405,179 @@ func TestDatabase_EngineOpt_WithSkipCreation(t *testing.T) { }) } } + +func TestDatabase_EngineOpt_WithLogLevel(t *testing.T) { + e := &engine{config: new(config)} + + tests := []struct { + failure bool + name string + logLevel string + want string + }{ + { + failure: false, + name: "log level set to debug", + logLevel: "debug", + want: "debug", + }, + { + failure: false, + name: "log level set to info", + logLevel: "info", + want: "info", + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + err := WithLogLevel(test.logLevel)(e) + + if test.failure { + if err == nil { + t.Errorf("WithLogLevel for %s should have returned err", test.name) + } + + return + } + + if err != nil { + t.Errorf("WithLogLevel returned err: %v", err) + } + + if !reflect.DeepEqual(e.config.LogLevel, test.want) { + t.Errorf("WithLogLevel is %v, want %v", e.config.SkipCreation, test.want) + } + }) + } +} + +func TestDatabase_EngineOpt_WithLogSkipNotFound(t *testing.T) { + e := &engine{config: new(config)} + + tests := []struct { + failure bool + name string + skip bool + want bool + }{ + { + failure: false, + name: "log skip not found set to true", + skip: true, + want: true, + }, + { + failure: false, + name: "log skip not found set to false", + skip: false, + want: false, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + err := WithLogSkipNotFound(test.skip)(e) + + if test.failure { + if err == nil { + t.Errorf("WithLogSkipNotFound for %s should have returned err", test.name) + } + + if err != nil { + t.Errorf("WithLogSkipNotFound for %s returned err: %v", test.name, err) + } + + if !reflect.DeepEqual(e.config.LogSkipNotFound, test.want) { + t.Errorf("WithLogSkipNotFound for %s is %v, want %v", test.name, e.config.LogSkipNotFound, test.want) + } + } + }) + } +} + +func TestDatabase_EngineOpt_WithLogSlowThreshold(t *testing.T) { + e := &engine{config: new(config)} + + tests := []struct { + failure bool + name string + threshold time.Duration + want time.Duration + }{ + { + failure: false, + name: "log slow threshold set to 1ms", + threshold: 1 * time.Millisecond, + want: 1 * time.Millisecond, + }, + { + failure: false, + name: "log slow threshold set to 2ms", + threshold: 2 * time.Millisecond, + want: 2 * time.Millisecond, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + err := WithLogSlowThreshold(test.threshold)(e) + + if test.failure { + if err == nil { + t.Errorf("WithLogSlowThreshold for %s should have returned err", test.name) + } + + if err != nil { + t.Errorf("WithLogSlowThreshold for %s returned err: %v", test.name, err) + } + + if !reflect.DeepEqual(e.config.LogSlowThreshold, test.want) { + t.Errorf("WithLogSlowThreshold for %s is %v, want %v", test.name, e.config.LogSlowThreshold, test.want) + } + } + }) + } +} + +func TestDatabase_EngineOpt_WithLogShowSQL(t *testing.T) { + e := &engine{config: new(config)} + + tests := []struct { + failure bool + name string + show bool + want bool + }{ + { + failure: false, + name: "log show SQL set to true", + show: true, + want: true, + }, + { + failure: false, + name: "log show SQL set to false", + show: false, + want: false, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + err := WithLogShowSQL(test.show)(e) + + if test.failure { + if err == nil { + t.Errorf("WithLogShowSQL for %s should have returned err", test.name) + } + + if err != nil { + t.Errorf("WithLogShowSQL for %s returned err: %v", test.name, err) + } + + if !reflect.DeepEqual(e.config.LogShowSQL, test.want) { + t.Errorf("WithLogShowSQL for %s is %v, want %v", test.name, e.config.LogShowSQL, test.want) + } + } + }) + } +} From b35f3513efa410c01f8d99dd20a4e5152cda09f4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 5 Jun 2024 13:18:57 -0500 Subject: [PATCH 60/71] chore(deps): update all non-major dependencies (#1094) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 4 +- .github/workflows/codeql-analysis.yml | 10 +- .github/workflows/integration-test.yml | 8 +- .github/workflows/prerelease.yml | 4 +- .github/workflows/publish.yml | 4 +- .github/workflows/reviewdog.yml | 8 +- .github/workflows/spec.yml | 4 +- .github/workflows/test.yml | 6 +- .github/workflows/validate.yml | 4 +- Dockerfile | 2 +- Dockerfile-alpine | 2 +- go.mod | 70 ++++++------ go.sum | 149 ++++++++++++------------- 13 files changed, 134 insertions(+), 141 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 176612ae8..e7d62f832 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,10 +13,10 @@ jobs: steps: - name: clone - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - name: install go - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 with: # use version from go.mod file go-version-file: 'go.mod' diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index b5d001de4..c0e70f907 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -35,10 +35,10 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - name: install go - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 with: # use version from go.mod file go-version-file: 'go.mod' @@ -47,7 +47,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@3ab4101902695724f9365a384f86c1074d94e18c # v3.24.7 + uses: github/codeql-action/init@2e230e8fe0ad3a14a340ad0815ddb96d599d2aff # v3.25.8 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -58,7 +58,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@3ab4101902695724f9365a384f86c1074d94e18c # v3.24.7 + uses: github/codeql-action/autobuild@2e230e8fe0ad3a14a340ad0815ddb96d599d2aff # v3.25.8 # ℹī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -72,4 +72,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@3ab4101902695724f9365a384f86c1074d94e18c # v3.24.7 + uses: github/codeql-action/analyze@2e230e8fe0ad3a14a340ad0815ddb96d599d2aff # v3.25.8 diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index 7b751dd55..d617cf5fd 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -40,10 +40,10 @@ jobs: steps: - name: clone - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - name: install go - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 with: # use version from go.mod file go-version-file: 'go.mod' @@ -62,10 +62,10 @@ jobs: steps: - name: clone - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - name: install go - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 with: # use version from go.mod file go-version-file: 'go.mod' diff --git a/.github/workflows/prerelease.yml b/.github/workflows/prerelease.yml index 8d7d886c4..56aa6ffd1 100644 --- a/.github/workflows/prerelease.yml +++ b/.github/workflows/prerelease.yml @@ -14,13 +14,13 @@ jobs: steps: - name: clone - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 with: # ensures we fetch tag history for the repository fetch-depth: 0 - name: install go - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 with: # use version from go.mod file go-version-file: 'go.mod' diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 6ba334f4e..16a62f5e2 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -13,13 +13,13 @@ jobs: steps: - name: clone - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 with: # ensures we fetch tag history for the repository fetch-depth: 0 - name: install go - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 with: # use version from go.mod file go-version-file: 'go.mod' diff --git a/.github/workflows/reviewdog.yml b/.github/workflows/reviewdog.yml index 9cf940fd5..79ad4b56a 100644 --- a/.github/workflows/reviewdog.yml +++ b/.github/workflows/reviewdog.yml @@ -12,10 +12,10 @@ jobs: steps: - name: clone - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - name: install go - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 with: # use version from go.mod file go-version-file: 'go.mod' @@ -36,10 +36,10 @@ jobs: steps: - name: clone - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - name: install go - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 with: # use version from go.mod file go-version-file: 'go.mod' diff --git a/.github/workflows/spec.yml b/.github/workflows/spec.yml index 57789b101..7aefbba05 100644 --- a/.github/workflows/spec.yml +++ b/.github/workflows/spec.yml @@ -13,10 +13,10 @@ jobs: steps: - name: clone - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - name: install go - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 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 08ecae82e..853c5b9bb 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,10 +13,10 @@ jobs: steps: - name: clone - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - name: install go - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 with: # use version from go.mod file go-version-file: 'go.mod' @@ -28,7 +28,7 @@ jobs: make test - name: coverage - uses: codecov/codecov-action@54bcd8715eee62d40e33596ef5e8f0f48dbbccab # v4.1.0 + uses: codecov/codecov-action@125fc84a9a348dbcf27191600683ec096ec9021c # v4.4.1 with: token: ${{ secrets.CODECOV_TOKEN }} file: coverage.out \ No newline at end of file diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 466a71d51..ee25cbd42 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -13,10 +13,10 @@ jobs: steps: - name: clone - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - name: install go - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 with: # use version from go.mod file go-version-file: 'go.mod' diff --git a/Dockerfile b/Dockerfile index 1a9604914..8b3860b37 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 -FROM alpine:3.19.1@sha256:c5b1261d6d3e43071626931fc004f70149baeba2c8ec672bd4f27761f8e1ad6b as certs +FROM alpine:3.20.0@sha256:77726ef6b57ddf65bb551896826ec38bc3e53f75cdde31354fbffb4f25238ebd as certs RUN apk add --update --no-cache ca-certificates diff --git a/Dockerfile-alpine b/Dockerfile-alpine index d1512ab9e..21dd79e8f 100644 --- a/Dockerfile-alpine +++ b/Dockerfile-alpine @@ -1,6 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 -FROM alpine:3.19.1@sha256:c5b1261d6d3e43071626931fc004f70149baeba2c8ec672bd4f27761f8e1ad6b +FROM alpine:3.20.0@sha256:77726ef6b57ddf65bb551896826ec38bc3e53f75cdde31354fbffb4f25238ebd RUN apk add --update --no-cache ca-certificates diff --git a/go.mod b/go.mod index f9837b3eb..a9cd2f263 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,8 @@ module github.com/go-vela/server -go 1.21.9 +go 1.22.0 + +toolchain go1.22.4 require ( github.com/Bose/minisentinel v0.0.0-20200130220412-917c5a9223bb @@ -8,13 +10,13 @@ require ( github.com/Masterminds/semver/v3 v3.2.1 github.com/Masterminds/sprig/v3 v3.2.3 github.com/adhocore/gronx v1.8.1 - github.com/alicebob/miniredis/v2 v2.32.1 - github.com/aws/aws-sdk-go v1.51.0 + github.com/alicebob/miniredis/v2 v2.33.0 + github.com/aws/aws-sdk-go v1.53.16 github.com/buildkite/yaml v0.0.0-20181016232759-0caa5f0796e3 github.com/distribution/reference v0.6.0 github.com/drone/envsubst v1.0.3 github.com/ghodss/yaml v1.0.0 - github.com/gin-gonic/gin v1.9.1 + github.com/gin-gonic/gin v1.10.0 github.com/go-playground/assert/v2 v2.2.0 github.com/go-vela/types v0.23.4-0.20240516161114-57d6b8f77b10 github.com/golang-jwt/jwt/v5 v5.2.1 @@ -24,30 +26,34 @@ require ( github.com/goware/urlx v0.3.2 github.com/hashicorp/go-cleanhttp v0.5.2 github.com/hashicorp/go-multierror v1.1.1 - github.com/hashicorp/go-retryablehttp v0.7.5 - github.com/hashicorp/vault/api v1.12.1 + github.com/hashicorp/go-retryablehttp v0.7.7 + github.com/hashicorp/vault/api v1.14.0 github.com/joho/godotenv v1.5.1 github.com/lib/pq v1.10.9 github.com/microcosm-cc/bluemonday v1.0.26 github.com/pkg/errors v0.9.1 - github.com/prometheus/client_golang v1.19.0 - github.com/redis/go-redis/v9 v9.5.1 + github.com/prometheus/client_golang v1.19.1 + github.com/redis/go-redis/v9 v9.5.2 github.com/sirupsen/logrus v1.9.3 github.com/spf13/afero v1.11.0 - github.com/urfave/cli/v2 v2.27.1 + github.com/urfave/cli/v2 v2.27.2 go.starlark.net v0.0.0-20240314022150-ee8ed142361c - golang.org/x/crypto v0.21.0 - golang.org/x/oauth2 v0.18.0 - golang.org/x/sync v0.6.0 + golang.org/x/crypto v0.24.0 + golang.org/x/oauth2 v0.21.0 + golang.org/x/sync v0.7.0 gopkg.in/square/go-jose.v2 v2.6.0 gorm.io/driver/postgres v1.5.7 gorm.io/driver/sqlite v1.5.5 - gorm.io/gorm v1.25.7 - k8s.io/apimachinery v0.29.2 + gorm.io/gorm v1.25.10 + k8s.io/apimachinery v0.30.1 ) require ( + github.com/bytedance/sonic/loader v0.1.1 // indirect + github.com/cloudwego/base64x v0.1.4 // indirect + github.com/cloudwego/iasm v0.2.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect + github.com/go-jose/go-jose/v4 v4.0.1 // indirect github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect github.com/lestrrat-go/blackmagic v1.0.2 // indirect github.com/lestrrat-go/httpcc v1.0.1 // indirect @@ -62,22 +68,19 @@ require ( github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a // indirect github.com/aymerick/douceur v0.2.0 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bytedance/sonic v1.9.1 // indirect + github.com/bytedance/sonic v1.11.6 // indirect github.com/cenkalti/backoff/v3 v3.0.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/gabriel-vasile/mimetype v1.4.2 // indirect + github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gin-contrib/sse v0.1.0 // indirect - github.com/go-jose/go-jose/v3 v3.0.3 // indirect - github.com/go-logr/logr v1.3.0 // indirect + github.com/go-logr/logr v1.4.1 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.14.0 // indirect + github.com/go-playground/validator/v10 v10.20.0 // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/protobuf v1.5.3 // indirect github.com/gomodule/redigo v2.0.0+incompatible // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/gofuzz v1.2.0 // indirect @@ -98,9 +101,9 @@ require ( github.com/jinzhu/now v1.1.5 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/cpuid/v2 v2.2.4 // indirect + github.com/klauspost/cpuid/v2 v2.2.7 // indirect github.com/kr/text v0.2.0 // indirect - github.com/leodido/go-urn v1.2.4 // indirect + github.com/leodido/go-urn v1.4.0 // indirect github.com/lestrrat-go/jwx v1.2.29 github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-sqlite3 v1.14.17 // indirect @@ -111,7 +114,7 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/pelletier/go-toml/v2 v2.0.8 // indirect + github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/prometheus/client_model v0.5.0 // indirect github.com/prometheus/common v0.48.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect @@ -120,18 +123,17 @@ require ( github.com/shopspring/decimal v1.2.0 // indirect github.com/spf13/cast v1.3.1 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect - github.com/ugorji/go/codec v1.2.11 // indirect - github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect + github.com/ugorji/go/codec v1.2.12 // indirect + github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect github.com/yuin/gopher-lua v1.1.1 // indirect - golang.org/x/arch v0.3.0 // indirect - golang.org/x/net v0.22.0 // indirect - golang.org/x/sys v0.18.0 // indirect - golang.org/x/text v0.14.0 // indirect + golang.org/x/arch v0.8.0 // indirect + golang.org/x/net v0.25.0 // indirect + golang.org/x/sys v0.21.0 // indirect + golang.org/x/text v0.16.0 // indirect golang.org/x/time v0.5.0 // indirect - google.golang.org/appengine v1.6.7 // indirect - google.golang.org/protobuf v1.33.0 // indirect + google.golang.org/protobuf v1.34.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/klog/v2 v2.110.1 // indirect + k8s.io/klog/v2 v2.120.1 // indirect k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect ) diff --git a/go.sum b/go.sum index 0f39a0a81..3a42e03fd 100644 --- a/go.sum +++ b/go.sum @@ -21,11 +21,11 @@ github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGn github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a h1:HbKu58rmZpUGpz5+4FfNmIU+FmZg2P3Xaj2v2bfNWmk= github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= github.com/alicebob/miniredis/v2 v2.11.1/go.mod h1:UA48pmi7aSazcGAvcdKcBB49z521IC9VjTTRz2nIaJE= -github.com/alicebob/miniredis/v2 v2.32.1 h1:Bz7CciDnYSaa0mX5xODh6GUITRSx+cVhjNoOR4JssBo= -github.com/alicebob/miniredis/v2 v2.32.1/go.mod h1:AqkLNAfUm0K07J28hnAyyQKf/x0YkCY/g5DCtuL01Mw= +github.com/alicebob/miniredis/v2 v2.33.0 h1:uvTF0EDeu9RLnUEG27Db5I68ESoIxTiXbNUiji6lZrA= +github.com/alicebob/miniredis/v2 v2.33.0/go.mod h1:MhP4a3EU7aENRi9aO+tHfTBZicLqQevyi/DJpoj6mi0= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/aws/aws-sdk-go v1.51.0 h1:EA6GlEYMT3ouCO+v+oTWzKB/vcoHD2T9H9qulRx3lPg= -github.com/aws/aws-sdk-go v1.51.0/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/aws/aws-sdk-go v1.53.16 h1:8oZjKQO/ml1WLUZw5hvF7pvYjPf8o9f57Wldoy/q9Qc= +github.com/aws/aws-sdk-go v1.53.16/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -37,21 +37,23 @@ github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= github.com/buildkite/yaml v0.0.0-20181016232759-0caa5f0796e3 h1:q+sMKdA6L8LyGVudTkpGoC73h6ak2iWSPFiFo/pFOU8= github.com/buildkite/yaml v0.0.0-20181016232759-0caa5f0796e3/go.mod h1:5hCug3EZaHXU3FdCA3gJm0YTNi+V+ooA2qNTiVpky4A= -github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= -github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= -github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= +github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0= +github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= +github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM= +github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= github.com/cenkalti/backoff/v3 v3.0.0 h1:ske+9nBpD9qZsTBoF41nW5L+AIuFBKMeze18XQ3eG1c= github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= -github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= -github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= +github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= +github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= +github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= +github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -68,26 +70,26 @@ github.com/drone/envsubst v1.0.3/go.mod h1:N2jZmlMufstn1KEqvbHjw40h1KyTmnVzHcSc9 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= -github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= -github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= +github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= +github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= -github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= -github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k= -github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= -github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= -github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= +github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= +github.com/go-jose/go-jose/v4 v4.0.1 h1:QVEPDE3OluqXBQZDcnNvQrInro2h0e4eqNbnZSWqS6U= +github.com/go-jose/go-jose/v4 v4.0.1/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js= -github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8= +github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw= github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/go-vela/types v0.23.4-0.20240516161114-57d6b8f77b10 h1:VQxIqxpJKIOzRnMi4z/d+EOo7jc5PXCnlUvZZl5ajzA= @@ -98,17 +100,11 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/gomodule/redigo v1.7.1-0.20190322064113-39e2c31b7ca3/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0= github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 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/google/go-github/v61 v61.0.0 h1:VwQCBwhyE9JclCI+22/7mLB1PuU9eowCXKY5pNlu1go= @@ -130,14 +126,13 @@ github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= -github.com/hashicorp/go-hclog v0.16.2 h1:K4ev2ib4LdQETX5cSZBG0DVLk1jwGqSPXBjdah3veNs= -github.com/hashicorp/go-hclog v0.16.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-retryablehttp v0.7.5 h1:bJj+Pj19UZMIweq/iie+1u5YCdGrnxCT9yvm0e+Nd5M= -github.com/hashicorp/go-retryablehttp v0.7.5/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= +github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= +github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 h1:om4Al8Oy7kCm/B86rLCLah4Dt5Aa0Fr5rYBG60OzwHQ= @@ -149,8 +144,8 @@ github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0S github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/vault/api v1.12.1 h1:WzGN4X5jrJdNO39g6Sa55djNio3I9DxEBOTmCZE7tm0= -github.com/hashicorp/vault/api v1.12.1/go.mod h1:1pqP/sErScodde+ybJCyP+ONC4jzEg7Dmawg/QLWo1k= +github.com/hashicorp/vault/api v1.14.0 h1:Ah3CFLixD5jmjusOgm8grfN9M0d+Y8fVR2SW0K6pJLU= +github.com/hashicorp/vault/api v1.14.0/go.mod h1:pV9YLxBGSz+cItFDd8Ii4G17waWOQ32zVjMWHe/cOqk= github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4= github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA= @@ -179,14 +174,15 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kisielk/sqlstruct v0.0.0-20201105191214-5f3e10d3ab46/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= -github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= +github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= -github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A= github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y= github.com/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N+AkAr5k= @@ -233,23 +229,23 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= -github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= +github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= +github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= -github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= +github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= +github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE= github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= -github.com/redis/go-redis/v9 v9.5.1 h1:H1X4D3yHPaYrkL5X06Wh6xNVM/pX0Ft4RV0vMGvLBh8= -github.com/redis/go-redis/v9 v9.5.1/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M= +github.com/redis/go-redis/v9 v9.5.2 h1:L0L3fcSNReTRGyZ6AqAEN0K56wYeYAwapBIhkvh0f3E= +github.com/redis/go-redis/v9 v9.5.2/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= @@ -277,19 +273,17 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= -github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= -github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/urfave/cli/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho= -github.com/urfave/cli/v2 v2.27.1/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= +github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/urfave/cli/v2 v2.27.2 h1:6e0H+AkS+zDckwPCUrZkKX38mRaau4nL2uipkJpbkcI= +github.com/urfave/cli/v2 v2.27.2/go.mod h1:g0+79LmHHATl7DAcHO99smiR/T7uGLw84w8Y42x+4eM= +github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 h1:+qGGcbkzsfDQNPPe9UDgpxAWQrhbbBXOYJFQDq/dtJw= +github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913/go.mod h1:4aEEwZQutDLsQv2Deui4iYQ6DWTxR14g6m8Wv88+Xqk= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= @@ -300,23 +294,23 @@ github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7 go.starlark.net v0.0.0-20240314022150-ee8ed142361c h1:roAjH18hZcwI4hHStHbkXjF5b7UUyZ/0SG3hXNN1SjA= go.starlark.net v0.0.0-20240314022150-ee8ed142361c/go.mod h1:YKMCv9b1WrfWmeqdV5MAuEHWsu5iC+fe6kYl2sQjdI8= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= -golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= +golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= @@ -326,17 +320,17 @@ golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= -golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= -golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= +golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -345,7 +339,6 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -353,8 +346,9 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= @@ -363,14 +357,14 @@ golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -383,12 +377,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -406,14 +396,15 @@ gorm.io/driver/postgres v1.5.7 h1:8ptbNJTDbEmhdr62uReG5BGkdQyeasu/FZHxI0IMGnM= gorm.io/driver/postgres v1.5.7/go.mod h1:3e019WlBaYI5o5LIdNV+LyxCMNtLOQETBXL2h4chKpA= gorm.io/driver/sqlite v1.5.5 h1:7MDMtUZhV065SilG62E0MquljeArQZNfJnjd9i9gx3E= gorm.io/driver/sqlite v1.5.5/go.mod h1:6NgQ7sQWAIFsPrJJl1lSNSu2TABh0ZZ/zm5fosATavE= -gorm.io/gorm v1.25.7 h1:VsD6acwRjz2zFxGO50gPO6AkNs7KKnvfzUjHQhZDz/A= -gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= -k8s.io/apimachinery v0.29.2 h1:EWGpfJ856oj11C52NRCHuU7rFDwxev48z+6DSlGNsV8= -k8s.io/apimachinery v0.29.2/go.mod h1:6HVkd1FwxIagpYrHSwJlQqZI3G9LfYWRPAkUvLnXTKU= -k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= -k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= +gorm.io/gorm v1.25.10 h1:dQpO+33KalOA+aFYGlK+EfxcI5MbO7EP2yYygwh9h+s= +gorm.io/gorm v1.25.10/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= +k8s.io/apimachinery v0.30.1 h1:ZQStsEfo4n65yAdlGTfP/uSHMQSoYzU/oeEbkmF7P2U= +k8s.io/apimachinery v0.30.1/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc= +k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= +k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= From 8e49d033822a7c3d91340165c8e15d3ba1767c50 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 5 Jun 2024 13:28:18 -0500 Subject: [PATCH 61/71] fix(deps): update module github.com/google/go-github/v61 to v62 (#1127) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- compiler/native/compile_test.go | 2 +- compiler/registry/github/github.go | 2 +- compiler/registry/github/github_test.go | 2 +- compiler/registry/github/template.go | 2 +- go.mod | 2 +- go.sum | 4 ++-- scm/github/access.go | 2 +- scm/github/authentication.go | 2 +- scm/github/changeset.go | 2 +- scm/github/deployment.go | 2 +- scm/github/github.go | 2 +- scm/github/github_test.go | 2 +- scm/github/repo.go | 2 +- scm/github/webhook.go | 2 +- 14 files changed, 15 insertions(+), 15 deletions(-) diff --git a/compiler/native/compile_test.go b/compiler/native/compile_test.go index 15f2ab8f3..bece3c659 100644 --- a/compiler/native/compile_test.go +++ b/compiler/native/compile_test.go @@ -15,7 +15,7 @@ import ( yml "github.com/buildkite/yaml" "github.com/gin-gonic/gin" "github.com/google/go-cmp/cmp" - "github.com/google/go-github/v61/github" + "github.com/google/go-github/v62/github" "github.com/urfave/cli/v2" api "github.com/go-vela/server/api/types" diff --git a/compiler/registry/github/github.go b/compiler/registry/github/github.go index d617d2c50..59b7b4ba6 100644 --- a/compiler/registry/github/github.go +++ b/compiler/registry/github/github.go @@ -7,7 +7,7 @@ import ( "net/url" "strings" - "github.com/google/go-github/v61/github" + "github.com/google/go-github/v62/github" "golang.org/x/oauth2" ) diff --git a/compiler/registry/github/github_test.go b/compiler/registry/github/github_test.go index 0ad0f2f55..b8f6278f8 100644 --- a/compiler/registry/github/github_test.go +++ b/compiler/registry/github/github_test.go @@ -10,7 +10,7 @@ import ( "reflect" "testing" - "github.com/google/go-github/v61/github" + "github.com/google/go-github/v62/github" "golang.org/x/oauth2" ) diff --git a/compiler/registry/github/template.go b/compiler/registry/github/template.go index 258c1ea95..f09b8b7ef 100644 --- a/compiler/registry/github/template.go +++ b/compiler/registry/github/template.go @@ -7,7 +7,7 @@ import ( "fmt" "net/http" - "github.com/google/go-github/v61/github" + "github.com/google/go-github/v62/github" api "github.com/go-vela/server/api/types" "github.com/go-vela/server/compiler/registry" diff --git a/go.mod b/go.mod index a9cd2f263..afe5316d8 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/go-vela/types v0.23.4-0.20240516161114-57d6b8f77b10 github.com/golang-jwt/jwt/v5 v5.2.1 github.com/google/go-cmp v0.6.0 - github.com/google/go-github/v61 v61.0.0 + github.com/google/go-github/v62 v62.0.0 github.com/google/uuid v1.6.0 github.com/goware/urlx v0.3.2 github.com/hashicorp/go-cleanhttp v0.5.2 diff --git a/go.sum b/go.sum index 3a42e03fd..355d39091 100644 --- a/go.sum +++ b/go.sum @@ -107,8 +107,8 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 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/google/go-github/v61 v61.0.0 h1:VwQCBwhyE9JclCI+22/7mLB1PuU9eowCXKY5pNlu1go= -github.com/google/go-github/v61 v61.0.0/go.mod h1:0WR+KmsWX75G2EbpyGsGmradjo3IiciuI4BmdVCobQY= +github.com/google/go-github/v62 v62.0.0 h1:/6mGCaRywZz9MuHyw9gD1CwsbmBX8GWsbFkwMmHdhl4= +github.com/google/go-github/v62 v62.0.0/go.mod h1:EMxeUqGJq2xRu9DYBMwel/mr7kZrzUOfQmmpYrZn2a4= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= diff --git a/scm/github/access.go b/scm/github/access.go index bec1307d3..4fd570497 100644 --- a/scm/github/access.go +++ b/scm/github/access.go @@ -6,7 +6,7 @@ import ( "context" "strings" - "github.com/google/go-github/v61/github" + "github.com/google/go-github/v62/github" "github.com/sirupsen/logrus" api "github.com/go-vela/server/api/types" diff --git a/scm/github/authentication.go b/scm/github/authentication.go index f152abb95..074a39d04 100644 --- a/scm/github/authentication.go +++ b/scm/github/authentication.go @@ -10,7 +10,7 @@ import ( "net/url" "strings" - "github.com/google/go-github/v61/github" + "github.com/google/go-github/v62/github" api "github.com/go-vela/server/api/types" "github.com/go-vela/server/random" diff --git a/scm/github/changeset.go b/scm/github/changeset.go index c36fe3c8f..770e603ab 100644 --- a/scm/github/changeset.go +++ b/scm/github/changeset.go @@ -6,7 +6,7 @@ import ( "context" "fmt" - "github.com/google/go-github/v61/github" + "github.com/google/go-github/v62/github" "github.com/sirupsen/logrus" api "github.com/go-vela/server/api/types" diff --git a/scm/github/deployment.go b/scm/github/deployment.go index 24d0f083e..852ca0bb2 100644 --- a/scm/github/deployment.go +++ b/scm/github/deployment.go @@ -6,7 +6,7 @@ import ( "context" "encoding/json" - "github.com/google/go-github/v61/github" + "github.com/google/go-github/v62/github" "github.com/sirupsen/logrus" api "github.com/go-vela/server/api/types" diff --git a/scm/github/github.go b/scm/github/github.go index 86129c2ab..30e2d2fc3 100644 --- a/scm/github/github.go +++ b/scm/github/github.go @@ -7,7 +7,7 @@ import ( "fmt" "net/url" - "github.com/google/go-github/v61/github" + "github.com/google/go-github/v62/github" "github.com/sirupsen/logrus" "golang.org/x/oauth2" ) diff --git a/scm/github/github_test.go b/scm/github/github_test.go index bfc70ac75..83a2d6033 100644 --- a/scm/github/github_test.go +++ b/scm/github/github_test.go @@ -10,7 +10,7 @@ import ( "reflect" "testing" - "github.com/google/go-github/v61/github" + "github.com/google/go-github/v62/github" "golang.org/x/oauth2" ) diff --git a/scm/github/repo.go b/scm/github/repo.go index c9b143763..6af6cdd5a 100644 --- a/scm/github/repo.go +++ b/scm/github/repo.go @@ -10,7 +10,7 @@ import ( "strings" "time" - "github.com/google/go-github/v61/github" + "github.com/google/go-github/v62/github" "github.com/sirupsen/logrus" api "github.com/go-vela/server/api/types" diff --git a/scm/github/webhook.go b/scm/github/webhook.go index 3092ae63e..a0c623604 100644 --- a/scm/github/webhook.go +++ b/scm/github/webhook.go @@ -13,7 +13,7 @@ import ( "strings" "time" - "github.com/google/go-github/v61/github" + "github.com/google/go-github/v62/github" "github.com/sirupsen/logrus" api "github.com/go-vela/server/api/types" From dc8b3f65e09e2f0298f4666e7910e11807059a9e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 5 Jun 2024 14:16:30 -0500 Subject: [PATCH 62/71] fix(deps): update all non-major dependencies (#1137) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index afe5316d8..c59a61153 100644 --- a/go.mod +++ b/go.mod @@ -11,14 +11,14 @@ require ( github.com/Masterminds/sprig/v3 v3.2.3 github.com/adhocore/gronx v1.8.1 github.com/alicebob/miniredis/v2 v2.33.0 - github.com/aws/aws-sdk-go v1.53.16 + github.com/aws/aws-sdk-go v1.53.17 github.com/buildkite/yaml v0.0.0-20181016232759-0caa5f0796e3 github.com/distribution/reference v0.6.0 github.com/drone/envsubst v1.0.3 github.com/ghodss/yaml v1.0.0 github.com/gin-gonic/gin v1.10.0 github.com/go-playground/assert/v2 v2.2.0 - github.com/go-vela/types v0.23.4-0.20240516161114-57d6b8f77b10 + github.com/go-vela/types v0.24.0-rc1 github.com/golang-jwt/jwt/v5 v5.2.1 github.com/google/go-cmp v0.6.0 github.com/google/go-github/v62 v62.0.0 diff --git a/go.sum b/go.sum index 355d39091..1ed70709f 100644 --- a/go.sum +++ b/go.sum @@ -24,8 +24,8 @@ github.com/alicebob/miniredis/v2 v2.11.1/go.mod h1:UA48pmi7aSazcGAvcdKcBB49z521I github.com/alicebob/miniredis/v2 v2.33.0 h1:uvTF0EDeu9RLnUEG27Db5I68ESoIxTiXbNUiji6lZrA= github.com/alicebob/miniredis/v2 v2.33.0/go.mod h1:MhP4a3EU7aENRi9aO+tHfTBZicLqQevyi/DJpoj6mi0= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/aws/aws-sdk-go v1.53.16 h1:8oZjKQO/ml1WLUZw5hvF7pvYjPf8o9f57Wldoy/q9Qc= -github.com/aws/aws-sdk-go v1.53.16/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/aws/aws-sdk-go v1.53.17 h1:TwtYMzVBTaqPVj/pcemHRIgk01OycWEcEUyUUX0tpCI= +github.com/aws/aws-sdk-go v1.53.17/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -92,8 +92,8 @@ github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBEx github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw= github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= -github.com/go-vela/types v0.23.4-0.20240516161114-57d6b8f77b10 h1:VQxIqxpJKIOzRnMi4z/d+EOo7jc5PXCnlUvZZl5ajzA= -github.com/go-vela/types v0.23.4-0.20240516161114-57d6b8f77b10/go.mod h1:vISsYDdjz9RPEK6qZ+MxtrdZEjTVU4K30NomB3826u8= +github.com/go-vela/types v0.24.0-rc1 h1:4NeH+YF8fVbs6ukilKySIY3uD2SVYgBz1yqREjgZaOw= +github.com/go-vela/types v0.24.0-rc1/go.mod h1:YWj6BIapl9Kbj4yHq/fp8jltXdGiwD/gTy1ez32Rzag= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= From ad8e820749fea137213da470de56b6878895c5b0 Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Fri, 7 Jun 2024 11:29:25 -0500 Subject: [PATCH 63/71] fix(jwk): upgrade lestrrat-go/jwx to v2 (#1138) * fix(jwk): upgrade lestrrat-go to v2 * nil errs and err checks --- api/types/oidc.go | 2 +- database/integration_test.go | 14 ++++--- database/jwk/create.go | 2 +- database/jwk/get.go | 2 +- database/jwk/get_test.go | 2 +- database/jwk/interface.go | 2 +- database/jwk/list.go | 7 +++- database/jwk/list_test.go | 14 +++++-- database/testutils/api_resources.go | 24 +++++++---- database/testutils/mock_args.go | 2 +- database/types/jwk.go | 2 +- go.mod | 5 ++- go.sum | 30 +++----------- internal/token/generate_rsa.go | 62 +++++++++++++++-------------- mock/server/authentication.go | 2 +- 15 files changed, 91 insertions(+), 81 deletions(-) diff --git a/api/types/oidc.go b/api/types/oidc.go index 7598351f6..50b106fb0 100644 --- a/api/types/oidc.go +++ b/api/types/oidc.go @@ -4,7 +4,7 @@ package types import ( "github.com/golang-jwt/jwt/v5" - "github.com/lestrrat-go/jwx/jwk" + "github.com/lestrrat-go/jwx/v2/jwk" ) // OpenIDConfig is a struct that represents the OpenID Connect configuration. diff --git a/database/integration_test.go b/database/integration_test.go index 9d70d53d2..ad3748c4f 100644 --- a/database/integration_test.go +++ b/database/integration_test.go @@ -12,7 +12,7 @@ import ( "github.com/adhocore/gronx" "github.com/google/go-cmp/cmp" - "github.com/lestrrat-go/jwx/jwk" + "github.com/lestrrat-go/jwx/v2/jwk" api "github.com/go-vela/server/api/types" "github.com/go-vela/server/api/types/settings" @@ -878,7 +878,7 @@ func testJWKs(t *testing.T, db Interface, resources *Resources) { } for i := 0; i < resources.JWKs.Len(); i++ { - jk, _ := resources.JWKs.Get(i) + jk, _ := resources.JWKs.Key(i) jkPub, _ := jk.(jwk.RSAPublicKey) @@ -901,7 +901,7 @@ func testJWKs(t *testing.T, db Interface, resources *Resources) { methods["ListJWKs"] = true for i := 0; i < resources.JWKs.Len(); i++ { - jk, _ := resources.JWKs.Get(i) + jk, _ := resources.JWKs.Key(i) jkPub, _ := jk.(jwk.RSAPublicKey) @@ -923,7 +923,7 @@ func testJWKs(t *testing.T, db Interface, resources *Resources) { } for i := 0; i < resources.JWKs.Len(); i++ { - jk, _ := resources.JWKs.Get(i) + jk, _ := resources.JWKs.Key(i) jkPub, _ := jk.(jwk.RSAPublicKey) @@ -2576,8 +2576,10 @@ func newResources() *Resources { jwkTwo := testutils.JWK() jwkSet := jwk.NewSet() - jwkSet.Add(jwkOne) - jwkSet.Add(jwkTwo) + + _ = jwkSet.AddKey(jwkOne) + + _ = jwkSet.AddKey(jwkTwo) logServiceOne := new(library.Log) logServiceOne.SetID(1) diff --git a/database/jwk/create.go b/database/jwk/create.go index 3f5896e41..161b3ef4a 100644 --- a/database/jwk/create.go +++ b/database/jwk/create.go @@ -6,7 +6,7 @@ import ( "context" "database/sql" - "github.com/lestrrat-go/jwx/jwk" + "github.com/lestrrat-go/jwx/v2/jwk" "github.com/sirupsen/logrus" "github.com/go-vela/server/constants" diff --git a/database/jwk/get.go b/database/jwk/get.go index 187753df8..0313b68a5 100644 --- a/database/jwk/get.go +++ b/database/jwk/get.go @@ -5,7 +5,7 @@ package jwk import ( "context" - "github.com/lestrrat-go/jwx/jwk" + "github.com/lestrrat-go/jwx/v2/jwk" "github.com/go-vela/server/constants" "github.com/go-vela/server/database/types" diff --git a/database/jwk/get_test.go b/database/jwk/get_test.go index 2cb131bae..7af354a63 100644 --- a/database/jwk/get_test.go +++ b/database/jwk/get_test.go @@ -9,7 +9,7 @@ import ( "github.com/DATA-DOG/go-sqlmock" "github.com/google/go-cmp/cmp" - "github.com/lestrrat-go/jwx/jwk" + "github.com/lestrrat-go/jwx/v2/jwk" "github.com/go-vela/server/database/testutils" ) diff --git a/database/jwk/interface.go b/database/jwk/interface.go index a83b1b300..2e66b4bcf 100644 --- a/database/jwk/interface.go +++ b/database/jwk/interface.go @@ -5,7 +5,7 @@ package jwk import ( "context" - "github.com/lestrrat-go/jwx/jwk" + "github.com/lestrrat-go/jwx/v2/jwk" ) // JWKInterface represents the Vela interface for JWK diff --git a/database/jwk/list.go b/database/jwk/list.go index 7c83b48b1..ed58fa36c 100644 --- a/database/jwk/list.go +++ b/database/jwk/list.go @@ -5,7 +5,7 @@ package jwk import ( "context" - "github.com/lestrrat-go/jwx/jwk" + "github.com/lestrrat-go/jwx/v2/jwk" "github.com/go-vela/server/constants" "github.com/go-vela/server/database/types" @@ -33,7 +33,10 @@ func (e *engine) ListJWKs(_ context.Context) (jwk.Set, error) { tmp := key // convert query result to API type - keySet.Add(tmp.ToAPI()) + err = keySet.AddKey(tmp.ToAPI()) + if err != nil { + return nil, err + } } return keySet, nil diff --git a/database/jwk/list_test.go b/database/jwk/list_test.go index f4d54dcc2..6e8bb5399 100644 --- a/database/jwk/list_test.go +++ b/database/jwk/list_test.go @@ -9,7 +9,7 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" - "github.com/lestrrat-go/jwx/jwk" + "github.com/lestrrat-go/jwx/v2/jwk" "github.com/go-vela/server/database/testutils" ) @@ -54,8 +54,16 @@ func TestJWK_Engine_ListJWKs(t *testing.T) { } wantSet := jwk.NewSet() - wantSet.Add(_jwkOne) - wantSet.Add(_jwkTwo) + + err = wantSet.AddKey(_jwkOne) + if err != nil { + t.Errorf("unable to add jwk to set: %v", err) + } + + err = wantSet.AddKey(_jwkTwo) + if err != nil { + t.Errorf("unable to add jwk to set: %v", err) + } // setup tests tests := []struct { diff --git a/database/testutils/api_resources.go b/database/testutils/api_resources.go index 83a3d5c3c..0831567ae 100644 --- a/database/testutils/api_resources.go +++ b/database/testutils/api_resources.go @@ -7,7 +7,7 @@ import ( "crypto/rsa" "github.com/google/uuid" - "github.com/lestrrat-go/jwx/jwk" + "github.com/lestrrat-go/jwx/v2/jwk" api "github.com/go-vela/server/api/types" "github.com/go-vela/server/api/types/actions" @@ -282,16 +282,26 @@ func JWK() jwk.RSAPublicKey { return nil } - // assign KID to key pair - kid, err := uuid.NewV7() + pubJwk, err := jwk.FromRaw(privateRSAKey.PublicKey) if err != nil { return nil } - j := jwk.NewRSAPublicKey() - _ = j.FromRaw(&privateRSAKey.PublicKey) + switch j := pubJwk.(type) { + case jwk.RSAPublicKey: + // assign KID to key pair + kid, err := uuid.NewV7() + if err != nil { + return nil + } - _ = j.Set(jwk.KeyIDKey, kid.String()) + err = pubJwk.Set(jwk.KeyIDKey, kid.String()) + if err != nil { + return nil + } - return j + return j + default: + return nil + } } diff --git a/database/testutils/mock_args.go b/database/testutils/mock_args.go index e6d8a9324..29a362664 100644 --- a/database/testutils/mock_args.go +++ b/database/testutils/mock_args.go @@ -8,7 +8,7 @@ import ( "time" "github.com/google/go-cmp/cmp" - "github.com/lestrrat-go/jwx/jwk" + "github.com/lestrrat-go/jwx/v2/jwk" ) // This will be used with the github.com/DATA-DOG/go-sqlmock library to compare values diff --git a/database/types/jwk.go b/database/types/jwk.go index 486512da1..69ba9ad43 100644 --- a/database/types/jwk.go +++ b/database/types/jwk.go @@ -8,7 +8,7 @@ import ( "errors" "github.com/google/uuid" - "github.com/lestrrat-go/jwx/jwk" + "github.com/lestrrat-go/jwx/v2/jwk" ) var ( diff --git a/go.mod b/go.mod index c59a61153..3498c9262 100644 --- a/go.mod +++ b/go.mod @@ -29,6 +29,7 @@ require ( github.com/hashicorp/go-retryablehttp v0.7.7 github.com/hashicorp/vault/api v1.14.0 github.com/joho/godotenv v1.5.1 + github.com/lestrrat-go/jwx/v2 v2.0.21 github.com/lib/pq v1.10.9 github.com/microcosm-cc/bluemonday v1.0.26 github.com/pkg/errors v0.9.1 @@ -54,11 +55,12 @@ require ( github.com/cloudwego/iasm v0.2.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/go-jose/go-jose/v4 v4.0.1 // indirect - github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect github.com/lestrrat-go/blackmagic v1.0.2 // indirect github.com/lestrrat-go/httpcc v1.0.1 // indirect + github.com/lestrrat-go/httprc v1.0.5 // indirect github.com/lestrrat-go/iter v1.0.2 // indirect github.com/lestrrat-go/option v1.0.1 // indirect + github.com/segmentio/asm v1.2.0 // indirect ) require ( @@ -104,7 +106,6 @@ require ( github.com/klauspost/cpuid/v2 v2.2.7 // indirect github.com/kr/text v0.2.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect - github.com/lestrrat-go/jwx v1.2.29 github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-sqlite3 v1.14.17 // indirect github.com/mitchellh/copystructure v1.0.0 // indirect diff --git a/go.sum b/go.sum index 1ed70709f..6d22f2b80 100644 --- a/go.sum +++ b/go.sum @@ -58,7 +58,6 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= @@ -183,17 +182,16 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= -github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A= -github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y= github.com/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N+AkAr5k= github.com/lestrrat-go/blackmagic v1.0.2/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU= github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE= github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E= +github.com/lestrrat-go/httprc v1.0.5 h1:bsTfiH8xaKOJPrg1R+E3iE/AWZr/x0Phj9PBTG/OLUk= +github.com/lestrrat-go/httprc v1.0.5/go.mod h1:mwwz3JMTPBjHUkkDv/IGJ39aALInZLrhBp0X7KGUZlo= github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI= github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4= -github.com/lestrrat-go/jwx v1.2.29 h1:QT0utmUJ4/12rmsVQrJ3u55bycPkKqGYuGT4tyRhxSQ= -github.com/lestrrat-go/jwx v1.2.29/go.mod h1:hU8k2l6WF0ncx20uQdOmik/Gjg6E3/wIRtXSNFeZuB8= -github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= +github.com/lestrrat-go/jwx/v2 v2.0.21 h1:jAPKupy4uHgrHFEdjVjNkUgoBKtVDgrQPB/h55FHrR0= +github.com/lestrrat-go/jwx/v2 v2.0.21/go.mod h1:09mLW8zto6bWL9GbwnqAli+ArLf+5M33QLQPDggkUWM= github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= @@ -253,6 +251,8 @@ github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= +github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys= +github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= @@ -301,14 +301,11 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -317,9 +314,6 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= @@ -328,7 +322,6 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -344,25 +337,15 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= @@ -372,7 +355,6 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/internal/token/generate_rsa.go b/internal/token/generate_rsa.go index 350ab8ea9..fae46aef2 100644 --- a/internal/token/generate_rsa.go +++ b/internal/token/generate_rsa.go @@ -6,9 +6,10 @@ import ( "context" "crypto/rand" "crypto/rsa" + "fmt" "github.com/google/uuid" - "github.com/lestrrat-go/jwx/jwk" + "github.com/lestrrat-go/jwx/v2/jwk" "github.com/go-vela/server/database" ) @@ -21,37 +22,40 @@ func (tm *Manager) GenerateRSA(ctx context.Context, db database.Interface) error return err } - // assign KID to key pair - kid, err := uuid.NewV7() + pubJwk, err := jwk.FromRaw(privateRSAKey.PublicKey) if err != nil { return err } - j := jwk.NewRSAPublicKey() - - err = j.FromRaw(&privateRSAKey.PublicKey) - if err != nil { - return err - } - - err = j.Set(jwk.KeyIDKey, kid.String()) - if err != nil { - return err + switch j := pubJwk.(type) { + case jwk.RSAPublicKey: + // assign KID to key pair + kid, err := uuid.NewV7() + if err != nil { + return err + } + + err = pubJwk.Set(jwk.KeyIDKey, kid.String()) + if err != nil { + return err + } + + // create the JWK in the database + err = db.CreateJWK(context.TODO(), j) + if err != nil { + return err + } + + // create the RSA key set for token manager + keySet := RSAKeySet{ + PrivateKey: privateRSAKey, + KID: kid.String(), + } + + tm.RSAKeySet = keySet + + return nil + default: + return fmt.Errorf("invalid JWK type parsed from generation") } - - // create the JWK in the database - err = db.CreateJWK(context.TODO(), j) - if err != nil { - return err - } - - // create the RSA key set for token manager - keySet := RSAKeySet{ - PrivateKey: privateRSAKey, - KID: kid.String(), - } - - tm.RSAKeySet = keySet - - return nil } diff --git a/mock/server/authentication.go b/mock/server/authentication.go index 6e9f4512b..b1903eeb9 100644 --- a/mock/server/authentication.go +++ b/mock/server/authentication.go @@ -7,7 +7,7 @@ import ( "net/http" "github.com/gin-gonic/gin" - "github.com/lestrrat-go/jwx/jwk" + "github.com/lestrrat-go/jwx/v2/jwk" api "github.com/go-vela/server/api/types" "github.com/go-vela/types" From a083311d9017a53da78f5c5b9493a04ecaaadaf1 Mon Sep 17 00:00:00 2001 From: david may <1301201+wass3r@users.noreply.github.com> Date: Fri, 7 Jun 2024 13:29:04 -0500 Subject: [PATCH 64/71] fix(swagger): various fixes and improved consistency (#1139) --- api/admin/build.go | 30 ++++++++++++++++-------------- api/admin/clean.go | 15 +++++++-------- api/admin/deployment.go | 9 ++++++--- api/admin/hook.go | 23 +++++++++++++---------- api/admin/repo.go | 23 +++++++++++++---------- api/admin/rotate_keys.go | 8 ++++++-- api/admin/secret.go | 23 +++++++++++++---------- api/admin/service.go | 21 ++++++++++++--------- api/admin/settings.go | 33 ++++++++++++++++----------------- api/admin/step.go | 21 ++++++++++++--------- api/admin/user.go | 21 ++++++++++++--------- api/admin/worker.go | 4 ++++ api/auth/get_token.go | 8 ++++---- api/auth/login.go | 6 +++--- api/auth/logout.go | 6 +++++- api/auth/post_token.go | 7 +++---- api/auth/redirect.go | 10 +++++----- api/auth/validate_oauth.go | 6 +++--- api/badge.go | 16 ++++++++++++---- api/build/approve.go | 25 ++++++++++++------------- api/build/cancel.go | 26 +++++++++++++++----------- api/build/clean.go | 3 +-- api/build/create.go | 18 +++++++++--------- api/build/delete.go | 22 +++++++++++++++------- api/build/executable.go | 22 +++++++++++++--------- api/build/get.go | 24 ++++++++++++++++++------ api/build/get_id.go | 17 ++++++++++------- api/build/graph.go | 20 ++++++++++++-------- api/build/id_request_token.go | 18 +++++++++--------- api/build/id_token.go | 18 +++++++++--------- api/build/list_org.go | 19 +++++++++++-------- api/build/list_repo.go | 28 ++++++++++++++++++---------- api/build/plan.go | 2 +- api/build/restart.go | 18 +++++++++--------- api/build/token.go | 16 ++++++++++------ api/build/update.go | 24 ++++++++++++++++-------- api/dashboard/create.go | 12 ++++++------ api/dashboard/delete.go | 17 ++++++++++------- api/dashboard/doc.go | 8 ++++++++ api/dashboard/get.go | 22 +++++++++++++--------- api/dashboard/list_user.go | 10 +++++----- api/dashboard/update.go | 15 +++++++-------- api/deployment/create.go | 20 ++++++++++++++------ api/deployment/get.go | 21 ++++++++++++++------- api/deployment/list.go | 23 +++++++++++++++-------- api/health.go | 2 +- api/hook/create.go | 33 ++++++++++++++++++++------------- api/hook/delete.go | 19 +++++++++++-------- api/hook/doc.go | 8 ++++++++ api/hook/get.go | 21 ++++++++++++++------- api/hook/list.go | 24 ++++++++++++++++-------- api/hook/redeliver.go | 18 +++++++++++------- api/hook/update.go | 19 +++++++++++-------- api/jwks.go | 2 +- api/log/create_service.go | 18 +++++++++++++----- api/log/create_step.go | 18 +++++++++++++----- api/log/delete_service.go | 20 ++++++++++++++++---- api/log/delete_step.go | 20 ++++++++++++++++---- api/log/get_service.go | 23 +++++++++++++++++------ api/log/get_step.go | 23 +++++++++++++++++------ api/log/list_build.go | 23 +++++++++++++++++------ api/log/update_service.go | 24 +++++++++++++++--------- api/log/update_step.go | 24 +++++++++++++++--------- api/metrics.go | 4 ++-- api/oi_config.go | 2 +- api/pipeline/compile.go | 24 ++++++++++++++++-------- api/pipeline/create.go | 20 ++++++++++++-------- api/pipeline/delete.go | 21 ++++++++++++++------- api/pipeline/expand.go | 24 ++++++++++++++++-------- api/pipeline/get.go | 25 ++++++++++++++++++++----- api/pipeline/list.go | 24 ++++++++++++++++-------- api/pipeline/template.go | 28 +++++++++++++++++++--------- api/pipeline/update.go | 22 +++++++++++++++------- api/pipeline/validate.go | 24 ++++++++++++++++-------- api/queue/doc.go | 8 ++++++++ api/repo/chown.go | 24 ++++++++++++++++++------ api/repo/create.go | 15 +++++++++------ api/repo/delete.go | 25 ++++++++++++++++--------- api/repo/get.go | 21 ++++++++++++++++----- api/repo/list.go | 16 ++++++++++------ api/repo/list_org.go | 18 +++++++++++------- api/repo/repair.go | 20 ++++++++++++++++---- api/repo/update.go | 19 +++++++++++-------- api/schedule/create.go | 22 +++++++++++++++------- api/schedule/delete.go | 25 ++++++++++++++++--------- api/schedule/doc.go | 8 ++++++++ api/schedule/get.go | 21 ++++++++++++++++----- api/schedule/list.go | 23 +++++++++++++++-------- api/schedule/update.go | 21 ++++++++++++--------- api/scm/sync.go | 21 ++++++++++++++------- api/scm/sync_org.go | 18 +++++++++++++----- api/secret/create.go | 16 ++++++++++------ api/secret/delete.go | 12 ++++++++---- api/secret/get.go | 12 ++++++++---- api/secret/list.go | 19 +++++++++++-------- api/secret/update.go | 14 +++++++++----- api/service/create.go | 22 +++++++++++++++------- api/service/delete.go | 23 +++++++++++++++++------ api/service/get.go | 21 ++++++++++++++------- api/service/list.go | 23 +++++++++++++++-------- api/service/plan.go | 2 +- api/service/update.go | 22 +++++++++++++++------- api/step/create.go | 20 ++++++++++++++------ api/step/delete.go | 21 ++++++++++++++++----- api/step/get.go | 21 ++++++++++++++++----- api/step/list.go | 23 +++++++++++++++-------- api/step/plan.go | 2 +- api/step/update.go | 20 ++++++++++++++------ api/user/create.go | 15 +++++++++------ api/user/create_token.go | 6 +++++- api/user/delete.go | 15 +++++++++------ api/user/delete_token.go | 8 ++++++-- api/user/get.go | 11 +++++++---- api/user/get_current.go | 8 ++++++-- api/user/get_source.go | 11 +++++++---- api/user/list.go | 15 +++++++++------ api/user/update.go | 17 ++++++++++------- api/user/update_current.go | 14 +++++++------- api/version.go | 2 +- api/webhook/post.go | 10 +++++----- api/worker/create.go | 14 +++++++++----- api/worker/delete.go | 21 ++++++++++++++++----- api/worker/get.go | 19 +++++++++++++++---- api/worker/list.go | 19 +++++++++++++------ api/worker/refresh.go | 12 ++++++++---- api/worker/update.go | 16 ++++++++++------ 126 files changed, 1399 insertions(+), 767 deletions(-) create mode 100644 api/dashboard/doc.go create mode 100644 api/hook/doc.go create mode 100644 api/queue/doc.go create mode 100644 api/schedule/doc.go diff --git a/api/admin/build.go b/api/admin/build.go index 1a4fe0489..aab5f4fca 100644 --- a/api/admin/build.go +++ b/api/admin/build.go @@ -19,7 +19,7 @@ import ( // swagger:operation GET /api/v1/admin/builds/queue admin AllBuildsQueue // -// Get all of the running and pending builds in the database +// Get running and pending builds // // --- // produces: @@ -38,14 +38,17 @@ import ( // schema: // type: array // items: -// "$ref": "#/definitions/BuildQueue" +// "$ref": "#/definitions/QueueBuild" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" // '500': -// description: Unable to retrieve all running and pending builds from the database +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// AllBuildsQueue represents the API handler to -// capture all running and pending builds stored in the database. +// AllBuildsQueue represents the API handler to get running and pending builds. func AllBuildsQueue(c *gin.Context) { // capture middleware values ctx := c.Request.Context() @@ -70,7 +73,7 @@ func AllBuildsQueue(c *gin.Context) { // swagger:operation PUT /api/v1/admin/build admin AdminUpdateBuild // -// Update a build in the database +// Update a build // // --- // produces: @@ -78,7 +81,7 @@ func AllBuildsQueue(c *gin.Context) { // parameters: // - in: body // name: body -// description: Payload containing build to update +// description: The build object with the fields to be updated // required: true // schema: // "$ref": "#/definitions/Build" @@ -86,20 +89,19 @@ func AllBuildsQueue(c *gin.Context) { // - ApiKeyAuth: [] // responses: // '200': -// description: Successfully updated the build in the database +// description: Successfully updated the build // schema: // "$ref": "#/definitions/Build" -// '404': -// description: Unable to update the build in the database +// '400': +// description: Invalid request payload // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to update the build in the database +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// UpdateBuild represents the API handler to -// update any build stored in the database. +// UpdateBuild represents the API handler to update a build. func UpdateBuild(c *gin.Context) { logrus.Info("Admin: updating build in database") @@ -113,7 +115,7 @@ func UpdateBuild(c *gin.Context) { if err != nil { retErr := fmt.Errorf("unable to decode JSON for build %d: %w", input.GetID(), err) - util.HandleError(c, http.StatusNotFound, retErr) + util.HandleError(c, http.StatusBadRequest, retErr) return } diff --git a/api/admin/clean.go b/api/admin/clean.go index 9813a7fc7..d6ecbde4d 100644 --- a/api/admin/clean.go +++ b/api/admin/clean.go @@ -20,7 +20,7 @@ import ( // swagger:operation PUT /api/v1/admin/clean admin AdminCleanResources // -// Update pending build resources to error status before a given time +// Update stale build resources to error status // // --- // produces: @@ -28,7 +28,7 @@ import ( // parameters: // - in: query // name: before -// description: filter pending resources created before a certain time +// description: Filter stale resources created before a certain time // required: true // type: integer // - in: body @@ -43,22 +43,21 @@ import ( // '200': // description: Successfully updated pending resources with error message // schema: -// type: string +// type: string // '400': -// description: Unable to update resources — bad request +// description: Invalid request payload // schema: // "$ref": "#/definitions/Error" // '401': -// description: Unable to update resources — unauthorized +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to update resources +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// CleanResources represents the API handler to -// update any user stored in the database. +// CleanResources represents the API handler to update stale resources. func CleanResources(c *gin.Context) { // capture middleware values u := user.Retrieve(c) diff --git a/api/admin/deployment.go b/api/admin/deployment.go index deeac0045..f205c90d1 100644 --- a/api/admin/deployment.go +++ b/api/admin/deployment.go @@ -10,20 +10,23 @@ import ( // swagger:operation PUT /api/v1/admin/deployment admin AdminUpdateDeployment // -// Get All (Not Implemented) +// Update a deployment (Not Implemented) // // --- // produces: // - application/json // parameters: // responses: +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" // '501': // description: This endpoint is not implemented // schema: // type: string -// UpdateDeployment represents the API handler to -// update any deployment stored in the database. +// UpdateDeployment represents the API handler to update a deployment. func UpdateDeployment(c *gin.Context) { c.JSON(http.StatusNotImplemented, "The server does not support the functionality required to fulfill the request.") } diff --git a/api/admin/hook.go b/api/admin/hook.go index 156110880..d9d7b4b17 100644 --- a/api/admin/hook.go +++ b/api/admin/hook.go @@ -17,7 +17,7 @@ import ( // swagger:operation PUT /api/v1/admin/hook admin AdminUpdateHook // -// Update a hook in the database +// Update a hook // // --- // produces: @@ -25,7 +25,7 @@ import ( // parameters: // - in: body // name: body -// description: Payload containing hook to update +// description: The hook object with the fields to be updated // required: true // schema: // "$ref": "#/definitions/Webhook" @@ -33,20 +33,23 @@ import ( // - ApiKeyAuth: [] // responses: // '200': -// description: Successfully updated the hook in the database +// description: Successfully updated the hook // schema: // "$ref": "#/definitions/Webhook" -// '404': -// description: Unable to update the hook in the database +// '401': +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" -// '501': -// description: Unable to update the hook in the database +// '400': +// description: Invalid request payload +// schema: +// "$ref": "#/definitions/Error" +// '500': +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// UpdateHook represents the API handler to -// update any hook stored in the database. +// UpdateHook represents the API handler to update a hook. func UpdateHook(c *gin.Context) { logrus.Info("Admin: updating hook in database") @@ -60,7 +63,7 @@ func UpdateHook(c *gin.Context) { if err != nil { retErr := fmt.Errorf("unable to decode JSON for hook %d: %w", input.GetID(), err) - util.HandleError(c, http.StatusNotFound, retErr) + util.HandleError(c, http.StatusBadRequest, retErr) return } diff --git a/api/admin/repo.go b/api/admin/repo.go index 52da52301..6ce1bac37 100644 --- a/api/admin/repo.go +++ b/api/admin/repo.go @@ -17,7 +17,7 @@ import ( // swagger:operation PUT /api/v1/admin/repo admin AdminUpdateRepo // -// Update a repo in the database +// Update a repository // // --- // produces: @@ -25,7 +25,7 @@ import ( // parameters: // - in: body // name: body -// description: Payload containing repo to update +// description: The repository object with the fields to be updated // required: true // schema: // "$ref": "#/definitions/Repo" @@ -33,20 +33,23 @@ import ( // - ApiKeyAuth: [] // responses: // '200': -// description: Successfully updated the repo in the database +// description: Successfully updated the repo // schema: // "$ref": "#/definitions/Repo" -// '404': -// description: Unable to update the repo in the database +// '401': +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" -// '501': -// description: Unable to update the repo in the database +// '400': +// description: Invalid request payload +// schema: +// "$ref": "#/definitions/Error" +// '500': +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// UpdateRepo represents the API handler to -// update any repo stored in the database. +// UpdateRepo represents the API handler to update a repo. func UpdateRepo(c *gin.Context) { logrus.Info("Admin: updating repo in database") @@ -60,7 +63,7 @@ func UpdateRepo(c *gin.Context) { if err != nil { retErr := fmt.Errorf("unable to decode JSON for repo %d: %w", input.GetID(), err) - util.HandleError(c, http.StatusNotFound, retErr) + util.HandleError(c, http.StatusBadRequest, retErr) return } diff --git a/api/admin/rotate_keys.go b/api/admin/rotate_keys.go index 56681a60c..0186c0c29 100644 --- a/api/admin/rotate_keys.go +++ b/api/admin/rotate_keys.go @@ -28,13 +28,17 @@ import ( // description: Successfully rotated OIDC provider keys // schema: // type: string +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" // '500': -// description: Error unable to rotate OIDC provider keys +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" // RotateOIDCKeys represents the API handler to -// rotate RSA keys in OIDC provider service. +// rotate RSA keys in the OIDC provider service. func RotateOIDCKeys(c *gin.Context) { logrus.Info("Admin: rotating keys for OIDC provider") diff --git a/api/admin/secret.go b/api/admin/secret.go index f9573d9dd..673134ba6 100644 --- a/api/admin/secret.go +++ b/api/admin/secret.go @@ -17,7 +17,7 @@ import ( // swagger:operation PUT /api/v1/admin/secret admin AdminUpdateSecret // -// Update a secret in the database +// Update a secret // // --- // produces: @@ -25,7 +25,7 @@ import ( // parameters: // - in: body // name: body -// description: Payload containing secret to update +// description: The secret object with the fields to be updated // required: true // schema: // "$ref": "#/definitions/Secret" @@ -33,20 +33,23 @@ import ( // - ApiKeyAuth: [] // responses: // '200': -// description: Successfully updated the secret in the database +// description: Successfully updated the secret // schema: // "$ref": "#/definitions/Secret" -// '404': -// description: Unable to update the secret in the database +// '401': +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" -// '501': -// description: Unable to update the secret in the database +// '400': +// description: Invalid request payload +// schema: +// "$ref": "#/definitions/Error" +// '500': +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// UpdateSecret represents the API handler to -// update any secret stored in the database. +// UpdateSecret represents the API handler to update a secret. func UpdateSecret(c *gin.Context) { logrus.Info("Admin: updating secret in database") @@ -60,7 +63,7 @@ func UpdateSecret(c *gin.Context) { if err != nil { retErr := fmt.Errorf("unable to decode JSON for secret %d: %w", input.GetID(), err) - util.HandleError(c, http.StatusNotFound, retErr) + util.HandleError(c, http.StatusBadRequest, retErr) return } diff --git a/api/admin/service.go b/api/admin/service.go index 4d74fb388..61153ad5f 100644 --- a/api/admin/service.go +++ b/api/admin/service.go @@ -17,7 +17,7 @@ import ( // swagger:operation PUT /api/v1/admin/service admin AdminUpdateService // -// Update a hook in the database +// Update a service // // --- // produces: @@ -25,7 +25,7 @@ import ( // parameters: // - in: body // name: body -// description: Payload containing service to update +// description: The service object with the fields to be updated // required: true // schema: // "$ref": "#/definitions/Service" @@ -33,21 +33,24 @@ import ( // - ApiKeyAuth: [] // responses: // '200': -// description: Successfully updated the service in the database +// description: Successfully updated the service // type: json // schema: // "$ref": "#/definitions/Service" -// '404': -// description: Unable to update the service in the database +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '400': +// description: Invalid request payload // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to update the service in the database +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// UpdateService represents the API handler to -// update any service stored in the database. +// UpdateService represents the API handler to update a service. func UpdateService(c *gin.Context) { logrus.Info("Admin: updating service in database") @@ -61,7 +64,7 @@ func UpdateService(c *gin.Context) { if err != nil { retErr := fmt.Errorf("unable to decode JSON for service %d: %w", input.GetID(), err) - util.HandleError(c, http.StatusNotFound, retErr) + util.HandleError(c, http.StatusBadRequest, retErr) return } diff --git a/api/admin/settings.go b/api/admin/settings.go index f04109680..8b5c525d8 100644 --- a/api/admin/settings.go +++ b/api/admin/settings.go @@ -23,7 +23,7 @@ import ( // swagger:operation GET /api/v1/admin/settings admin GetSettings // -// Get the currently configured settings. +// Get platform settings // // --- // produces: @@ -41,12 +41,11 @@ import ( // schema: // "$ref": "#/definitions/Error" // '404': -// description: Unable to retrieve settings +// description: Not found // schema: // "$ref": "#/definitions/Error" -// GetSettings represents the API handler to -// captures settings stored in the database. +// GetSettings represents the API handler to get platform settings. func GetSettings(c *gin.Context) { // capture middleware values s := sMiddleware.FromContext(c) @@ -68,7 +67,7 @@ func GetSettings(c *gin.Context) { // swagger:operation PUT /api/v1/admin/settings admin UpdateSettings // -// Update the platform settings singleton in the database. +// Update platform settings // // --- // produces: @@ -76,7 +75,7 @@ func GetSettings(c *gin.Context) { // parameters: // - in: body // name: body -// description: Payload containing settings to update +// description: The settings object with the fields to be updated // required: true // schema: // "$ref": "#/definitions/Platform" @@ -84,12 +83,12 @@ func GetSettings(c *gin.Context) { // - ApiKeyAuth: [] // responses: // '200': -// description: Successfully updated platform settings in the database +// description: Successfully updated platform settings // type: json // schema: // "$ref": "#/definitions/Platform" // '400': -// description: Unable to update settings — bad request +// description: Invalid request payload // schema: // "$ref": "#/definitions/Error" // '401': @@ -97,16 +96,16 @@ func GetSettings(c *gin.Context) { // schema: // "$ref": "#/definitions/Error" // '404': -// description: Unable to retrieve platform settings to update +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to update platform settings in the database +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// UpdateSettings represents the API handler to -// update the settings singleton stored in the database. +// UpdateSettings represents the API handler to update the +// platform settings singleton. func UpdateSettings(c *gin.Context) { // capture middleware values s := sMiddleware.FromContext(c) @@ -201,7 +200,7 @@ func UpdateSettings(c *gin.Context) { // swagger:operation DELETE /api/v1/admin/settings admin RestoreSettings // -// Restore the currently configured settings to the environment defaults. +// Restore platform settings to the environment defaults // // --- // produces: @@ -210,7 +209,7 @@ func UpdateSettings(c *gin.Context) { // - ApiKeyAuth: [] // responses: // '200': -// description: Successfully restored default settings in the database +// description: Successfully restored default platform settings // type: json // schema: // "$ref": "#/definitions/Platform" @@ -219,16 +218,16 @@ func UpdateSettings(c *gin.Context) { // schema: // "$ref": "#/definitions/Error" // '404': -// description: Unable to retrieve settings to restore +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to restore settings in the database +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" // RestoreSettings represents the API handler to -// restore settings stored in the database to the environment defaults. +// restore platform settings to the environment defaults. func RestoreSettings(c *gin.Context) { // capture middleware values s := sMiddleware.FromContext(c) diff --git a/api/admin/step.go b/api/admin/step.go index aeb2e1f4b..b2250b9ec 100644 --- a/api/admin/step.go +++ b/api/admin/step.go @@ -16,7 +16,7 @@ import ( // swagger:operation PUT /api/v1/admin/step admin AdminUpdateStep // -// Update a step in the database +// Update a step // // --- // produces: @@ -24,7 +24,7 @@ import ( // parameters: // - in: body // name: body -// description: Payload containing step to update +// description: The step object with the fields to be updated // required: true // schema: // "$ref": "#/definitions/Step" @@ -32,20 +32,23 @@ import ( // - ApiKeyAuth: [] // responses: // '200': -// description: Successfully updated the step in the database +// description: Successfully updated the step // schema: // "$ref": "#/definitions/Step" -// '404': -// description: Unable to update the step in the database +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '400': +// description: Invalid request payload // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to update the step in the database +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// UpdateStep represents the API handler to -// update any step stored in the database. +// UpdateStep represents the API handler to update a step. func UpdateStep(c *gin.Context) { logrus.Info("Admin: updating step in database") @@ -57,7 +60,7 @@ func UpdateStep(c *gin.Context) { if err != nil { retErr := fmt.Errorf("unable to decode JSON for step %d: %w", input.GetID(), err) - util.HandleError(c, http.StatusNotFound, retErr) + util.HandleError(c, http.StatusBadRequest, retErr) return } diff --git a/api/admin/user.go b/api/admin/user.go index 7e5db6072..c8b0482a3 100644 --- a/api/admin/user.go +++ b/api/admin/user.go @@ -17,7 +17,7 @@ import ( // swagger:operation PUT /api/v1/admin/user admin AdminUpdateUser // -// Update a user in the database +// Update a user // // --- // produces: @@ -25,7 +25,7 @@ import ( // parameters: // - in: body // name: body -// description: Payload containing user to update +// description: The user object with the fields to be updated // required: true // schema: // "$ref": "#/definitions/User" @@ -33,20 +33,23 @@ import ( // - ApiKeyAuth: [] // responses: // '200': -// description: Successfully updated the user in the database +// description: Successfully updated the user // schema: // "$ref": "#/definitions/User" -// '404': -// description: Unable to update the user in the database +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '400': +// description: Invalid request payload // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to update the user in the database +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// UpdateUser represents the API handler to -// update any user stored in the database. +// UpdateUser represents the API handler to update a user. func UpdateUser(c *gin.Context) { logrus.Info("Admin: updating user in database") @@ -60,7 +63,7 @@ func UpdateUser(c *gin.Context) { if err != nil { retErr := fmt.Errorf("unable to decode JSON for user %d: %w", input.GetID(), err) - util.HandleError(c, http.StatusNotFound, retErr) + util.HandleError(c, http.StatusBadRequest, retErr) return } diff --git a/api/admin/worker.go b/api/admin/worker.go index 82d7e9b5c..36be236ac 100644 --- a/api/admin/worker.go +++ b/api/admin/worker.go @@ -40,6 +40,10 @@ import ( // description: Unauthorized // schema: // "$ref": "#/definitions/Error" +// '500': +// description: Unexpected server error +// schema: +// "$ref": "#/definitions/Error" // RegisterToken represents the API handler to // generate a registration token for onboarding a worker. diff --git a/api/auth/get_token.go b/api/auth/get_token.go index 82fe08892..83adef396 100644 --- a/api/auth/get_token.go +++ b/api/auth/get_token.go @@ -26,15 +26,15 @@ import ( // parameters: // - in: query // name: code -// description: the code received after identity confirmation +// description: The code received after identity confirmation // type: string // - in: query // name: state -// description: a random string +// description: A random string // type: string // - in: query // name: redirect_uri -// description: the url where the user will be sent after authorization +// description: The URL where the user will be sent after authorization // type: string // responses: // '200': @@ -47,7 +47,7 @@ import ( // '307': // description: Redirected for authentication // '401': -// description: Unable to authenticate +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '503': diff --git a/api/auth/login.go b/api/auth/login.go index 3c6edcaa4..05b975f8d 100644 --- a/api/auth/login.go +++ b/api/auth/login.go @@ -16,20 +16,20 @@ import ( // swagger:operation GET /login authenticate GetLogin // -// Log into the Vela api +// Log into the Vela API // // --- // parameters: // - in: query // name: type -// description: the login type ("cli" or "web") +// description: The login type ("cli" or "web") // type: string // enum: // - web // - cli // - in: query // name: port -// description: the port number when type=cli +// description: The port number when type=cli // type: integer // responses: // '307': diff --git a/api/auth/logout.go b/api/auth/logout.go index ad21740ed..8c0af25fa 100644 --- a/api/auth/logout.go +++ b/api/auth/logout.go @@ -19,7 +19,7 @@ import ( // swagger:operation GET /logout authenticate GetLogout // -// Log out of the Vela api +// Log out of the Vela API // // --- // produces: @@ -29,6 +29,10 @@ import ( // description: Successfully logged out // schema: // type: string +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" // '503': // description: Logout did not succeed // schema: diff --git a/api/auth/post_token.go b/api/auth/post_token.go index 40ffbf99a..929ef17ca 100644 --- a/api/auth/post_token.go +++ b/api/auth/post_token.go @@ -36,7 +36,7 @@ import ( // schema: // "$ref": "#/definitions/Token" // '401': -// description: Unable to authenticate +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '503': @@ -44,9 +44,8 @@ import ( // schema: // "$ref": "#/definitions/Error" -// PostAuthToken represents the API handler to -// process a user logging in using PAT to Vela from -// the API. +// PostAuthToken represents the API handler to process +// a user logging in using PAT to Vela from the API. func PostAuthToken(c *gin.Context) { // capture middleware values ctx := c.Request.Context() diff --git a/api/auth/redirect.go b/api/auth/redirect.go index dcaba1844..7837ca07e 100644 --- a/api/auth/redirect.go +++ b/api/auth/redirect.go @@ -25,11 +25,11 @@ import ( // parameters: // - in: query // name: code -// description: the code received after identity confirmation +// description: The code received after identity confirmation // type: string // - in: query // name: state -// description: a random string +// description: A random string // type: string // responses: // '307': @@ -48,15 +48,15 @@ import ( // - in: path // name: port // required: true -// description: the port number +// description: The port number // type: integer // - in: query // name: code -// description: the code received after identity confirmation +// description: The code received after identity confirmation // type: string // - in: query // name: state -// description: a random string +// description: A random string // type: string // responses: // '307': diff --git a/api/auth/validate_oauth.go b/api/auth/validate_oauth.go index 399d3e2e2..94af8ca86 100644 --- a/api/auth/validate_oauth.go +++ b/api/auth/validate_oauth.go @@ -14,7 +14,7 @@ import ( // swagger:operation GET /validate-oauth authenticate ValidateOAuthToken // -// Validate that a user oauth token was created by Vela +// Validate that a user OAuth token was created by Vela // // --- // produces: @@ -32,12 +32,12 @@ import ( // schema: // "$ref": "#/definitions/Token" // '401': -// description: Unable to validate +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // ValidateOAuthToken represents the API handler to -// validate that a user oauth token was created by Vela. +// validate that a user OAuth token was created by Vela. func ValidateOAuthToken(c *gin.Context) { // capture middleware values ctx := c.Request.Context() diff --git a/api/badge.go b/api/badge.go index 4f3dfc380..c926c64f3 100644 --- a/api/badge.go +++ b/api/badge.go @@ -17,7 +17,7 @@ import ( // swagger:operation GET /badge/{org}/{repo}/status.svg base GetBadge // -// Get a badge for the repo +// Get a build status badge for a repository // // --- // produces: @@ -25,19 +25,27 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org the repo belongs to +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo to get the badge for +// description: Name of the repository // required: true // type: string // responses: // '200': -// description: Successfully retrieved a status Badge +// description: Successfully retrieved the build status badge // schema: // type: string +// '400': +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Not found +// schema: +// "$ref": "#/definitions/Error" // GetBadge represents the API handler to // return a build status badge. diff --git a/api/build/approve.go b/api/build/approve.go index 16c1fcc65..cc7159d53 100644 --- a/api/build/approve.go +++ b/api/build/approve.go @@ -24,7 +24,7 @@ import ( // swagger:operation POST /api/v1/repos/{org}/{repo}/builds/{build}/approve builds ApproveBuild // -// Sign off on a build to run from an outside contributor +// Approve a build to run // // --- // produces: @@ -32,17 +32,17 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: path // name: build -// description: Build number to retrieve +// description: Build number // required: true // type: integer // security: @@ -52,25 +52,24 @@ import ( // description: Request processed but build was skipped // schema: // type: string -// '201': -// description: Successfully created the build -// type: json -// schema: -// "$ref": "#/definitions/Build" // '400': -// description: Unable to create the build +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '404': -// description: Unable to create the build +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to create the build +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// ApproveBuild represents the API handler to approve a build to run in the configured backend. +// ApproveBuild represents the API handler to approve a build to run. func ApproveBuild(c *gin.Context) { // capture middleware values b := build.Retrieve(c) diff --git a/api/build/cancel.go b/api/build/cancel.go index afad5d0e0..e4ee0b84e 100644 --- a/api/build/cancel.go +++ b/api/build/cancel.go @@ -26,25 +26,25 @@ import ( // swagger:operation DELETE /api/v1/repos/{org}/{repo}/builds/{build}/cancel builds CancelBuild // -// Cancel a running build +// Cancel a build // // --- // produces: // - application/json // parameters: // - in: path -// name: repo -// description: Name of the repo +// name: org +// description: Name of the organization // required: true // type: string // - in: path -// name: org -// description: Name of the org +// name: repo +// description: Name of the repository // required: true // type: string // - in: path // name: build -// description: Build number to cancel +// description: Build number // required: true // type: integer // security: @@ -53,21 +53,25 @@ import ( // '200': // description: Successfully canceled the build // schema: -// type: string +// "$ref": "#/definitions/Build" // '400': -// description: Unable to cancel build +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '404': -// description: Unable to cancel build +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to cancel build +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// CancelBuild represents the API handler to cancel a running build. +// CancelBuild represents the API handler to cancel a build. // //nolint:funlen // ignore statement count func CancelBuild(c *gin.Context) { diff --git a/api/build/clean.go b/api/build/clean.go index 235efc989..8473c25e1 100644 --- a/api/build/clean.go +++ b/api/build/clean.go @@ -17,8 +17,7 @@ import ( // cleanBuild is a helper function to kill the build // without execution. This will kill all resources, -// like steps and services, for the build in the -// configured backend. +// like steps and services, for the build. func CleanBuild(ctx context.Context, database database.Interface, b *types.Build, services []*library.Service, steps []*library.Step, e error) { // update fields in build object b.SetError(fmt.Sprintf("unable to publish to queue: %s", e.Error())) diff --git a/api/build/create.go b/api/build/create.go index f5782d331..e3745cfeb 100644 --- a/api/build/create.go +++ b/api/build/create.go @@ -23,7 +23,7 @@ import ( // swagger:operation POST /api/v1/repos/{org}/{repo}/builds builds CreateBuild // -// Create a build in the configured backend +// Create a build // // --- // produces: @@ -31,17 +31,17 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: body // name: body -// description: Payload containing the build to create +// description: Build object to create // required: true // schema: // "$ref": "#/definitions/Build" @@ -58,15 +58,15 @@ import ( // schema: // "$ref": "#/definitions/Build" // '400': -// description: Malformed request payload or improper pipeline configuration +// description: Invalid request payload or path // schema: // "$ref": "#/definitions/Error" // '401': -// description: Repository owner does not have proper access +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '404': -// description: Unable to find resources for build +// description: Not found // schema: // "$ref": "#/definitions/Error" // '429': @@ -74,11 +74,11 @@ import ( // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to receive the request or internal error while processing +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// CreateBuild represents the API handler to create a build in the configured backend. +// CreateBuild represents the API handler to create a build. func CreateBuild(c *gin.Context) { // capture middleware values m := c.MustGet("metadata").(*internal.Metadata) diff --git a/api/build/delete.go b/api/build/delete.go index 3da622da0..e4330ecc2 100644 --- a/api/build/delete.go +++ b/api/build/delete.go @@ -19,7 +19,7 @@ import ( // swagger:operation DELETE /api/v1/repos/{org}/{repo}/builds/{build} builds DeleteBuild // -// Delete a build in the configured backend +// Delete a build // // --- // produces: @@ -27,17 +27,17 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: path // name: build -// description: Build number to delete +// description: Build number // required: true // type: integer // security: @@ -48,16 +48,24 @@ import ( // schema: // type: string // '400': -// description: Unable to delete the build +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to delete the build +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" // DeleteBuild represents the API handler to remove -// a build for a repo from the configured backend. +// a build for a repo. func DeleteBuild(c *gin.Context) { // capture middleware values b := build.Retrieve(c) diff --git a/api/build/executable.go b/api/build/executable.go index 324984b10..a5d250cbc 100644 --- a/api/build/executable.go +++ b/api/build/executable.go @@ -24,7 +24,7 @@ import ( // swagger:operation GET /api/v1/repos/{org}/{repo}/builds/{build}/executable builds GetBuildExecutable // -// Get a build executable in the configured backend +// Get a build executable // // --- // produces: @@ -32,17 +32,17 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: path // name: build -// description: Build number to retrieve +// description: Build number // required: true // type: integer // security: @@ -52,22 +52,26 @@ import ( // description: Successfully retrieved the build executable // type: json // schema: -// "$ref": "#/definitions/Build" +// "$ref": "#/definitions/BuildExecutable" // '400': -// description: Bad request +// description: Invalid request payload or path // schema: // "$ref": "#/definitions/Error" // '401': // description: Unauthorized // schema: // "$ref": "#/definitions/Error" +// '404': +// description: Not found +// schema: +// "$ref": "#/definitions/Error" // '500': -// description: Could not retrieve build executable +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// GetBuildExecutable represents the API handler to capture -// a build executable for a repo from the configured backend. +// GetBuildExecutable represents the API handler to get +// a build executable for a repository. func GetBuildExecutable(c *gin.Context) { // capture middleware values b := build.Retrieve(c) diff --git a/api/build/get.go b/api/build/get.go index afa0994d6..df8c87bfd 100644 --- a/api/build/get.go +++ b/api/build/get.go @@ -16,7 +16,7 @@ import ( // swagger:operation GET /api/v1/repos/{org}/{repo}/builds/{build} builds GetBuild // -// Get a build in the configured backend +// Get a build // // --- // produces: @@ -24,17 +24,17 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: path // name: build -// description: Build number to retrieve +// description: Build number // required: true // type: integer // security: @@ -45,9 +45,21 @@ import ( // type: json // schema: // "$ref": "#/definitions/Build" +// '400': +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Not found +// schema: +// "$ref": "#/definitions/Error" -// GetBuild represents the API handler to capture -// a build for a repo from the configured backend. +// GetBuild represents the API handler to get +// a build for a repository. func GetBuild(c *gin.Context) { // capture middleware values b := build.Retrieve(c) diff --git a/api/build/get_id.go b/api/build/get_id.go index d0a72191d..f27fde5f2 100644 --- a/api/build/get_id.go +++ b/api/build/get_id.go @@ -18,7 +18,7 @@ import ( // swagger:operation GET /api/v1/search/builds/{id} builds GetBuildByID // -// Get a single build by its id in the configured backend +// Get a build by id // // --- // produces: @@ -26,7 +26,7 @@ import ( // parameters: // - in: path // name: id -// description: build id +// description: Build ID // required: true // type: number // security: @@ -37,16 +37,20 @@ import ( // schema: // "$ref": "#/definitions/Build" // '400': -// description: Unable to retrieve the build +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to retrieve the build +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// GetBuildByID represents the API handler to capture a -// build by its id from the configured backend. +// GetBuildByID represents the API handler to get a +// build by its id. func GetBuildByID(c *gin.Context) { // Capture user from middleware u := user.Retrieve(c) @@ -54,7 +58,6 @@ func GetBuildByID(c *gin.Context) { // Parse build ID from path id, err := strconv.ParseInt(c.Param("id"), 10, 64) - if err != nil { retErr := fmt.Errorf("unable to parse build id: %w", err) diff --git a/api/build/graph.go b/api/build/graph.go index 454cdd27a..e7207625c 100644 --- a/api/build/graph.go +++ b/api/build/graph.go @@ -91,7 +91,7 @@ const ( // swagger:operation GET /api/v1/repos/{org}/{repo}/builds/{build}/graph builds GetBuildGraph // -// Get directed a-cyclical graph for a build in the configured backend +// Get directed a-cyclical graph for a build // // --- // produces: @@ -99,12 +99,12 @@ const ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: path @@ -120,21 +120,25 @@ const ( // type: json // schema: // "$ref": "#/definitions/Graph" +// '400': +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" // '401': -// description: Unable to retrieve graph for the build — unauthorized +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '404': -// description: Unable to retrieve graph for the build — not found +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to retrieve graph for the build +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// GetBuildGraph represents the API handler to capture a -// directed a-cyclical graph for a build from the configured backend. +// GetBuildGraph represents the API handler to get a +// directed a-cyclical graph for a build. // //nolint:funlen,goconst,gocyclo // ignore function length and constants func GetBuildGraph(c *gin.Context) { diff --git a/api/build/id_request_token.go b/api/build/id_request_token.go index f5e3c9f93..1af34ce59 100644 --- a/api/build/id_request_token.go +++ b/api/build/id_request_token.go @@ -22,20 +22,20 @@ import ( // swagger:operation GET /api/v1/repos/{org}/{repo}/builds/{build}/id_request_token builds GetIDRequestToken // -// Get a Vela OIDC request token associated with a build +// Get a Vela OIDC request token for a build // // --- // produces: // - application/json // parameters: // - in: path -// name: repo -// description: Name of the repo +// name: org +// description: Name of the organization // required: true // type: string // - in: path -// name: org -// description: Name of the org +// name: repo +// description: Name of the repository // required: true // type: string // - in: path @@ -63,19 +63,19 @@ import ( // schema: // "$ref": "#/definitions/Token" // '400': -// description: Bad request +// description: Invalid request payload or path // schema: // "$ref": "#/definitions/Error" // '401': -// description: Unauthorized request +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '404': -// description: Unable to find build +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to generate ID request token +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" diff --git a/api/build/id_token.go b/api/build/id_token.go index a2b7fdab7..54744e983 100644 --- a/api/build/id_token.go +++ b/api/build/id_token.go @@ -20,20 +20,20 @@ import ( // swagger:operation GET /api/v1/repos/{org}/{repo}/builds/{build}/id_token builds GetIDToken // -// Get a Vela OIDC token associated with a build +// Get a Vela OIDC token for a build // // --- // produces: // - application/json // parameters: // - in: path -// name: repo -// description: Name of the repo +// name: org +// description: Name of the organization // required: true // type: string // - in: path -// name: org -// description: Name of the org +// name: repo +// description: Name of the repository // required: true // type: string // - in: path @@ -56,19 +56,19 @@ import ( // schema: // "$ref": "#/definitions/Token" // '400': -// description: Bad request +// description: Invalid request payload or path // schema: // "$ref": "#/definitions/Error" // '401': -// description: Unauthorized request +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '404': -// description: Unable to find build +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to generate id token +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" diff --git a/api/build/list_org.go b/api/build/list_org.go index a8e491a47..ff516c39c 100644 --- a/api/build/list_org.go +++ b/api/build/list_org.go @@ -22,7 +22,7 @@ import ( // swagger:operation GET /api/v1/repos/{org}/builds builds ListBuildsForOrg // -// Get a list of builds by org in the configured backend +// Get all builds for an organization // // --- // produces: @@ -30,7 +30,7 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: query @@ -85,19 +85,23 @@ import ( // description: Total number of results // type: integer // Link: -// description: see https://tools.ietf.org/html/rfc5988 +// description: See https://tools.ietf.org/html/rfc5988 // type: string // '400': -// description: Unable to retrieve the list of builds +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to retrieve the list of builds +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// ListBuildsForOrg represents the API handler to capture a -// list of builds associated with an org from the configured backend. +// ListBuildsForOrg represents the API handler to get a +// list of builds associated with an organization. func ListBuildsForOrg(c *gin.Context) { // variables that will hold the build list, build list filters and total count var ( @@ -201,7 +205,6 @@ func ListBuildsForOrg(c *gin.Context) { // send API call to capture the list of builds for the org (and event type if passed in) b, t, err = database.FromContext(c).ListBuildsForOrg(ctx, o, filters, page, perPage) - if err != nil { retErr := fmt.Errorf("unable to list builds for org %s: %w", o, err) diff --git a/api/build/list_repo.go b/api/build/list_repo.go index 9c3fca345..f631e68ef 100644 --- a/api/build/list_repo.go +++ b/api/build/list_repo.go @@ -23,7 +23,7 @@ import ( // swagger:operation GET /api/v1/repos/{org}/{repo}/builds builds ListBuildsForRepo // -// Get builds from the configured backend +// Get all builds for a repository // // --- // produces: @@ -31,12 +31,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: query @@ -83,12 +83,12 @@ import ( // default: 10 // - in: query // name: before -// description: filter builds created before a certain time +// description: Filter builds created before a certain time // type: integer // default: 1 // - in: query // name: after -// description: filter builds created after a certain time +// description: Filter builds created after a certain time // type: integer // default: 0 // security: @@ -105,19 +105,27 @@ import ( // description: Total number of results // type: integer // Link: -// description: see https://tools.ietf.org/html/rfc5988 +// description: See https://tools.ietf.org/html/rfc5988 // type: string // '400': -// description: Unable to retrieve the list of builds +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to retrieve the list of builds +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// ListBuildsForRepo represents the API handler to capture a -// list of builds for a repo from the configured backend. +// ListBuildsForRepo represents the API handler to get a +// list of builds for a repository. func ListBuildsForRepo(c *gin.Context) { // variables that will hold the build list, build list filters and total count var ( diff --git a/api/build/plan.go b/api/build/plan.go index 49e700d52..f7c23b971 100644 --- a/api/build/plan.go +++ b/api/build/plan.go @@ -17,7 +17,7 @@ import ( // PlanBuild is a helper function to plan the build for // execution. This creates all resources, like steps -// and services, for the build in the configured backend. +// and services, for the build. // TODO: // - return build and error. func PlanBuild(ctx context.Context, database database.Interface, scm scm.Service, p *pipeline.Build, b *types.Build, r *types.Repo) error { diff --git a/api/build/restart.go b/api/build/restart.go index f8798fbb6..4cf0a21e0 100644 --- a/api/build/restart.go +++ b/api/build/restart.go @@ -26,7 +26,7 @@ import ( // swagger:operation POST /api/v1/repos/{org}/{repo}/builds/{build} builds RestartBuild // -// Restart a build in the configured backend +// Restart a build // // --- // produces: @@ -34,17 +34,17 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: path // name: build -// description: Build number to restart +// description: Build number // required: true // type: integer // security: @@ -60,15 +60,15 @@ import ( // schema: // "$ref": "#/definitions/Build" // '400': -// description: Malformed request payload or improper pipeline configuration +// description: Invalid request payload or path // schema: // "$ref": "#/definitions/Error" // '401': -// description: Repository owner does not have proper access +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '404': -// description: Unable to find resources for build +// description: Not found // schema: // "$ref": "#/definitions/Error" // '429': @@ -76,11 +76,11 @@ import ( // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to receive the request or internal error while processing +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// RestartBuild represents the API handler to restart an existing build in the configured backend. +// RestartBuild represents the API handler to restart an existing build. func RestartBuild(c *gin.Context) { // capture middleware values m := c.MustGet("metadata").(*internal.Metadata) diff --git a/api/build/token.go b/api/build/token.go index fd0664684..d58a60bc5 100644 --- a/api/build/token.go +++ b/api/build/token.go @@ -30,13 +30,13 @@ import ( // - application/json // parameters: // - in: path -// name: repo -// description: Name of the repo +// name: org +// description: Name of the organization // required: true // type: string // - in: path -// name: org -// description: Name of the org +// name: repo +// description: Name of the repository // required: true // type: string // - in: path @@ -52,7 +52,11 @@ import ( // schema: // "$ref": "#/definitions/Token" // '400': -// description: Bad request +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '409': @@ -60,7 +64,7 @@ import ( // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to generate build token +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" diff --git a/api/build/update.go b/api/build/update.go index e1b64b423..e5e3385a0 100644 --- a/api/build/update.go +++ b/api/build/update.go @@ -23,7 +23,7 @@ import ( // swagger:operation PUT /api/v1/repos/{org}/{repo}/builds/{build} builds UpdateBuild // -// Updates a build in the configured backend +// Update a build // // --- // produces: @@ -31,22 +31,22 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: path // name: build -// description: Build number to update +// description: Build number // required: true // type: integer // - in: body // name: body -// description: Payload containing the build to update +// description: The build object with the fields to be updated // required: true // schema: // "$ref": "#/definitions/Build" @@ -57,17 +57,25 @@ import ( // description: Successfully updated the build // schema: // "$ref": "#/definitions/Build" +// '400': +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" // '404': -// description: Unable to update the build +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to update the build +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" // UpdateBuild represents the API handler to update -// a build for a repo in the configured backend. +// a build for a repo. func UpdateBuild(c *gin.Context) { // capture middleware values cl := claims.Retrieve(c) diff --git a/api/dashboard/create.go b/api/dashboard/create.go index f14a06fe1..38cb95115 100644 --- a/api/dashboard/create.go +++ b/api/dashboard/create.go @@ -20,7 +20,7 @@ import ( // swagger:operation POST /api/v1/dashboards dashboards CreateDashboard // -// Create a dashboard in the configured backend +// Create a dashboard // // --- // produces: @@ -28,7 +28,7 @@ import ( // parameters: // - in: body // name: body -// description: Payload containing the dashboard to create +// description: Dashboard object to create // required: true // schema: // "$ref": "#/definitions/Dashboard" @@ -40,20 +40,20 @@ import ( // schema: // "$ref": "#/definitions/Dashboard" // '400': -// description: Bad request when creating dashboard +// description: Invalid request payload // schema: // "$ref": "#/definitions/Error" // '401': -// description: Unauthorized to create dashboard +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '500': -// description: Server error when creating dashboard +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" // CreateDashboard represents the API handler to -// create a dashboard in the configured backend. +// create a dashboard. func CreateDashboard(c *gin.Context) { // capture middleware values u := user.Retrieve(c) diff --git a/api/dashboard/delete.go b/api/dashboard/delete.go index a2798c940..bf921abe1 100644 --- a/api/dashboard/delete.go +++ b/api/dashboard/delete.go @@ -18,7 +18,7 @@ import ( // swagger:operation DELETE /api/v1/dashboards/{dashboard} dashboards DeleteDashboard // -// Delete a dashboard in the configured backend +// Delete a dashboard // // --- // produces: @@ -26,7 +26,7 @@ import ( // parameters: // - in: path // name: dashboard -// description: id of the dashboard +// description: Dashboard ID // required: true // type: string // security: @@ -36,21 +36,24 @@ import ( // description: Successfully deleted dashboard // schema: // type: string +// '400': +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" // '401': -// description: Unauthorized to delete dashboard +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '404': -// description: Unable to find dashboard +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Server error when deleting dashboard +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// DeleteDashboard represents the API handler to remove -// a dashboard from the configured backend. +// DeleteDashboard represents the API handler to remove a dashboard. func DeleteDashboard(c *gin.Context) { // capture middleware values d := dashboard.Retrieve(c) diff --git a/api/dashboard/doc.go b/api/dashboard/doc.go new file mode 100644 index 000000000..eb9f60c2d --- /dev/null +++ b/api/dashboard/doc.go @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: Apache-2.0 + +// Package dashboard provides the dashboard handlers for the Vela API. +// +// Usage: +// +// import "github.com/go-vela/server/api/dashboard" +package dashboard diff --git a/api/dashboard/get.go b/api/dashboard/get.go index 3535cb8b4..4cc34e93d 100644 --- a/api/dashboard/get.go +++ b/api/dashboard/get.go @@ -19,7 +19,7 @@ import ( // swagger:operation GET /api/v1/dashboards/{dashboard} dashboards GetDashboard // -// Get a dashboard in the configured backend +// Get a dashboard // // --- // produces: @@ -38,21 +38,25 @@ import ( // type: json // schema: // "$ref": "#/definitions/Dashboard" +// '400': +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" // '401': -// description: Unauthorized to retrieve dashboard +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '404': -// description: Unable to find dashboard +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Server error when retrieving dashboard +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// GetDashboard represents the API handler to capture -// a dashboard for a repo from the configured backend. +// GetDashboard represents the API handler to get +// a dashboard for a repository. func GetDashboard(c *gin.Context) { // capture middleware values d := dashboard.Retrieve(c) @@ -83,9 +87,9 @@ func GetDashboard(c *gin.Context) { c.JSON(http.StatusOK, dashboard) } -// buildRepoPartials is a helper function which takes the dashboard repo list and builds -// a list of RepoPartials with information about the associated repository and its latest -// five builds. +// buildRepoPartials is a helper function which takes the dashboard repo list +// and builds a list of RepoPartials with information about the associated +// repository and its latest five builds. func buildRepoPartials(c context.Context, repos []*types.DashboardRepo) ([]types.RepoPartial, error) { var result []types.RepoPartial diff --git a/api/dashboard/list_user.go b/api/dashboard/list_user.go index 656704358..c43a89f05 100644 --- a/api/dashboard/list_user.go +++ b/api/dashboard/list_user.go @@ -19,7 +19,7 @@ import ( // swagger:operation GET /api/v1/user/dashboards dashboards ListUserDashboards // -// Get all dashboards for the current user in the configured backend +// Get all dashboards for the current user // // --- // produces: @@ -33,20 +33,20 @@ import ( // schema: // "$ref": "#/definitions/Dashboard" // '400': -// description: Bad request to retrieve user dashboards +// description: Invalid request payload // schema: // "$ref": "#/definitions/Error" // '401': -// description: Unauthorized to retrieve user dashboards +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '500': -// description: Server error when retrieving user dashboards +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" // ListUserDashboards represents the API handler to capture a list -// of dashboards for a user from the configured backend. +// of dashboards for a user. func ListUserDashboards(c *gin.Context) { // capture middleware values u := user.Retrieve(c) diff --git a/api/dashboard/update.go b/api/dashboard/update.go index 7958ef72d..db11d4355 100644 --- a/api/dashboard/update.go +++ b/api/dashboard/update.go @@ -18,7 +18,7 @@ import ( // swagger:operation PUT /api/v1/dashboards/{dashboard} dashboards UpdateDashboard // -// Update a dashboard for the configured backend +// Update a dashboard // // --- // produces: @@ -31,7 +31,7 @@ import ( // type: string // - name: body // in: body -// description: Payload containing the dashboard to update +// description: The dashboard object with the fields to be updated // required: true // schema: // $ref: '#/definitions/Dashboard' @@ -43,24 +43,23 @@ import ( // schema: // "$ref": "#/definitions/Dashboard" // '400': -// description: Bad request when updating dashboard +// description: Invalid request payload or path // schema: // "$ref": "#/definitions/Error" // '401': -// description: Unauthorized to update dashboard +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '404': -// description: Unable to find dashboard +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Error while updating dashboard +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// UpdateDashboard represents the API handler to update -// a dashboard in the configured backend. +// UpdateDashboard represents the API handler to update a dashboard. func UpdateDashboard(c *gin.Context) { // capture middleware values d := dashboard.Retrieve(c) diff --git a/api/deployment/create.go b/api/deployment/create.go index b0fb02156..b596f75be 100644 --- a/api/deployment/create.go +++ b/api/deployment/create.go @@ -21,7 +21,7 @@ import ( // swagger:operation POST /api/v1/deployments/{org}/{repo} deployments CreateDeployment // -// Create a deployment for the configured backend +// Create a deployment // // --- // produces: @@ -29,12 +29,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // security: @@ -45,16 +45,24 @@ import ( // schema: // "$ref": "#/definitions/Deployment" // '400': -// description: Unable to create the deployment +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to create the deployment +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" // CreateDeployment represents the API handler to -// create a deployment in the configured backend. +// create a deployment. func CreateDeployment(c *gin.Context) { // capture middleware values o := org.Retrieve(c) diff --git a/api/deployment/get.go b/api/deployment/get.go index c881bc800..8f890ab77 100644 --- a/api/deployment/get.go +++ b/api/deployment/get.go @@ -20,7 +20,7 @@ import ( // swagger:operation GET /api/v1/deployments/{org}/{repo}/{deployment} deployments GetDeployment // -// Get a deployment from the configured backend +// Get a deployment // // --- // produces: @@ -28,12 +28,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: path @@ -49,16 +49,23 @@ import ( // schema: // "$ref": "#/definitions/Deployment" // '400': -// description: Unable to retrieve the deployment +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to retrieve the deployment +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// GetDeployment represents the API handler to -// capture a deployment from the configured backend. +// GetDeployment represents the API handler to get a deployment. func GetDeployment(c *gin.Context) { // capture middleware values o := org.Retrieve(c) diff --git a/api/deployment/list.go b/api/deployment/list.go index 55667fdac..b07e3ba0a 100644 --- a/api/deployment/list.go +++ b/api/deployment/list.go @@ -20,7 +20,7 @@ import ( // swagger:operation GET /api/v1/deployments/{org}/{repo} deployments ListDeployments // -// Get a list of deployments for the configured backend +// Get all deployments for a repository // // --- // produces: @@ -28,12 +28,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: query @@ -61,19 +61,26 @@ import ( // description: Total number of results // type: integer // Link: -// description: see https://tools.ietf.org/html/rfc5988 +// description: See https://tools.ietf.org/html/rfc5988 // type: string // '400': -// description: Unable to retrieve the list of deployments +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to retrieve the list of deployments +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// ListDeployments represents the API handler to capture -// a list of deployments from the configured backend. +// ListDeployments represents the API handler to get a list of deployments. func ListDeployments(c *gin.Context) { // capture middleware values o := org.Retrieve(c) diff --git a/api/health.go b/api/health.go index 71c8eacf4..12497408d 100644 --- a/api/health.go +++ b/api/health.go @@ -10,7 +10,7 @@ import ( // swagger:operation GET /health base Health // -// Check if the Vela API is available +// Check the Vela API health // // --- // produces: diff --git a/api/hook/create.go b/api/hook/create.go index a039371c5..bb8fbbaa0 100644 --- a/api/hook/create.go +++ b/api/hook/create.go @@ -20,28 +20,28 @@ import ( // swagger:operation POST /api/v1/hooks/{org}/{repo} webhook CreateHook // -// Create a webhook for the configured backend +// Create a hook // // --- // produces: // - application/json // parameters: -// - in: body -// name: body -// description: Webhook payload that we expect from the user or VCS -// required: true -// schema: -// "$ref": "#/definitions/Webhook" // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string +// - in: body +// name: body +// description: Hook object from the user or VCS to create +// required: true +// schema: +// "$ref": "#/definitions/Webhook" // security: // - ApiKeyAuth: [] // responses: @@ -50,16 +50,23 @@ import ( // schema: // "$ref": "#/definitions/Webhook" // '400': -// description: The webhook was unable to be created +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: The webhook was unable to be created +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// CreateHook represents the API handler to create -// a webhook in the configured backend. +// CreateHook represents the API handler to create a webhook. func CreateHook(c *gin.Context) { // capture middleware values o := org.Retrieve(c) diff --git a/api/hook/delete.go b/api/hook/delete.go index e31909a9f..f15f122df 100644 --- a/api/hook/delete.go +++ b/api/hook/delete.go @@ -19,7 +19,7 @@ import ( // swagger:operation DELETE /api/v1/hooks/{org}/{repo}/{hook} webhook DeleteHook // -// Delete a webhook for the configured backend +// Delete a hook // // --- // produces: @@ -27,12 +27,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: path @@ -48,20 +48,23 @@ import ( // schema: // type: string // '400': -// description: The webhook was unable to be deleted +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '404': -// description: The webhook was unable to be deleted +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: The webhook was unable to be deleted +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// DeleteHook represents the API handler to remove -// a webhook from the configured backend. +// DeleteHook represents the API handler to remove a webhook. func DeleteHook(c *gin.Context) { // capture middleware values o := org.Retrieve(c) diff --git a/api/hook/doc.go b/api/hook/doc.go new file mode 100644 index 000000000..828826073 --- /dev/null +++ b/api/hook/doc.go @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: Apache-2.0 + +// Package hook provides the hook handlers for the Vela API. +// +// Usage: +// +// import "github.com/go-vela/server/api/hook" +package hook diff --git a/api/hook/get.go b/api/hook/get.go index 849aa60f7..792a76a30 100644 --- a/api/hook/get.go +++ b/api/hook/get.go @@ -19,7 +19,7 @@ import ( // swagger:operation GET /api/v1/hooks/{org}/{repo}/{hook} webhook GetHook // -// Retrieve a webhook for the configured backend +// Get a hook // // --- // produces: @@ -27,12 +27,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: path @@ -48,16 +48,23 @@ import ( // schema: // "$ref": "#/definitions/Webhook" // '400': -// description: Unable to retrieve the webhook +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to retrieve the webhook +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// GetHook represents the API handler to capture a -// webhook from the configured backend. +// GetHook represents the API handler to get a hook. func GetHook(c *gin.Context) { // capture middleware values o := org.Retrieve(c) diff --git a/api/hook/list.go b/api/hook/list.go index e7235dba2..3f1b47851 100644 --- a/api/hook/list.go +++ b/api/hook/list.go @@ -20,7 +20,7 @@ import ( // swagger:operation GET /api/v1/hooks/{org}/{repo} webhook ListHooks // -// Retrieve the webhooks for the configured backend +// Get all hooks for a repository // // --- // produces: @@ -28,12 +28,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: query @@ -61,19 +61,27 @@ import ( // description: Total number of results // type: integer // Link: -// description: see https://tools.ietf.org/html/rfc5988 +// description: See https://tools.ietf.org/html/rfc5988 // type: string // '400': -// description: Unable to retrieve webhooks +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to retrieve webhooks +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// ListHooks represents the API handler to capture a list -// of webhooks from the configured backend. +// ListHooks represents the API handler to get all hooks +// for a repository. func ListHooks(c *gin.Context) { // capture middleware values o := org.Retrieve(c) diff --git a/api/hook/redeliver.go b/api/hook/redeliver.go index a860c1718..f95c598b5 100644 --- a/api/hook/redeliver.go +++ b/api/hook/redeliver.go @@ -20,7 +20,7 @@ import ( // swagger:operation POST /api/v1/hooks/{org}/{repo}/{hook}/redeliver webhook RedeliverHook // -// Redeliver a webhook from the SCM +// Redeliver a hook // // --- // produces: @@ -28,12 +28,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: path @@ -47,17 +47,21 @@ import ( // '200': // description: Successfully redelivered the webhook // schema: -// "$ref": "#/definitions/Webhook" +// type: string // '400': -// description: The webhook was unable to be redelivered +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '404': -// description: The webhook was unable to be redelivered +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: The webhook was unable to be redelivered +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" diff --git a/api/hook/update.go b/api/hook/update.go index 8d662b31c..35b2617a2 100644 --- a/api/hook/update.go +++ b/api/hook/update.go @@ -20,7 +20,7 @@ import ( // swagger:operation PUT /api/v1/hooks/{org}/{repo}/{hook} webhook UpdateHook // -// Update a webhook for the configured backend +// Update a hook // // --- // produces: @@ -28,12 +28,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: path @@ -55,20 +55,23 @@ import ( // schema: // "$ref": "#/definitions/Webhook" // '400': -// description: The webhook was unable to be updated +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '404': -// description: The webhook was unable to be updated +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: The webhook was unable to be updated +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// UpdateHook represents the API handler to update -// a webhook in the configured backend. +// UpdateHook represents the API handler to update a hook. func UpdateHook(c *gin.Context) { // capture middleware values o := org.Retrieve(c) diff --git a/api/jwks.go b/api/jwks.go index 3d124f77d..4b0be0153 100644 --- a/api/jwks.go +++ b/api/jwks.go @@ -28,7 +28,7 @@ import ( // schema: // "$ref": "#/definitions/JWKSet" // '500': -// description: Unable to get the Vela JWKS +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" diff --git a/api/log/create_service.go b/api/log/create_service.go index 442714c27..275b86b64 100644 --- a/api/log/create_service.go +++ b/api/log/create_service.go @@ -31,12 +31,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: path @@ -61,16 +61,24 @@ import ( // '201': // description: Successfully created the service logs // '400': -// description: Unable to create the service logs +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to create the service logs +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" // CreateServiceLog represents the API handler to create -// the logs for a service in the configured backend. +// the logs for a service. func CreateServiceLog(c *gin.Context) { // capture middleware values b := build.Retrieve(c) diff --git a/api/log/create_step.go b/api/log/create_step.go index c5ed5f49f..42465299f 100644 --- a/api/log/create_step.go +++ b/api/log/create_step.go @@ -31,12 +31,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: path @@ -61,16 +61,24 @@ import ( // '201': // description: Successfully created the logs for step // '400': -// description: Unable to create the logs for a step +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to create the logs for a step +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" // CreateStepLog represents the API handler to create -// the logs for a step in the configured backend. +// the logs for a step. func CreateStepLog(c *gin.Context) { // capture middleware values b := build.Retrieve(c) diff --git a/api/log/delete_service.go b/api/log/delete_service.go index 9893d60d3..6c8b63c42 100644 --- a/api/log/delete_service.go +++ b/api/log/delete_service.go @@ -29,12 +29,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: path @@ -54,13 +54,25 @@ import ( // description: Successfully deleted the service logs // schema: // type: string +// '400': +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Not found +// schema: +// "$ref": "#/definitions/Error" // '500': -// description: Unable to delete the service logs +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" // DeleteServiceLog represents the API handler to remove -// the logs for a service from the configured backend. +// the logs for a service. func DeleteServiceLog(c *gin.Context) { // capture middleware values b := build.Retrieve(c) diff --git a/api/log/delete_step.go b/api/log/delete_step.go index ebf505f1f..36ebfacff 100644 --- a/api/log/delete_step.go +++ b/api/log/delete_step.go @@ -29,12 +29,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: path @@ -54,13 +54,25 @@ import ( // description: Successfully deleted the logs for the step // schema: // type: string +// '400': +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Not found +// schema: +// "$ref": "#/definitions/Error" // '500': -// description: Unable to delete the logs for the step +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" // DeleteStepLog represents the API handler to remove -// the logs for a step from the configured backend. +// the logs for a step. func DeleteStepLog(c *gin.Context) { // capture middleware values b := build.Retrieve(c) diff --git a/api/log/get_service.go b/api/log/get_service.go index 193850e90..c7c72fc73 100644 --- a/api/log/get_service.go +++ b/api/log/get_service.go @@ -21,7 +21,7 @@ import ( // swagger:operation GET /api/v1/repos/{org}/{repo}/builds/{build}/services/{service}/logs services GetServiceLog // -// Retrieve the logs for a service +// Get the logs for a service // // --- // produces: @@ -29,12 +29,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: path @@ -54,13 +54,24 @@ import ( // description: Successfully retrieved the service logs // schema: // "$ref": "#/definitions/Log" +// '400': +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Not found +// schema: +// "$ref": "#/definitions/Error" // '500': -// description: Unable to retrieve the service logs +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// GetServiceLog represents the API handler to capture -// the logs for a service from the configured backend. +// GetServiceLog represents the API handler to get the logs for a service. func GetServiceLog(c *gin.Context) { // capture middleware values b := build.Retrieve(c) diff --git a/api/log/get_step.go b/api/log/get_step.go index 2e8b524be..8e0a30223 100644 --- a/api/log/get_step.go +++ b/api/log/get_step.go @@ -21,7 +21,7 @@ import ( // swagger:operation GET /api/v1/repos/{org}/{repo}/builds/{build}/steps/{step}/logs steps GetStepLog // -// Retrieve the logs for a step +// Get the logs for a step // // --- // produces: @@ -29,12 +29,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: path @@ -55,13 +55,24 @@ import ( // type: json // schema: // "$ref": "#/definitions/Log" +// '400': +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Not found +// schema: +// "$ref": "#/definitions/Error" // '500': -// description: Unable to retrieve the logs for a step +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// GetStepLog represents the API handler to capture -// the logs for a step from the configured backend. +// GetStepLog represents the API handler to get the logs for a step. func GetStepLog(c *gin.Context) { // capture middleware values b := build.Retrieve(c) diff --git a/api/log/list_build.go b/api/log/list_build.go index 5fc996ef0..a33fd2c32 100644 --- a/api/log/list_build.go +++ b/api/log/list_build.go @@ -21,7 +21,7 @@ import ( // swagger:operation GET /api/v1/repos/{org}/{repo}/builds/{build}/logs builds ListLogsForBuild // -// List logs for a build in the configured backend +// Get all logs for a build // // --- // produces: @@ -29,12 +29,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: path @@ -62,13 +62,24 @@ import ( // type: array // items: // "$ref": "#/definitions/Log" +// '400': +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Not found +// schema: +// "$ref": "#/definitions/Error" // '500': -// description: Unable to retrieve logs for the build +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// ListLogsForBuild represents the API handler to capture a -// list of logs for a build from the configured backend. +// ListLogsForBuild represents the API handler to get a list of logs for a build. func ListLogsForBuild(c *gin.Context) { // capture middleware values b := build.Retrieve(c) diff --git a/api/log/update_service.go b/api/log/update_service.go index 6d36b9bea..54e1fade8 100644 --- a/api/log/update_service.go +++ b/api/log/update_service.go @@ -22,7 +22,7 @@ import ( // swagger:operation PUT /api/v1/repos/{org}/{repo}/builds/{build}/services/{service}/logs services UpdateServiceLog // -// Update the logs for a service +// Update service logs for a build // // --- // deprecated: true @@ -31,12 +31,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: path @@ -51,7 +51,7 @@ import ( // type: integer // - in: body // name: body -// description: Payload containing the log to update +// description: The log object with the fields to be updated // required: true // schema: // "$ref": "#/definitions/Log" @@ -60,19 +60,25 @@ import ( // responses: // '200': // description: Successfully updated the service logs -// schema: -// "$ref": "#/definitions/Log" // '400': -// description: Unable to updated the service logs +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to updates the service logs +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" // UpdateServiceLog represents the API handler to update -// the logs for a service in the configured backend. +// the logs for a service. func UpdateServiceLog(c *gin.Context) { // capture middleware values b := build.Retrieve(c) diff --git a/api/log/update_step.go b/api/log/update_step.go index c34596a0f..4c27dd0ad 100644 --- a/api/log/update_step.go +++ b/api/log/update_step.go @@ -22,7 +22,7 @@ import ( // swagger:operation PUT /api/v1/repos/{org}/{repo}/builds/{build}/steps/{step}/logs steps UpdateStepLog // -// Update the logs for a step +// Update step logs for a build // // --- // deprecated: true @@ -31,12 +31,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: path @@ -51,7 +51,7 @@ import ( // type: integer // - in: body // name: body -// description: Payload containing the log to update +// description: The log object with the fields to be updated // required: true // schema: // "$ref": "#/definitions/Log" @@ -60,19 +60,25 @@ import ( // responses: // '200': // description: Successfully updated the logs for step -// schema: -// "$ref": "#/definitions/Log" // '400': -// description: Unable to update the logs for a step +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to update the logs for a step +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" // UpdateStepLog represents the API handler to update -// the logs for a step in the configured backend. +// the logs for a step. func UpdateStepLog(c *gin.Context) { // capture middleware values b := build.Retrieve(c) diff --git a/api/metrics.go b/api/metrics.go index 4a3323315..e23fa1d62 100644 --- a/api/metrics.go +++ b/api/metrics.go @@ -101,7 +101,7 @@ var ( // swagger:operation GET /metrics base BaseMetrics // -// Retrieve metrics from the Vela api +// Get Vela API metrics // // --- // produces: @@ -114,7 +114,7 @@ var ( // default: false // - in: query // name: repo_count -// description: Indicates a request for repo count +// description: Indicates a request for repository count // type: boolean // default: false // - in: query diff --git a/api/oi_config.go b/api/oi_config.go index 02edeb939..1111e352f 100644 --- a/api/oi_config.go +++ b/api/oi_config.go @@ -15,7 +15,7 @@ import ( // swagger:operation GET /_services/token/.well-known/openid-configuration token GetOpenIDConfig // -// Get the OpenID configuration for the Vela OIDC service +// Get the Vela OIDC service configuration // // --- // produces: diff --git a/api/pipeline/compile.go b/api/pipeline/compile.go index 4585451ba..67419d91d 100644 --- a/api/pipeline/compile.go +++ b/api/pipeline/compile.go @@ -22,21 +22,21 @@ import ( // swagger:operation POST /api/v1/pipelines/{org}/{repo}/{pipeline}/compile pipelines CompilePipeline // -// Get, expand and compile a pipeline from the configured backend +// Get, expand and compile a pipeline // // --- // produces: -// - application/x-yaml +// - application/yaml // - application/json // parameters: // - in: path -// name: repo -// description: Name of the repo +// name: org +// description: Name of the organization // required: true // type: string // - in: path -// name: org -// description: Name of the org +// name: repo +// description: Name of the repository // required: true // type: string // - in: path @@ -60,11 +60,19 @@ import ( // schema: // "$ref": "#/definitions/PipelineBuild" // '400': -// description: Unable to validate the pipeline configuration +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '404': -// description: Unable to retrieve the pipeline configuration +// description: Not found +// schema: +// "$ref": "#/definitions/Error" +// '500': +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" diff --git a/api/pipeline/create.go b/api/pipeline/create.go index 1092a4051..1420fdc67 100644 --- a/api/pipeline/create.go +++ b/api/pipeline/create.go @@ -19,7 +19,7 @@ import ( // swagger:operation POST /api/v1/pipelines/{org}/{repo} pipelines CreatePipeline // -// Create a pipeline in the configured backend +// Create a pipeline // // --- // produces: @@ -27,17 +27,17 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: body // name: body -// description: Payload containing the pipeline to create +// description: Pipeline object to create // required: true // schema: // "$ref": "#/definitions/Pipeline" @@ -50,20 +50,24 @@ import ( // schema: // "$ref": "#/definitions/Pipeline" // '400': -// description: Unable to create the pipeline +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '404': -// description: Unable to create the pipeline +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to create the pipeline +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" // CreatePipeline represents the API handler to -// create a pipeline in the configured backend. +// create a pipeline. func CreatePipeline(c *gin.Context) { // capture middleware values o := org.Retrieve(c) diff --git a/api/pipeline/delete.go b/api/pipeline/delete.go index b59f1adc3..89c0f362c 100644 --- a/api/pipeline/delete.go +++ b/api/pipeline/delete.go @@ -19,7 +19,7 @@ import ( // swagger:operation DELETE /api/v1/pipelines/{org}/{repo}/{pipeline} pipelines DeletePipeline // -// Delete a pipeline from the configured backend +// Delete a pipeline // // --- // produces: @@ -27,12 +27,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: path @@ -48,16 +48,23 @@ import ( // schema: // type: string // '400': -// description: Unable to delete the pipeline +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to delete the pipeline +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// DeletePipeline represents the API handler to remove -// a pipeline for a repo from the configured backend. +// DeletePipeline represents the API handler to remove a pipeline for a repository. func DeletePipeline(c *gin.Context) { // capture middleware values o := org.Retrieve(c) diff --git a/api/pipeline/expand.go b/api/pipeline/expand.go index 17e62181c..062992a81 100644 --- a/api/pipeline/expand.go +++ b/api/pipeline/expand.go @@ -21,21 +21,21 @@ import ( // swagger:operation POST /api/v1/pipelines/{org}/{repo}/{pipeline}/expand pipelines ExpandPipeline // -// Get and expand a pipeline from the configured backend +// Expand a pipeline // // --- // produces: -// - application/x-yaml +// - application/yaml // - application/json // parameters: // - in: path -// name: repo -// description: Name of the repo +// name: org +// description: Name of the organization // required: true // type: string // - in: path -// name: org -// description: Name of the org +// name: repo +// description: Name of the repository // required: true // type: string // - in: path @@ -60,11 +60,19 @@ import ( // schema: // "$ref": "#/definitions/PipelineBuild" // '400': -// description: Unable to expand the pipeline configuration +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '404': -// description: Unable to retrieve the pipeline configuration +// description: Not found +// schema: +// "$ref": "#/definitions/Error" +// '500': +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" diff --git a/api/pipeline/get.go b/api/pipeline/get.go index 69739f523..d6fdcbeed 100644 --- a/api/pipeline/get.go +++ b/api/pipeline/get.go @@ -16,7 +16,7 @@ import ( // swagger:operation GET /api/v1/pipelines/{org}/{repo}/{pipeline} pipelines GetPipeline // -// Get a pipeline from the configured backend +// Get a pipeline // // --- // produces: @@ -24,12 +24,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: path @@ -45,9 +45,24 @@ import ( // type: json // schema: // "$ref": "#/definitions/Pipeline" +// '400': +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Not found +// schema: +// "$ref": "#/definitions/Error" +// '500': +// description: Unexpected server error +// schema: +// "$ref": "#/definitions/Error" -// GetPipeline represents the API handler to capture -// a pipeline for a repo from the configured backend. +// GetPipeline represents the API handler to get a pipeline for a repo. func GetPipeline(c *gin.Context) { // capture middleware values o := org.Retrieve(c) diff --git a/api/pipeline/list.go b/api/pipeline/list.go index 0ffdcff95..c2fd7f0b6 100644 --- a/api/pipeline/list.go +++ b/api/pipeline/list.go @@ -20,7 +20,7 @@ import ( // swagger:operation GET /api/v1/pipelines/{org}/{repo} pipelines ListPipelines // -// List pipelines from the configured backend +// Get all pipelines for a repository // // --- // produces: @@ -28,12 +28,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: query @@ -61,19 +61,27 @@ import ( // description: Total number of results // type: integer // Link: -// description: see https://tools.ietf.org/html/rfc5988 +// description: See https://tools.ietf.org/html/rfc5988 // type: string // '400': -// description: Unable to retrieve the list of pipelines +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to retrieve the list of pipelines +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// ListPipelines represents the API handler to capture a list -// of pipelines for a repo from the configured backend. +// ListPipelines represents the API handler to get a list +// of pipelines for a repository. func ListPipelines(c *gin.Context) { // capture middleware values o := org.Retrieve(c) diff --git a/api/pipeline/template.go b/api/pipeline/template.go index 66c8cd627..8271732b6 100644 --- a/api/pipeline/template.go +++ b/api/pipeline/template.go @@ -25,21 +25,21 @@ import ( // swagger:operation GET /api/v1/pipelines/{org}/{repo}/{pipeline}/templates pipelines GetTemplates // -// Get a map of templates utilized by a pipeline from the configured backend +// Get pipeline templates // // --- // produces: -// - application/x-yaml +// - application/yaml // - application/json // parameters: // - in: path -// name: repo -// description: Name of the repo +// name: org +// description: Name of the organization // required: true // type: string // - in: path -// name: org -// description: Name of the org +// name: repo +// description: Name of the repository // required: true // type: string // - in: path @@ -61,13 +61,23 @@ import ( // '200': // description: Successfully retrieved the map of pipeline templates // schema: -// "$ref": "#/definitions/Template" +// type: array +// items: +// "$ref": "#/definitions/Template" // '400': -// description: Unable to retrieve the pipeline configuration templates +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '404': -// description: Unable to retrieve the pipeline configuration templates +// description: Not found +// schema: +// "$ref": "#/definitions/Error" +// '500': +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" diff --git a/api/pipeline/update.go b/api/pipeline/update.go index f5230fbe8..bc70d53c4 100644 --- a/api/pipeline/update.go +++ b/api/pipeline/update.go @@ -20,7 +20,7 @@ import ( // swagger:operation PUT /api/v1/pipelines/{org}/{repo}/{pipeline} pipelines UpdatePipeline // -// Update a pipeline in the configured backend +// Update a pipeline // // --- // produces: @@ -28,12 +28,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: path @@ -43,7 +43,7 @@ import ( // type: string // - in: body // name: body -// description: Payload containing the pipeline to update +// description: The pipeline object with the fields to be updated // required: true // schema: // "$ref": "#/definitions/Pipeline" @@ -54,17 +54,25 @@ import ( // description: Successfully updated the pipeline // schema: // "$ref": "#/definitions/Pipeline" +// '400': +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" // '404': -// description: Unable to update the pipeline +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to update the pipeline +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" // UpdatePipeline represents the API handler to update -// a pipeline for a repo in the configured backend. +// a pipeline for a repo. func UpdatePipeline(c *gin.Context) { // capture middleware values o := org.Retrieve(c) diff --git a/api/pipeline/validate.go b/api/pipeline/validate.go index b7f43664d..335f61850 100644 --- a/api/pipeline/validate.go +++ b/api/pipeline/validate.go @@ -20,21 +20,21 @@ import ( // swagger:operation POST /api/v1/pipelines/{org}/{repo}/{pipeline}/validate pipelines ValidatePipeline // -// Get, expand and validate a pipeline from the configured backend +// Get, expand and validate a pipeline // // --- // produces: -// - application/x-yaml +// - application/yaml // - application/json // parameters: // - in: path -// name: repo -// description: Name of the repo +// name: org +// description: Name of the organization // required: true // type: string // - in: path -// name: org -// description: Name of the org +// name: repo +// description: Name of the repository // required: true // type: string // - in: path @@ -58,11 +58,19 @@ import ( // schema: // type: string // '400': -// description: Unable to validate the pipeline configuration +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '404': -// description: Unable to retrieve the pipeline configuration +// description: Not found +// schema: +// "$ref": "#/definitions/Error" +// '500': +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" diff --git a/api/queue/doc.go b/api/queue/doc.go new file mode 100644 index 000000000..e794792cf --- /dev/null +++ b/api/queue/doc.go @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: Apache-2.0 + +// Package queue provides the queue handlers for the Vela API. +// +// Usage: +// +// import "github.com/go-vela/server/api/queue" +package queue diff --git a/api/repo/chown.go b/api/repo/chown.go index f68a4fac6..30442c683 100644 --- a/api/repo/chown.go +++ b/api/repo/chown.go @@ -18,7 +18,7 @@ import ( // swagger:operation PATCH /api/v1/repos/{org}/{repo}/chown repos ChownRepo // -// Change the owner of the webhook for a repo +// Change the owner of a repository // // --- // produces: @@ -26,28 +26,40 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // security: // - ApiKeyAuth: [] // responses: // '200': -// description: Successfully changed the owner for the repo +// description: Successfully changed the owner for the repository // schema: // type: string +// '400': +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Not found +// schema: +// "$ref": "#/definitions/Error" // '500': -// description: Unable to change the owner for the repo +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" // ChownRepo represents the API handler to change -// the owner of a repo in the configured backend. +// the owner of a repo. func ChownRepo(c *gin.Context) { // capture middleware values o := org.Retrieve(c) diff --git a/api/repo/create.go b/api/repo/create.go index 7249bbfa4..7516b9682 100644 --- a/api/repo/create.go +++ b/api/repo/create.go @@ -25,7 +25,7 @@ import ( // swagger:operation POST /api/v1/repos repos CreateRepo // -// Create a repo in the configured backend +// Create a repository // // --- // produces: @@ -33,7 +33,7 @@ import ( // parameters: // - in: body // name: body -// description: Payload containing the repo to create +// description: Repo object to create // required: true // schema: // "$ref": "#/definitions/Repo" @@ -45,7 +45,11 @@ import ( // schema: // "$ref": "#/definitions/Repo" // '400': -// description: Unable to create the repo +// description: Invalid request payload +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '403': @@ -57,7 +61,7 @@ import ( // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to create the repo +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" // '503': @@ -65,8 +69,7 @@ import ( // schema: // "$ref": "#/definitions/Error" -// CreateRepo represents the API handler to -// create a repo in the configured backend. +// CreateRepo represents the API handler to create a repository. // //nolint:funlen,gocyclo // ignore function length and cyclomatic complexity func CreateRepo(c *gin.Context) { diff --git a/api/repo/delete.go b/api/repo/delete.go index 7a70ceac4..c75d2fc51 100644 --- a/api/repo/delete.go +++ b/api/repo/delete.go @@ -19,7 +19,7 @@ import ( // swagger:operation DELETE /api/v1/repos/{org}/{repo} repos DeleteRepo // -// Delete a repo in the configured backend +// Delete a repository // // --- // produces: @@ -27,12 +27,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // security: @@ -42,17 +42,24 @@ import ( // description: Successfully deleted the repo // schema: // type: string -// '500': -// description: Unable to deleted the repo +// '400': +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" -// '510': -// description: Unable to deleted the repo +// '404': +// description: Not found +// schema: +// "$ref": "#/definitions/Error" +// '500': +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// DeleteRepo represents the API handler to remove -// a repo from the configured backend. +// DeleteRepo represents the API handler to remove a repository. func DeleteRepo(c *gin.Context) { // capture middleware values o := org.Retrieve(c) diff --git a/api/repo/get.go b/api/repo/get.go index 61df846d4..ac988093c 100644 --- a/api/repo/get.go +++ b/api/repo/get.go @@ -15,7 +15,7 @@ import ( // swagger:operation GET /api/v1/repos/{org}/{repo} repos GetRepo // -// Get a repo in the configured backend +// Get a repository // // --- // produces: @@ -23,12 +23,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // security: @@ -38,9 +38,20 @@ import ( // description: Successfully retrieved the repo // schema: // "$ref": "#/definitions/Repo" +// '400': +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Repo" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Repo" +// '404': +// description: Not found +// schema: +// "$ref": "#/definitions/Repo" -// GetRepo represents the API handler to -// capture a repo from the configured backend. +// GetRepo represents the API handler to get a repository. func GetRepo(c *gin.Context) { // capture middleware values o := org.Retrieve(c) diff --git a/api/repo/list.go b/api/repo/list.go index 010ae0cfe..306214605 100644 --- a/api/repo/list.go +++ b/api/repo/list.go @@ -18,7 +18,7 @@ import ( // swagger:operation GET /api/v1/repos repos ListRepos // -// Get all repos in the configured backend +// Get all repositories // // --- // produces: @@ -49,19 +49,23 @@ import ( // description: Total number of results // type: integer // Link: -// description: see https://tools.ietf.org/html/rfc5988 +// description: See https://tools.ietf.org/html/rfc5988 // type: string // '400': -// description: Unable to retrieve the repo +// description: Invalid request payload +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to retrieve the repo +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// ListRepos represents the API handler to capture a list -// of repos for a user from the configured backend. +// ListRepos represents the API handler to get a list +// of repositories for a user. func ListRepos(c *gin.Context) { // capture middleware values u := user.Retrieve(c) diff --git a/api/repo/list_org.go b/api/repo/list_org.go index 565082f97..2466efce1 100644 --- a/api/repo/list_org.go +++ b/api/repo/list_org.go @@ -21,7 +21,7 @@ import ( // swagger:operation GET /api/v1/repos/{org} repos ListReposForOrg // -// Get all repos for the provided org in the configured backend +// Get all repositories for an organization // // --- // produces: @@ -31,7 +31,7 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: query @@ -70,19 +70,23 @@ import ( // description: Total number of results // type: integer // Link: -// description: see https://tools.ietf.org/html/rfc5988 +// description: See https://tools.ietf.org/html/rfc5988 // type: string // '400': -// description: Unable to retrieve the org +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to retrieve the org +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// ListReposForOrg represents the API handler to capture a list -// of repos for an org from the configured backend. +// ListReposForOrg represents the API handler to get a list +// of repositories for an organization. func ListReposForOrg(c *gin.Context) { // capture middleware values o := org.Retrieve(c) diff --git a/api/repo/repair.go b/api/repo/repair.go index 1e3eefb33..af43148e7 100644 --- a/api/repo/repair.go +++ b/api/repo/repair.go @@ -21,7 +21,7 @@ import ( // swagger:operation PATCH /api/v1/repos/{org}/{repo}/repair repos RepairRepo // -// Remove and recreate the webhook for a repo +// Repair a hook for a repository in Vela and the configured SCM // // --- // produces: @@ -29,12 +29,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // security: @@ -44,8 +44,20 @@ import ( // description: Successfully repaired the repo // schema: // type: string +// '400': +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Not found +// schema: +// "$ref": "#/definitions/Error" // '500': -// description: Unable to repair the repo +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" diff --git a/api/repo/update.go b/api/repo/update.go index 82fd02922..4626dd72b 100644 --- a/api/repo/update.go +++ b/api/repo/update.go @@ -24,7 +24,7 @@ import ( // swagger:operation PUT /api/v1/repos/{org}/{repo} repos UpdateRepo // -// Update a repo in the configured backend +// Update a repository // // --- // produces: @@ -32,17 +32,17 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: body // name: body -// description: Payload containing the repo to update +// description: The repository object with the fields to be updated // required: true // schema: // "$ref": "#/definitions/Repo" @@ -54,11 +54,15 @@ import ( // schema: // "$ref": "#/definitions/Repo" // '400': -// description: Unable to update the repo +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to update the repo +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" // '503': @@ -66,8 +70,7 @@ import ( // schema: // "$ref": "#/definitions/Error" -// UpdateRepo represents the API handler to update -// a repo in the configured backend. +// UpdateRepo represents the API handler to update a repo. // //nolint:funlen,gocyclo // ignore function length func UpdateRepo(c *gin.Context) { diff --git a/api/schedule/create.go b/api/schedule/create.go index a63d60fa4..938c31e1f 100644 --- a/api/schedule/create.go +++ b/api/schedule/create.go @@ -21,7 +21,7 @@ import ( // swagger:operation POST /api/v1/schedules/{org}/{repo} schedules CreateSchedule // -// Create a schedule in the configured backend +// Create a schedule // // --- // produces: @@ -29,17 +29,17 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: body // name: body -// description: Payload containing the schedule to create +// description: Schedule object to create // required: true // schema: // "$ref": "#/definitions/Schedule" @@ -51,19 +51,27 @@ import ( // schema: // "$ref": "#/definitions/Schedule" // '400': -// description: Unable to create the schedule +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '403': // description: Unable to create the schedule // schema: // "$ref": "#/definitions/Error" +// '404': +// description: Not found +// schema: +// "$ref": "#/definitions/Error" // '409': // description: Unable to create the schedule // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to create the schedule +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" // '503': @@ -72,7 +80,7 @@ import ( // "$ref": "#/definitions/Error" // CreateSchedule represents the API handler to -// create a schedule in the configured backend. +// create a schedule. func CreateSchedule(c *gin.Context) { // capture middleware values u := user.Retrieve(c) diff --git a/api/schedule/delete.go b/api/schedule/delete.go index 73c60a8c0..19c448aa1 100644 --- a/api/schedule/delete.go +++ b/api/schedule/delete.go @@ -19,7 +19,7 @@ import ( // swagger:operation DELETE /api/v1/repos/{org}/{repo}/{schedule} schedules DeleteSchedule // -// Delete a schedule in the configured backend +// Delete a schedule // // --- // produces: @@ -27,12 +27,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: path @@ -47,17 +47,24 @@ import ( // description: Successfully deleted the schedule // schema: // type: string -// '500': -// description: Unable to delete the schedule +// '400': +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" -// '510': -// description: Unable to delete the schedule +// '404': +// description: Not found +// schema: +// "$ref": "#/definitions/Error" +// '500': +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// DeleteSchedule represents the API handler to remove -// a schedule from the configured backend. +// DeleteSchedule represents the API handler to remove a schedule. func DeleteSchedule(c *gin.Context) { // capture middleware values o := org.Retrieve(c) diff --git a/api/schedule/doc.go b/api/schedule/doc.go new file mode 100644 index 000000000..c6736d529 --- /dev/null +++ b/api/schedule/doc.go @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: Apache-2.0 + +// Package schedule provides the schedule handlers for the Vela API. +// +// Usage: +// +// import "github.com/go-vela/server/api/schedule" +package schedule diff --git a/api/schedule/get.go b/api/schedule/get.go index d9ff954b2..2978860b9 100644 --- a/api/schedule/get.go +++ b/api/schedule/get.go @@ -16,7 +16,7 @@ import ( // swagger:operation GET /api/v1/schedules/{org}/{repo}/{schedule} schedules GetSchedule // -// Get a schedule in the configured backend +// Get a schedule // // --- // produces: @@ -24,12 +24,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: path @@ -44,9 +44,20 @@ import ( // description: Successfully retrieved the schedule // schema: // "$ref": "#/definitions/Schedule" +// '400': +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Not found +// schema: +// "$ref": "#/definitions/Error" -// GetSchedule represents the API handler to -// capture a schedule from the configured backend. +// GetSchedule represents the API handler to get a schedule. func GetSchedule(c *gin.Context) { // capture middleware values o := org.Retrieve(c) diff --git a/api/schedule/list.go b/api/schedule/list.go index c6c424647..a42569ba0 100644 --- a/api/schedule/list.go +++ b/api/schedule/list.go @@ -18,7 +18,7 @@ import ( // swagger:operation GET /api/v1/schedules/{org}/{repo} schedules ListSchedules // -// Get all schedules in the configured backend +// Get all schedules for a repository // // --- // produces: @@ -28,12 +28,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: query @@ -59,19 +59,26 @@ import ( // description: Total number of results // type: integer // Link: -// description: see https://tools.ietf.org/html/rfc5988 +// description: See https://tools.ietf.org/html/rfc5988 // type: string // '400': -// description: Unable to retrieve the schedules +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to retrieve the schedules +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// ListSchedules represents the API handler to capture a list -// of schedules for a repo from the configured backend. +// ListSchedules represents the API handler to get a list of schedules for a repository. func ListSchedules(c *gin.Context) { // capture middleware values r := repo.Retrieve(c) diff --git a/api/schedule/update.go b/api/schedule/update.go index c29678570..149cd3e74 100644 --- a/api/schedule/update.go +++ b/api/schedule/update.go @@ -20,7 +20,7 @@ import ( // swagger:operation PUT /api/v1/schedules/{org}/{repo}/{schedule} schedules UpdateSchedule // -// Update a schedule for the configured backend +// Update a schedule // // --- // produces: @@ -28,12 +28,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: path @@ -43,7 +43,7 @@ import ( // type: string // - in: body // name: body -// description: Payload containing the schedule to update +// description: The schedule object with the fields to be updated // required: true // schema: // "$ref": "#/definitions/Schedule" @@ -55,20 +55,23 @@ import ( // schema: // "$ref": "#/definitions/Schedule" // '400': -// description: Unable to update the schedule +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '404': -// description: Unable to update the schedule +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to update the schedule +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// UpdateSchedule represents the API handler to update -// a schedule in the configured backend. +// UpdateSchedule represents the API handler to update a schedule. func UpdateSchedule(c *gin.Context) { // capture middleware values r := repo.Retrieve(c) diff --git a/api/scm/sync.go b/api/scm/sync.go index 9520fb143..66e2e6fd2 100644 --- a/api/scm/sync.go +++ b/api/scm/sync.go @@ -20,7 +20,7 @@ import ( // swagger:operation PATCH /api/v1/scm/repos/{org}/{repo}/sync scm SyncRepo // -// Sync up scm service and database in the context of a specific repo +// Sync a repository with the scm service // // --- // produces: @@ -28,12 +28,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // security: @@ -46,15 +46,23 @@ import ( // '204': // description: Successful request resulting in no change // '301': -// description: Repo has moved permanently +// description: Repo has moved permanently (from SCM) +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '403': -// description: User has been forbidden access to repository +// description: User has been forbidden access to repository (from SCM) +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to synchronize repo +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" @@ -83,7 +91,6 @@ func SyncRepo(c *gin.Context) { // retrieve repo from source code manager service _, respCode, err := scm.FromContext(c).GetRepo(ctx, u, r) - // if there is an error retrieving repo, we know it is deleted: set to inactive if err != nil { if respCode == http.StatusNotFound { diff --git a/api/scm/sync_org.go b/api/scm/sync_org.go index b1162503c..8809e7b4f 100644 --- a/api/scm/sync_org.go +++ b/api/scm/sync_org.go @@ -19,7 +19,7 @@ import ( // swagger:operation PATCH /api/v1/scm/orgs/{org}/sync scm SyncReposForOrg // -// Sync up repos from scm service and database in a specified org +// Sync repositories from scm service and database in a specified organization // // --- // produces: @@ -27,7 +27,7 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // security: @@ -42,15 +42,23 @@ import ( // '204': // description: Successful request resulting in no change // '301': -// description: One repo in the org has moved permanently +// description: One repository in the organiation has moved permanently (from SCM) +// schema: +// "$ref": "#/definitions/Error" +// '400': +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '403': -// description: User has been forbidden access to at least one repository in org +// description: User has been forbidden access to at least one repository in organiation (from SCM) // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to synchronize org repositories +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" diff --git a/api/secret/create.go b/api/secret/create.go index fd44f1779..e2d3e2c50 100644 --- a/api/secret/create.go +++ b/api/secret/create.go @@ -45,17 +45,17 @@ import ( // type: string // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: name -// description: Name of the repo if a repo secret, team name if a shared secret, or '*' if an org secret +// description: Name of the repository if a repository secret, team name if a shared secret, or '*' if an organization secret // required: true // type: string // - in: body // name: body -// description: Payload containing the secret to create +// description: Secret object to create // required: true // schema: // "$ref": "#/definitions/Secret" @@ -67,16 +67,20 @@ import ( // schema: // "$ref": "#/definitions/Secret" // '400': -// description: Unable to create the secret +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to create the secret +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" // CreateSecret represents the API handler to -// create a secret in the configured backend. +// create a secret. // //nolint:funlen // suppress long function error func CreateSecret(c *gin.Context) { diff --git a/api/secret/delete.go b/api/secret/delete.go index dd4db4145..188016155 100644 --- a/api/secret/delete.go +++ b/api/secret/delete.go @@ -19,7 +19,7 @@ import ( // // swagger:operation DELETE /api/v1/secrets/{engine}/{type}/{org}/{name}/{secret} secrets DeleteSecret // -// Delete a secret from the configured backend +// Delete a secret // // --- // produces: @@ -41,12 +41,12 @@ import ( // type: string // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: name -// description: Name of the repo if a repo secret, team name if a shared secret, or '*' if an org secret +// description: Name of the repository if a repository secret, team name if a shared secret, or '*' if an organzation secret // required: true // type: string // - in: path @@ -61,8 +61,12 @@ import ( // description: Successfully deleted the secret // schema: // type: string +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" // '500': -// description: Unable to delete the secret +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" diff --git a/api/secret/get.go b/api/secret/get.go index 44c379f8b..dc4d4da1f 100644 --- a/api/secret/get.go +++ b/api/secret/get.go @@ -20,7 +20,7 @@ import ( // // swagger:operation GET /api/v1/secrets/{engine}/{type}/{org}/{name}/{secret} secrets GetSecret // -// Retrieve a secret from the configured backend +// Get a secret // // --- // produces: @@ -42,12 +42,12 @@ import ( // type: string // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: name -// description: Name of the repo if a repo secret, team name if a shared secret, or '*' if an org secret +// description: Name of the repository if a repository secret, team name if a shared secret, or '*' if an organization secret // required: true // type: string // - in: path @@ -62,8 +62,12 @@ import ( // description: Successfully retrieved the secret // schema: // "$ref": "#/definitions/Secret" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" // '500': -// description: Unable to retrieve the secret +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" diff --git a/api/secret/list.go b/api/secret/list.go index c142b89a6..a6699ef34 100644 --- a/api/secret/list.go +++ b/api/secret/list.go @@ -23,7 +23,7 @@ import ( // // swagger:operation GET /api/v1/secrets/{engine}/{type}/{org}/{name} secrets ListSecrets // -// Retrieve a list of secrets from the configured backend +// Get all organization or shared secrets // // --- // produces: @@ -45,12 +45,12 @@ import ( // type: string // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: name -// description: Name of the repo if a repo secret, team name if a shared secret, or '*' if an org secret +// description: Name of the repository if a repository secret, team name if a shared secret, or '*' if an organization secret // required: true // type: string // - in: query @@ -78,19 +78,22 @@ import ( // description: Total number of results // type: integer // Link: -// description: see https://tools.ietf.org/html/rfc5988 +// description: See https://tools.ietf.org/html/rfc5988 // type: string // '400': -// description: Unable to retrieve the list of secrets +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to retrieve the list of secrets +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// ListSecrets represents the API handler to capture -// a list of secrets from the configured backend. +// ListSecrets represents the API handler to get a list of secrets. func ListSecrets(c *gin.Context) { // capture middleware values u := user.Retrieve(c) diff --git a/api/secret/update.go b/api/secret/update.go index cb012c719..dc66df7ce 100644 --- a/api/secret/update.go +++ b/api/secret/update.go @@ -21,7 +21,7 @@ import ( // // swagger:operation PUT /api/v1/secrets/{engine}/{type}/{org}/{name}/{secret} secrets UpdateSecret // -// Update a secret on the configured backend +// Update a secret // // --- // produces: @@ -43,12 +43,12 @@ import ( // type: string // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: name -// description: Name of the repo if a repo secret, team name if a shared secret, or '*' if an org secret +// description: Name of the repository if a repository secret, team name if a shared secret, or '*' if an organization secret // required: true // type: string // - in: path @@ -70,11 +70,15 @@ import ( // schema: // "$ref": "#/definitions/Secret" // '400': -// description: Unable to update the secret +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to update the secret +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" diff --git a/api/service/create.go b/api/service/create.go index 2ccb9e314..e4289cc0b 100644 --- a/api/service/create.go +++ b/api/service/create.go @@ -22,7 +22,7 @@ import ( // swagger:operation POST /api/v1/repos/{org}/{repo}/builds/{build}/services services CreateService // -// Create a service for a build in the configured backend +// Create a service for a build // // --- // produces: @@ -30,12 +30,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: path @@ -45,7 +45,7 @@ import ( // type: integer // - in: body // name: body -// description: Payload containing the service to create +// description: Service object to create // required: true // schema: // "$ref": "#/definitions/Service" @@ -57,16 +57,24 @@ import ( // schema: // "$ref": "#/definitions/Service" // '400': -// description: Unable to create the service +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to create the service +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" // CreateService represents the API handler to create -// a service for a build in the configured backend. +// a service for a build. func CreateService(c *gin.Context) { // capture middleware values b := build.Retrieve(c) diff --git a/api/service/delete.go b/api/service/delete.go index 915804a27..90ca9b9b6 100644 --- a/api/service/delete.go +++ b/api/service/delete.go @@ -21,7 +21,7 @@ import ( // // swagger:operation DELETE /api/v1/repos/{org}/{repo}/builds/{build}/services/{service} services DeleteService // -// Delete a service for a build in the configured backend +// Delete a service for a build // // --- // produces: @@ -29,12 +29,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: path @@ -54,13 +54,24 @@ import ( // description: Successfully deleted the service // schema: // type: string +// '400': +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Not found +// schema: +// "$ref": "#/definitions/Error" // '500': -// description: Unable to delete the service +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// DeleteService represents the API handler to remove -// a service for a build from the configured backend. +// DeleteService represents the API handler to remove a service for a build. func DeleteService(c *gin.Context) { // capture middleware values b := build.Retrieve(c) diff --git a/api/service/get.go b/api/service/get.go index b81b69735..c54d1427d 100644 --- a/api/service/get.go +++ b/api/service/get.go @@ -18,7 +18,7 @@ import ( // // swagger:operation GET /api/v1/repos/{org}/{repo}/builds/{build}/services/{service} services GetService // -// Get a service for a build in the configured backend +// Get a service for a build // // --- // produces: @@ -26,12 +26,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: path @@ -52,16 +52,23 @@ import ( // schema: // "$ref": "#/definitions/Service" // '400': -// description: Unable to retrieve the service +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to retrieve the service +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// GetService represents the API handler to capture a -// service for a build from the configured backend. +// GetService represents the API handler to get a service for a build. func GetService(c *gin.Context) { // capture middleware values b := build.Retrieve(c) diff --git a/api/service/list.go b/api/service/list.go index 6697a7282..2862a28d4 100644 --- a/api/service/list.go +++ b/api/service/list.go @@ -21,7 +21,7 @@ import ( // swagger:operation GET /api/v1/repos/{org}/{repo}/builds/{build}/services services ListServices // -// Get a list of all services for a build in the configured backend +// Get all services for a build // // --- // produces: @@ -29,12 +29,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: path @@ -67,19 +67,26 @@ import ( // description: Total number of results // type: integer // Link: -// description: see https://tools.ietf.org/html/rfc5988 +// description: See https://tools.ietf.org/html/rfc5988 // type: string // '400': -// description: Unable to retrieve the list of services +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to retrieve the list of services +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// ListServices represents the API handler to capture a list -// of services for a build from the configured backend. +// ListServices represents the API handler to get a list of services for a build. func ListServices(c *gin.Context) { // capture middleware values b := build.Retrieve(c) diff --git a/api/service/plan.go b/api/service/plan.go index 05673f05e..faed795cb 100644 --- a/api/service/plan.go +++ b/api/service/plan.go @@ -16,7 +16,7 @@ import ( // PlanServices is a helper function to plan all services // in the build for execution. This creates the services -// for the build in the configured backend. +// for the build. func PlanServices(ctx context.Context, database database.Interface, p *pipeline.Build, b *types.Build) ([]*library.Service, error) { // variable to store planned services services := []*library.Service{} diff --git a/api/service/update.go b/api/service/update.go index a539270e3..0b2825997 100644 --- a/api/service/update.go +++ b/api/service/update.go @@ -22,7 +22,7 @@ import ( // // swagger:operation PUT /api/v1/repos/{org}/{repo}/builds/{build}/services/{service} services UpdateService // -// Update a service for a build in the configured backend +// Update a service for a build // // --- // produces: @@ -30,12 +30,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: path @@ -50,7 +50,7 @@ import ( // type: integer // - in: body // name: body -// description: Payload containing the service to update +// description: The service object with the fields to be updated // required: true // schema: // "$ref": "#/definitions/Service" @@ -62,16 +62,24 @@ import ( // schema: // "$ref": "#/definitions/Service" // '400': -// description: Unable to update the service +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to update the service +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" // UpdateService represents the API handler to update -// a service for a build in the configured backend. +// a service for a build. func UpdateService(c *gin.Context) { // capture middleware values b := build.Retrieve(c) diff --git a/api/step/create.go b/api/step/create.go index 2218d214d..33225a93f 100644 --- a/api/step/create.go +++ b/api/step/create.go @@ -30,12 +30,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: path @@ -45,7 +45,7 @@ import ( // type: integer // - in: body // name: body -// description: Payload containing the step to create +// description: Step object to create // required: true // schema: // "$ref": "#/definitions/Step" @@ -57,16 +57,24 @@ import ( // schema: // "$ref": "#/definitions/Step" // '400': -// description: Unable to create the step +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to create the step +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" // CreateStep represents the API handler to create -// a step for a build in the configured backend. +// a step for a build. func CreateStep(c *gin.Context) { // capture middleware values b := build.Retrieve(c) diff --git a/api/step/delete.go b/api/step/delete.go index 8d735717a..27a3eff1d 100644 --- a/api/step/delete.go +++ b/api/step/delete.go @@ -28,12 +28,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: path @@ -53,13 +53,24 @@ import ( // description: Successfully deleted the step // schema: // type: string +// '400': +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Not found +// schema: +// "$ref": "#/definitions/Error" // '500': -// description: Successfully deleted the step +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// DeleteStep represents the API handler to remove -// a step for a build from the configured backend. +// DeleteStep represents the API handler to remove a step for a build. func DeleteStep(c *gin.Context) { // capture middleware values b := build.Retrieve(c) diff --git a/api/step/get.go b/api/step/get.go index 9582b5928..09267ffb3 100644 --- a/api/step/get.go +++ b/api/step/get.go @@ -17,7 +17,7 @@ import ( // swagger:operation GET /api/v1/repos/{org}/{repo}/builds/{build}/steps/{step} steps GetStep // -// Retrieve a step for a build +// Get a step for a build // // --- // produces: @@ -25,12 +25,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: path @@ -50,9 +50,20 @@ import ( // description: Successfully retrieved the step // schema: // "$ref": "#/definitions/Step" +// '400': +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Not found +// schema: +// "$ref": "#/definitions/Error" -// GetStep represents the API handler to capture a -// step for a build from the configured backend. +// GetStep represents the API handler to get a step for a build. func GetStep(c *gin.Context) { // capture middleware values b := build.Retrieve(c) diff --git a/api/step/list.go b/api/step/list.go index 603d7083b..67617b2b6 100644 --- a/api/step/list.go +++ b/api/step/list.go @@ -21,7 +21,7 @@ import ( // swagger:operation GET /api/v1/repos/{org}/{repo}/builds/{build}/steps steps ListSteps // -// Retrieve a list of steps for a build +// Get all steps for a build // // --- // produces: @@ -29,12 +29,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: path @@ -67,19 +67,26 @@ import ( // description: Total number of results // type: integer // Link: -// description: see https://tools.ietf.org/html/rfc5988 +// description: See https://tools.ietf.org/html/rfc5988 // type: string // '400': -// description: Unable to retrieve the list of steps +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to retrieve the list of steps +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// ListSteps represents the API handler to capture a list -// of steps for a build from the configured backend. +// ListSteps represents the API handler to get a list of steps for a build. func ListSteps(c *gin.Context) { // capture middleware values b := build.Retrieve(c) diff --git a/api/step/plan.go b/api/step/plan.go index f685170a3..6b3faac06 100644 --- a/api/step/plan.go +++ b/api/step/plan.go @@ -19,7 +19,7 @@ import ( // PlanSteps is a helper function to plan all steps // in the build for execution. This creates the steps -// for the build in the configured backend. +// for the build. func PlanSteps(ctx context.Context, database database.Interface, scm scm.Service, p *pipeline.Build, b *types.Build) ([]*library.Step, error) { // variable to store planned steps steps := []*library.Step{} diff --git a/api/step/update.go b/api/step/update.go index cb767de4e..87e2fc6dd 100644 --- a/api/step/update.go +++ b/api/step/update.go @@ -31,12 +31,12 @@ import ( // parameters: // - in: path // name: org -// description: Name of the org +// description: Name of the organization // required: true // type: string // - in: path // name: repo -// description: Name of the repo +// description: Name of the repository // required: true // type: string // - in: path @@ -51,7 +51,7 @@ import ( // type: integer // - in: body // name: body -// description: Payload containing the step to update +// description: The step object with the fields to be updated // required: true // schema: // "$ref": "#/definitions/Step" @@ -63,16 +63,24 @@ import ( // schema: // "$ref": "#/definitions/Step" // '400': -// description: Unable to update the step +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to update the step +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" // UpdateStep represents the API handler to update -// a step for a build in the configured backend. +// a step for a build. func UpdateStep(c *gin.Context) { // capture middleware values b := build.Retrieve(c) diff --git a/api/user/create.go b/api/user/create.go index cd68556bf..bf37a8472 100644 --- a/api/user/create.go +++ b/api/user/create.go @@ -17,7 +17,7 @@ import ( // swagger:operation POST /api/v1/users users CreateUser // -// Create a user for the configured backend +// Create a user // // --- // produces: @@ -25,7 +25,7 @@ import ( // parameters: // - in: body // name: body -// description: Payload containing the user to create +// description: User object to create // required: true // schema: // "$ref": "#/definitions/User" @@ -37,16 +37,19 @@ import ( // schema: // "$ref": "#/definitions/User" // '400': -// description: Unable to create the user +// description: Invalid request payload +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to create the user +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// CreateUser represents the API handler to create -// a user in the configured backend. +// CreateUser represents the API handler to create a user. func CreateUser(c *gin.Context) { // capture middleware values u := user.Retrieve(c) diff --git a/api/user/create_token.go b/api/user/create_token.go index e1b8fa9c0..6a3bb2678 100644 --- a/api/user/create_token.go +++ b/api/user/create_token.go @@ -31,13 +31,17 @@ import ( // description: Successfully created a token for the current user // schema: // "$ref": "#/definitions/Token" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" // '503': // description: Unable to create a token for the current user // schema: // "$ref": "#/definitions/Error" // CreateToken represents the API handler to create -// a user token in the configured backend. +// a user token. func CreateToken(c *gin.Context) { // capture middleware values u := user.Retrieve(c) diff --git a/api/user/delete.go b/api/user/delete.go index fd32d75d0..35c026736 100644 --- a/api/user/delete.go +++ b/api/user/delete.go @@ -16,7 +16,7 @@ import ( // swagger:operation DELETE /api/v1/users/{user} users DeleteUser // -// Delete a user for the configured backend +// Delete a user // // --- // produces: @@ -31,20 +31,23 @@ import ( // - ApiKeyAuth: [] // responses: // '200': -// description: Successfully deleted of user +// description: Successfully deleted user // schema: // type: string +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" // '404': -// description: Unable to delete user +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to delete user +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// DeleteUser represents the API handler to remove -// a user from the configured backend. +// DeleteUser represents the API handler to remove a user. func DeleteUser(c *gin.Context) { // capture middleware values u := user.Retrieve(c) diff --git a/api/user/delete_token.go b/api/user/delete_token.go index b0caa2ac1..1f21a7a24 100644 --- a/api/user/delete_token.go +++ b/api/user/delete_token.go @@ -31,13 +31,17 @@ import ( // description: Successfully delete a token for the current user // schema: // type: string -// '500': +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '503': // description: Unable to delete a token for the current user // schema: // "$ref": "#/definitions/Error" // DeleteToken represents the API handler to revoke -// and recreate a user token in the configured backend. +// and recreate a user token. func DeleteToken(c *gin.Context) { // capture middleware values u := user.Retrieve(c) diff --git a/api/user/get.go b/api/user/get.go index 488cd9705..708eb56bb 100644 --- a/api/user/get.go +++ b/api/user/get.go @@ -16,7 +16,7 @@ import ( // swagger:operation GET /api/v1/users/{user} users GetUser // -// Retrieve a user for the configured backend +// Get a user // // --- // produces: @@ -34,13 +34,16 @@ import ( // description: Successfully retrieved the user // schema: // "$ref": "#/definitions/User" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" // '404': -// description: Unable to retrieve the user +// description: Not found // schema: // "$ref": "#/definitions/Error" -// GetUser represents the API handler to capture a -// user from the configured backend. +// GetUser represents the API handler to get a user. func GetUser(c *gin.Context) { // capture middleware values u := user.Retrieve(c) diff --git a/api/user/get_current.go b/api/user/get_current.go index 455a4e8e7..1cd21526d 100644 --- a/api/user/get_current.go +++ b/api/user/get_current.go @@ -13,7 +13,7 @@ import ( // swagger:operation GET /api/v1/user users GetCurrentUser // -// Retrieve the current authenticated user from the configured backend +// Get the current authenticated user // // --- // produces: @@ -25,9 +25,13 @@ import ( // description: Successfully retrieved the current user // schema: // "$ref": "#/definitions/User" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" // GetCurrentUser represents the API handler to capture the -// currently authenticated user from the configured backend. +// currently authenticated user. func GetCurrentUser(c *gin.Context) { // capture middleware values u := user.Retrieve(c) diff --git a/api/user/get_source.go b/api/user/get_source.go index d0b666090..b74639f96 100644 --- a/api/user/get_source.go +++ b/api/user/get_source.go @@ -18,7 +18,7 @@ import ( // swagger:operation GET /api/v1/user/source/repos users GetSourceRepos // -// Retrieve a list of repos for the current authenticated user +// Get all repos for the current authenticated user // // --- // produces: @@ -30,13 +30,16 @@ import ( // description: Successfully retrieved a list of repos for the current user // schema: // "$ref": "#/definitions/Repo" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" // '404': -// description: Unable to retrieve a list of repos for the current user +// description: Not found // schema: // "$ref": "#/definitions/Error" -// GetSourceRepos represents the API handler to capture -// the list of repos for a user from the configured backend. +// GetSourceRepos represents the API handler to get a list of repos for a user. func GetSourceRepos(c *gin.Context) { // capture middleware values u := user.Retrieve(c) diff --git a/api/user/list.go b/api/user/list.go index 55f67f64e..d4f5ad0ff 100644 --- a/api/user/list.go +++ b/api/user/list.go @@ -18,7 +18,7 @@ import ( // swagger:operation GET /api/v1/users users ListUsers // -// Retrieve a list of users for the configured backend +// Get all users // // --- // produces: @@ -49,19 +49,22 @@ import ( // description: Total number of results // type: integer // Link: -// description: see https://tools.ietf.org/html/rfc5988 +// description: See https://tools.ietf.org/html/rfc5988 // type: string // '400': -// description: Unable to retrieve the list of users +// description: Invalid request payload +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to retrieve the list of users +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// ListUsers represents the API handler to capture a list -// of users from the configured backend. +// ListUsers represents the API handler to get a list of users. func ListUsers(c *gin.Context) { // capture middleware values u := user.Retrieve(c) diff --git a/api/user/update.go b/api/user/update.go index 3983abd0f..9ebd37c36 100644 --- a/api/user/update.go +++ b/api/user/update.go @@ -17,7 +17,7 @@ import ( // swagger:operation PUT /api/v1/users/{user} users UpdateUser // -// Update a user for the configured backend +// Update a user // // --- // produces: @@ -30,7 +30,7 @@ import ( // type: string // - in: body // name: body -// description: Payload containing the user to update +// description: The user object with the fields to be updated // required: true // schema: // "$ref": "#/definitions/User" @@ -42,20 +42,23 @@ import ( // schema: // "$ref": "#/definitions/User" // '400': -// description: Unable to update the user +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '404': -// description: Unable to update the user +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to update the user +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// UpdateUser represents the API handler to update -// a user in the configured backend. +// UpdateUser represents the API handler to update a user. func UpdateUser(c *gin.Context) { // capture middleware values u := user.Retrieve(c) diff --git a/api/user/update_current.go b/api/user/update_current.go index dec97ba71..3853611ec 100644 --- a/api/user/update_current.go +++ b/api/user/update_current.go @@ -17,7 +17,7 @@ import ( // swagger:operation PUT /api/v1/user users UpdateCurrentUser // -// Update the current authenticated user in the configured backend +// Update the current authenticated user // // --- // produces: @@ -25,7 +25,7 @@ import ( // parameters: // - in: body // name: body -// description: Payload containing the user to update +// description: The user object with the fields to be updated // required: true // schema: // "$ref": "#/definitions/User" @@ -37,20 +37,20 @@ import ( // schema: // "$ref": "#/definitions/User" // '400': -// description: Unable to update the current user +// description: Invalid request payload // schema: // "$ref": "#/definitions/Error" -// '404': -// description: Unable to update the current user +// '401': +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to update the current user +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" // UpdateCurrentUser represents the API handler to capture and -// update the currently authenticated user from the configured backend. +// update the currently authenticated user. func UpdateCurrentUser(c *gin.Context) { // capture middleware values u := user.Retrieve(c) diff --git a/api/version.go b/api/version.go index 349fd5ea4..726e7cc3f 100644 --- a/api/version.go +++ b/api/version.go @@ -12,7 +12,7 @@ import ( // swagger:operation GET /version base Version // -// Get the version of the Vela API +// Get the Vela API version // // --- // produces: diff --git a/api/webhook/post.go b/api/webhook/post.go index 50d69d315..ddc0a047e 100644 --- a/api/webhook/post.go +++ b/api/webhook/post.go @@ -33,7 +33,7 @@ var baseErr = "unable to process webhook" // swagger:operation POST /webhook base PostWebhook // -// Deliver a webhook to the vela api +// Deliver a webhook to the Vela API // // --- // produces: @@ -56,15 +56,15 @@ var baseErr = "unable to process webhook" // schema: // "$ref": "#/definitions/Build" // '400': -// description: Malformed webhook payload or improper pipeline configuration +// description: Invalid request payload // schema: // "$ref": "#/definitions/Error" // '401': -// description: Repository owner does not have proper access +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '404': -// description: Unable to receive the webhook +// description: Not found // schema: // "$ref": "#/definitions/Error" // '429': @@ -72,7 +72,7 @@ var baseErr = "unable to process webhook" // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to receive the webhook or internal error while processing +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" diff --git a/api/worker/create.go b/api/worker/create.go index 557cb1858..c8af50b5e 100644 --- a/api/worker/create.go +++ b/api/worker/create.go @@ -23,7 +23,7 @@ import ( // swagger:operation POST /api/v1/workers workers CreateWorker // -// Create a worker for the configured backend +// Create a worker // // --- // produces: @@ -31,7 +31,7 @@ import ( // parameters: // - in: body // name: body -// description: Payload containing the worker to create +// description: Worker object to create // required: true // schema: // "$ref": "#/definitions/Worker" @@ -43,16 +43,20 @@ import ( // schema: // "$ref": "#/definitions/Token" // '400': -// description: Unable to create the worker +// description: Invalid request payload +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to create the worker +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" // CreateWorker represents the API handler to -// create a worker in the configured backend. +// create a worker. func CreateWorker(c *gin.Context) { // capture middleware values u := user.Retrieve(c) diff --git a/api/worker/delete.go b/api/worker/delete.go index ebb718aeb..84f1442c0 100644 --- a/api/worker/delete.go +++ b/api/worker/delete.go @@ -17,7 +17,7 @@ import ( // swagger:operation DELETE /api/v1/workers/{worker} workers DeleteWorker // -// Delete a worker for the configured backend +// Delete a worker // // --- // produces: @@ -32,16 +32,27 @@ import ( // - ApiKeyAuth: [] // responses: // '200': -// description: Successfully deleted of worker +// description: Successfully deleted worker // schema: // type: string +// '400': +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" +// '404': +// description: Not found +// schema: +// "$ref": "#/definitions/Error" // '500': -// description: Unable to delete worker +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// DeleteWorker represents the API handler to remove -// a worker from the configured backend. +// DeleteWorker represents the API handler to remove a worker. func DeleteWorker(c *gin.Context) { // capture middleware values u := user.Retrieve(c) diff --git a/api/worker/get.go b/api/worker/get.go index 64ce34173..c7d3f5227 100644 --- a/api/worker/get.go +++ b/api/worker/get.go @@ -18,7 +18,7 @@ import ( // swagger:operation GET /api/v1/workers/{worker} workers GetWorker // -// Retrieve a worker for the configured backend +// Get a worker // // --- // produces: @@ -36,13 +36,24 @@ import ( // description: Successfully retrieved the worker // schema: // "$ref": "#/definitions/Worker" +// '400': +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" // '404': -// description: Unable to retrieve the worker +// description: Not found +// schema: +// "$ref": "#/definitions/Error" +// '500': +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// GetWorker represents the API handler to capture a -// worker from the configured backend. +// GetWorker represents the API handler to get a worker. func GetWorker(c *gin.Context) { // capture middleware values u := user.Retrieve(c) diff --git a/api/worker/list.go b/api/worker/list.go index 5141335ba..eb20d58f8 100644 --- a/api/worker/list.go +++ b/api/worker/list.go @@ -19,7 +19,7 @@ import ( // swagger:operation GET /api/v1/workers workers ListWorkers // -// Retrieve a list of workers for the configured backend +// Get all workers // // --- // produces: @@ -31,11 +31,11 @@ import ( // type: boolean // - in: query // name: checked_in_before -// description: filter workers that have checked in before a certain time +// description: Filter workers that have checked in before a certain time // type: integer // - in: query // name: checked_in_after -// description: filter workers that have checked in after a certain time +// description: Filter workers that have checked in after a certain time // type: integer // default: 0 // security: @@ -47,13 +47,20 @@ import ( // type: array // items: // "$ref": "#/definitions/Worker" +// '400': +// description: Invalid request payload +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized +// schema: +// "$ref": "#/definitions/Error" // '500': -// description: Unable to retrieve the list of workers +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" -// ListWorkers represents the API handler to capture a -// list of workers from the configured backend. +// ListWorkers represents the API handler to get a list of workers. func ListWorkers(c *gin.Context) { // capture middleware values u := user.Retrieve(c) diff --git a/api/worker/refresh.go b/api/worker/refresh.go index 4aff87a17..5fca4b884 100644 --- a/api/worker/refresh.go +++ b/api/worker/refresh.go @@ -22,7 +22,7 @@ import ( // swagger:operation POST /api/v1/workers/{worker}/refresh workers RefreshWorkerAuth // -// Refresh authorization token for worker +// Refresh authorization token for a worker // // --- // produces: @@ -41,15 +41,19 @@ import ( // schema: // "$ref": "#/definitions/Token" // '400': -// description: Unable to refresh worker auth +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '404': -// description: Unable to refresh worker auth +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to refresh worker auth +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" diff --git a/api/worker/update.go b/api/worker/update.go index db187b7c0..b717f9838 100644 --- a/api/worker/update.go +++ b/api/worker/update.go @@ -18,7 +18,7 @@ import ( // swagger:operation PUT /api/v1/workers/{worker} workers UpdateWorker // -// Update a worker for the configured backend +// Update a worker // // --- // produces: @@ -26,7 +26,7 @@ import ( // parameters: // - in: body // name: body -// description: Payload containing the worker to update +// description: The worker object with the fields to be updated // required: true // schema: // "$ref": "#/definitions/Worker" @@ -43,20 +43,24 @@ import ( // schema: // "$ref": "#/definitions/Worker" // '400': -// description: Unable to update the worker +// description: Invalid request payload or path +// schema: +// "$ref": "#/definitions/Error" +// '401': +// description: Unauthorized // schema: // "$ref": "#/definitions/Error" // '404': -// description: Unable to update the worker +// description: Not found // schema: // "$ref": "#/definitions/Error" // '500': -// description: Unable to update the worker +// description: Unexpected server error // schema: // "$ref": "#/definitions/Error" // UpdateWorker represents the API handler to -// update a worker in the configured backend. +// update a worker. func UpdateWorker(c *gin.Context) { // capture middleware values u := user.Retrieve(c) From d08606598172d3388b552d11efeeec653d189654 Mon Sep 17 00:00:00 2001 From: dave vader <48764154+plyr4@users.noreply.github.com> Date: Mon, 10 Jun 2024 10:23:00 -0500 Subject: [PATCH 65/71] fix: only convert commands query param when provided (#1140) * fix: only convert commands query param when provided * fix: lint --- api/build/id_request_token.go | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/api/build/id_request_token.go b/api/build/id_request_token.go index 1af34ce59..22e4d117c 100644 --- a/api/build/id_request_token.go +++ b/api/build/id_request_token.go @@ -113,13 +113,19 @@ func GetIDRequestToken(c *gin.Context) { return } - commands, err := strconv.ParseBool(c.Query("commands")) - if err != nil { - retErr := fmt.Errorf("unable to parse 'commands' query parameter as boolean %s: %w", c.Query("commands"), err) + commands := false - util.HandleError(c, http.StatusBadRequest, retErr) + var err error - return + if len(c.Query("commands")) > 0 { + commands, err = strconv.ParseBool(c.Query("commands")) + if err != nil { + retErr := fmt.Errorf("unable to parse 'commands' query parameter as boolean %s: %w", c.Query("commands"), err) + + util.HandleError(c, http.StatusBadRequest, retErr) + + return + } } // retrieve token manager from context From 1b68ff6bbf5fe43087bdd09db1d0f749c54e5a80 Mon Sep 17 00:00:00 2001 From: david may <1301201+wass3r@users.noreply.github.com> Date: Mon, 10 Jun 2024 12:00:12 -0500 Subject: [PATCH 66/71] fix(deps): switch go-jose lib (#1141) --- go.mod | 26 +++++++++++--------------- go.sum | 2 -- queue/redis/length_test.go | 4 +--- queue/redis/pop_test.go | 2 +- 4 files changed, 13 insertions(+), 21 deletions(-) diff --git a/go.mod b/go.mod index 3498c9262..e5501ee7a 100644 --- a/go.mod +++ b/go.mod @@ -42,27 +42,12 @@ require ( golang.org/x/crypto v0.24.0 golang.org/x/oauth2 v0.21.0 golang.org/x/sync v0.7.0 - gopkg.in/square/go-jose.v2 v2.6.0 gorm.io/driver/postgres v1.5.7 gorm.io/driver/sqlite v1.5.5 gorm.io/gorm v1.25.10 k8s.io/apimachinery v0.30.1 ) -require ( - github.com/bytedance/sonic/loader v0.1.1 // indirect - github.com/cloudwego/base64x v0.1.4 // indirect - github.com/cloudwego/iasm v0.2.0 // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect - github.com/go-jose/go-jose/v4 v4.0.1 // indirect - github.com/lestrrat-go/blackmagic v1.0.2 // indirect - github.com/lestrrat-go/httpcc v1.0.1 // indirect - github.com/lestrrat-go/httprc v1.0.5 // indirect - github.com/lestrrat-go/iter v1.0.2 // indirect - github.com/lestrrat-go/option v1.0.1 // indirect - github.com/segmentio/asm v1.2.0 // indirect -) - require ( github.com/Masterminds/goutils v1.1.1 // indirect github.com/PuerkitoBio/purell v1.1.1 // indirect @@ -71,12 +56,17 @@ require ( github.com/aymerick/douceur v0.2.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bytedance/sonic v1.11.6 // indirect + github.com/bytedance/sonic/loader v0.1.1 // indirect github.com/cenkalti/backoff/v3 v3.0.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cloudwego/base64x v0.1.4 // indirect + github.com/cloudwego/iasm v0.2.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/gin-contrib/sse v0.1.0 // indirect + github.com/go-jose/go-jose/v4 v4.0.1 // indirect github.com/go-logr/logr v1.4.1 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect @@ -106,6 +96,11 @@ require ( github.com/klauspost/cpuid/v2 v2.2.7 // indirect github.com/kr/text v0.2.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect + github.com/lestrrat-go/blackmagic v1.0.2 // indirect + github.com/lestrrat-go/httpcc v1.0.1 // indirect + github.com/lestrrat-go/httprc v1.0.5 // indirect + github.com/lestrrat-go/iter v1.0.2 // indirect + github.com/lestrrat-go/option v1.0.1 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-sqlite3 v1.14.17 // indirect github.com/mitchellh/copystructure v1.0.0 // indirect @@ -121,6 +116,7 @@ require ( github.com/prometheus/procfs v0.12.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/ryanuber/go-glob v1.0.0 // indirect + github.com/segmentio/asm v1.2.0 // indirect github.com/shopspring/decimal v1.2.0 // indirect github.com/spf13/cast v1.3.1 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect diff --git a/go.sum b/go.sum index 6d22f2b80..b605035f1 100644 --- a/go.sum +++ b/go.sum @@ -364,8 +364,6 @@ google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHh gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= -gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/queue/redis/length_test.go b/queue/redis/length_test.go index 9656a8c20..cd87b1036 100644 --- a/queue/redis/length_test.go +++ b/queue/redis/length_test.go @@ -4,11 +4,10 @@ package redis import ( "context" + "encoding/json" "reflect" "testing" - "gopkg.in/square/go-jose.v2/json" - "github.com/go-vela/server/queue/models" ) @@ -59,7 +58,6 @@ func TestRedis_Length(t *testing.T) { } } got, err := _redis.Length(context.Background()) - if err != nil { t.Errorf("Length returned err: %v", err) } diff --git a/queue/redis/pop_test.go b/queue/redis/pop_test.go index 190839f80..8afcad695 100644 --- a/queue/redis/pop_test.go +++ b/queue/redis/pop_test.go @@ -4,12 +4,12 @@ package redis import ( "context" + "encoding/json" "testing" "time" "github.com/google/go-cmp/cmp" "golang.org/x/crypto/nacl/sign" - "gopkg.in/square/go-jose.v2/json" "github.com/go-vela/server/queue/models" ) From 15a34ddf0c00d420cbc20b6354153efcb9200d39 Mon Sep 17 00:00:00 2001 From: david may <1301201+wass3r@users.noreply.github.com> Date: Mon, 10 Jun 2024 15:14:51 -0500 Subject: [PATCH 67/71] fix: swagger error and golangci-lint config (#1142) --- .golangci.yml | 5 ++++- api/auth/validate_oauth.go | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index f857a2c9f..df7592d27 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -8,7 +8,10 @@ # outputs it results from the linters it executes. output: # colored-line-number|line-number|json|tab|checkstyle|code-climate, default is "colored-line-number" - format: colored-line-number + formats: + - format: json + path: stderr + - format: colored-line-number # print lines of code with issue, default is true print-issued-lines: true diff --git a/api/auth/validate_oauth.go b/api/auth/validate_oauth.go index 94af8ca86..b96918325 100644 --- a/api/auth/validate_oauth.go +++ b/api/auth/validate_oauth.go @@ -30,7 +30,7 @@ import ( // '200': // description: Successfully validated // schema: -// "$ref": "#/definitions/Token" +// type: string // '401': // description: Unauthorized // schema: From 1d15b986385baff1e1b3324f7d7caca03093adef Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 14 Jun 2024 10:55:11 -0500 Subject: [PATCH 68/71] chore(deps): update all non-major dependencies (#1143) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- .github/workflows/codeql-analysis.yml | 8 ++++---- .github/workflows/integration-test.yml | 4 ++-- .github/workflows/prerelease.yml | 2 +- .github/workflows/publish.yml | 2 +- .github/workflows/reviewdog.yml | 4 ++-- .github/workflows/spec.yml | 2 +- .github/workflows/test.yml | 4 ++-- .github/workflows/validate.yml | 2 +- go.mod | 14 ++++++------- go.sum | 28 +++++++++++++------------- 11 files changed, 36 insertions(+), 36 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e7d62f832..baa356165 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,7 +13,7 @@ jobs: steps: - name: clone - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: install go uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index c0e70f907..b479ecef8 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -35,7 +35,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: install go uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 @@ -47,7 +47,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@2e230e8fe0ad3a14a340ad0815ddb96d599d2aff # v3.25.8 + uses: github/codeql-action/init@23acc5c183826b7a8a97bce3cecc52db901f8251 # v3.25.10 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -58,7 +58,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@2e230e8fe0ad3a14a340ad0815ddb96d599d2aff # v3.25.8 + uses: github/codeql-action/autobuild@23acc5c183826b7a8a97bce3cecc52db901f8251 # v3.25.10 # ℹī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -72,4 +72,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@2e230e8fe0ad3a14a340ad0815ddb96d599d2aff # v3.25.8 + uses: github/codeql-action/analyze@23acc5c183826b7a8a97bce3cecc52db901f8251 # v3.25.10 diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index d617cf5fd..144dad16c 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -40,7 +40,7 @@ jobs: steps: - name: clone - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: install go uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 @@ -62,7 +62,7 @@ jobs: steps: - name: clone - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: install go uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 diff --git a/.github/workflows/prerelease.yml b/.github/workflows/prerelease.yml index 56aa6ffd1..8bd6d0a11 100644 --- a/.github/workflows/prerelease.yml +++ b/.github/workflows/prerelease.yml @@ -14,7 +14,7 @@ jobs: steps: - name: clone - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 with: # ensures we fetch tag history for the repository fetch-depth: 0 diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 16a62f5e2..5ed24b19b 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -13,7 +13,7 @@ jobs: steps: - name: clone - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 with: # ensures we fetch tag history for the repository fetch-depth: 0 diff --git a/.github/workflows/reviewdog.yml b/.github/workflows/reviewdog.yml index 79ad4b56a..61f82e8c6 100644 --- a/.github/workflows/reviewdog.yml +++ b/.github/workflows/reviewdog.yml @@ -12,7 +12,7 @@ jobs: steps: - name: clone - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: install go uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 @@ -36,7 +36,7 @@ jobs: steps: - name: clone - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: install go uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 diff --git a/.github/workflows/spec.yml b/.github/workflows/spec.yml index 7aefbba05..6e73989b2 100644 --- a/.github/workflows/spec.yml +++ b/.github/workflows/spec.yml @@ -13,7 +13,7 @@ jobs: steps: - name: clone - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: install go uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 853c5b9bb..52c9d17ed 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,7 +13,7 @@ jobs: steps: - name: clone - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: install go uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 @@ -28,7 +28,7 @@ jobs: make test - name: coverage - uses: codecov/codecov-action@125fc84a9a348dbcf27191600683ec096ec9021c # v4.4.1 + uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 # v4.5.0 with: token: ${{ secrets.CODECOV_TOKEN }} file: coverage.out \ No newline at end of file diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index ee25cbd42..ad53c2bf8 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -13,7 +13,7 @@ jobs: steps: - name: clone - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: install go uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 diff --git a/go.mod b/go.mod index e5501ee7a..12ac6e5cc 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/Masterminds/sprig/v3 v3.2.3 github.com/adhocore/gronx v1.8.1 github.com/alicebob/miniredis/v2 v2.33.0 - github.com/aws/aws-sdk-go v1.53.17 + github.com/aws/aws-sdk-go v1.54.1 github.com/buildkite/yaml v0.0.0-20181016232759-0caa5f0796e3 github.com/distribution/reference v0.6.0 github.com/drone/envsubst v1.0.3 @@ -34,7 +34,7 @@ require ( github.com/microcosm-cc/bluemonday v1.0.26 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.19.1 - github.com/redis/go-redis/v9 v9.5.2 + github.com/redis/go-redis/v9 v9.5.3 github.com/sirupsen/logrus v1.9.3 github.com/spf13/afero v1.11.0 github.com/urfave/cli/v2 v2.27.2 @@ -42,10 +42,10 @@ require ( golang.org/x/crypto v0.24.0 golang.org/x/oauth2 v0.21.0 golang.org/x/sync v0.7.0 - gorm.io/driver/postgres v1.5.7 - gorm.io/driver/sqlite v1.5.5 + gorm.io/driver/postgres v1.5.9 + gorm.io/driver/sqlite v1.5.6 gorm.io/gorm v1.25.10 - k8s.io/apimachinery v0.30.1 + k8s.io/apimachinery v0.30.2 ) require ( @@ -87,7 +87,7 @@ require ( github.com/imdario/mergo v0.3.11 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect - github.com/jackc/pgx/v5 v5.5.4 // indirect + github.com/jackc/pgx/v5 v5.5.5 // indirect github.com/jackc/puddle/v2 v2.2.1 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect @@ -102,7 +102,7 @@ require ( github.com/lestrrat-go/iter v1.0.2 // indirect github.com/lestrrat-go/option v1.0.1 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-sqlite3 v1.14.17 // indirect + github.com/mattn/go-sqlite3 v1.14.22 // indirect github.com/mitchellh/copystructure v1.0.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect diff --git a/go.sum b/go.sum index b605035f1..d53868cd2 100644 --- a/go.sum +++ b/go.sum @@ -24,8 +24,8 @@ github.com/alicebob/miniredis/v2 v2.11.1/go.mod h1:UA48pmi7aSazcGAvcdKcBB49z521I github.com/alicebob/miniredis/v2 v2.33.0 h1:uvTF0EDeu9RLnUEG27Db5I68ESoIxTiXbNUiji6lZrA= github.com/alicebob/miniredis/v2 v2.33.0/go.mod h1:MhP4a3EU7aENRi9aO+tHfTBZicLqQevyi/DJpoj6mi0= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/aws/aws-sdk-go v1.53.17 h1:TwtYMzVBTaqPVj/pcemHRIgk01OycWEcEUyUUX0tpCI= -github.com/aws/aws-sdk-go v1.53.17/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/aws/aws-sdk-go v1.54.1 h1:+ULL7oLC+v3T00fOMIohUarPI3SR3oyDd6FBEvgdhvs= +github.com/aws/aws-sdk-go v1.54.1/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -153,8 +153,8 @@ github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsI github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= -github.com/jackc/pgx/v5 v5.5.4 h1:Xp2aQS8uXButQdnCMWNmvx6UysWQQC+u1EoizjguY+8= -github.com/jackc/pgx/v5 v5.5.4/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A= +github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw= +github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A= github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk= github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= @@ -204,8 +204,8 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM= -github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= +github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= +github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/microcosm-cc/bluemonday v1.0.26 h1:xbqSvqzQMeEHCqMi64VAs4d8uy6Mequs3rQ0k/Khz58= github.com/microcosm-cc/bluemonday v1.0.26/go.mod h1:JyzOCs9gkyQyjs+6h10UEVSe02CGwkhd72Xdqh78TWs= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= @@ -242,8 +242,8 @@ github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSz github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= -github.com/redis/go-redis/v9 v9.5.2 h1:L0L3fcSNReTRGyZ6AqAEN0K56wYeYAwapBIhkvh0f3E= -github.com/redis/go-redis/v9 v9.5.2/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M= +github.com/redis/go-redis/v9 v9.5.3 h1:fOAp1/uJG+ZtcITgZOfYFmTKPE7n4Vclj1wZFgRciUU= +github.com/redis/go-redis/v9 v9.5.3/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= @@ -372,14 +372,14 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gorm.io/driver/postgres v1.5.7 h1:8ptbNJTDbEmhdr62uReG5BGkdQyeasu/FZHxI0IMGnM= -gorm.io/driver/postgres v1.5.7/go.mod h1:3e019WlBaYI5o5LIdNV+LyxCMNtLOQETBXL2h4chKpA= -gorm.io/driver/sqlite v1.5.5 h1:7MDMtUZhV065SilG62E0MquljeArQZNfJnjd9i9gx3E= -gorm.io/driver/sqlite v1.5.5/go.mod h1:6NgQ7sQWAIFsPrJJl1lSNSu2TABh0ZZ/zm5fosATavE= +gorm.io/driver/postgres v1.5.9 h1:DkegyItji119OlcaLjqN11kHoUgZ/j13E0jkJZgD6A8= +gorm.io/driver/postgres v1.5.9/go.mod h1:DX3GReXH+3FPWGrrgffdvCk3DQ1dwDPdmbenSkweRGI= +gorm.io/driver/sqlite v1.5.6 h1:fO/X46qn5NUEEOZtnjJRWRzZMe8nqJiQ9E+0hi+hKQE= +gorm.io/driver/sqlite v1.5.6/go.mod h1:U+J8craQU6Fzkcvu8oLeAQmi50TkwPEhHDEjQZXDah4= gorm.io/gorm v1.25.10 h1:dQpO+33KalOA+aFYGlK+EfxcI5MbO7EP2yYygwh9h+s= gorm.io/gorm v1.25.10/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= -k8s.io/apimachinery v0.30.1 h1:ZQStsEfo4n65yAdlGTfP/uSHMQSoYzU/oeEbkmF7P2U= -k8s.io/apimachinery v0.30.1/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc= +k8s.io/apimachinery v0.30.2 h1:fEMcnBj6qkzzPGSVsAZtQThU62SmQ4ZymlXRC5yFSCg= +k8s.io/apimachinery v0.30.2/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc= k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= From d90925990293a53ed5746148db561059ea510208 Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Fri, 14 Jun 2024 11:03:52 -0500 Subject: [PATCH 69/71] chore(release): upgrade types to v0.24.0-rc2 (#1144) --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 12ac6e5cc..cb3eb31f1 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/ghodss/yaml v1.0.0 github.com/gin-gonic/gin v1.10.0 github.com/go-playground/assert/v2 v2.2.0 - github.com/go-vela/types v0.24.0-rc1 + github.com/go-vela/types v0.24.0-rc2 github.com/golang-jwt/jwt/v5 v5.2.1 github.com/google/go-cmp v0.6.0 github.com/google/go-github/v62 v62.0.0 diff --git a/go.sum b/go.sum index d53868cd2..df09c67b6 100644 --- a/go.sum +++ b/go.sum @@ -91,8 +91,8 @@ github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBEx github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw= github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= -github.com/go-vela/types v0.24.0-rc1 h1:4NeH+YF8fVbs6ukilKySIY3uD2SVYgBz1yqREjgZaOw= -github.com/go-vela/types v0.24.0-rc1/go.mod h1:YWj6BIapl9Kbj4yHq/fp8jltXdGiwD/gTy1ez32Rzag= +github.com/go-vela/types v0.24.0-rc2 h1:sdOtUL+pBjgD+4hFDrHN/8ZFXSICTnl+eYcRP2IZ0Wk= +github.com/go-vela/types v0.24.0-rc2/go.mod h1:YWj6BIapl9Kbj4yHq/fp8jltXdGiwD/gTy1ez32Rzag= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= From 62c42257a729908e8d2334e7fa32abee735293a5 Mon Sep 17 00:00:00 2001 From: David May <49894298+wass3rw3rk@users.noreply.github.com> Date: Tue, 18 Jun 2024 13:25:27 -0500 Subject: [PATCH 70/71] fix(scm): avoid usage of deprecated method in github module (#1146) --- scm/github/repo.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scm/github/repo.go b/scm/github/repo.go index 6af6cdd5a..c3b7ab7c9 100644 --- a/scm/github/repo.go +++ b/scm/github/repo.go @@ -515,14 +515,14 @@ func (c *client) ListUserRepos(ctx context.Context, u *api.User) ([]*api.Repo, e f := []*api.Repo{} // set the max per page for the options to capture the list of repos - opts := &github.RepositoryListOptions{ + opts := &github.RepositoryListByAuthenticatedUserOptions{ ListOptions: github.ListOptions{PerPage: 100}, // 100 is max } // loop to capture *ALL* the repos for { // send API call to capture the user's repos - repos, resp, err := client.Repositories.List(ctx, "", opts) + repos, resp, err := client.Repositories.ListByAuthenticatedUser(ctx, opts) if err != nil { return nil, fmt.Errorf("unable to list user repos: %w", err) } From 4fd820a25b96a149e3316211a26d4484d5aae14f Mon Sep 17 00:00:00 2001 From: David May <49894298+wass3rw3rk@users.noreply.github.com> Date: Thu, 20 Jun 2024 14:53:00 -0500 Subject: [PATCH 71/71] fix: logging (#1145) --- api/admin/build.go | 28 +- api/admin/clean.go | 15 +- api/admin/hook.go | 14 +- api/admin/repo.go | 18 +- api/admin/rotate_keys.go | 4 +- api/admin/secret.go | 24 +- api/admin/service.go | 15 +- api/admin/settings.go | 49 ++- api/admin/step.go | 18 +- api/admin/user.go | 19 +- api/admin/worker.go | 11 +- api/auth/get_token.go | 18 +- api/auth/login.go | 7 +- api/auth/logout.go | 14 +- api/auth/post_token.go | 15 +- api/auth/redirect.go | 3 +- api/auth/refresh.go | 5 + api/auth/validate.go | 4 + api/auth/validate_oauth.go | 4 + api/badge.go | 11 +- api/build/approve.go | 18 +- api/build/auto_cancel.go | 26 ++ api/build/cancel.go | 23 +- api/build/clean.go | 28 +- api/build/compile_publish.go | 37 ++- api/build/create.go | 21 +- api/build/delete.go | 15 +- api/build/enqueue.go | 22 +- api/build/executable.go | 23 +- api/build/get.go | 15 +- api/build/get_id.go | 11 +- api/build/graph.go | 26 +- api/build/id_request_token.go | 15 +- api/build/id_token.go | 11 +- api/build/list_org.go | 11 +- api/build/list_repo.go | 14 +- api/build/plan.go | 7 + api/build/restart.go | 21 +- api/build/token.go | 13 +- api/build/update.go | 38 ++- api/dashboard/create.go | 15 +- api/dashboard/delete.go | 9 +- api/dashboard/get.go | 11 +- api/dashboard/list_user.go | 13 +- api/dashboard/update.go | 10 +- api/deployment/create.go | 16 +- api/deployment/get.go | 12 +- api/deployment/list.go | 16 +- api/hook/create.go | 19 +- api/hook/delete.go | 44 +-- api/hook/get.go | 44 +-- api/hook/list.go | 14 +- api/hook/redeliver.go | 42 +-- api/hook/update.go | 40 +-- api/jwks.go | 5 + api/log/create_service.go | 21 +- api/log/create_step.go | 21 +- api/log/delete_service.go | 20 +- api/log/delete_step.go | 20 +- api/log/get_service.go | 20 +- api/log/get_step.go | 20 +- api/log/list_build.go | 19 +- api/log/update_service.go | 22 +- api/log/update_step.go | 22 +- api/oi_config.go | 5 + api/pipeline/compile.go | 13 +- api/pipeline/create.go | 21 +- api/pipeline/delete.go | 15 +- api/pipeline/expand.go | 13 +- api/pipeline/get.go | 15 +- api/pipeline/list.go | 14 +- api/pipeline/template.go | 11 +- api/pipeline/update.go | 15 +- api/pipeline/validate.go | 13 +- api/queue/queue.go | 7 +- api/repo/chown.go | 14 +- api/repo/create.go | 28 +- api/repo/delete.go | 12 +- api/repo/get.go | 14 +- api/repo/list.go | 8 +- api/repo/list_org.go | 11 +- api/repo/repair.go | 21 +- api/repo/update.go | 18 +- api/schedule/create.go | 20 +- api/schedule/delete.go | 16 +- api/schedule/get.go | 17 +- api/schedule/list.go | 9 +- api/schedule/update.go | 14 +- api/scm/sync.go | 18 +- api/scm/sync_org.go | 17 +- api/secret/create.go | 50 +-- api/secret/delete.go | 31 +- api/secret/get.go | 31 +- api/secret/list.go | 26 +- api/secret/update.go | 26 +- api/service/create.go | 20 +- api/service/delete.go | 16 +- api/service/get.go | 16 +- api/service/list.go | 15 +- api/service/plan.go | 19 ++ api/service/update.go | 16 +- api/step/create.go | 20 +- api/step/delete.go | 16 +- api/step/get.go | 16 +- api/step/list.go | 15 +- api/step/plan.go | 17 + api/step/update.go | 18 +- api/types/dashboard.go | 2 + api/user/create.go | 10 +- api/user/create_token.go | 10 +- api/user/delete.go | 10 +- api/user/delete_token.go | 10 +- api/user/get.go | 10 +- api/user/get_current.go | 8 +- api/user/get_source.go | 8 +- api/user/list.go | 10 +- api/user/update.go | 12 +- api/user/update_current.go | 8 +- api/webhook/post.go | 151 +++++++-- api/worker/create.go | 19 +- api/worker/delete.go | 11 +- api/worker/get.go | 11 +- api/worker/list.go | 10 +- api/worker/refresh.go | 16 +- api/worker/update.go | 11 +- cmd/vela-server/metadata.go | 10 +- cmd/vela-server/schedule.go | 15 + cmd/vela-server/scm.go | 2 +- cmd/vela-server/secret.go | 2 +- cmd/vela-server/server.go | 2 + cmd/vela-server/token.go | 2 +- cmd/vela-server/validate.go | 6 +- compiler/native/native.go | 6 +- database/build/build.go | 2 +- database/build/clean.go | 2 +- database/build/count.go | 2 +- database/build/count_deployment.go | 2 +- database/build/count_org.go | 2 +- database/build/count_repo.go | 2 +- database/build/count_status.go | 2 +- database/build/create.go | 2 +- database/build/delete.go | 2 +- database/build/get.go | 2 +- database/build/get_repo.go | 2 +- database/build/index.go | 2 +- database/build/last_repo.go | 2 +- database/build/list.go | 2 +- database/build/list_dashboard.go | 2 +- database/build/list_org.go | 2 +- database/build/list_pending_running.go | 2 +- database/build/list_pending_running_repo.go | 2 +- database/build/list_repo.go | 2 +- database/build/table.go | 2 +- database/build/update.go | 2 +- database/dashboard/create.go | 2 +- database/dashboard/dashboard.go | 2 +- database/dashboard/delete.go | 2 +- database/dashboard/get.go | 2 +- database/dashboard/table.go | 2 +- database/dashboard/update.go | 2 +- database/deployment/count.go | 2 +- database/deployment/count_repo.go | 2 +- database/deployment/create.go | 2 +- database/deployment/delete.go | 2 +- database/deployment/deployment.go | 2 +- database/deployment/get.go | 2 +- database/deployment/get_repo.go | 2 +- database/deployment/index.go | 2 +- database/deployment/list.go | 2 +- database/deployment/list_repo.go | 2 +- database/deployment/table.go | 2 +- database/deployment/update.go | 2 +- database/executable/pop.go | 3 +- database/executable/table.go | 2 +- database/hook/count.go | 2 +- database/hook/count_repo.go | 2 +- database/hook/create.go | 2 +- database/hook/delete.go | 2 +- database/hook/get.go | 2 +- database/hook/get_repo.go | 2 +- database/hook/get_webhook.go | 2 +- database/hook/hook.go | 2 +- database/hook/index.go | 2 +- database/hook/last_repo.go | 2 +- database/hook/list.go | 2 +- database/hook/list_repo.go | 2 +- database/hook/table.go | 2 +- database/hook/update.go | 2 +- database/jwk/create.go | 2 +- database/jwk/get.go | 2 +- database/jwk/jwk.go | 2 +- database/jwk/list.go | 2 +- database/jwk/rotate.go | 2 +- database/jwk/table.go | 2 +- database/log/count.go | 2 +- database/log/count_build.go | 2 +- database/log/create.go | 4 +- database/log/delete.go | 4 +- database/log/get.go | 2 +- database/log/get_service.go | 2 +- database/log/get_step.go | 2 +- database/log/index.go | 2 +- database/log/list.go | 2 +- database/log/list_build.go | 2 +- database/log/log.go | 2 +- database/log/table.go | 2 +- database/log/update.go | 4 +- database/pipeline/count.go | 2 +- database/pipeline/count_repo.go | 2 +- database/pipeline/delete.go | 2 +- database/pipeline/get.go | 2 +- database/pipeline/get_repo.go | 2 +- database/pipeline/list.go | 2 +- database/pipeline/list_repo.go | 2 +- database/repo/count.go | 2 +- database/repo/count_org.go | 2 +- database/repo/count_user.go | 2 +- database/repo/create.go | 2 +- database/repo/delete.go | 2 +- database/repo/get.go | 2 +- database/repo/get_org.go | 2 +- database/repo/index.go | 2 +- database/repo/list.go | 2 +- database/repo/list_org.go | 2 +- database/repo/list_user.go | 2 +- database/repo/repo.go | 2 +- database/repo/table.go | 2 +- database/repo/update.go | 2 +- database/schedule/count.go | 2 +- database/schedule/count_active.go | 2 +- database/schedule/count_repo.go | 2 +- database/schedule/get.go | 2 +- database/schedule/get_repo.go | 2 +- database/schedule/list.go | 2 +- database/schedule/list_active.go | 2 +- database/schedule/list_repo.go | 2 +- database/secret/count.go | 2 +- database/secret/count_org.go | 2 +- database/secret/count_repo.go | 2 +- database/secret/count_team.go | 4 +- database/secret/create.go | 4 +- database/secret/delete.go | 4 +- database/secret/get.go | 2 +- database/secret/get_org.go | 2 +- database/secret/get_repo.go | 2 +- database/secret/get_team.go | 2 +- database/secret/index.go | 2 +- database/secret/list.go | 2 +- database/secret/list_org.go | 2 +- database/secret/list_repo.go | 2 +- database/secret/list_team.go | 4 +- database/secret/secret.go | 2 +- database/secret/table.go | 2 +- database/secret/update.go | 4 +- database/service/count.go | 2 +- database/service/count_build.go | 2 +- database/service/delete.go | 2 +- database/service/get.go | 2 +- database/service/get_build.go | 2 +- database/service/list.go | 2 +- database/service/list_build.go | 2 +- database/service/list_image.go | 2 +- database/service/list_status.go | 2 +- database/service/table.go | 2 +- database/service/update.go | 2 +- database/settings/create.go | 2 +- database/settings/get.go | 2 +- database/settings/settings.go | 2 +- database/settings/table.go | 2 +- database/step/count.go | 2 +- database/step/count_build.go | 2 +- database/step/delete.go | 2 +- database/step/get.go | 2 +- database/step/get_build.go | 2 +- database/step/list.go | 2 +- database/step/list_build.go | 2 +- database/step/list_image.go | 2 +- database/step/list_status.go | 2 +- database/user/count.go | 2 +- database/user/create.go | 2 +- database/user/delete.go | 2 +- database/user/get.go | 2 +- database/user/get_name.go | 2 +- database/user/index.go | 2 +- database/user/list.go | 2 +- database/user/list_lite.go | 2 +- database/user/table.go | 2 +- database/user/update.go | 2 +- database/user/user.go | 2 +- database/worker/count.go | 2 +- database/worker/create.go | 2 +- database/worker/delete.go | 2 +- database/worker/get.go | 2 +- database/worker/get_hostname.go | 2 +- database/worker/index.go | 2 +- database/worker/list.go | 2 +- database/worker/table.go | 2 +- database/worker/update.go | 2 +- database/worker/worker.go | 2 +- queue/queue.go | 2 +- router/admin.go | 1 - router/dashboard.go | 11 +- router/hook.go | 13 +- router/middleware/build/build.go | 23 +- router/middleware/build/build_test.go | 6 + router/middleware/claims/claims.go | 10 + router/middleware/claims/claims_test.go | 4 + router/middleware/dashboard/dashboard.go | 16 +- router/middleware/dashboard/dashboard_test.go | 4 + router/middleware/dashboard/doc.go | 10 + router/middleware/header.go | 2 + router/middleware/hook/context.go | 37 +++ router/middleware/hook/context_test.go | 88 +++++ router/middleware/hook/doc.go | 10 + router/middleware/hook/hook.go | 76 +++++ router/middleware/hook/hook_test.go | 302 ++++++++++++++++++ router/middleware/logger.go | 69 +++- router/middleware/org/org.go | 12 +- router/middleware/org/org_test.go | 3 + router/middleware/perm/perm.go | 148 +++------ router/middleware/perm/perm_test.go | 30 ++ router/middleware/pipeline/pipeline.go | 22 +- router/middleware/pipeline/pipeline_test.go | 5 + router/middleware/repo/repo.go | 20 +- router/middleware/repo/repo_test.go | 5 + router/middleware/schedule/schedule.go | 20 +- router/middleware/service/service.go | 22 +- router/middleware/service/service_test.go | 7 + router/middleware/step/step.go | 22 +- router/middleware/step/step_test.go | 7 + router/middleware/user/user.go | 11 +- router/middleware/user/user_test.go | 6 + router/middleware/worker/worker.go | 11 +- router/middleware/worker/worker_test.go | 3 + router/queue.go | 2 +- scm/github/deployment.go | 7 +- scm/github/repo.go | 2 +- 337 files changed, 2014 insertions(+), 1689 deletions(-) create mode 100644 router/middleware/dashboard/doc.go create mode 100644 router/middleware/hook/context.go create mode 100644 router/middleware/hook/context_test.go create mode 100644 router/middleware/hook/doc.go create mode 100644 router/middleware/hook/hook.go create mode 100644 router/middleware/hook/hook_test.go diff --git a/api/admin/build.go b/api/admin/build.go index aab5f4fca..525179256 100644 --- a/api/admin/build.go +++ b/api/admin/build.go @@ -1,6 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -//nolint:dupl // ignore similar code package admin import ( @@ -50,11 +49,13 @@ import ( // AllBuildsQueue represents the API handler to get running and pending builds. func AllBuildsQueue(c *gin.Context) { + l := c.MustGet("logger").(*logrus.Entry) + + l.Debug("platform admin: reading running and pending builds") + // capture middleware values ctx := c.Request.Context() - logrus.Info("Admin: reading running and pending builds") - // default timestamp to 24 hours ago if user did not provide it as query parameter after := c.DefaultQuery("after", strconv.FormatInt(time.Now().UTC().Add(-24*time.Hour).Unix(), 10)) @@ -103,11 +104,12 @@ func AllBuildsQueue(c *gin.Context) { // UpdateBuild represents the API handler to update a build. func UpdateBuild(c *gin.Context) { - logrus.Info("Admin: updating build in database") - // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) ctx := c.Request.Context() + l.Debug("platform admin: updating build") + // capture body from API request input := new(types.Build) @@ -120,6 +122,14 @@ func UpdateBuild(c *gin.Context) { return } + l.WithFields(logrus.Fields{ + "build": input.GetNumber(), + "build_id": input.GetID(), + "repo": util.EscapeValue(input.GetRepo().GetName()), + "repo_id": input.GetRepo().GetID(), + "org": util.EscapeValue(input.GetRepo().GetOrg()), + }).Debug("platform admin: attempting to update build") + // send API call to update the build b, err := database.FromContext(c).UpdateBuild(ctx, input) if err != nil { @@ -130,5 +140,13 @@ func UpdateBuild(c *gin.Context) { return } + l.WithFields(logrus.Fields{ + "build": b.GetNumber(), + "build_id": b.GetID(), + "repo": b.GetRepo().GetName(), + "repo_id": b.GetRepo().GetID(), + "org": b.GetRepo().GetOrg(), + }).Info("platform admin: updated build") + c.JSON(http.StatusOK, b) } diff --git a/api/admin/clean.go b/api/admin/clean.go index d6ecbde4d..da3949568 100644 --- a/api/admin/clean.go +++ b/api/admin/clean.go @@ -12,7 +12,6 @@ import ( "github.com/sirupsen/logrus" "github.com/go-vela/server/database" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types" "github.com/go-vela/types/constants" @@ -60,10 +59,10 @@ import ( // CleanResources represents the API handler to update stale resources. func CleanResources(c *gin.Context) { // capture middleware values - u := user.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) ctx := c.Request.Context() - logrus.Infof("platform admin %s: updating pending resources in database", u.GetName()) + l.Debug("platform admin: cleaning resources") // default error message msg := "build cleaned by platform admin" @@ -82,7 +81,7 @@ func CleanResources(c *gin.Context) { // if a message is provided, set the error message to that if input.Message != nil { - msg = *input.Message + msg = util.EscapeValue(*input.Message) } // capture before query parameter, default to max build timeout @@ -105,7 +104,7 @@ func CleanResources(c *gin.Context) { return } - logrus.Infof("platform admin %s: cleaned %d builds in database", u.GetName(), builds) + l.Debugf("platform admin: cleaned %d builds", builds) // clean executables executables, err := database.FromContext(c).CleanBuildExecutables(ctx) @@ -117,6 +116,8 @@ func CleanResources(c *gin.Context) { return } + l.Debugf("platform admin: cleaned %d executables", executables) + // clean services services, err := database.FromContext(c).CleanServices(ctx, msg, before) if err != nil { @@ -127,7 +128,7 @@ func CleanResources(c *gin.Context) { return } - logrus.Infof("platform admin %s: cleaned %d services in database", u.GetName(), services) + l.Debugf("platform admin: cleaned %d services", services) // clean steps steps, err := database.FromContext(c).CleanSteps(ctx, msg, before) @@ -139,7 +140,7 @@ func CleanResources(c *gin.Context) { return } - logrus.Infof("platform admin %s: cleaned %d steps in database", u.GetName(), steps) + l.Debugf("platform admin: cleaned %d steps", steps) c.JSON(http.StatusOK, fmt.Sprintf("%d builds cleaned. %d executables cleaned. %d services cleaned. %d steps cleaned.", builds, executables, services, steps)) } diff --git a/api/admin/hook.go b/api/admin/hook.go index d9d7b4b17..a7d0ef303 100644 --- a/api/admin/hook.go +++ b/api/admin/hook.go @@ -1,6 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -//nolint:dupl // ignore similar code package admin import ( @@ -51,11 +50,12 @@ import ( // UpdateHook represents the API handler to update a hook. func UpdateHook(c *gin.Context) { - logrus.Info("Admin: updating hook in database") - // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) ctx := c.Request.Context() + l.Debug("platform admin: updating hook") + // capture body from API request input := new(library.Hook) @@ -68,6 +68,10 @@ func UpdateHook(c *gin.Context) { return } + l.WithFields(logrus.Fields{ + "hook_id": input.GetID(), + }).Debug("platform admin: attempting to update hook") + // send API call to update the hook h, err := database.FromContext(c).UpdateHook(ctx, input) if err != nil { @@ -78,5 +82,9 @@ func UpdateHook(c *gin.Context) { return } + l.WithFields(logrus.Fields{ + "hook_id": h.GetID(), + }).Info("platform admin: hook updated") + c.JSON(http.StatusOK, h) } diff --git a/api/admin/repo.go b/api/admin/repo.go index 6ce1bac37..16a26fef0 100644 --- a/api/admin/repo.go +++ b/api/admin/repo.go @@ -1,6 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -//nolint:dupl // ignore similar code package admin import ( @@ -51,11 +50,12 @@ import ( // UpdateRepo represents the API handler to update a repo. func UpdateRepo(c *gin.Context) { - logrus.Info("Admin: updating repo in database") - // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) ctx := c.Request.Context() + l.Debug("platform admin: updating repo") + // capture body from API request input := new(types.Repo) @@ -68,6 +68,12 @@ func UpdateRepo(c *gin.Context) { return } + l.WithFields(logrus.Fields{ + "org": util.EscapeValue(input.GetOrg()), + "repo": util.EscapeValue(input.GetName()), + "repo_id": input.GetID(), + }).Debug("platform admin: attempting to update repo") + // send API call to update the repo r, err := database.FromContext(c).UpdateRepo(ctx, input) if err != nil { @@ -78,5 +84,11 @@ func UpdateRepo(c *gin.Context) { return } + l.WithFields(logrus.Fields{ + "org": r.GetOrg(), + "repo": r.GetName(), + "repo_id": r.GetID(), + }).Info("platform admin: repo updated") + c.JSON(http.StatusOK, r) } diff --git a/api/admin/rotate_keys.go b/api/admin/rotate_keys.go index 0186c0c29..4fba00616 100644 --- a/api/admin/rotate_keys.go +++ b/api/admin/rotate_keys.go @@ -40,7 +40,9 @@ import ( // RotateOIDCKeys represents the API handler to // rotate RSA keys in the OIDC provider service. func RotateOIDCKeys(c *gin.Context) { - logrus.Info("Admin: rotating keys for OIDC provider") + l := c.MustGet("logger").(*logrus.Entry) + + l.Info("platform admin: rotating keys for OIDC provider") // capture middleware values ctx := c.Request.Context() diff --git a/api/admin/secret.go b/api/admin/secret.go index 673134ba6..f287e4227 100644 --- a/api/admin/secret.go +++ b/api/admin/secret.go @@ -1,6 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 -//nolint:dupl // ignore similar code package admin import ( @@ -51,11 +50,12 @@ import ( // UpdateSecret represents the API handler to update a secret. func UpdateSecret(c *gin.Context) { - logrus.Info("Admin: updating secret in database") - // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) ctx := c.Request.Context() + l.Debug("platform admin: updating secret") + // capture body from API request input := new(library.Secret) @@ -68,6 +68,15 @@ func UpdateSecret(c *gin.Context) { return } + l.WithFields(logrus.Fields{ + "secret_id": input.GetID(), + "secret_org": util.EscapeValue(input.GetOrg()), + "secret_repo": util.EscapeValue(input.GetRepo()), + "secret_type": util.EscapeValue(input.GetType()), + "secret_name": util.EscapeValue(input.GetName()), + "secret_team": util.EscapeValue(input.GetTeam()), + }).Debug("platform admin: attempting to update secret") + // send API call to update the secret s, err := database.FromContext(c).UpdateSecret(ctx, input) if err != nil { @@ -78,5 +87,14 @@ func UpdateSecret(c *gin.Context) { return } + l.WithFields(logrus.Fields{ + "secret_id": s.GetID(), + "secret_org": s.GetOrg(), + "secret_repo": s.GetRepo(), + "secret_type": s.GetType(), + "secret_name": s.GetName(), + "secret_team": s.GetTeam(), + }).Info("platform admin: secret updated") + c.JSON(http.StatusOK, s) } diff --git a/api/admin/service.go b/api/admin/service.go index 61153ad5f..13d33d199 100644 --- a/api/admin/service.go +++ b/api/admin/service.go @@ -52,11 +52,12 @@ import ( // UpdateService represents the API handler to update a service. func UpdateService(c *gin.Context) { - logrus.Info("Admin: updating service in database") - // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) ctx := c.Request.Context() + l.Debug("platform admin: updating service") + // capture body from API request input := new(library.Service) @@ -69,6 +70,11 @@ func UpdateService(c *gin.Context) { return } + l.WithFields(logrus.Fields{ + "service_id": input.GetID(), + "service": util.EscapeValue(input.GetName()), + }).Debug("platform admin: attempting to update service") + // send API call to update the service s, err := database.FromContext(c).UpdateService(ctx, input) if err != nil { @@ -79,5 +85,10 @@ func UpdateService(c *gin.Context) { return } + l.WithFields(logrus.Fields{ + "service_id": s.GetID(), + "service": s.GetName(), + }).Info("platform admin: updated service") + c.JSON(http.StatusOK, s) } diff --git a/api/admin/settings.go b/api/admin/settings.go index 8b5c525d8..dfb8cb338 100644 --- a/api/admin/settings.go +++ b/api/admin/settings.go @@ -47,15 +47,17 @@ import ( // GetSettings represents the API handler to get platform settings. func GetSettings(c *gin.Context) { + l := c.MustGet("logger").(*logrus.Entry) + + l.Debug("platform admin: reading platform settings") + // capture middleware values s := sMiddleware.FromContext(c) - logrus.Info("Admin: reading settings") - // check captured value because we aren't retrieving settings from the database // instead we are retrieving the auto-refreshed middleware value if s == nil { - retErr := fmt.Errorf("settings not found") + retErr := fmt.Errorf("platform settings not found") util.HandleError(c, http.StatusNotFound, retErr) @@ -108,16 +110,17 @@ func GetSettings(c *gin.Context) { // platform settings singleton. func UpdateSettings(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) s := sMiddleware.FromContext(c) u := uMiddleware.FromContext(c) ctx := c.Request.Context() - logrus.Info("Admin: updating settings") + l.Debug("platform admin: updating platform settings") // check captured value because we aren't retrieving settings from the database // instead we are retrieving the auto-refreshed middleware value if s == nil { - retErr := fmt.Errorf("settings not found") + retErr := fmt.Errorf("platform settings not found") util.HandleError(c, http.StatusNotFound, retErr) @@ -136,7 +139,7 @@ func UpdateSettings(c *gin.Context) { err := c.Bind(input) if err != nil { - retErr := fmt.Errorf("unable to decode JSON for settings: %w", err) + retErr := fmt.Errorf("unable to decode JSON for platform settings: %w", err) util.HandleError(c, http.StatusBadRequest, retErr) @@ -150,7 +153,7 @@ func UpdateSettings(c *gin.Context) { _, err = image.ParseWithError(cloneImage) if err != nil { - retErr := fmt.Errorf("invalid clone image %s: %w", cloneImage, err) + retErr := fmt.Errorf("invalid clone image %s for platform settings: %w", cloneImage, err) util.HandleError(c, http.StatusBadRequest, retErr) @@ -158,14 +161,20 @@ func UpdateSettings(c *gin.Context) { } _s.SetCloneImage(cloneImage) + + l.Infof("platform admin: updating clone image to %s", cloneImage) } if input.TemplateDepth != nil { _s.SetTemplateDepth(*input.TemplateDepth) + + l.Infof("platform admin: updating template depth to %d", *input.TemplateDepth) } if input.StarlarkExecLimit != nil { _s.SetStarlarkExecLimit(*input.StarlarkExecLimit) + + l.Infof("platform admin: updating starlark exec limit to %d", *input.StarlarkExecLimit) } } @@ -173,14 +182,20 @@ func UpdateSettings(c *gin.Context) { if input.Queue.Routes != nil { _s.SetRoutes(input.GetRoutes()) } + + l.Infof("platform admin: updating queue routes to: %s", input.GetRoutes()) } if input.RepoAllowlist != nil { _s.SetRepoAllowlist(input.GetRepoAllowlist()) + + l.Infof("platform admin: updating repo allowlist to: %s", input.GetRepoAllowlist()) } if input.ScheduleAllowlist != nil { _s.SetScheduleAllowlist(input.GetScheduleAllowlist()) + + l.Infof("platform admin: updating schedule allowlist to: %s", input.GetScheduleAllowlist()) } _s.SetUpdatedBy(u.GetName()) @@ -188,7 +203,7 @@ func UpdateSettings(c *gin.Context) { // send API call to update the settings _s, err = database.FromContext(c).UpdateSettings(ctx, _s) if err != nil { - retErr := fmt.Errorf("unable to update settings: %w", err) + retErr := fmt.Errorf("unable to update platform settings: %w", err) util.HandleError(c, http.StatusInternalServerError, retErr) @@ -229,18 +244,20 @@ func UpdateSettings(c *gin.Context) { // RestoreSettings represents the API handler to // restore platform settings to the environment defaults. func RestoreSettings(c *gin.Context) { + l := c.MustGet("logger").(*logrus.Entry) + + l.Debug("platform admin: restoring platform settings") + // capture middleware values + ctx := c.Request.Context() + cliCtx := cliMiddleware.FromContext(c) s := sMiddleware.FromContext(c) u := uMiddleware.FromContext(c) - cliCtx := cliMiddleware.FromContext(c) - ctx := c.Request.Context() - - logrus.Info("Admin: restoring settings") // check captured value because we aren't retrieving settings from the database // instead we are retrieving the auto-refreshed middleware value if s == nil { - retErr := fmt.Errorf("settings not found") + retErr := fmt.Errorf("platform settings not found") util.HandleError(c, http.StatusNotFound, retErr) @@ -249,7 +266,7 @@ func RestoreSettings(c *gin.Context) { compiler, err := native.FromCLIContext(cliCtx) if err != nil { - retErr := fmt.Errorf("unable to restore settings: %w", err) + retErr := fmt.Errorf("unable to restore platform settings: %w", err) util.HandleError(c, http.StatusInternalServerError, retErr) @@ -258,7 +275,7 @@ func RestoreSettings(c *gin.Context) { queue, err := queue.FromCLIContext(cliCtx) if err != nil { - retErr := fmt.Errorf("unable to restore settings: %w", err) + retErr := fmt.Errorf("unable to restore platform settings: %w", err) util.HandleError(c, http.StatusInternalServerError, retErr) @@ -281,7 +298,7 @@ func RestoreSettings(c *gin.Context) { // send API call to update the settings s, err = database.FromContext(c).UpdateSettings(ctx, _s) if err != nil { - retErr := fmt.Errorf("unable to update (restore) settings: %w", err) + retErr := fmt.Errorf("unable to update (restore) platform settings: %w", err) util.HandleError(c, http.StatusInternalServerError, retErr) diff --git a/api/admin/step.go b/api/admin/step.go index b2250b9ec..b29fc57e0 100644 --- a/api/admin/step.go +++ b/api/admin/step.go @@ -1,5 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 +//nolint:dupl // ignore similar code with user.go package admin import ( @@ -50,11 +51,14 @@ import ( // UpdateStep represents the API handler to update a step. func UpdateStep(c *gin.Context) { - logrus.Info("Admin: updating step in database") + // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) + ctx := c.Request.Context() + + l.Debug("platform admin: updating step") // capture body from API request input := new(library.Step) - ctx := c.Request.Context() err := c.Bind(input) if err != nil { @@ -65,6 +69,11 @@ func UpdateStep(c *gin.Context) { return } + l.WithFields(logrus.Fields{ + "step_id": input.GetID(), + "step": util.EscapeValue(input.GetName()), + }).Debug("platform admin: attempting to update step") + // send API call to update the step s, err := database.FromContext(c).UpdateStep(ctx, input) if err != nil { @@ -75,5 +84,10 @@ func UpdateStep(c *gin.Context) { return } + l.WithFields(logrus.Fields{ + "step_id": s.GetID(), + "step": s.GetName(), + }).Info("platform admin: updated step") + c.JSON(http.StatusOK, s) } diff --git a/api/admin/user.go b/api/admin/user.go index c8b0482a3..3f6d1b1ca 100644 --- a/api/admin/user.go +++ b/api/admin/user.go @@ -51,11 +51,12 @@ import ( // UpdateUser represents the API handler to update a user. func UpdateUser(c *gin.Context) { - logrus.Info("Admin: updating user in database") - // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) ctx := c.Request.Context() + l.Debug("platform admin: updating user") + // capture body from API request input := new(types.User) @@ -68,8 +69,13 @@ func UpdateUser(c *gin.Context) { return } + l.WithFields(logrus.Fields{ + "target_user_id": input.GetID(), + "target_user": util.EscapeValue(input.GetName()), + }).Debug("platform admin: attempting to update user") + // send API call to update the user - u, err := database.FromContext(c).UpdateUser(ctx, input) + tu, err := database.FromContext(c).UpdateUser(ctx, input) if err != nil { retErr := fmt.Errorf("unable to update user %d: %w", input.GetID(), err) @@ -78,5 +84,10 @@ func UpdateUser(c *gin.Context) { return } - c.JSON(http.StatusOK, u) + l.WithFields(logrus.Fields{ + "target_user_id": tu.GetID(), + "target_user": tu.GetName(), + }).Info("platform admin: updated user") + + c.JSON(http.StatusOK, tu) } diff --git a/api/admin/worker.go b/api/admin/worker.go index 36be236ac..59ed71a5e 100644 --- a/api/admin/worker.go +++ b/api/admin/worker.go @@ -10,7 +10,6 @@ import ( "github.com/sirupsen/logrus" "github.com/go-vela/server/internal/token" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" @@ -48,11 +47,9 @@ import ( // RegisterToken represents the API handler to // generate a registration token for onboarding a worker. func RegisterToken(c *gin.Context) { - // retrieve user from context - u := user.Retrieve(c) - - logrus.Infof("Platform admin %s: generating registration token", u.GetName()) + l := c.MustGet("logger").(*logrus.Entry) + // capture middleware values host := util.PathParameter(c, "worker") tm := c.MustGet("token-manager").(*token.Manager) @@ -62,6 +59,8 @@ func RegisterToken(c *gin.Context) { TokenDuration: tm.WorkerRegisterTokenDuration, } + l.Debug("platform admin: generating worker registration token") + rt, err := tm.MintToken(rmto) if err != nil { retErr := fmt.Errorf("unable to generate registration token: %w", err) @@ -71,5 +70,7 @@ func RegisterToken(c *gin.Context) { return } + l.Infof("platform admin: generated worker registration token for %s", host) + c.JSON(http.StatusOK, library.Token{Token: &rt}) } diff --git a/api/auth/get_token.go b/api/auth/get_token.go index 83adef396..07df70b0c 100644 --- a/api/auth/get_token.go +++ b/api/auth/get_token.go @@ -7,6 +7,7 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" @@ -61,8 +62,9 @@ import ( func GetAuthToken(c *gin.Context) { var err error - tm := c.MustGet("token-manager").(*token.Manager) // capture middleware values + tm := c.MustGet("token-manager").(*token.Manager) + l := c.MustGet("logger").(*logrus.Entry) ctx := c.Request.Context() // capture the OAuth state if present @@ -123,7 +125,7 @@ func GetAuthToken(c *gin.Context) { u.SetRefreshToken(rt) // send API call to create the user in the database - _, err = database.FromContext(c).CreateUser(ctx, u) + ur, err := database.FromContext(c).CreateUser(ctx, u) if err != nil { retErr := fmt.Errorf("unable to create user %s: %w", u.GetName(), err) @@ -132,6 +134,11 @@ func GetAuthToken(c *gin.Context) { return } + l.WithFields(logrus.Fields{ + "user": ur.GetName(), + "user_id": ur.GetID(), + }).Info("new user created") + // return the jwt access token c.JSON(http.StatusOK, library.Token{Token: &at}) @@ -156,7 +163,7 @@ func GetAuthToken(c *gin.Context) { u.SetRefreshToken(rt) // send API call to update the user in the database - _, err = database.FromContext(c).UpdateUser(ctx, u) + ur, err := database.FromContext(c).UpdateUser(ctx, u) if err != nil { retErr := fmt.Errorf("unable to update user %s: %w", u.GetName(), err) @@ -165,6 +172,11 @@ func GetAuthToken(c *gin.Context) { return } + l.WithFields(logrus.Fields{ + "user": ur.GetName(), + "user_id": ur.GetID(), + }).Info("user updated - new token") + // return the user with their jwt access token c.JSON(http.StatusOK, library.Token{Token: &at}) } diff --git a/api/auth/login.go b/api/auth/login.go index 05b975f8d..f2bf5adc5 100644 --- a/api/auth/login.go +++ b/api/auth/login.go @@ -40,6 +40,7 @@ import ( func Login(c *gin.Context) { // load the metadata m := c.MustGet("metadata").(*internal.Metadata) + l := c.MustGet("logger").(*logrus.Entry) // capture query params t := util.FormParameter(c, "type") @@ -51,18 +52,20 @@ func Login(c *gin.Context) { // default path (headless mode) path := "/authenticate" + l.Info("logging in user") + // handle web and cli logins switch t { case "web": r = fmt.Sprintf("%s/authenticate/%s", m.Vela.Address, t) - logrus.Debugf("web login request, setting redirect to: %s", r) + l.Infof("web login request, setting redirect to: %s", r) case "cli": // port must be supplied if len(p) > 0 { r = fmt.Sprintf("%s/authenticate/%s/%s", m.Vela.Address, t, p) - logrus.Debugf("cli login request, setting redirect to: %s", r) + l.Infof("cli login request, setting redirect to: %s", r) } } diff --git a/api/auth/logout.go b/api/auth/logout.go index 8c0af25fa..9acb575cd 100644 --- a/api/auth/logout.go +++ b/api/auth/logout.go @@ -45,25 +45,19 @@ import ( func Logout(c *gin.Context) { // grab the metadata to help deal with the cookie m := c.MustGet("metadata").(*internal.Metadata) + l := c.MustGet("logger").(*logrus.Entry) // capture middleware values u := user.Retrieve(c) ctx := c.Request.Context() - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logger := logrus.WithFields(logrus.Fields{ - "user": u.GetName(), - }) - - logger.Infof("logging out user %s", u.GetName()) + l.Debug("logging out user") // parse the address for the backend server // so we can set it for the cookie domain addr, err := url.Parse(m.Vela.Address) if err != nil { // silently fail - logger.Error("unable to parse Vela address during logout") + l.Error("unable to parse Vela address during logout") } // set the same samesite attribute we used to create the cookie @@ -86,6 +80,8 @@ func Logout(c *gin.Context) { return } + l.Info("updated user - logged out") + // return 200 for successful logout c.JSON(http.StatusOK, "ok") } diff --git a/api/auth/post_token.go b/api/auth/post_token.go index 929ef17ca..d5fc345c9 100644 --- a/api/auth/post_token.go +++ b/api/auth/post_token.go @@ -7,6 +7,7 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" "github.com/go-vela/server/database" "github.com/go-vela/server/internal/token" @@ -48,6 +49,7 @@ import ( // a user logging in using PAT to Vela from the API. func PostAuthToken(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) ctx := c.Request.Context() // attempt to get user from source @@ -60,16 +62,23 @@ func PostAuthToken(c *gin.Context) { return } + l.Infof("SCM user %s authenticated using PAT", u.GetName()) + // check if the user exists u, err = database.FromContext(c).GetUserForName(ctx, u.GetName()) if err != nil { - retErr := fmt.Errorf("user %s not found", u.GetName()) + retErr := fmt.Errorf("unable to authenticate: user %s not found", u.GetName()) util.HandleError(c, http.StatusUnauthorized, retErr) return } + l.WithFields(logrus.Fields{ + "user": u.GetName(), + "user_id": u.GetID(), + }).Info("user successfully authenticated via SCM PAT") + // We don't need refresh token for this scenario // We only need access token and are configured based on the config defined tm := c.MustGet("token-manager").(*token.Manager) @@ -80,14 +89,14 @@ func PostAuthToken(c *gin.Context) { TokenType: constants.UserAccessTokenType, TokenDuration: tm.UserAccessTokenDuration, } - at, err := tm.MintToken(amto) + at, err := tm.MintToken(amto) if err != nil { retErr := fmt.Errorf("unable to compose token for user %s: %w", u.GetName(), err) util.HandleError(c, http.StatusServiceUnavailable, retErr) } - // return the user with their jwt access token + // return jwt access token c.JSON(http.StatusOK, library.Token{Token: &at}) } diff --git a/api/auth/redirect.go b/api/auth/redirect.go index 7837ca07e..83022abc5 100644 --- a/api/auth/redirect.go +++ b/api/auth/redirect.go @@ -70,8 +70,9 @@ import ( func GetAuthRedirect(c *gin.Context) { // load the metadata m := c.MustGet("metadata").(*internal.Metadata) + l := c.MustGet("logger").(*logrus.Entry) - logrus.Info("redirecting for final auth flow destination") + l.Debug("redirecting for final auth flow destination") // capture the path elements t := util.PathParameter(c, "type") diff --git a/api/auth/refresh.go b/api/auth/refresh.go index 0dc10b7e7..69d61bb1e 100644 --- a/api/auth/refresh.go +++ b/api/auth/refresh.go @@ -7,6 +7,7 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" "github.com/go-vela/server/internal/token" "github.com/go-vela/server/router/middleware/auth" @@ -36,6 +37,10 @@ import ( // RefreshAccessToken will return a new access token if the provided // refresh token via cookie is valid. func RefreshAccessToken(c *gin.Context) { + l := c.MustGet("logger").(*logrus.Entry) + + l.Info("refreshing access token") + // capture the refresh token // TODO: move this into token package and do it internally // since we are already passsing context diff --git a/api/auth/validate.go b/api/auth/validate.go index 3282baafb..40bab2c38 100644 --- a/api/auth/validate.go +++ b/api/auth/validate.go @@ -8,6 +8,7 @@ import ( "strings" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" "github.com/go-vela/server/router/middleware/claims" "github.com/go-vela/server/util" @@ -35,8 +36,11 @@ import ( // ValidateServerToken will validate if a token was issued by the server // if it is provided in the auth header. func ValidateServerToken(c *gin.Context) { + l := c.MustGet("logger").(*logrus.Entry) cl := claims.Retrieve(c) + l.Info("validating server token") + if !strings.EqualFold(cl.Subject, "vela-server") { retErr := fmt.Errorf("token is not a valid server token") diff --git a/api/auth/validate_oauth.go b/api/auth/validate_oauth.go index b96918325..25325a353 100644 --- a/api/auth/validate_oauth.go +++ b/api/auth/validate_oauth.go @@ -7,6 +7,7 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" "github.com/go-vela/server/scm" "github.com/go-vela/server/util" @@ -40,8 +41,11 @@ import ( // validate that a user OAuth token was created by Vela. func ValidateOAuthToken(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) ctx := c.Request.Context() + l.Info("validating oauth token") + token := c.Request.Header.Get("Token") if len(token) == 0 { retErr := fmt.Errorf("unable to validate oauth token: no token provided in header") diff --git a/api/badge.go b/api/badge.go index c926c64f3..9aed49600 100644 --- a/api/badge.go +++ b/api/badge.go @@ -9,7 +9,6 @@ import ( "github.com/sirupsen/logrus" "github.com/go-vela/server/database" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/util" "github.com/go-vela/types/constants" @@ -51,19 +50,13 @@ import ( // return a build status badge. func GetBadge(c *gin.Context) { // capture middleware values - o := org.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) r := repo.Retrieve(c) ctx := c.Request.Context() branch := util.QueryParameter(c, "branch", r.GetBranch()) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "org": o, - "repo": r.GetName(), - }).Infof("creating latest build badge for repo %s on branch %s", r.GetFullName(), branch) + l.Debugf("creating latest build badge for repo %s on branch %s", r.GetFullName(), branch) // send API call to capture the last build for the repo and branch b, err := database.FromContext(c).LastBuildForRepo(ctx, r, branch) diff --git a/api/build/approve.go b/api/build/approve.go index cc7159d53..86c491c04 100644 --- a/api/build/approve.go +++ b/api/build/approve.go @@ -15,7 +15,6 @@ import ( "github.com/go-vela/server/queue" "github.com/go-vela/server/queue/models" "github.com/go-vela/server/router/middleware/build" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" @@ -72,20 +71,13 @@ import ( // ApproveBuild represents the API handler to approve a build to run. func ApproveBuild(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) b := build.Retrieve(c) - o := org.Retrieve(c) r := repo.Retrieve(c) u := user.Retrieve(c) ctx := c.Request.Context() - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logger := logrus.WithFields(logrus.Fields{ - "org": o, - "repo": r.GetName(), - "user": u.GetName(), - }) + l.Debugf("approving build %d", b.GetID()) // verify build is in correct status if !strings.EqualFold(b.GetStatus(), constants.StatusPendingApproval) { @@ -103,8 +95,6 @@ func ApproveBuild(c *gin.Context) { return } - logger.Debugf("user %s approved build %s/%d for execution", u.GetName(), r.GetFullName(), b.GetNumber()) - // set fields b.SetStatus(constants.StatusPending) b.SetApprovedAt(time.Now().Unix()) @@ -113,9 +103,11 @@ func ApproveBuild(c *gin.Context) { // update the build in the db _, err := database.FromContext(c).UpdateBuild(ctx, b) if err != nil { - logrus.Errorf("Failed to update build %d during publish to queue for %s: %v", b.GetNumber(), r.GetFullName(), err) + l.Errorf("failed to update build during publish to queue: %v", err) } + l.Info("build updated - user approved build execution") + // publish the build to the queue go Enqueue( ctx, diff --git a/api/build/auto_cancel.go b/api/build/auto_cancel.go index 62b2922a1..d1ba091fe 100644 --- a/api/build/auto_cancel.go +++ b/api/build/auto_cancel.go @@ -12,6 +12,7 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" @@ -23,6 +24,17 @@ import ( // AutoCancel is a helper function that checks to see if any pending or running // builds for the repo can be replaced by the current build. func AutoCancel(c *gin.Context, b *types.Build, rB *types.Build, cancelOpts *pipeline.CancelOptions) (bool, error) { + l := c.MustGet("logger").(*logrus.Entry) + + // in this path, the middleware doesn't inject build, + // so we need to set it manually + l = l.WithFields(logrus.Fields{ + "build": b.GetNumber(), + "build_id": b.GetID(), + }) + + l.Debug("checking if builds should be auto canceled") + // if build is the current build, continue if rB.GetID() == b.GetID() { return false, nil @@ -44,6 +56,11 @@ func AutoCancel(c *gin.Context, b *types.Build, rB *types.Build, cancelOpts *pip return false, err } + l.WithFields(logrus.Fields{ + "build": rB.GetNumber(), + "build_id": rB.GetID(), + }).Info("build updated - build canceled") + // remove executable from table _, err = database.FromContext(c).PopBuildExecutable(c, rB.GetID()) if err != nil { @@ -67,6 +84,11 @@ func AutoCancel(c *gin.Context, b *types.Build, rB *types.Build, cancelOpts *pip // if this call fails, we still canceled the build, so return true return true, err } + + l.WithFields(logrus.Fields{ + "build": rB.GetNumber(), + "build_id": rB.GetID(), + }).Info("build updated - build canceled") } return true, nil @@ -75,6 +97,8 @@ func AutoCancel(c *gin.Context, b *types.Build, rB *types.Build, cancelOpts *pip // cancelRunning is a helper function that determines the executor currently running a build and sends an API call // to that executor's worker to cancel the build. func cancelRunning(c *gin.Context, b *types.Build) error { + l := c.MustGet("logger").(*logrus.Entry) + e := new([]types.Executor) // retrieve the worker w, err := database.FromContext(c).GetWorkerForHostname(c, b.GetHost()) @@ -170,6 +194,8 @@ func cancelRunning(c *gin.Context, b *types.Build) error { } defer resp.Body.Close() + l.Debugf("sent cancel request to worker %s (executor %d) for build %d", w.GetHostname(), executor.GetID(), b.GetID()) + // Read Response Body respBody, err := io.ReadAll(resp.Body) if err != nil { diff --git a/api/build/cancel.go b/api/build/cancel.go index e4ee0b84e..79d186799 100644 --- a/api/build/cancel.go +++ b/api/build/cancel.go @@ -17,7 +17,6 @@ import ( "github.com/go-vela/server/internal/token" "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/executors" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" @@ -76,24 +75,16 @@ import ( //nolint:funlen // ignore statement count func CancelBuild(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) b := build.Retrieve(c) e := executors.Retrieve(c) - o := org.Retrieve(c) r := repo.Retrieve(c) user := user.Retrieve(c) ctx := c.Request.Context() entry := fmt.Sprintf("%s/%d", r.GetFullName(), b.GetNumber()) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "build": b.GetNumber(), - "org": o, - "repo": r.GetName(), - "user": user.GetName(), - }).Infof("canceling build %s", entry) + l.Debugf("canceling build %s", entry) switch b.GetStatus() { case constants.StatusRunning: @@ -182,6 +173,11 @@ func CancelBuild(c *gin.Context) { return } + l.WithFields(logrus.Fields{ + "build": b.GetNumber(), + "build_id": b.GetID(), + }).Info("build updated - build canceled") + c.JSON(resp.StatusCode, b) return @@ -211,6 +207,11 @@ func CancelBuild(c *gin.Context) { return } + l.WithFields(logrus.Fields{ + "build": b.GetNumber(), + "build_id": b.GetID(), + }).Info("build updated - build canceled") + // remove build executable for clean up _, err = database.FromContext(c).PopBuildExecutable(ctx, b.GetID()) if err != nil { diff --git a/api/build/clean.go b/api/build/clean.go index 8473c25e1..5c70b5164 100644 --- a/api/build/clean.go +++ b/api/build/clean.go @@ -19,6 +19,16 @@ import ( // without execution. This will kill all resources, // like steps and services, for the build. func CleanBuild(ctx context.Context, database database.Interface, b *types.Build, services []*library.Service, steps []*library.Step, e error) { + l := logrus.WithFields(logrus.Fields{ + "build": b.GetNumber(), + "build_id": b.GetID(), + "org": b.GetRepo().GetOrg(), + "repo": b.GetRepo().GetName(), + "repo_id": b.GetRepo().GetID(), + }) + + l.Debug("cleaning build") + // update fields in build object b.SetError(fmt.Sprintf("unable to publish to queue: %s", e.Error())) b.SetStatus(constants.StatusError) @@ -27,9 +37,11 @@ func CleanBuild(ctx context.Context, database database.Interface, b *types.Build // send API call to update the build b, err := database.UpdateBuild(ctx, b) if err != nil { - logrus.Errorf("unable to kill build %d: %v", b.GetNumber(), err) + l.Errorf("unable to kill build %d: %v", b.GetNumber(), err) } + l.Info("build updated - build cleaned") + for _, s := range services { // update fields in service object s.SetStatus(constants.StatusKilled) @@ -38,8 +50,13 @@ func CleanBuild(ctx context.Context, database database.Interface, b *types.Build // send API call to update the service _, err := database.UpdateService(ctx, s) if err != nil { - logrus.Errorf("unable to kill service %s for build %d: %v", s.GetName(), b.GetNumber(), err) + l.Errorf("unable to kill service %s for build %d: %v", s.GetName(), b.GetNumber(), err) } + + l.WithFields(logrus.Fields{ + "service": s.GetName(), + "service_id": s.GetID(), + }).Info("service updated - service cleaned") } for _, s := range steps { @@ -50,7 +67,12 @@ func CleanBuild(ctx context.Context, database database.Interface, b *types.Build // send API call to update the step _, err := database.UpdateStep(ctx, s) if err != nil { - logrus.Errorf("unable to kill step %s for build %d: %v", s.GetName(), b.GetNumber(), err) + l.Errorf("unable to kill step %s for build %d: %v", s.GetName(), b.GetNumber(), err) } + + l.WithFields(logrus.Fields{ + "step": s.GetName(), + "step_id": s.GetID(), + }).Info("step updated - step cleaned") } } diff --git a/api/build/compile_publish.go b/api/build/compile_publish.go index 29f2cdac2..a4e458c7a 100644 --- a/api/build/compile_publish.go +++ b/api/build/compile_publish.go @@ -49,7 +49,15 @@ func CompileAndPublish( compiler compiler.Engine, queue queue.Service, ) (*pipeline.Build, *models.Item, int, error) { - logrus.Debugf("generating queue items for build %s/%d", cfg.Build.GetRepo().GetFullName(), cfg.Build.GetNumber()) + logger := logrus.WithFields(logrus.Fields{ + "org": cfg.Build.GetRepo().GetOrg(), + "repo": cfg.Build.GetRepo().GetName(), + "repo_id": cfg.Build.GetRepo().GetID(), + "build": cfg.Build.GetNumber(), + "build_id": cfg.Build.GetID(), + }) + + logger.Debug("generating queue items") // assign variables from form for readibility r := cfg.Build.GetRepo() @@ -118,7 +126,7 @@ func CompileAndPublish( return nil, nil, http.StatusInternalServerError, retErr } - logrus.Debugf("currently %d builds running on repo %s", builds, r.GetFullName()) + logger.Debugf("currently %d builds running on repo %s", builds, r.GetFullName()) // check if the number of pending and running builds exceeds the limit for the repo if builds >= r.GetBuildLimit() { @@ -186,7 +194,7 @@ func CompileAndPublish( // failing to successfully process the request. This logic ensures we attempt our // best efforts to handle these cases gracefully. for i := 0; i < cfg.Retries; i++ { - logrus.Debugf("compilation loop - attempt %d", i+1) + logger.Debugf("compilation loop - attempt %d", i+1) // check if we're on the first iteration of the loop if i > 0 { // incrementally sleep in between retries @@ -214,7 +222,7 @@ func CompileAndPublish( // check if the retry limit has been exceeded if i < cfg.Retries-1 { - logrus.WithError(retErr).Warningf("retrying #%d", i+1) + logger.WithError(retErr).Warningf("retrying #%d", i+1) // continue to the next iteration of the loop continue @@ -267,7 +275,7 @@ func CompileAndPublish( err = fmt.Errorf("unable to compile pipeline configuration for %s: %w", repo.GetFullName(), err) // log the error for traceability - logrus.Error(err.Error()) + logger.Error(err.Error()) return nil, nil, http.StatusInternalServerError, fmt.Errorf("%s: %w", baseErr, err) } @@ -289,7 +297,7 @@ func CompileAndPublish( // send API call to set the status on the commit err = scm.Status(c, u, b, repo.GetOrg(), repo.GetName()) if err != nil { - logrus.Errorf("unable to set commit status for %s/%d: %v", repo.GetFullName(), b.GetNumber(), err) + logger.Errorf("unable to set commit status for %s/%d: %v", repo.GetFullName(), b.GetNumber(), err) } return nil, @@ -314,7 +322,7 @@ func CompileAndPublish( // check if the retry limit has been exceeded if i < cfg.Retries-1 { - logrus.WithError(retErr).Warningf("retrying #%d", i+1) + logger.WithError(retErr).Warningf("retrying #%d", i+1) // continue to the next iteration of the loop continue @@ -322,6 +330,13 @@ func CompileAndPublish( return nil, nil, http.StatusInternalServerError, retErr } + + logger.WithFields(logrus.Fields{ + "pipeline": pipeline.GetID(), + "org": repo.GetOrg(), + "repo": repo.GetName(), + "repo_id": repo.GetID(), + }).Info("pipeline created") } b.SetPipelineID(pipeline.GetID()) @@ -339,7 +354,7 @@ func CompileAndPublish( // check if the retry limit has been exceeded if i < cfg.Retries-1 { - logrus.WithError(retErr).Warningf("retrying #%d", i+1) + logger.WithError(retErr).Warningf("retrying #%d", i+1) // reset fields set by cleanBuild for retry b.SetError("") @@ -365,6 +380,12 @@ func CompileAndPublish( return nil, nil, http.StatusInternalServerError, retErr } + logger.WithFields(logrus.Fields{ + "org": repo.GetOrg(), + "repo": repo.GetName(), + "repo_id": repo.GetID(), + }).Info("repo updated - counter incremented") + // return error if pipeline didn't get populated if p == nil { retErr := fmt.Errorf("%s: failed to set pipeline for %s: %w", baseErr, repo.GetFullName(), err) diff --git a/api/build/create.go b/api/build/create.go index e3745cfeb..8fef779c7 100644 --- a/api/build/create.go +++ b/api/build/create.go @@ -14,9 +14,7 @@ import ( "github.com/go-vela/server/database" "github.com/go-vela/server/internal" "github.com/go-vela/server/queue" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" "github.com/go-vela/server/util" ) @@ -82,21 +80,11 @@ import ( func CreateBuild(c *gin.Context) { // capture middleware values m := c.MustGet("metadata").(*internal.Metadata) - o := org.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) r := repo.Retrieve(c) - u := user.Retrieve(c) ctx := c.Request.Context() - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logger := logrus.WithFields(logrus.Fields{ - "org": o, - "repo": r.GetName(), - "user": u.GetName(), - }) - - logger.Infof("creating new build for repo %s", r.GetFullName()) + l.Debugf("creating new build for repo %s", r.GetFullName()) // capture body from API request input := new(types.Build) @@ -152,6 +140,11 @@ func CreateBuild(c *gin.Context) { return } + l.WithFields(logrus.Fields{ + "build": item.Build.GetNumber(), + "build_id": item.Build.GetID(), + }).Info("build created") + c.JSON(http.StatusCreated, item.Build) // publish the build to the queue diff --git a/api/build/delete.go b/api/build/delete.go index e4330ecc2..c7824e3f7 100644 --- a/api/build/delete.go +++ b/api/build/delete.go @@ -11,9 +11,7 @@ import ( "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" ) @@ -68,23 +66,14 @@ import ( // a build for a repo. func DeleteBuild(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) b := build.Retrieve(c) - o := org.Retrieve(c) r := repo.Retrieve(c) - u := user.Retrieve(c) ctx := c.Request.Context() entry := fmt.Sprintf("%s/%d", r.GetFullName(), b.GetNumber()) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "build": b.GetNumber(), - "org": o, - "repo": r.GetName(), - "user": u.GetName(), - }).Infof("deleting build %s", entry) + l.Debugf("deleting build %s", entry) // send API call to remove the build err := database.FromContext(c).DeleteBuild(ctx, b) diff --git a/api/build/enqueue.go b/api/build/enqueue.go index 297a974f5..aa87f4473 100644 --- a/api/build/enqueue.go +++ b/api/build/enqueue.go @@ -16,11 +16,19 @@ import ( // Enqueue is a helper function that pushes a queue item (build, repo, user) to the queue. func Enqueue(ctx context.Context, queue queue.Service, db database.Interface, item *models.Item, route string) { - logrus.Infof("Converting queue item to json for build %d for %s", item.Build.GetNumber(), item.Build.GetRepo().GetFullName()) + l := logrus.WithFields(logrus.Fields{ + "build": item.Build.GetNumber(), + "build_id": item.Build.GetID(), + "org": item.Build.GetRepo().GetOrg(), + "repo": item.Build.GetRepo().GetName(), + "repo_id": item.Build.GetRepo().GetID(), + }) + + l.Debug("adding item to queue") byteItem, err := json.Marshal(item) if err != nil { - logrus.Errorf("Failed to convert item to json for build %d for %s: %v", item.Build.GetNumber(), item.Build.GetRepo().GetFullName(), err) + l.Errorf("failed to convert item to json: %v", err) // error out the build CleanBuild(ctx, db, item.Build, nil, nil, err) @@ -28,16 +36,16 @@ func Enqueue(ctx context.Context, queue queue.Service, db database.Interface, it return } - logrus.Infof("Pushing item for build %d for %s to queue route %s", item.Build.GetNumber(), item.Build.GetRepo().GetFullName(), route) + l.Debugf("pushing item for build to queue route %s", route) // push item on to the queue err = queue.Push(context.Background(), route, byteItem) if err != nil { - logrus.Errorf("Retrying; Failed to publish build %d for %s: %v", item.Build.GetNumber(), item.Build.GetRepo().GetFullName(), err) + l.Errorf("retrying; failed to publish build: %v", err) err = queue.Push(context.Background(), route, byteItem) if err != nil { - logrus.Errorf("Failed to publish build %d for %s: %v", item.Build.GetNumber(), item.Build.GetRepo().GetFullName(), err) + l.Errorf("failed to publish build: %v", err) // error out the build CleanBuild(ctx, db, item.Build, nil, nil, err) @@ -52,6 +60,8 @@ func Enqueue(ctx context.Context, queue queue.Service, db database.Interface, it // update the build in the db to reflect the time it was enqueued _, err = db.UpdateBuild(ctx, item.Build) if err != nil { - logrus.Errorf("Failed to update build %d during publish to queue for %s: %v", item.Build.GetNumber(), item.Build.GetRepo().GetFullName(), err) + l.Errorf("failed to update build during publish to queue: %v", err) } + + l.Info("updated build as enqueued") } diff --git a/api/build/executable.go b/api/build/executable.go index a5d250cbc..19f66c3a6 100644 --- a/api/build/executable.go +++ b/api/build/executable.go @@ -14,8 +14,6 @@ import ( "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" - "github.com/go-vela/server/router/middleware/claims" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/util" "github.com/go-vela/types/library" @@ -74,21 +72,12 @@ import ( // a build executable for a repository. func GetBuildExecutable(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) b := build.Retrieve(c) - o := org.Retrieve(c) r := repo.Retrieve(c) - cl := claims.Retrieve(c) ctx := c.Request.Context() - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "build": b.GetNumber(), - "org": o, - "repo": r.GetName(), - "subject": cl.Subject, - }).Infof("reading build executable %s/%d", r.GetFullName(), b.GetNumber()) + l.Debugf("reading build executable %s/%d", r.GetFullName(), b.GetNumber()) // send database call to pop the requested build executable from the table bExecutable, err := database.FromContext(c).PopBuildExecutable(ctx, b.GetID()) @@ -108,7 +97,7 @@ func PublishBuildExecutable(ctx context.Context, db database.Interface, p *pipel // marshal pipeline build into byte data to add to the build executable object byteExecutable, err := json.Marshal(p) if err != nil { - logrus.Errorf("Failed to marshal build executable: %v", err) + logrus.Errorf("failed to marshal build executable: %v", err) // error out the build CleanBuild(ctx, db, b, nil, nil, err) @@ -124,7 +113,7 @@ func PublishBuildExecutable(ctx context.Context, db database.Interface, p *pipel // send database call to create a build executable err = db.CreateBuildExecutable(ctx, bExecutable) if err != nil { - logrus.Errorf("Failed to publish build executable to database: %v", err) + logrus.Errorf("failed to publish build executable to database: %v", err) // error out the build CleanBuild(ctx, db, b, nil, nil, err) @@ -132,5 +121,9 @@ func PublishBuildExecutable(ctx context.Context, db database.Interface, p *pipel return err } + logrus.WithFields(logrus.Fields{ + "build_executable_id": bExecutable.GetBuildID(), + }).Info("created build executable") + return nil } diff --git a/api/build/get.go b/api/build/get.go index df8c87bfd..773cec777 100644 --- a/api/build/get.go +++ b/api/build/get.go @@ -9,9 +9,7 @@ import ( "github.com/sirupsen/logrus" "github.com/go-vela/server/router/middleware/build" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" - "github.com/go-vela/server/router/middleware/user" ) // swagger:operation GET /api/v1/repos/{org}/{repo}/builds/{build} builds GetBuild @@ -62,20 +60,11 @@ import ( // a build for a repository. func GetBuild(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) b := build.Retrieve(c) - o := org.Retrieve(c) r := repo.Retrieve(c) - u := user.Retrieve(c) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "build": b.GetNumber(), - "org": o, - "repo": r.GetName(), - "user": u.GetName(), - }).Infof("reading build %s/%d", r.GetFullName(), b.GetNumber()) + l.Debugf("reading build %s/%d", r.GetFullName(), b.GetNumber()) c.JSON(http.StatusOK, b) } diff --git a/api/build/get_id.go b/api/build/get_id.go index f27fde5f2..2a9e4201e 100644 --- a/api/build/get_id.go +++ b/api/build/get_id.go @@ -53,6 +53,7 @@ import ( // build by its id. func GetBuildByID(c *gin.Context) { // Capture user from middleware + l := c.MustGet("logger").(*logrus.Entry) u := user.Retrieve(c) ctx := c.Request.Context() @@ -66,13 +67,7 @@ func GetBuildByID(c *gin.Context) { return } - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "build": id, - "user": u.GetName(), - }).Infof("reading build %d", id) + l.Debugf("reading build %d", id) // Get build from database b, err := database.FromContext(c).GetBuild(ctx, id) @@ -88,7 +83,7 @@ func GetBuildByID(c *gin.Context) { // just retrieving any build using a random id number. perm, err := scm.FromContext(c).RepoAccess(ctx, u.GetName(), u.GetToken(), b.GetRepo().GetOrg(), b.GetRepo().GetName()) if err != nil { - logrus.Errorf("unable to get user %s access level for repo %s", u.GetName(), b.GetRepo().GetFullName()) + l.Errorf("unable to get user %s access level for repo %s", u.GetName(), b.GetRepo().GetFullName()) } // Ensure that user has at least read access to repo to return the build diff --git a/api/build/graph.go b/api/build/graph.go index e7207625c..5fb3ea1ee 100644 --- a/api/build/graph.go +++ b/api/build/graph.go @@ -15,7 +15,6 @@ import ( "github.com/go-vela/server/database" "github.com/go-vela/server/internal" "github.com/go-vela/server/router/middleware/build" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" @@ -143,29 +142,18 @@ const ( //nolint:funlen,goconst,gocyclo // ignore function length and constants func GetBuildGraph(c *gin.Context) { // capture middleware values + m := c.MustGet("metadata").(*internal.Metadata) + l := c.MustGet("logger").(*logrus.Entry) b := build.Retrieve(c) - o := org.Retrieve(c) r := repo.Retrieve(c) u := user.Retrieve(c) - m := c.MustGet("metadata").(*internal.Metadata) ctx := c.Request.Context() - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields entry := fmt.Sprintf("%s/%d", r.GetFullName(), b.GetNumber()) - logger := logrus.WithFields(logrus.Fields{ - "build": b.GetNumber(), - "org": o, - "repo": r.GetName(), - "user": u.GetName(), - }) baseErr := "unable to retrieve graph" - logger.Infof("constructing graph for build %s", entry) - - logger.Info("retrieving pipeline configuration") + l.Debugf("constructing graph for build %s and retrieving pipeline configuration", entry) var config []byte @@ -210,7 +198,7 @@ func GetBuildGraph(c *gin.Context) { } } - logger.Info("compiling pipeline configuration") + l.Debug("compiling pipeline configuration") // parse and compile the pipeline configuration file p, _, err := compiler.FromContext(c). @@ -226,7 +214,7 @@ func GetBuildGraph(c *gin.Context) { // format the error message with extra information err = fmt.Errorf("unable to compile pipeline configuration for %s: %w", r.GetFullName(), err) - logger.Error(err.Error()) + l.Error(err.Error()) retErr := fmt.Errorf("%s: %w", baseErr, err) @@ -238,7 +226,7 @@ func GetBuildGraph(c *gin.Context) { if p == nil { retErr := fmt.Errorf("unable to compile pipeline configuration for %s: pipeline is nil", r.GetFullName()) - logger.Error(retErr) + l.Error(retErr) util.HandleError(c, http.StatusInternalServerError, retErr) @@ -331,7 +319,7 @@ func GetBuildGraph(c *gin.Context) { return } - logger.Info("generating build graph") + l.Debug("generating build graph") // create nodes from pipeline stages nodes := make(map[int]*node) diff --git a/api/build/id_request_token.go b/api/build/id_request_token.go index 22e4d117c..77869a44c 100644 --- a/api/build/id_request_token.go +++ b/api/build/id_request_token.go @@ -15,7 +15,6 @@ import ( "github.com/go-vela/server/constants" "github.com/go-vela/server/internal/token" "github.com/go-vela/server/router/middleware/build" - "github.com/go-vela/server/router/middleware/claims" "github.com/go-vela/server/util" "github.com/go-vela/types/library" ) @@ -82,18 +81,10 @@ import ( // GetIDRequestToken represents the API handler to generate and return an ID request token. func GetIDRequestToken(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) b := build.Retrieve(c) - cl := claims.Retrieve(c) - - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "build": b.GetNumber(), - "org": b.GetRepo().GetOrg(), - "repo": b.GetRepo().GetName(), - "user": cl.Subject, - }).Infof("generating ID request token for build %s/%d", b.GetRepo().GetFullName(), b.GetNumber()) + + l.Infof("generating ID request token for build %s/%d", b.GetRepo().GetFullName(), b.GetNumber()) image := c.Query("image") if len(image) == 0 { diff --git a/api/build/id_token.go b/api/build/id_token.go index 54744e983..e049dcebd 100644 --- a/api/build/id_token.go +++ b/api/build/id_token.go @@ -75,19 +75,12 @@ import ( // GetIDToken represents the API handler to generate a id token. func GetIDToken(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) b := build.Retrieve(c) cl := claims.Retrieve(c) ctx := c.Request.Context() - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "build": b.GetNumber(), - "org": b.GetRepo().GetOrg(), - "repo": b.GetRepo().GetName(), - "subject": cl.Subject, - }).Infof("generating ID token for build %s/%d", b.GetRepo().GetFullName(), b.GetNumber()) + l.Infof("generating ID token for build %s/%d", b.GetRepo().GetFullName(), b.GetNumber()) // retrieve token manager from context tm := c.MustGet("token-manager").(*token.Manager) diff --git a/api/build/list_org.go b/api/build/list_org.go index ff516c39c..339baa0df 100644 --- a/api/build/list_org.go +++ b/api/build/list_org.go @@ -111,17 +111,12 @@ func ListBuildsForOrg(c *gin.Context) { ) // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) o := org.Retrieve(c) u := user.Retrieve(c) ctx := c.Request.Context() - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "org": o, - "user": u.GetName(), - }).Infof("listing builds for org %s", o) + l.Debugf("listing builds for org %s", o) // capture the branch name parameter branch := c.Query("branch") @@ -196,7 +191,7 @@ func ListBuildsForOrg(c *gin.Context) { // See if the user is an org admin to bypass individual permission checks perm, err := scm.FromContext(c).OrgAccess(ctx, u, o) if err != nil { - logrus.Errorf("unable to get user %s access level for org %s", u.GetName(), o) + l.Errorf("unable to get user %s access level for org %s", u.GetName(), o) } // Only show public repos to non-admins if perm != "admin" { diff --git a/api/build/list_repo.go b/api/build/list_repo.go index f631e68ef..b4771eefe 100644 --- a/api/build/list_repo.go +++ b/api/build/list_repo.go @@ -14,9 +14,7 @@ import ( "github.com/go-vela/server/api" "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/constants" ) @@ -135,19 +133,11 @@ func ListBuildsForRepo(c *gin.Context) { ) // capture middleware values - o := org.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) r := repo.Retrieve(c) - u := user.Retrieve(c) ctx := c.Request.Context() - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "org": o, - "repo": r.GetName(), - "user": u.GetName(), - }).Infof("listing builds for repo %s", r.GetFullName()) + l.Debugf("listing builds for repo %s", r.GetFullName()) // capture the branch name parameter branch := c.Query("branch") diff --git a/api/build/plan.go b/api/build/plan.go index f7c23b971..fcdcd2dff 100644 --- a/api/build/plan.go +++ b/api/build/plan.go @@ -7,6 +7,8 @@ import ( "fmt" "time" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/api/service" "github.com/go-vela/server/api/step" "github.com/go-vela/server/api/types" @@ -40,6 +42,11 @@ func PlanBuild(ctx context.Context, database database.Interface, scm scm.Service return fmt.Errorf("unable to create new build for %s: %w", r.GetFullName(), err) } + logrus.WithFields(logrus.Fields{ + "build": b.GetNumber(), + "build_id": b.GetID(), + }).Info("build created") + // plan all services for the build services, err := service.PlanServices(ctx, database, p, b) if err != nil { diff --git a/api/build/restart.go b/api/build/restart.go index 4cf0a21e0..aed5fccd4 100644 --- a/api/build/restart.go +++ b/api/build/restart.go @@ -16,7 +16,6 @@ import ( "github.com/go-vela/server/queue" "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/claims" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" @@ -84,9 +83,9 @@ import ( func RestartBuild(c *gin.Context) { // capture middleware values m := c.MustGet("metadata").(*internal.Metadata) + l := c.MustGet("logger").(*logrus.Entry) cl := claims.Retrieve(c) b := build.Retrieve(c) - o := org.Retrieve(c) r := repo.Retrieve(c) u := user.Retrieve(c) scm := scm.FromContext(c) @@ -94,15 +93,7 @@ func RestartBuild(c *gin.Context) { entry := fmt.Sprintf("%s/%d", r.GetFullName(), b.GetNumber()) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logger := logrus.WithFields(logrus.Fields{ - "build": b.GetNumber(), - "org": o, - "repo": r.GetName(), - "user": u.GetName(), - }) + l.Debugf("restarting build %d", b.GetNumber()) // a build that is in a pending approval state cannot be restarted if strings.EqualFold(b.GetStatus(), constants.StatusPendingApproval) { @@ -131,7 +122,7 @@ func RestartBuild(c *gin.Context) { // parent to the previous build b.SetParent(b.GetNumber()) - logger.Debugf("Generating queue items for build %s", entry) + l.Debugf("generating queue items for build %s", entry) // restart form config := CompileAndPublishConfig{ @@ -151,13 +142,17 @@ func RestartBuild(c *gin.Context) { compiler.FromContext(c), queue.FromContext(c), ) - if err != nil { util.HandleError(c, code, err) return } + l.WithFields(logrus.Fields{ + "new_build": item.Build.GetNumber(), + "new_build_id": item.Build.GetID(), + }).Info("build created via restart") + c.JSON(http.StatusCreated, item.Build) // publish the build to the queue diff --git a/api/build/token.go b/api/build/token.go index d58a60bc5..b2126bb84 100644 --- a/api/build/token.go +++ b/api/build/token.go @@ -14,7 +14,6 @@ import ( "github.com/go-vela/server/internal/token" "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/claims" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/util" "github.com/go-vela/types/constants" @@ -71,20 +70,12 @@ import ( // GetBuildToken represents the API handler to generate a build token. func GetBuildToken(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) b := build.Retrieve(c) - o := org.Retrieve(c) r := repo.Retrieve(c) cl := claims.Retrieve(c) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "build": b.GetNumber(), - "org": o, - "repo": r.GetName(), - "user": cl.Subject, - }).Infof("generating build token for build %s/%d", r.GetFullName(), b.GetNumber()) + l.Infof("generating build token for build %s/%d", r.GetFullName(), b.GetNumber()) // if build is not in a pending state, then a build token should not be needed - conflict if !strings.EqualFold(b.GetStatus(), constants.StatusPending) { diff --git a/api/build/update.go b/api/build/update.go index e5e3385a0..eabe94981 100644 --- a/api/build/update.go +++ b/api/build/update.go @@ -12,8 +12,6 @@ import ( "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" - "github.com/go-vela/server/router/middleware/claims" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/scm" "github.com/go-vela/server/util" @@ -78,23 +76,14 @@ import ( // a build for a repo. func UpdateBuild(c *gin.Context) { // capture middleware values - cl := claims.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) b := build.Retrieve(c) - o := org.Retrieve(c) r := repo.Retrieve(c) ctx := c.Request.Context() entry := fmt.Sprintf("%s/%d", r.GetFullName(), b.GetNumber()) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "build": b.GetNumber(), - "org": o, - "repo": r.GetName(), - "user": cl.Subject, - }).Infof("updating build %s", entry) + l.Debugf("updating build %s", entry) // capture body from API request input := new(types.Build) @@ -181,15 +170,26 @@ func UpdateBuild(c *gin.Context) { // send API call to set the status on the commit err = scm.FromContext(c).Status(ctx, r.GetOwner(), b, r.GetOrg(), r.GetName()) if err != nil { - logrus.Errorf("unable to set commit status for build %s: %v", entry, err) + l.Errorf("unable to set commit status for build %s: %v", entry, err) } } } // UpdateComponentStatuses updates all components (steps and services) for a build to a given status. func UpdateComponentStatuses(c *gin.Context, b *types.Build, status string) error { + l := c.MustGet("logger").(*logrus.Entry) ctx := c.Request.Context() + l = l.WithFields(logrus.Fields{ + "build": b.GetNumber(), + "build_id": b.GetID(), + "org": b.GetRepo().GetOrg(), + "repo": b.GetRepo().GetName(), + "repo_id": b.GetRepo().GetID(), + }) + + l.Debug("updating component statuses") + // retrieve the steps for the build from the step table steps := []*library.Step{} page := 1 @@ -222,6 +222,11 @@ func UpdateComponentStatuses(c *gin.Context, b *types.Build, status string) erro if err != nil { return err } + + l.WithFields(logrus.Fields{ + "step": step.GetNumber(), + "step_id": step.GetID(), + }).Infof("step status updated") } // retrieve the services for the build from the service table @@ -255,6 +260,11 @@ func UpdateComponentStatuses(c *gin.Context, b *types.Build, status string) erro if err != nil { return err } + + l.WithFields(logrus.Fields{ + "service": service.GetNumber(), + "service_id": service.GetID(), + }).Info("service status updated") } return nil diff --git a/api/dashboard/create.go b/api/dashboard/create.go index 38cb95115..104a59074 100644 --- a/api/dashboard/create.go +++ b/api/dashboard/create.go @@ -56,6 +56,7 @@ import ( // create a dashboard. func CreateDashboard(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) u := user.Retrieve(c) // capture body from API request @@ -77,12 +78,7 @@ func CreateDashboard(c *gin.Context) { return } - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "user": u.GetName(), - }).Infof("creating new dashboard %s", input.GetName()) + l.Debugf("creating new dashboard %s", input.GetName()) d := new(types.Dashboard) @@ -123,6 +119,11 @@ func CreateDashboard(c *gin.Context) { return } + l.WithFields(logrus.Fields{ + "dashboard": d.GetName(), + "dashboard_id": d.GetID(), + }).Info("dashboard created") + // add dashboard to claims' user's dashboard set u.SetDashboards(append(u.GetDashboards(), d.GetID())) @@ -136,6 +137,8 @@ func CreateDashboard(c *gin.Context) { return } + l.Infof("user updated with new dashboard %s", d.GetName()) + c.JSON(http.StatusCreated, d) } diff --git a/api/dashboard/delete.go b/api/dashboard/delete.go index bf921abe1..05b14e86b 100644 --- a/api/dashboard/delete.go +++ b/api/dashboard/delete.go @@ -56,16 +56,11 @@ import ( // DeleteDashboard represents the API handler to remove a dashboard. func DeleteDashboard(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) d := dashboard.Retrieve(c) u := user.Retrieve(c) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "dashboard": d.GetID(), - "user": u.GetName(), - }).Infof("deleting dashboard %s", d.GetID()) + l.Debugf("deleting dashboard %s", d.GetID()) if !isAdmin(d, u) { retErr := fmt.Errorf("unable to delete dashboard %s: user is not an admin", d.GetID()) diff --git a/api/dashboard/get.go b/api/dashboard/get.go index 4cc34e93d..c009e4127 100644 --- a/api/dashboard/get.go +++ b/api/dashboard/get.go @@ -13,7 +13,6 @@ import ( "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/dashboard" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" ) @@ -59,18 +58,12 @@ import ( // a dashboard for a repository. func GetDashboard(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) d := dashboard.Retrieve(c) - u := user.Retrieve(c) var err error - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "dashboard": d.GetID(), - "user": u.GetName(), - }).Infof("reading dashboard %s", d.GetID()) + l.Debugf("reading dashboard %s", d.GetID()) // initialize DashCard and set dashboard to the dashboard info pulled from database dashboard := new(types.DashCard) diff --git a/api/dashboard/list_user.go b/api/dashboard/list_user.go index c43a89f05..d2e8e300a 100644 --- a/api/dashboard/list_user.go +++ b/api/dashboard/list_user.go @@ -29,9 +29,10 @@ import ( // responses: // '200': // description: Successfully retrieved user dashboards -// type: json // schema: -// "$ref": "#/definitions/Dashboard" +// type: array +// items: +// "$ref": "#/definitions/DashCard" // '400': // description: Invalid request payload // schema: @@ -49,14 +50,10 @@ import ( // of dashboards for a user. func ListUserDashboards(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) u := user.Retrieve(c) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "user": u.GetName(), - }).Infof("listing dashboards for user %s", u.GetName()) + l.Debugf("listing dashboards for user %s", u.GetName()) var dashCards []types.DashCard diff --git a/api/dashboard/update.go b/api/dashboard/update.go index db11d4355..aec6affa4 100644 --- a/api/dashboard/update.go +++ b/api/dashboard/update.go @@ -62,9 +62,12 @@ import ( // UpdateDashboard represents the API handler to update a dashboard. func UpdateDashboard(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) d := dashboard.Retrieve(c) u := user.Retrieve(c) + l.Debugf("updating dashboard %s", d.GetID()) + if !isAdmin(d, u) { retErr := fmt.Errorf("unable to update dashboard %s: user is not an admin", d.GetID()) @@ -73,13 +76,6 @@ func UpdateDashboard(c *gin.Context) { return } - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "dashboard": d.GetID(), - }).Infof("updating dashboard %s", d.GetID()) - // capture body from API request input := new(types.Dashboard) diff --git a/api/deployment/create.go b/api/deployment/create.go index b596f75be..fa980e5e1 100644 --- a/api/deployment/create.go +++ b/api/deployment/create.go @@ -11,7 +11,6 @@ import ( "github.com/sirupsen/logrus" "github.com/go-vela/server/database" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" @@ -65,19 +64,12 @@ import ( // create a deployment. func CreateDeployment(c *gin.Context) { // capture middleware values - o := org.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) r := repo.Retrieve(c) u := user.Retrieve(c) ctx := c.Request.Context() - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "org": o, - "repo": r.GetName(), - "user": u.GetName(), - }).Infof("creating new deployment for repo %s", r.GetFullName()) + l.Debugf("creating new deployment for repo %s", r.GetFullName()) // capture body from API request input := new(library.Deployment) @@ -129,5 +121,9 @@ func CreateDeployment(c *gin.Context) { return } + l.WithFields(logrus.Fields{ + "deployment_id": d.GetID(), + }).Info("deployment created") + c.JSON(http.StatusCreated, d) } diff --git a/api/deployment/get.go b/api/deployment/get.go index 8f890ab77..5c978cf64 100644 --- a/api/deployment/get.go +++ b/api/deployment/get.go @@ -11,7 +11,6 @@ import ( "github.com/sirupsen/logrus" "github.com/go-vela/server/database" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" @@ -68,7 +67,7 @@ import ( // GetDeployment represents the API handler to get a deployment. func GetDeployment(c *gin.Context) { // capture middleware values - o := org.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) r := repo.Retrieve(c) u := user.Retrieve(c) deployment := util.PathParameter(c, "deployment") @@ -76,14 +75,7 @@ func GetDeployment(c *gin.Context) { entry := fmt.Sprintf("%s/%s", r.GetFullName(), deployment) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "org": o, - "repo": r.GetName(), - "user": u.GetName(), - }).Infof("reading deployment %s", entry) + l.Debugf("reading deployment %s", entry) number, err := strconv.Atoi(deployment) if err != nil { diff --git a/api/deployment/list.go b/api/deployment/list.go index b07e3ba0a..34f4c74a2 100644 --- a/api/deployment/list.go +++ b/api/deployment/list.go @@ -12,9 +12,7 @@ import ( "github.com/go-vela/server/api" "github.com/go-vela/server/database" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" ) @@ -83,18 +81,10 @@ import ( // ListDeployments represents the API handler to get a list of deployments. func ListDeployments(c *gin.Context) { // capture middleware values - o := org.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) r := repo.Retrieve(c) - u := user.Retrieve(c) - - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "org": o, - "repo": r.GetName(), - "user": u.GetName(), - }).Infof("reading deployments for repo %s", r.GetFullName()) + + l.Debugf("reading deployments for repo %s", r.GetFullName()) // capture page query parameter if present page, err := strconv.Atoi(c.DefaultQuery("page", "1")) diff --git a/api/hook/create.go b/api/hook/create.go index bb8fbbaa0..67eb86789 100644 --- a/api/hook/create.go +++ b/api/hook/create.go @@ -11,9 +11,7 @@ import ( "github.com/sirupsen/logrus" "github.com/go-vela/server/database" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/library" ) @@ -69,19 +67,11 @@ import ( // CreateHook represents the API handler to create a webhook. func CreateHook(c *gin.Context) { // capture middleware values - o := org.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) r := repo.Retrieve(c) - u := user.Retrieve(c) ctx := c.Request.Context() - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "org": o, - "repo": r.GetName(), - "user": u.GetName(), - }).Infof("creating new hook for repo %s", r.GetFullName()) + l.Debugf("creating new hook for repo %s", r.GetFullName()) // capture body from API request input := new(library.Hook) @@ -129,5 +119,10 @@ func CreateHook(c *gin.Context) { return } + l.WithFields(logrus.Fields{ + "hook": h.GetNumber(), + "hook_id": h.GetID(), + }).Info("hook created") + c.JSON(http.StatusCreated, h) } diff --git a/api/hook/delete.go b/api/hook/delete.go index f15f122df..a67f35263 100644 --- a/api/hook/delete.go +++ b/api/hook/delete.go @@ -5,15 +5,13 @@ package hook import ( "fmt" "net/http" - "strconv" "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" "github.com/go-vela/server/database" - "github.com/go-vela/server/router/middleware/org" + "github.com/go-vela/server/router/middleware/hook" "github.com/go-vela/server/router/middleware/repo" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" ) @@ -67,47 +65,19 @@ import ( // DeleteHook represents the API handler to remove a webhook. func DeleteHook(c *gin.Context) { // capture middleware values - o := org.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) r := repo.Retrieve(c) - u := user.Retrieve(c) - hook := util.PathParameter(c, "hook") + h := hook.Retrieve(c) ctx := c.Request.Context() - entry := fmt.Sprintf("%s/%s", r.GetFullName(), hook) + entry := fmt.Sprintf("%s/%d", r.GetFullName(), h.GetNumber()) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "org": o, - "hook": hook, - "repo": r.GetName(), - "user": u.GetName(), - }).Infof("deleting hook %s", entry) - - number, err := strconv.Atoi(hook) - if err != nil { - retErr := fmt.Errorf("invalid hook parameter provided: %s", hook) - - util.HandleError(c, http.StatusBadRequest, retErr) - - return - } - - // send API call to capture the webhook - h, err := database.FromContext(c).GetHookForRepo(ctx, r, number) - if err != nil { - retErr := fmt.Errorf("unable to get hook %s: %w", hook, err) - - util.HandleError(c, http.StatusNotFound, retErr) - - return - } + l.Debugf("deleting hook %s", entry) // send API call to remove the webhook - err = database.FromContext(c).DeleteHook(ctx, h) + err := database.FromContext(c).DeleteHook(ctx, h) if err != nil { - retErr := fmt.Errorf("unable to delete hook %s: %w", hook, err) + retErr := fmt.Errorf("unable to delete hook %s: %w", entry, err) util.HandleError(c, http.StatusInternalServerError, retErr) diff --git a/api/hook/get.go b/api/hook/get.go index 792a76a30..d31e6e659 100644 --- a/api/hook/get.go +++ b/api/hook/get.go @@ -3,18 +3,13 @@ package hook import ( - "fmt" "net/http" - "strconv" "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" - "github.com/go-vela/server/database" - "github.com/go-vela/server/router/middleware/org" + "github.com/go-vela/server/router/middleware/hook" "github.com/go-vela/server/router/middleware/repo" - "github.com/go-vela/server/router/middleware/user" - "github.com/go-vela/server/util" ) // swagger:operation GET /api/v1/hooks/{org}/{repo}/{hook} webhook GetHook @@ -67,42 +62,11 @@ import ( // GetHook represents the API handler to get a hook. func GetHook(c *gin.Context) { // capture middleware values - o := org.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) r := repo.Retrieve(c) - u := user.Retrieve(c) - hook := util.PathParameter(c, "hook") - ctx := c.Request.Context() + h := hook.Retrieve(c) - entry := fmt.Sprintf("%s/%s", r.GetFullName(), hook) - - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "org": o, - "hook": hook, - "repo": r.GetName(), - "user": u.GetName(), - }).Infof("reading hook %s", entry) - - number, err := strconv.Atoi(hook) - if err != nil { - retErr := fmt.Errorf("invalid hook parameter provided: %s", hook) - - util.HandleError(c, http.StatusBadRequest, retErr) - - return - } - - // send API call to capture the webhook - h, err := database.FromContext(c).GetHookForRepo(ctx, r, number) - if err != nil { - retErr := fmt.Errorf("unable to get hook %s: %w", entry, err) - - util.HandleError(c, http.StatusInternalServerError, retErr) - - return - } + l.Debugf("reading hook %s/%d", r.GetFullName(), h.GetNumber()) c.JSON(http.StatusOK, h) } diff --git a/api/hook/list.go b/api/hook/list.go index 3f1b47851..d2e65d1ac 100644 --- a/api/hook/list.go +++ b/api/hook/list.go @@ -12,9 +12,7 @@ import ( "github.com/go-vela/server/api" "github.com/go-vela/server/database" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" ) @@ -84,19 +82,11 @@ import ( // for a repository. func ListHooks(c *gin.Context) { // capture middleware values - o := org.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) r := repo.Retrieve(c) - u := user.Retrieve(c) ctx := c.Request.Context() - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "org": o, - "repo": r.GetName(), - "user": u.GetName(), - }).Infof("reading hooks for repo %s", r.GetFullName()) + l.Debugf("reading hooks for repo %s", r.GetFullName()) // capture page query parameter if present page, err := strconv.Atoi(c.DefaultQuery("page", "1")) diff --git a/api/hook/redeliver.go b/api/hook/redeliver.go index f95c598b5..13ec3f57a 100644 --- a/api/hook/redeliver.go +++ b/api/hook/redeliver.go @@ -5,13 +5,11 @@ package hook import ( "fmt" "net/http" - "strconv" "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" - "github.com/go-vela/server/database" - "github.com/go-vela/server/router/middleware/org" + "github.com/go-vela/server/router/middleware/hook" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" @@ -69,44 +67,16 @@ import ( // a webhook from the SCM. func RedeliverHook(c *gin.Context) { // capture middleware values - o := org.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) r := repo.Retrieve(c) u := user.Retrieve(c) - hook := util.PathParameter(c, "hook") - ctx := c.Request.Context() + h := hook.Retrieve(c) - entry := fmt.Sprintf("%s/%s", r.GetFullName(), hook) + entry := fmt.Sprintf("%s/%d", r.GetFullName(), h.GetNumber()) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "org": o, - "hook": hook, - "repo": r.GetName(), - "user": u.GetName(), - }).Infof("redelivering hook %s", entry) + l.Debugf("redelivering hook %s", entry) - number, err := strconv.Atoi(hook) - if err != nil { - retErr := fmt.Errorf("invalid hook parameter provided: %s", hook) - - util.HandleError(c, http.StatusBadRequest, retErr) - - return - } - - // send API call to capture the webhook - h, err := database.FromContext(c).GetHookForRepo(ctx, r, number) - if err != nil { - retErr := fmt.Errorf("unable to get hook %s: %w", entry, err) - - util.HandleError(c, http.StatusNotFound, retErr) - - return - } - - err = scm.FromContext(c).RedeliverWebhook(c, u, r, h) + err := scm.FromContext(c).RedeliverWebhook(c, u, r, h) if err != nil { retErr := fmt.Errorf("unable to redeliver hook %s: %w", entry, err) diff --git a/api/hook/update.go b/api/hook/update.go index 35b2617a2..75492e45a 100644 --- a/api/hook/update.go +++ b/api/hook/update.go @@ -5,15 +5,13 @@ package hook import ( "fmt" "net/http" - "strconv" "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" "github.com/go-vela/server/database" - "github.com/go-vela/server/router/middleware/org" + "github.com/go-vela/server/router/middleware/hook" "github.com/go-vela/server/router/middleware/repo" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/library" ) @@ -74,23 +72,14 @@ import ( // UpdateHook represents the API handler to update a hook. func UpdateHook(c *gin.Context) { // capture middleware values - o := org.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) r := repo.Retrieve(c) - u := user.Retrieve(c) - hook := util.PathParameter(c, "hook") + h := hook.Retrieve(c) ctx := c.Request.Context() - entry := fmt.Sprintf("%s/%s", r.GetFullName(), hook) + entry := fmt.Sprintf("%s/%d", r.GetFullName(), h.GetNumber()) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "org": o, - "hook": hook, - "repo": r.GetName(), - "user": u.GetName(), - }).Infof("updating hook %s", entry) + l.Debugf("updating hook %s", entry) // capture body from API request input := new(library.Hook) @@ -104,25 +93,6 @@ func UpdateHook(c *gin.Context) { return } - number, err := strconv.Atoi(hook) - if err != nil { - retErr := fmt.Errorf("invalid hook parameter provided: %s", hook) - - util.HandleError(c, http.StatusBadRequest, retErr) - - return - } - - // send API call to capture the webhook - h, err := database.FromContext(c).GetHookForRepo(ctx, r, number) - if err != nil { - retErr := fmt.Errorf("unable to get hook %s: %w", entry, err) - - util.HandleError(c, http.StatusNotFound, retErr) - - return - } - // update webhook fields if provided if input.GetCreated() > 0 { // update created if set diff --git a/api/jwks.go b/api/jwks.go index 4b0be0153..166ccc15d 100644 --- a/api/jwks.go +++ b/api/jwks.go @@ -7,6 +7,7 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" "github.com/go-vela/server/database" "github.com/go-vela/server/util" @@ -34,6 +35,10 @@ import ( // GetJWKS represents the API handler for requests to public keys in the Vela OpenID service. func GetJWKS(c *gin.Context) { + l := c.MustGet("logger").(*logrus.Entry) + + l.Debug("reading JWKS") + // retrieve JWKs from the database keys, err := database.FromContext(c).ListJWKs(c) if err != nil { diff --git a/api/log/create_service.go b/api/log/create_service.go index 275b86b64..736f1fca5 100644 --- a/api/log/create_service.go +++ b/api/log/create_service.go @@ -12,10 +12,8 @@ import ( "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/service" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/library" ) @@ -81,25 +79,15 @@ import ( // the logs for a service. func CreateServiceLog(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) b := build.Retrieve(c) - o := org.Retrieve(c) r := repo.Retrieve(c) s := service.Retrieve(c) - u := user.Retrieve(c) ctx := c.Request.Context() entry := fmt.Sprintf("%s/%d/%d", r.GetFullName(), b.GetNumber(), s.GetNumber()) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "build": b.GetNumber(), - "org": o, - "repo": r.GetName(), - "service": s.GetNumber(), - "user": u.GetName(), - }).Infof("creating logs for service %s", entry) + l.Debugf("creating logs for service %s", entry) // capture body from API request input := new(library.Log) @@ -128,5 +116,10 @@ func CreateServiceLog(c *gin.Context) { return } + l.WithFields(logrus.Fields{ + "service": s.GetName(), + "service_id": s.GetID(), + }).Info("logs created for service") + c.JSON(http.StatusCreated, nil) } diff --git a/api/log/create_step.go b/api/log/create_step.go index 42465299f..2a92abab7 100644 --- a/api/log/create_step.go +++ b/api/log/create_step.go @@ -12,10 +12,8 @@ import ( "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/step" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/library" ) @@ -81,25 +79,15 @@ import ( // the logs for a step. func CreateStepLog(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) b := build.Retrieve(c) - o := org.Retrieve(c) r := repo.Retrieve(c) s := step.Retrieve(c) - u := user.Retrieve(c) ctx := c.Request.Context() entry := fmt.Sprintf("%s/%d/%d", r.GetFullName(), b.GetNumber(), s.GetNumber()) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "build": b.GetNumber(), - "org": o, - "repo": r.GetName(), - "step": s.GetNumber(), - "user": u.GetName(), - }).Infof("creating logs for step %s", entry) + l.Debugf("creating logs for step %s", entry) // capture body from API request input := new(library.Log) @@ -128,5 +116,10 @@ func CreateStepLog(c *gin.Context) { return } + l.WithFields(logrus.Fields{ + "step": s.GetName(), + "step_id": s.GetID(), + }).Info("logs created for step") + c.JSON(http.StatusCreated, nil) } diff --git a/api/log/delete_service.go b/api/log/delete_service.go index 6c8b63c42..598874def 100644 --- a/api/log/delete_service.go +++ b/api/log/delete_service.go @@ -12,10 +12,8 @@ import ( "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/service" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" ) @@ -75,28 +73,18 @@ import ( // the logs for a service. func DeleteServiceLog(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) b := build.Retrieve(c) - o := org.Retrieve(c) r := repo.Retrieve(c) s := service.Retrieve(c) - u := user.Retrieve(c) ctx := c.Request.Context() entry := fmt.Sprintf("%s/%d/%d", r.GetFullName(), b.GetNumber(), s.GetNumber()) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "build": b.GetNumber(), - "org": o, - "repo": r.GetName(), - "service": s.GetNumber(), - "user": u.GetName(), - }).Infof("deleting logs for service %s", entry) + l.Debugf("deleting logs for service %s", entry) // send API call to capture the service logs - l, err := database.FromContext(c).GetLogForService(ctx, s) + sl, err := database.FromContext(c).GetLogForService(ctx, s) if err != nil { retErr := fmt.Errorf("unable to get logs for service %s: %w", entry, err) @@ -106,7 +94,7 @@ func DeleteServiceLog(c *gin.Context) { } // send API call to remove the log - err = database.FromContext(c).DeleteLog(ctx, l) + err = database.FromContext(c).DeleteLog(ctx, sl) if err != nil { retErr := fmt.Errorf("unable to delete logs for service %s: %w", entry, err) diff --git a/api/log/delete_step.go b/api/log/delete_step.go index 36ebfacff..28b8b6cd5 100644 --- a/api/log/delete_step.go +++ b/api/log/delete_step.go @@ -12,10 +12,8 @@ import ( "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/step" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" ) @@ -75,28 +73,18 @@ import ( // the logs for a step. func DeleteStepLog(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) b := build.Retrieve(c) - o := org.Retrieve(c) r := repo.Retrieve(c) s := step.Retrieve(c) - u := user.Retrieve(c) ctx := c.Request.Context() entry := fmt.Sprintf("%s/%d/%d", r.GetFullName(), b.GetNumber(), s.GetNumber()) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "build": b.GetNumber(), - "org": o, - "repo": r.GetName(), - "step": s.GetNumber(), - "user": u.GetName(), - }).Infof("deleting logs for step %s", entry) + l.Debugf("deleting logs for step %s", entry) // send API call to capture the step logs - l, err := database.FromContext(c).GetLogForStep(ctx, s) + sl, err := database.FromContext(c).GetLogForStep(ctx, s) if err != nil { retErr := fmt.Errorf("unable to get logs for step %s: %w", entry, err) @@ -106,7 +94,7 @@ func DeleteStepLog(c *gin.Context) { } // send API call to remove the log - err = database.FromContext(c).DeleteLog(ctx, l) + err = database.FromContext(c).DeleteLog(ctx, sl) if err != nil { retErr := fmt.Errorf("unable to delete logs for step %s: %w", entry, err) diff --git a/api/log/get_service.go b/api/log/get_service.go index c7c72fc73..de223da08 100644 --- a/api/log/get_service.go +++ b/api/log/get_service.go @@ -12,10 +12,8 @@ import ( "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/service" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" ) @@ -74,28 +72,18 @@ import ( // GetServiceLog represents the API handler to get the logs for a service. func GetServiceLog(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) b := build.Retrieve(c) - o := org.Retrieve(c) r := repo.Retrieve(c) s := service.Retrieve(c) - u := user.Retrieve(c) ctx := c.Request.Context() entry := fmt.Sprintf("%s/%d/%d", r.GetFullName(), b.GetNumber(), s.GetNumber()) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "build": b.GetNumber(), - "org": o, - "repo": r.GetName(), - "service": s.GetNumber(), - "user": u.GetName(), - }).Infof("reading logs for service %s", entry) + l.Debugf("reading logs for service %s", entry) // send API call to capture the service logs - l, err := database.FromContext(c).GetLogForService(ctx, s) + sl, err := database.FromContext(c).GetLogForService(ctx, s) if err != nil { retErr := fmt.Errorf("unable to get logs for service %s: %w", entry, err) @@ -104,5 +92,5 @@ func GetServiceLog(c *gin.Context) { return } - c.JSON(http.StatusOK, l) + c.JSON(http.StatusOK, sl) } diff --git a/api/log/get_step.go b/api/log/get_step.go index 8e0a30223..1bf6c4191 100644 --- a/api/log/get_step.go +++ b/api/log/get_step.go @@ -12,10 +12,8 @@ import ( "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/step" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" ) @@ -75,28 +73,18 @@ import ( // GetStepLog represents the API handler to get the logs for a step. func GetStepLog(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) b := build.Retrieve(c) - o := org.Retrieve(c) r := repo.Retrieve(c) s := step.Retrieve(c) - u := user.Retrieve(c) ctx := c.Request.Context() entry := fmt.Sprintf("%s/%d/%d", r.GetFullName(), b.GetNumber(), s.GetNumber()) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "build": b.GetNumber(), - "org": o, - "repo": r.GetName(), - "step": s.GetNumber(), - "user": u.GetName(), - }).Infof("reading logs for step %s", entry) + l.Debugf("reading logs for step %s", entry) // send API call to capture the step logs - l, err := database.FromContext(c).GetLogForStep(ctx, s) + sl, err := database.FromContext(c).GetLogForStep(ctx, s) if err != nil { retErr := fmt.Errorf("unable to get logs for step %s: %w", entry, err) @@ -105,5 +93,5 @@ func GetStepLog(c *gin.Context) { return } - c.JSON(http.StatusOK, l) + c.JSON(http.StatusOK, sl) } diff --git a/api/log/list_build.go b/api/log/list_build.go index a33fd2c32..72d4ce7ab 100644 --- a/api/log/list_build.go +++ b/api/log/list_build.go @@ -13,9 +13,7 @@ import ( "github.com/go-vela/server/api" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" ) @@ -82,23 +80,14 @@ import ( // ListLogsForBuild represents the API handler to get a list of logs for a build. func ListLogsForBuild(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) b := build.Retrieve(c) - o := org.Retrieve(c) r := repo.Retrieve(c) - u := user.Retrieve(c) ctx := c.Request.Context() entry := fmt.Sprintf("%s/%d", r.GetFullName(), b.GetNumber()) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "build": b.GetNumber(), - "org": o, - "repo": r.GetName(), - "user": u.GetName(), - }).Infof("listing logs for build %s", entry) + l.Debugf("listing logs for build %s", entry) // capture page query parameter if present page, err := strconv.Atoi(c.DefaultQuery("page", "1")) @@ -123,7 +112,7 @@ func ListLogsForBuild(c *gin.Context) { perPage = util.MaxInt(1, util.MinInt(100, perPage)) // send API call to capture the list of logs for the build - l, t, err := database.FromContext(c).ListLogsForBuild(ctx, b, page, perPage) + bl, t, err := database.FromContext(c).ListLogsForBuild(ctx, b, page, perPage) if err != nil { retErr := fmt.Errorf("unable to list logs for build %s: %w", entry, err) @@ -141,5 +130,5 @@ func ListLogsForBuild(c *gin.Context) { // set pagination headers pagination.SetHeaderLink(c) - c.JSON(http.StatusOK, l) + c.JSON(http.StatusOK, bl) } diff --git a/api/log/update_service.go b/api/log/update_service.go index 54e1fade8..dd8b8329d 100644 --- a/api/log/update_service.go +++ b/api/log/update_service.go @@ -12,10 +12,8 @@ import ( "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/service" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/library" ) @@ -81,28 +79,18 @@ import ( // the logs for a service. func UpdateServiceLog(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) b := build.Retrieve(c) - o := org.Retrieve(c) r := repo.Retrieve(c) s := service.Retrieve(c) - u := user.Retrieve(c) ctx := c.Request.Context() entry := fmt.Sprintf("%s/%d/%d", r.GetFullName(), b.GetNumber(), s.GetNumber()) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "build": b.GetNumber(), - "org": o, - "repo": r.GetName(), - "service": s.GetNumber(), - "user": u.GetName(), - }).Infof("updating logs for service %s", entry) + l.Debugf("updating logs for service %s", entry) // send API call to capture the service logs - l, err := database.FromContext(c).GetLogForService(ctx, s) + sl, err := database.FromContext(c).GetLogForService(ctx, s) if err != nil { retErr := fmt.Errorf("unable to get logs for service %s: %w", entry, err) @@ -126,11 +114,11 @@ func UpdateServiceLog(c *gin.Context) { // update log fields if provided if len(input.GetData()) > 0 { // update data if set - l.SetData(input.GetData()) + sl.SetData(input.GetData()) } // send API call to update the log - err = database.FromContext(c).UpdateLog(ctx, l) + err = database.FromContext(c).UpdateLog(ctx, sl) if err != nil { retErr := fmt.Errorf("unable to update logs for service %s: %w", entry, err) diff --git a/api/log/update_step.go b/api/log/update_step.go index 4c27dd0ad..ff19da7da 100644 --- a/api/log/update_step.go +++ b/api/log/update_step.go @@ -12,10 +12,8 @@ import ( "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/step" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/library" ) @@ -81,28 +79,18 @@ import ( // the logs for a step. func UpdateStepLog(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) b := build.Retrieve(c) - o := org.Retrieve(c) r := repo.Retrieve(c) s := step.Retrieve(c) - u := user.Retrieve(c) ctx := c.Request.Context() entry := fmt.Sprintf("%s/%d/%d", r.GetFullName(), b.GetNumber(), s.GetNumber()) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "build": b.GetNumber(), - "org": o, - "repo": r.GetName(), - "step": s.GetNumber(), - "user": u.GetName(), - }).Infof("updating logs for step %s", entry) + l.Debugf("updating logs for step %s", entry) // send API call to capture the step logs - l, err := database.FromContext(c).GetLogForStep(ctx, s) + sl, err := database.FromContext(c).GetLogForStep(ctx, s) if err != nil { retErr := fmt.Errorf("unable to get logs for step %s: %w", entry, err) @@ -126,11 +114,11 @@ func UpdateStepLog(c *gin.Context) { // update log fields if provided if len(input.GetData()) > 0 { // update data if set - l.SetData(input.GetData()) + sl.SetData(input.GetData()) } // send API call to update the log - err = database.FromContext(c).UpdateLog(ctx, l) + err = database.FromContext(c).UpdateLog(ctx, sl) if err != nil { retErr := fmt.Errorf("unable to update logs for step %s: %w", entry, err) diff --git a/api/oi_config.go b/api/oi_config.go index 1111e352f..2e600577d 100644 --- a/api/oi_config.go +++ b/api/oi_config.go @@ -8,6 +8,7 @@ import ( "github.com/gin-gonic/gin" "github.com/golang-jwt/jwt/v5" + "github.com/sirupsen/logrus" "github.com/go-vela/server/api/types" "github.com/go-vela/server/internal" @@ -32,6 +33,10 @@ import ( // GetOpenIDConfig represents the API handler for requests for configurations in the Vela OpenID service. func GetOpenIDConfig(c *gin.Context) { m := c.MustGet("metadata").(*internal.Metadata) + l := c.MustGet("logger").(*logrus.Entry) + + l.Debug("reading OpenID configuration") + config := types.OpenIDConfig{ Issuer: fmt.Sprintf("%s/_services/token", m.Vela.Address), JWKSAddress: fmt.Sprintf("%s/%s", m.Vela.Address, "_services/token/.well-known/jwks"), diff --git a/api/pipeline/compile.go b/api/pipeline/compile.go index 67419d91d..a7c24af80 100644 --- a/api/pipeline/compile.go +++ b/api/pipeline/compile.go @@ -12,7 +12,6 @@ import ( "github.com/go-vela/server/compiler" "github.com/go-vela/server/internal" - "github.com/go-vela/server/router/middleware/org" pMiddleware "github.com/go-vela/server/router/middleware/pipeline" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" @@ -81,22 +80,14 @@ import ( func CompilePipeline(c *gin.Context) { // capture middleware values m := c.MustGet("metadata").(*internal.Metadata) - o := org.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) p := pMiddleware.Retrieve(c) r := repo.Retrieve(c) u := user.Retrieve(c) entry := fmt.Sprintf("%s/%s", r.GetFullName(), p.GetCommit()) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "org": o, - "pipeline": p.GetCommit(), - "repo": r.GetName(), - "user": u.GetName(), - }).Infof("compiling pipeline %s", entry) + l.Debugf("compiling pipeline %s", entry) // ensure we use the expected pipeline type when compiling r.SetPipelineType(p.GetType()) diff --git a/api/pipeline/create.go b/api/pipeline/create.go index 1420fdc67..2dc5d5067 100644 --- a/api/pipeline/create.go +++ b/api/pipeline/create.go @@ -10,9 +10,7 @@ import ( "github.com/sirupsen/logrus" "github.com/go-vela/server/database" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/library" ) @@ -70,21 +68,11 @@ import ( // create a pipeline. func CreatePipeline(c *gin.Context) { // capture middleware values - o := org.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) r := repo.Retrieve(c) - u := user.Retrieve(c) ctx := c.Request.Context() - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logger := logrus.WithFields(logrus.Fields{ - "org": o, - "repo": r.GetName(), - "user": u.GetName(), - }) - - logger.Infof("creating new pipeline for repo %s", r.GetFullName()) + l.Debugf("creating new pipeline for repo %s", r.GetFullName()) // capture body from API request input := new(library.Pipeline) @@ -111,5 +99,10 @@ func CreatePipeline(c *gin.Context) { return } + l.WithFields(logrus.Fields{ + "pipeline": p.GetCommit(), + "pipeline_id": p.GetID(), + }).Info("pipeline created for repo") + c.JSON(http.StatusCreated, p) } diff --git a/api/pipeline/delete.go b/api/pipeline/delete.go index 89c0f362c..0af419b78 100644 --- a/api/pipeline/delete.go +++ b/api/pipeline/delete.go @@ -10,10 +10,8 @@ import ( "github.com/sirupsen/logrus" "github.com/go-vela/server/database" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/pipeline" "github.com/go-vela/server/router/middleware/repo" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" ) @@ -67,23 +65,14 @@ import ( // DeletePipeline represents the API handler to remove a pipeline for a repository. func DeletePipeline(c *gin.Context) { // capture middleware values - o := org.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) p := pipeline.Retrieve(c) r := repo.Retrieve(c) - u := user.Retrieve(c) ctx := c.Request.Context() entry := fmt.Sprintf("%s/%s", r.GetFullName(), p.GetCommit()) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "org": o, - "pipeline": p.GetCommit(), - "repo": r.GetName(), - "user": u.GetName(), - }).Infof("deleting pipeline %s", entry) + l.Debugf("deleting pipeline %s", entry) // send API call to remove the build err := database.FromContext(c).DeletePipeline(ctx, p) diff --git a/api/pipeline/expand.go b/api/pipeline/expand.go index 062992a81..be77aba50 100644 --- a/api/pipeline/expand.go +++ b/api/pipeline/expand.go @@ -12,7 +12,6 @@ import ( "github.com/go-vela/server/compiler" "github.com/go-vela/server/internal" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/pipeline" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" @@ -81,22 +80,14 @@ import ( func ExpandPipeline(c *gin.Context) { // capture middleware values m := c.MustGet("metadata").(*internal.Metadata) - o := org.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) p := pipeline.Retrieve(c) r := repo.Retrieve(c) u := user.Retrieve(c) entry := fmt.Sprintf("%s/%s", r.GetFullName(), p.GetCommit()) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "org": o, - "pipeline": p.GetCommit(), - "repo": r.GetName(), - "user": u.GetName(), - }).Infof("expanding templates for pipeline %s", entry) + l.Debugf("expanding templates for pipeline %s", entry) // ensure we use the expected pipeline type when compiling r.SetPipelineType(p.GetType()) diff --git a/api/pipeline/get.go b/api/pipeline/get.go index d6fdcbeed..e0c5b17af 100644 --- a/api/pipeline/get.go +++ b/api/pipeline/get.go @@ -8,10 +8,8 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/pipeline" "github.com/go-vela/server/router/middleware/repo" - "github.com/go-vela/server/router/middleware/user" ) // swagger:operation GET /api/v1/pipelines/{org}/{repo}/{pipeline} pipelines GetPipeline @@ -65,20 +63,11 @@ import ( // GetPipeline represents the API handler to get a pipeline for a repo. func GetPipeline(c *gin.Context) { // capture middleware values - o := org.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) p := pipeline.Retrieve(c) r := repo.Retrieve(c) - u := user.Retrieve(c) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "org": o, - "pipeline": p.GetCommit(), - "repo": r.GetName(), - "user": u.GetName(), - }).Infof("reading pipeline %s/%s", r.GetFullName(), p.GetCommit()) + l.Debugf("reading pipeline %s/%s", r.GetFullName(), p.GetCommit()) c.JSON(http.StatusOK, p) } diff --git a/api/pipeline/list.go b/api/pipeline/list.go index c2fd7f0b6..4203c987f 100644 --- a/api/pipeline/list.go +++ b/api/pipeline/list.go @@ -12,9 +12,7 @@ import ( "github.com/go-vela/server/api" "github.com/go-vela/server/database" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" ) @@ -84,19 +82,11 @@ import ( // of pipelines for a repository. func ListPipelines(c *gin.Context) { // capture middleware values - o := org.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) r := repo.Retrieve(c) - u := user.Retrieve(c) ctx := c.Request.Context() - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "org": o, - "repo": r.GetName(), - "user": u.GetName(), - }).Infof("listing pipelines for repo %s", r.GetFullName()) + l.Debugf("listing pipelines for repo %s", r.GetFullName()) // capture page query parameter if present page, err := strconv.Atoi(c.DefaultQuery("page", "1")) diff --git a/api/pipeline/template.go b/api/pipeline/template.go index 8271732b6..8dc9742b8 100644 --- a/api/pipeline/template.go +++ b/api/pipeline/template.go @@ -86,6 +86,7 @@ import ( func GetTemplates(c *gin.Context) { // capture middleware values m := c.MustGet("metadata").(*internal.Metadata) + l := c.MustGet("logger").(*logrus.Entry) o := org.Retrieve(c) p := pipeline.Retrieve(c) r := repo.Retrieve(c) @@ -94,15 +95,7 @@ func GetTemplates(c *gin.Context) { entry := fmt.Sprintf("%s/%s", r.GetFullName(), p.GetCommit()) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "org": o, - "pipeline": p.GetCommit(), - "repo": r.GetName(), - "user": u.GetName(), - }).Infof("reading templates from pipeline %s", entry) + l.Debugf("reading templates from pipeline %s", entry) // create the compiler object compiler := compiler.FromContext(c).Duplicate().WithCommit(p.GetCommit()).WithMetadata(m).WithRepo(r).WithUser(u) diff --git a/api/pipeline/update.go b/api/pipeline/update.go index bc70d53c4..babd29494 100644 --- a/api/pipeline/update.go +++ b/api/pipeline/update.go @@ -10,10 +10,8 @@ import ( "github.com/sirupsen/logrus" "github.com/go-vela/server/database" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/pipeline" "github.com/go-vela/server/router/middleware/repo" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/library" ) @@ -75,23 +73,14 @@ import ( // a pipeline for a repo. func UpdatePipeline(c *gin.Context) { // capture middleware values - o := org.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) p := pipeline.Retrieve(c) r := repo.Retrieve(c) - u := user.Retrieve(c) ctx := c.Request.Context() entry := fmt.Sprintf("%s/%s", r.GetFullName(), p.GetCommit()) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "org": o, - "pipeline": p.GetCommit(), - "repo": r.GetName(), - "user": u.GetName(), - }).Infof("updating pipeline %s", entry) + l.Debugf("updating pipeline %s", entry) // capture body from API request input := new(library.Pipeline) diff --git a/api/pipeline/validate.go b/api/pipeline/validate.go index 335f61850..6ff069347 100644 --- a/api/pipeline/validate.go +++ b/api/pipeline/validate.go @@ -11,7 +11,6 @@ import ( "github.com/go-vela/server/compiler" "github.com/go-vela/server/internal" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/pipeline" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" @@ -79,22 +78,14 @@ import ( func ValidatePipeline(c *gin.Context) { // capture middleware values m := c.MustGet("metadata").(*internal.Metadata) - o := org.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) p := pipeline.Retrieve(c) r := repo.Retrieve(c) u := user.Retrieve(c) entry := fmt.Sprintf("%s/%s", r.GetFullName(), p.GetCommit()) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "org": o, - "pipeline": p.GetCommit(), - "repo": r.GetName(), - "user": u.GetName(), - }).Infof("validating pipeline %s", entry) + l.Debugf("validating pipeline %s", entry) // ensure we use the expected pipeline type when compiling r.SetPipelineType(p.GetType()) diff --git a/api/queue/queue.go b/api/queue/queue.go index 5c861572e..2c5698bb6 100644 --- a/api/queue/queue.go +++ b/api/queue/queue.go @@ -8,7 +8,6 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" - "github.com/go-vela/server/router/middleware/claims" "github.com/go-vela/types/library" ) @@ -34,11 +33,9 @@ import ( // Info represents the API handler to // retrieve queue credentials as part of worker onboarding. func Info(c *gin.Context) { - cl := claims.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) - logrus.WithFields(logrus.Fields{ - "user": cl.Subject, - }).Info("requesting queue credentials with registration token") + l.Info("requesting queue credentials with registration token") // extract the public key that was packed into gin context k := c.MustGet("public-key").(string) diff --git a/api/repo/chown.go b/api/repo/chown.go index 30442c683..a30eab938 100644 --- a/api/repo/chown.go +++ b/api/repo/chown.go @@ -10,7 +10,6 @@ import ( "github.com/sirupsen/logrus" "github.com/go-vela/server/database" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" @@ -62,19 +61,12 @@ import ( // the owner of a repo. func ChownRepo(c *gin.Context) { // capture middleware values - o := org.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) r := repo.Retrieve(c) u := user.Retrieve(c) ctx := c.Request.Context() - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "org": o, - "repo": r.GetName(), - "user": u.GetName(), - }).Infof("changing owner of repo %s to %s", r.GetFullName(), u.GetName()) + l.Debugf("changing owner of repo %s to %s", r.GetFullName(), u.GetName()) // update repo owner r.SetOwner(u) @@ -89,5 +81,7 @@ func ChownRepo(c *gin.Context) { return } + l.Infof("updated repo - changed owner to %s", u.GetName()) + c.JSON(http.StatusOK, fmt.Sprintf("repo %s changed owner to %s", r.GetFullName(), u.GetName())) } diff --git a/api/repo/create.go b/api/repo/create.go index 7516b9682..25719f2b4 100644 --- a/api/repo/create.go +++ b/api/repo/create.go @@ -74,6 +74,7 @@ import ( //nolint:funlen,gocyclo // ignore function length and cyclomatic complexity func CreateRepo(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) u := user.Retrieve(c) s := settings.FromContext(c) @@ -98,14 +99,7 @@ func CreateRepo(c *gin.Context) { return } - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "org": input.GetOrg(), - "repo": input.GetName(), - "user": u.GetName(), - }).Infof("creating new repo %s", input.GetFullName()) + l.Debugf("creating new repo %s", input.GetFullName()) // get repo information from the source r, _, err := scm.FromContext(c).GetRepo(ctx, u, input) @@ -290,6 +284,8 @@ func CreateRepo(c *gin.Context) { dbRepo.SetActive(true) // send API call to update the repo + // NOTE: not logging modification out separately + // although we are CREATING a repo in this path r, err = database.FromContext(c).UpdateRepo(ctx, dbRepo) if err != nil { retErr := fmt.Errorf("unable to set repo %s to active: %w", dbRepo.GetFullName(), err) @@ -298,6 +294,12 @@ func CreateRepo(c *gin.Context) { return } + + l.WithFields(logrus.Fields{ + "org": r.GetOrg(), + "repo": r.GetName(), + "repo_id": r.GetID(), + }).Infof("repo %s activated", r.GetFullName()) } else { // send API call to create the repo r, err = database.FromContext(c).CreateRepo(ctx, r) @@ -308,6 +310,12 @@ func CreateRepo(c *gin.Context) { return } + + l.WithFields(logrus.Fields{ + "org": r.GetOrg(), + "repo": r.GetName(), + "repo_id": r.GetID(), + }).Infof("repo %s created", r.GetFullName()) } // create init hook in the DB after repo has been added in order to capture its ID @@ -323,6 +331,10 @@ func CreateRepo(c *gin.Context) { return } + + l.WithFields(logrus.Fields{ + "hook": h.GetID(), + }).Infof("hook %d created for repo %s", h.GetID(), r.GetFullName()) } c.JSON(http.StatusCreated, r) diff --git a/api/repo/delete.go b/api/repo/delete.go index c75d2fc51..0d8be5d84 100644 --- a/api/repo/delete.go +++ b/api/repo/delete.go @@ -10,7 +10,6 @@ import ( "github.com/sirupsen/logrus" "github.com/go-vela/server/database" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" @@ -62,19 +61,12 @@ import ( // DeleteRepo represents the API handler to remove a repository. func DeleteRepo(c *gin.Context) { // capture middleware values - o := org.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) r := repo.Retrieve(c) u := user.Retrieve(c) ctx := c.Request.Context() - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "org": o, - "repo": r.GetName(), - "user": u.GetName(), - }).Infof("deleting repo %s", r.GetFullName()) + l.Debugf("deleting repo %s", r.GetFullName()) // send API call to remove the webhook err := scm.FromContext(c).Disable(ctx, u, r.GetOrg(), r.GetName()) diff --git a/api/repo/get.go b/api/repo/get.go index ac988093c..ab0254f7e 100644 --- a/api/repo/get.go +++ b/api/repo/get.go @@ -8,9 +8,7 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" - "github.com/go-vela/server/router/middleware/user" ) // swagger:operation GET /api/v1/repos/{org}/{repo} repos GetRepo @@ -54,18 +52,10 @@ import ( // GetRepo represents the API handler to get a repository. func GetRepo(c *gin.Context) { // capture middleware values - o := org.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) r := repo.Retrieve(c) - u := user.Retrieve(c) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "org": o, - "repo": r.GetName(), - "user": u.GetName(), - }).Infof("reading repo %s", r.GetFullName()) + l.Debug("reading repo") c.JSON(http.StatusOK, r) } diff --git a/api/repo/list.go b/api/repo/list.go index 306214605..0e408e41d 100644 --- a/api/repo/list.go +++ b/api/repo/list.go @@ -68,15 +68,11 @@ import ( // of repositories for a user. func ListRepos(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) u := user.Retrieve(c) ctx := c.Request.Context() - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "user": u.GetName(), - }).Infof("listing repos for user %s", u.GetName()) + l.Debugf("listing repos for user %s", u.GetName()) // capture page query parameter if present page, err := strconv.Atoi(c.DefaultQuery("page", "1")) diff --git a/api/repo/list_org.go b/api/repo/list_org.go index 2466efce1..2152006c9 100644 --- a/api/repo/list_org.go +++ b/api/repo/list_org.go @@ -89,17 +89,12 @@ import ( // of repositories for an organization. func ListReposForOrg(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) o := org.Retrieve(c) u := user.Retrieve(c) ctx := c.Request.Context() - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "org": o, - "user": u.GetName(), - }).Infof("listing repos for org %s", o) + l.Debugf("listing repos for org %s", o) // capture page query parameter if present page, err := strconv.Atoi(c.DefaultQuery("page", "1")) @@ -142,7 +137,7 @@ func ListReposForOrg(c *gin.Context) { // See if the user is an org admin to bypass individual permission checks perm, err := scm.FromContext(c).OrgAccess(ctx, u, o) if err != nil { - logrus.Errorf("unable to get user %s access level for org %s", u.GetName(), o) + l.Errorf("unable to get user %s access level for org %s", u.GetName(), o) } // Only show public repos to non-admins if perm != "admin" { diff --git a/api/repo/repair.go b/api/repo/repair.go index af43148e7..27e720c37 100644 --- a/api/repo/repair.go +++ b/api/repo/repair.go @@ -12,7 +12,6 @@ import ( wh "github.com/go-vela/server/api/webhook" "github.com/go-vela/server/database" "github.com/go-vela/server/internal" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" @@ -65,21 +64,13 @@ import ( // and then create a webhook for a repo. func RepairRepo(c *gin.Context) { // capture middleware values - o := org.Retrieve(c) + m := c.MustGet("metadata").(*internal.Metadata) + l := c.MustGet("logger").(*logrus.Entry) r := repo.Retrieve(c) u := user.Retrieve(c) ctx := c.Request.Context() - // capture middleware values - m := c.MustGet("metadata").(*internal.Metadata) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "org": o, - "repo": r.GetName(), - "user": u.GetName(), - }).Infof("repairing repo %s", r.GetFullName()) + l.Debugf("repairing repo %s", r.GetFullName()) // check if we should create the webhook if c.Value("webhookvalidation").(bool) { @@ -131,6 +122,10 @@ func RepairRepo(c *gin.Context) { return } + + l.WithFields(logrus.Fields{ + "hook": hook.GetID(), + }).Info("new webhook created") } // get repo information from the source @@ -181,6 +176,8 @@ func RepairRepo(c *gin.Context) { return } + + l.Infof("repo %s updated - set to active", r.GetFullName()) } c.JSON(http.StatusOK, fmt.Sprintf("repo %s repaired", r.GetFullName())) diff --git a/api/repo/update.go b/api/repo/update.go index 4626dd72b..db3342326 100644 --- a/api/repo/update.go +++ b/api/repo/update.go @@ -14,7 +14,6 @@ import ( "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" @@ -75,7 +74,7 @@ import ( //nolint:funlen,gocyclo // ignore function length func UpdateRepo(c *gin.Context) { // capture middleware values - o := org.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) r := repo.Retrieve(c) u := user.Retrieve(c) maxBuildLimit := c.Value("maxBuildLimit").(int64) @@ -83,14 +82,7 @@ func UpdateRepo(c *gin.Context) { defaultRepoEventsMask := c.Value("defaultRepoEventsMask").(int64) ctx := c.Request.Context() - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "org": o, - "repo": r.GetName(), - "user": u.GetName(), - }).Infof("updating repo %s", r.GetFullName()) + l.Debug("updating repo") // capture body from API request input := new(types.Repo) @@ -259,11 +251,7 @@ func UpdateRepo(c *gin.Context) { admn := u.GetName() // log admin override update repo hook - logrus.WithFields(logrus.Fields{ - "org": o, - "repo": r.GetName(), - "user": u.GetName(), - }).Infof("platform admin %s updating repo webhook events for repo %s", admn, r.GetFullName()) + l.Debugf("platform admin %s updating repo webhook events for repo %s", admn, r.GetFullName()) u = r.GetOwner() } diff --git a/api/schedule/create.go b/api/schedule/create.go index 938c31e1f..36741832b 100644 --- a/api/schedule/create.go +++ b/api/schedule/create.go @@ -83,6 +83,7 @@ import ( // create a schedule. func CreateSchedule(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) u := user.Retrieve(c) r := repo.Retrieve(c) ctx := c.Request.Context() @@ -119,14 +120,7 @@ func CreateSchedule(c *gin.Context) { return } - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "org": r.GetOrg(), - "repo": r.GetName(), - "user": u.GetName(), - }).Infof("creating new schedule %s", input.GetName()) + l.Debugf("creating new schedule %s", input.GetName()) // ensure repo is allowed to create new schedules if !util.CheckAllowlist(r, s.GetScheduleAllowlist()) { @@ -196,6 +190,11 @@ func CreateSchedule(c *gin.Context) { return } + + l.WithFields(logrus.Fields{ + "schedule": schedule.GetName(), + "schedule_id": schedule.GetID(), + }).Infof("schedule %s updated - activated", schedule.GetName()) } else { // send API call to create the schedule schedule, err = database.FromContext(c).CreateSchedule(ctx, schedule) @@ -206,6 +205,11 @@ func CreateSchedule(c *gin.Context) { return } + + l.WithFields(logrus.Fields{ + "schedule": schedule.GetName(), + "schedule_id": schedule.GetID(), + }).Infof("schedule %s created", schedule.GetName()) } c.JSON(http.StatusCreated, schedule) diff --git a/api/schedule/delete.go b/api/schedule/delete.go index 19c448aa1..1cf2da000 100644 --- a/api/schedule/delete.go +++ b/api/schedule/delete.go @@ -10,10 +10,7 @@ import ( "github.com/sirupsen/logrus" "github.com/go-vela/server/database" - "github.com/go-vela/server/router/middleware/org" - "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/schedule" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" ) @@ -67,20 +64,11 @@ import ( // DeleteSchedule represents the API handler to remove a schedule. func DeleteSchedule(c *gin.Context) { // capture middleware values - o := org.Retrieve(c) - r := repo.Retrieve(c) - u := user.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) s := schedule.Retrieve(c) ctx := c.Request.Context() - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "org": o, - "repo": r.GetName(), - "user": u.GetName(), - }).Infof("deleting schedule %s", s.GetName()) + l.Debugf("deleting schedule %s", s.GetName()) err := database.FromContext(c).DeleteSchedule(ctx, s) if err != nil { diff --git a/api/schedule/get.go b/api/schedule/get.go index 2978860b9..287debf42 100644 --- a/api/schedule/get.go +++ b/api/schedule/get.go @@ -8,10 +8,7 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" - "github.com/go-vela/server/router/middleware/org" - "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/schedule" - "github.com/go-vela/server/router/middleware/user" ) // swagger:operation GET /api/v1/schedules/{org}/{repo}/{schedule} schedules GetSchedule @@ -60,20 +57,10 @@ import ( // GetSchedule represents the API handler to get a schedule. func GetSchedule(c *gin.Context) { // capture middleware values - o := org.Retrieve(c) - r := repo.Retrieve(c) - u := user.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) s := schedule.Retrieve(c) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "org": o, - "repo": r.GetName(), - "user": u.GetName(), - "schedule": s.GetName(), - }).Infof("reading schedule %s", s.GetName()) + l.Debugf("reading schedule %s", s.GetName()) c.JSON(http.StatusOK, s) } diff --git a/api/schedule/list.go b/api/schedule/list.go index a42569ba0..22b1fd43a 100644 --- a/api/schedule/list.go +++ b/api/schedule/list.go @@ -81,16 +81,11 @@ import ( // ListSchedules represents the API handler to get a list of schedules for a repository. func ListSchedules(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) r := repo.Retrieve(c) ctx := c.Request.Context() - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "repo": r.GetName(), - "org": r.GetOrg(), - }).Infof("listing schedules for repo %s", r.GetFullName()) + l.Debugf("listing schedules for repo %s", r.GetFullName()) // capture page query parameter if present page, err := strconv.Atoi(c.DefaultQuery("page", "1")) diff --git a/api/schedule/update.go b/api/schedule/update.go index 149cd3e74..3aedde1a1 100644 --- a/api/schedule/update.go +++ b/api/schedule/update.go @@ -12,7 +12,6 @@ import ( api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" - "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/schedule" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" @@ -74,21 +73,14 @@ import ( // UpdateSchedule represents the API handler to update a schedule. func UpdateSchedule(c *gin.Context) { // capture middleware values - r := repo.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) s := schedule.Retrieve(c) - ctx := c.Request.Context() u := user.Retrieve(c) + ctx := c.Request.Context() scheduleName := util.PathParameter(c, "schedule") minimumFrequency := c.Value("scheduleminimumfrequency").(time.Duration) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "schedule": scheduleName, - "repo": r.GetName(), - "org": r.GetOrg(), - }).Infof("updating schedule %s", scheduleName) + l.Debugf("updating schedule %s", scheduleName) // capture body from API request input := new(api.Schedule) diff --git a/api/scm/sync.go b/api/scm/sync.go index 66e2e6fd2..66522510a 100644 --- a/api/scm/sync.go +++ b/api/scm/sync.go @@ -73,21 +73,13 @@ import ( // subscribed events with allowed events. func SyncRepo(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) o := org.Retrieve(c) r := repo.Retrieve(c) u := user.Retrieve(c) ctx := c.Request.Context() - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logger := logrus.WithFields(logrus.Fields{ - "org": o, - "repo": r.GetName(), - "user": u.GetName(), - }) - - logger.Infof("syncing repo %s", r.GetFullName()) + l.Debugf("syncing repo %s", r.GetFullName()) // retrieve repo from source code manager service _, respCode, err := scm.FromContext(c).GetRepo(ctx, u, r) @@ -107,6 +99,8 @@ func SyncRepo(c *gin.Context) { return } + l.Infof("repo %s has been updated - set to inactive", r.GetFullName()) + // exit with success as hook sync will be unnecessary c.JSON(http.StatusOK, r) @@ -124,7 +118,7 @@ func SyncRepo(c *gin.Context) { // we cannot use our normal permissions check due to the possibility the repo was deleted perm, err := scm.FromContext(c).RepoAccess(ctx, u.GetName(), u.GetToken(), o, r.GetName()) if err != nil { - logger.Errorf("unable to get user %s access level for org %s", u.GetName(), o) + l.Errorf("unable to get user %s access level for org %s", u.GetName(), o) } if !strings.EqualFold(perm, "admin") { @@ -165,6 +159,8 @@ func SyncRepo(c *gin.Context) { return } + l.Infof("repo %s has been updated - set to inactive", r.GetFullName()) + c.JSON(http.StatusOK, r) return diff --git a/api/scm/sync_org.go b/api/scm/sync_org.go index 8809e7b4f..e8efee734 100644 --- a/api/scm/sync_org.go +++ b/api/scm/sync_org.go @@ -69,24 +69,17 @@ import ( // subscribed events with allowed events. func SyncReposForOrg(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) o := org.Retrieve(c) u := user.Retrieve(c) ctx := c.Request.Context() - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logger := logrus.WithFields(logrus.Fields{ - "org": o, - "user": u.GetName(), - }) - - logger.Infof("syncing repos for org %s", o) + l.Debugf("syncing repos for org %s", o) // see if the user is an org admin perm, err := scm.FromContext(c).OrgAccess(ctx, u, o) if err != nil { - logger.Errorf("unable to get user %s access level for org %s", u.GetName(), o) + l.Errorf("unable to get user %s access level for org %s", u.GetName(), o) } // only allow org-wide syncing if user is admin of org @@ -143,6 +136,8 @@ func SyncReposForOrg(c *gin.Context) { return } + l.Infof("repo %s has been updated - set to inactive", repo.GetFullName()) + results = append(results, repo) } else { retErr := fmt.Errorf("error while retrieving repo %s from %s: %w", repo.GetFullName(), scm.FromContext(c).Driver(), err) @@ -183,6 +178,8 @@ func SyncReposForOrg(c *gin.Context) { return } + l.Infof("repo %s has been updated - set to inactive", repo.GetFullName()) + results = append(results, repo) continue diff --git a/api/secret/create.go b/api/secret/create.go index e2d3e2c50..6c4c502b1 100644 --- a/api/secret/create.go +++ b/api/secret/create.go @@ -20,7 +20,6 @@ import ( "github.com/go-vela/types/library/actions" ) -// // swagger:operation POST /api/v1/secrets/{engine}/{type}/{org}/{name} secrets CreateSecret // // Create a secret @@ -85,6 +84,7 @@ import ( //nolint:funlen // suppress long function error func CreateSecret(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) u := user.Retrieve(c) e := util.PathParameter(c, "engine") t := util.PathParameter(c, "type") @@ -96,25 +96,24 @@ func CreateSecret(c *gin.Context) { // create log fields from API metadata fields := logrus.Fields{ - "engine": e, - "org": o, - "repo": n, - "type": t, - "user": u.GetName(), + "secret_engine": e, + "secret_org": o, + "secret_repo": n, + "secret_type": t, } // check if secret is a shared secret if strings.EqualFold(t, constants.SecretShared) { - // update log fields from API metadata - fields = logrus.Fields{ - "engine": e, - "org": o, - "team": n, - "type": t, - "user": u.GetName(), - } + // update log fields for shared secret + delete(fields, "secret_repo") + fields["secret_team"] = n } + // update engine logger with API metadata + // + // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields + logger := l.WithFields(fields) + if strings.EqualFold(t, constants.SecretOrg) { // retrieve org name from SCM // @@ -173,10 +172,7 @@ func CreateSecret(c *gin.Context) { } } - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(fields).Infof("creating new secret %s for %s service", entry, e) + logger.Debugf("creating new secret %s for %s service", entry, e) // capture body from API request input := new(library.Secret) @@ -259,5 +255,23 @@ func CreateSecret(c *gin.Context) { return } + // update log fields from create response + fields = logrus.Fields{ + "secret_id": s.GetID(), + "secret_name": s.GetName(), + "secret_org": s.GetOrg(), + "secret_repo": s.GetRepo(), + "secret_type": s.GetType(), + } + + // check if secret is a shared secret + if strings.EqualFold(t, constants.SecretShared) { + // update log fields for shared secret + delete(fields, "secret_repo") + fields["secret_team"] = s.GetTeam() + } + + l.WithFields(fields).Infof("created secret %s for %s service", entry, e) + c.JSON(http.StatusOK, s.Sanitize()) } diff --git a/api/secret/delete.go b/api/secret/delete.go index 188016155..c038c1a08 100644 --- a/api/secret/delete.go +++ b/api/secret/delete.go @@ -10,13 +10,11 @@ import ( "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/secret" "github.com/go-vela/server/util" "github.com/go-vela/types/constants" ) -// // swagger:operation DELETE /api/v1/secrets/{engine}/{type}/{org}/{name}/{secret} secrets DeleteSecret // // Delete a secret @@ -73,7 +71,7 @@ import ( // DeleteSecret deletes a secret from the provided secrets service. func DeleteSecret(c *gin.Context) { // capture middleware values - u := user.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) e := util.PathParameter(c, "engine") t := util.PathParameter(c, "type") o := util.PathParameter(c, "org") @@ -85,31 +83,26 @@ func DeleteSecret(c *gin.Context) { // create log fields from API metadata fields := logrus.Fields{ - "engine": e, - "org": o, - "repo": n, - "secret": s, - "type": t, - "user": u.GetName(), + "secret_engine": e, + "secret_org": o, + "secret_repo": n, + "secret_name": s, + "secret_type": t, } // check if secret is a shared secret if strings.EqualFold(t, constants.SecretShared) { // update log fields from API metadata - fields = logrus.Fields{ - "engine": e, - "org": o, - "secret": s, - "team": n, - "type": t, - "user": u.GetName(), - } + delete(fields, "secret_repo") + fields["secret_team"] = n } // update engine logger with API metadata // // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(fields).Infof("deleting secret %s from %s service", entry, e) + logger := l.WithFields(fields) + + logger.Debugf("deleting secret %s from %s service", entry, e) // send API call to remove the secret err := secret.FromContext(c, e).Delete(ctx, t, o, n, s) @@ -121,5 +114,7 @@ func DeleteSecret(c *gin.Context) { return } + logger.Infof("secret %s deleted from %s service", entry, e) + c.JSON(http.StatusOK, fmt.Sprintf("secret %s deleted from %s service", entry, e)) } diff --git a/api/secret/get.go b/api/secret/get.go index dc4d4da1f..72a84fc18 100644 --- a/api/secret/get.go +++ b/api/secret/get.go @@ -11,13 +11,11 @@ import ( "github.com/sirupsen/logrus" "github.com/go-vela/server/router/middleware/claims" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/secret" "github.com/go-vela/server/util" "github.com/go-vela/types/constants" ) -// // swagger:operation GET /api/v1/secrets/{engine}/{type}/{org}/{name}/{secret} secrets GetSecret // // Get a secret @@ -74,8 +72,8 @@ import ( // GetSecret gets a secret from the provided secrets service. func GetSecret(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) cl := claims.Retrieve(c) - u := user.Retrieve(c) e := util.PathParameter(c, "engine") t := util.PathParameter(c, "type") o := util.PathParameter(c, "org") @@ -87,31 +85,26 @@ func GetSecret(c *gin.Context) { // create log fields from API metadata fields := logrus.Fields{ - "engine": e, - "org": o, - "repo": n, - "secret": s, - "type": t, - "user": u.GetName(), + "secret_engine": e, + "secret_org": o, + "secret_repo": n, + "secret_name": s, + "secret_type": t, } // check if secret is a shared secret if strings.EqualFold(t, constants.SecretShared) { // update log fields from API metadata - fields = logrus.Fields{ - "engine": e, - "org": o, - "secret": s, - "team": n, - "type": t, - "user": u.GetName(), - } + delete(fields, "secret_repo") + fields["secret_team"] = n } // update engine logger with API metadata // // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(fields).Infof("reading secret %s from %s service", entry, e) + logger := l.WithFields(fields) + + logger.Debugf("reading secret %s from %s service", entry, e) // send API call to capture the secret secret, err := secret.FromContext(c, e).Get(ctx, t, o, n, s) @@ -130,5 +123,7 @@ func GetSecret(c *gin.Context) { return } + logger.Infof("retrieved secret %s from %s service", entry, e) + c.JSON(http.StatusOK, secret.Sanitize()) } diff --git a/api/secret/list.go b/api/secret/list.go index a6699ef34..793b594f7 100644 --- a/api/secret/list.go +++ b/api/secret/list.go @@ -20,7 +20,6 @@ import ( "github.com/go-vela/types/library" ) -// // swagger:operation GET /api/v1/secrets/{engine}/{type}/{org}/{name} secrets ListSecrets // // Get all organization or shared secrets @@ -96,6 +95,7 @@ import ( // ListSecrets represents the API handler to get a list of secrets. func ListSecrets(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) u := user.Retrieve(c) e := util.PathParameter(c, "engine") t := util.PathParameter(c, "type") @@ -122,29 +122,25 @@ func ListSecrets(c *gin.Context) { // create log fields from API metadata fields := logrus.Fields{ - "engine": e, - "org": o, - "repo": n, - "type": t, - "user": u.GetName(), + "secret_engine": e, + "secret_org": o, + "secret_repo": n, + "secret_type": t, } // check if secret is a shared secret if strings.EqualFold(t, constants.SecretShared) { // update log fields from API metadata - fields = logrus.Fields{ - "engine": e, - "org": o, - "team": n, - "type": t, - "user": u.GetName(), - } + delete(fields, "secret_repo") + fields["secret_team"] = n } // update engine logger with API metadata // // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(fields).Infof("listing secrets %s from %s service", entry, e) + logger := l.WithFields(fields) + + logger.Debugf("listing secrets %s from %s service", entry, e) // capture page query parameter if present page, err := strconv.Atoi(c.DefaultQuery("page", "1")) @@ -209,5 +205,7 @@ func ListSecrets(c *gin.Context) { secrets = append(secrets, tmp.Sanitize()) } + logger.Infof("successfully listed secrets %s from %s service", entry, e) + c.JSON(http.StatusOK, secrets) } diff --git a/api/secret/update.go b/api/secret/update.go index dc66df7ce..0d7d62072 100644 --- a/api/secret/update.go +++ b/api/secret/update.go @@ -85,6 +85,7 @@ import ( // UpdateSecret updates a secret for the provided secrets service. func UpdateSecret(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) u := user.Retrieve(c) e := util.PathParameter(c, "engine") t := util.PathParameter(c, "type") @@ -97,31 +98,24 @@ func UpdateSecret(c *gin.Context) { // create log fields from API metadata fields := logrus.Fields{ - "engine": e, - "org": o, - "repo": n, - "secret": s, - "type": t, - "user": u.GetName(), + "secret_engine": e, + "secret_org": o, + "secret_repo": n, + "secret_name": s, + "secret_type": t, } // check if secret is a shared secret if strings.EqualFold(t, constants.SecretShared) { // update log fields from API metadata - fields = logrus.Fields{ - "engine": e, - "org": o, - "secret": s, - "team": n, - "type": t, - "user": u.GetName(), - } + delete(fields, "secret_repo") + fields["secret_team"] = n } // update engine logger with API metadata // // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(fields).Infof("updating secret %s for %s service", entry, e) + l.WithFields(fields).Debugf("updating secret %s for %s service", entry, e) // capture body from API request input := new(library.Secret) @@ -174,5 +168,7 @@ func UpdateSecret(c *gin.Context) { return } + l.WithFields(fields).Info("secret updated") + c.JSON(http.StatusOK, secret.Sanitize()) } diff --git a/api/service/create.go b/api/service/create.go index e4289cc0b..4e3ee47c7 100644 --- a/api/service/create.go +++ b/api/service/create.go @@ -12,9 +12,7 @@ import ( "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" @@ -77,23 +75,14 @@ import ( // a service for a build. func CreateService(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) b := build.Retrieve(c) - o := org.Retrieve(c) r := repo.Retrieve(c) - u := user.Retrieve(c) ctx := c.Request.Context() entry := fmt.Sprintf("%s/%d", r.GetFullName(), b.GetNumber()) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "build": b.GetNumber(), - "org": o, - "repo": r.GetName(), - "user": u.GetName(), - }).Infof("creating new service for build %s", entry) + l.Debugf("creating new service for build %s", entry) // capture body from API request input := new(library.Service) @@ -129,5 +118,10 @@ func CreateService(c *gin.Context) { return } + l.WithFields(logrus.Fields{ + "service": s.GetName(), + "service_id": s.GetID(), + }).Infof("service %s created for build %s", s.GetName(), entry) + c.JSON(http.StatusCreated, s) } diff --git a/api/service/delete.go b/api/service/delete.go index 90ca9b9b6..5bd8269fd 100644 --- a/api/service/delete.go +++ b/api/service/delete.go @@ -11,10 +11,8 @@ import ( "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/service" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" ) @@ -74,25 +72,15 @@ import ( // DeleteService represents the API handler to remove a service for a build. func DeleteService(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) b := build.Retrieve(c) - o := org.Retrieve(c) r := repo.Retrieve(c) s := service.Retrieve(c) - u := user.Retrieve(c) ctx := c.Request.Context() entry := fmt.Sprintf("%s/%d/%d", r.GetFullName(), b.GetNumber(), s.GetNumber()) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "build": b.GetNumber(), - "org": o, - "repo": r.GetName(), - "service": s.GetNumber(), - "user": u.GetName(), - }).Infof("deleting service %s", entry) + l.Debugf("deleting service %s", entry) // send API call to remove the service err := database.FromContext(c).DeleteService(ctx, s) diff --git a/api/service/get.go b/api/service/get.go index c54d1427d..9538d3300 100644 --- a/api/service/get.go +++ b/api/service/get.go @@ -9,10 +9,8 @@ import ( "github.com/sirupsen/logrus" "github.com/go-vela/server/router/middleware/build" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/service" - "github.com/go-vela/server/router/middleware/user" ) // @@ -71,22 +69,12 @@ import ( // GetService represents the API handler to get a service for a build. func GetService(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) b := build.Retrieve(c) - o := org.Retrieve(c) r := repo.Retrieve(c) s := service.Retrieve(c) - u := user.Retrieve(c) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "build": b.GetNumber(), - "org": o, - "repo": r.GetName(), - "service": s.GetNumber(), - "user": u.GetName(), - }).Infof("reading service %s/%d/%d", r.GetFullName(), b.GetNumber(), s.GetNumber()) + l.Debugf("reading service %s/%d/%d", r.GetFullName(), b.GetNumber(), s.GetNumber()) c.JSON(http.StatusOK, s) } diff --git a/api/service/list.go b/api/service/list.go index 2862a28d4..efc4aa5a0 100644 --- a/api/service/list.go +++ b/api/service/list.go @@ -13,9 +13,7 @@ import ( "github.com/go-vela/server/api" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" ) @@ -89,23 +87,14 @@ import ( // ListServices represents the API handler to get a list of services for a build. func ListServices(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) b := build.Retrieve(c) - o := org.Retrieve(c) r := repo.Retrieve(c) - u := user.Retrieve(c) ctx := c.Request.Context() entry := fmt.Sprintf("%s/%d", r.GetFullName(), b.GetNumber()) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "build": b.GetNumber(), - "org": o, - "repo": r.GetName(), - "user": u.GetName(), - }).Infof("reading services for build %s", entry) + l.Debugf("reading services for build %s", entry) // capture page query parameter if present page, err := strconv.Atoi(c.DefaultQuery("page", "1")) diff --git a/api/service/plan.go b/api/service/plan.go index faed795cb..bc8408ddb 100644 --- a/api/service/plan.go +++ b/api/service/plan.go @@ -7,6 +7,8 @@ import ( "fmt" "time" + "github.com/sirupsen/logrus" + "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/types/constants" @@ -39,6 +41,14 @@ func PlanServices(ctx context.Context, database database.Interface, p *pipeline. return services, fmt.Errorf("unable to create service %s: %w", s.GetName(), err) } + logrus.WithFields(logrus.Fields{ + "service": s.GetName(), + "service_id": s.GetID(), + "org": b.GetRepo().GetOrg(), + "repo": b.GetRepo().GetName(), + "repo_id": b.GetRepo().GetID(), + }).Info("service created") + // populate environment variables from service library // // https://pkg.go.dev/github.com/go-vela/types/library#Service.Environment @@ -59,6 +69,15 @@ func PlanServices(ctx context.Context, database database.Interface, p *pipeline. if err != nil { return services, fmt.Errorf("unable to create service logs for service %s: %w", s.GetName(), err) } + + logrus.WithFields(logrus.Fields{ + "service": s.GetName(), + "service_id": s.GetID(), + "log_id": l.GetID(), // it won't have an ID here, because CreateLog doesn't return the created log + "org": b.GetRepo().GetOrg(), + "repo": b.GetRepo().GetName(), + "repo_id": b.GetRepo().GetID(), + }).Info("log for service created") } return services, nil diff --git a/api/service/update.go b/api/service/update.go index 0b2825997..a7e047a60 100644 --- a/api/service/update.go +++ b/api/service/update.go @@ -11,10 +11,8 @@ import ( "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/service" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/library" ) @@ -82,25 +80,15 @@ import ( // a service for a build. func UpdateService(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) b := build.Retrieve(c) - o := org.Retrieve(c) r := repo.Retrieve(c) s := service.Retrieve(c) - u := user.Retrieve(c) ctx := c.Request.Context() entry := fmt.Sprintf("%s/%d/%d", r.GetFullName(), b.GetNumber(), s.GetNumber()) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "build": b.GetNumber(), - "org": o, - "repo": r.GetName(), - "service": s.GetNumber(), - "user": u.GetName(), - }).Infof("updating service %s", entry) + l.Debugf("updating service %s", entry) // capture body from API request input := new(library.Service) diff --git a/api/step/create.go b/api/step/create.go index 33225a93f..b9a113de4 100644 --- a/api/step/create.go +++ b/api/step/create.go @@ -12,9 +12,7 @@ import ( "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" @@ -77,23 +75,14 @@ import ( // a step for a build. func CreateStep(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) b := build.Retrieve(c) - o := org.Retrieve(c) r := repo.Retrieve(c) - u := user.Retrieve(c) ctx := c.Request.Context() entry := fmt.Sprintf("%s/%d", r.GetFullName(), b.GetNumber()) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "build": b.GetNumber(), - "org": o, - "repo": r.GetName(), - "user": u.GetName(), - }).Infof("creating new step for build %s", entry) + l.Debugf("creating new step for build %s", entry) // capture body from API request input := new(library.Step) @@ -129,5 +118,10 @@ func CreateStep(c *gin.Context) { return } + l.WithFields(logrus.Fields{ + "step": s.GetName(), + "step_id": s.GetID(), + }).Infof("step %s created for build %s", s.GetName(), entry) + c.JSON(http.StatusCreated, s) } diff --git a/api/step/delete.go b/api/step/delete.go index 27a3eff1d..b59f9b1d0 100644 --- a/api/step/delete.go +++ b/api/step/delete.go @@ -11,10 +11,8 @@ import ( "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/step" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" ) @@ -73,25 +71,15 @@ import ( // DeleteStep represents the API handler to remove a step for a build. func DeleteStep(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) b := build.Retrieve(c) - o := org.Retrieve(c) r := repo.Retrieve(c) s := step.Retrieve(c) - u := user.Retrieve(c) ctx := c.Request.Context() entry := fmt.Sprintf("%s/%d/%d", r.GetFullName(), b.GetNumber(), s.GetNumber()) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "build": b.GetNumber(), - "org": o, - "repo": r.GetName(), - "step": s.GetNumber(), - "user": u.GetName(), - }).Infof("deleting step %s", entry) + l.Debugf("deleting step %s", entry) // send API call to remove the step err := database.FromContext(c).DeleteStep(ctx, s) diff --git a/api/step/get.go b/api/step/get.go index 09267ffb3..627937371 100644 --- a/api/step/get.go +++ b/api/step/get.go @@ -9,10 +9,8 @@ import ( "github.com/sirupsen/logrus" "github.com/go-vela/server/router/middleware/build" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/step" - "github.com/go-vela/server/router/middleware/user" ) // swagger:operation GET /api/v1/repos/{org}/{repo}/builds/{build}/steps/{step} steps GetStep @@ -66,22 +64,12 @@ import ( // GetStep represents the API handler to get a step for a build. func GetStep(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) b := build.Retrieve(c) - o := org.Retrieve(c) r := repo.Retrieve(c) s := step.Retrieve(c) - u := user.Retrieve(c) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "build": b.GetNumber(), - "org": o, - "repo": r.GetName(), - "step": s.GetNumber(), - "user": u.GetName(), - }).Infof("reading step %s/%d/%d", r.GetFullName(), b.GetNumber(), s.GetNumber()) + l.Debugf("reading step %s/%d/%d", r.GetFullName(), b.GetNumber(), s.GetNumber()) c.JSON(http.StatusOK, s) } diff --git a/api/step/list.go b/api/step/list.go index 67617b2b6..194235f5c 100644 --- a/api/step/list.go +++ b/api/step/list.go @@ -13,9 +13,7 @@ import ( "github.com/go-vela/server/api" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" ) @@ -89,23 +87,14 @@ import ( // ListSteps represents the API handler to get a list of steps for a build. func ListSteps(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) b := build.Retrieve(c) - o := org.Retrieve(c) r := repo.Retrieve(c) - u := user.Retrieve(c) ctx := c.Request.Context() entry := fmt.Sprintf("%s/%d", r.GetFullName(), b.GetNumber()) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "build": b.GetNumber(), - "org": o, - "repo": r.GetName(), - "user": u.GetName(), - }).Infof("listing steps for build %s", entry) + l.Debugf("listing steps for build %s", entry) // capture page query parameter if present page, err := strconv.Atoi(c.DefaultQuery("page", "1")) diff --git a/api/step/plan.go b/api/step/plan.go index 6b3faac06..cfb55652e 100644 --- a/api/step/plan.go +++ b/api/step/plan.go @@ -70,6 +70,14 @@ func planStep(ctx context.Context, database database.Interface, scm scm.Service, return nil, fmt.Errorf("unable to create step %s: %w", s.GetName(), err) } + logrus.WithFields(logrus.Fields{ + "step": s.GetName(), + "step_id": s.GetID(), + "org": b.GetRepo().GetOrg(), + "repo": b.GetRepo().GetName(), + "repo_id": b.GetRepo().GetID(), + }).Info("step created") + // populate environment variables from step library // // https://pkg.go.dev/github.com/go-vela/types/library#step.Environment @@ -91,6 +99,15 @@ func planStep(ctx context.Context, database database.Interface, scm scm.Service, return nil, fmt.Errorf("unable to create logs for step %s: %w", s.GetName(), err) } + logrus.WithFields(logrus.Fields{ + "step": s.GetName(), + "step_id": s.GetID(), + "log_id": l.GetID(), // it won't have an ID here + "org": b.GetRepo().GetOrg(), + "repo": b.GetRepo().GetName(), + "repo_id": b.GetRepo().GetID(), + }).Info("log for step created") + if len(s.GetReportAs()) > 0 { // send API call to set the status on the commit err = scm.StepStatus(ctx, b.GetRepo().GetOwner(), b, s, b.GetRepo().GetOrg(), b.GetRepo().GetName()) diff --git a/api/step/update.go b/api/step/update.go index 87e2fc6dd..c543de2c8 100644 --- a/api/step/update.go +++ b/api/step/update.go @@ -11,10 +11,8 @@ import ( "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/build" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/step" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" "github.com/go-vela/server/util" "github.com/go-vela/types/constants" @@ -83,25 +81,15 @@ import ( // a step for a build. func UpdateStep(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) b := build.Retrieve(c) - o := org.Retrieve(c) r := repo.Retrieve(c) s := step.Retrieve(c) - u := user.Retrieve(c) ctx := c.Request.Context() entry := fmt.Sprintf("%s/%d/%d", r.GetFullName(), b.GetNumber(), s.GetNumber()) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "build": b.GetNumber(), - "org": o, - "repo": r.GetName(), - "step": s.GetNumber(), - "user": u.GetName(), - }).Infof("updating step %s", entry) + l.Debugf("updating step %s", entry) // capture body from API request input := new(library.Step) @@ -180,7 +168,7 @@ func UpdateStep(c *gin.Context) { // send API call to set the status on the commit err = scm.FromContext(c).StepStatus(ctx, r.GetOwner(), b, s, r.GetOrg(), r.GetName()) if err != nil { - logrus.Errorf("unable to set commit status for build %s: %v", entry, err) + l.Errorf("unable to set commit status for build %s: %v", entry, err) } } } diff --git a/api/types/dashboard.go b/api/types/dashboard.go index 11c3883ee..08954350f 100644 --- a/api/types/dashboard.go +++ b/api/types/dashboard.go @@ -31,6 +31,8 @@ type BuildPartial struct { // DashCard is an API type that holds the dashboard information as // well as a list of RepoPartials attached to the dashboard. +// +// swagger:model DashCard type DashCard struct { Dashboard *Dashboard `json:"dashboard,omitempty"` Repos []RepoPartial `json:"repos,omitempty"` diff --git a/api/user/create.go b/api/user/create.go index bf37a8472..e856a8736 100644 --- a/api/user/create.go +++ b/api/user/create.go @@ -52,6 +52,7 @@ import ( // CreateUser represents the API handler to create a user. func CreateUser(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) u := user.Retrieve(c) ctx := c.Request.Context() @@ -70,9 +71,9 @@ func CreateUser(c *gin.Context) { // update engine logger with API metadata // // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ + l.WithFields(logrus.Fields{ "user": u.GetName(), - }).Infof("creating new user %s", input.GetName()) + }).Debugf("creating new user %s", input.GetName()) // send API call to create the user user, err := database.FromContext(c).CreateUser(ctx, input) @@ -84,5 +85,10 @@ func CreateUser(c *gin.Context) { return } + l.WithFields(logrus.Fields{ + "user": user.GetName(), + "user_id": user.GetID(), + }).Info("user created") + c.JSON(http.StatusCreated, user) } diff --git a/api/user/create_token.go b/api/user/create_token.go index 6a3bb2678..2eb0c9028 100644 --- a/api/user/create_token.go +++ b/api/user/create_token.go @@ -44,15 +44,11 @@ import ( // a user token. func CreateToken(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) u := user.Retrieve(c) ctx := c.Request.Context() - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "user": u.GetName(), - }).Infof("composing token for user %s", u.GetName()) + l.Debugf("composing token for user %s", u.GetName()) tm := c.MustGet("token-manager").(*token.Manager) @@ -78,5 +74,7 @@ func CreateToken(c *gin.Context) { return } + l.Info("user updated - token created") + c.JSON(http.StatusOK, library.Token{Token: &at}) } diff --git a/api/user/delete.go b/api/user/delete.go index 35c026736..e3cd1e184 100644 --- a/api/user/delete.go +++ b/api/user/delete.go @@ -10,7 +10,6 @@ import ( "github.com/sirupsen/logrus" "github.com/go-vela/server/database" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" ) @@ -50,16 +49,11 @@ import ( // DeleteUser represents the API handler to remove a user. func DeleteUser(c *gin.Context) { // capture middleware values - u := user.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) user := util.PathParameter(c, "user") ctx := c.Request.Context() - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "user": u.GetName(), - }).Infof("deleting user %s", user) + l.Debugf("deleting user %s", user) // send API call to capture the user u, err := database.FromContext(c).GetUserForName(ctx, user) diff --git a/api/user/delete_token.go b/api/user/delete_token.go index 1f21a7a24..8ee9f27da 100644 --- a/api/user/delete_token.go +++ b/api/user/delete_token.go @@ -44,15 +44,11 @@ import ( // and recreate a user token. func DeleteToken(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) u := user.Retrieve(c) ctx := c.Request.Context() - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "user": u.GetName(), - }).Infof("revoking token for user %s", u.GetName()) + l.Debugf("revoking token for user %s", u.GetName()) tm := c.MustGet("token-manager").(*token.Manager) @@ -78,5 +74,7 @@ func DeleteToken(c *gin.Context) { return } + l.Info("user updated - token rotated") + c.JSON(http.StatusOK, library.Token{Token: &at}) } diff --git a/api/user/get.go b/api/user/get.go index 708eb56bb..5d39b9518 100644 --- a/api/user/get.go +++ b/api/user/get.go @@ -10,7 +10,6 @@ import ( "github.com/sirupsen/logrus" "github.com/go-vela/server/database" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" ) @@ -46,16 +45,11 @@ import ( // GetUser represents the API handler to get a user. func GetUser(c *gin.Context) { // capture middleware values - u := user.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) user := util.PathParameter(c, "user") ctx := c.Request.Context() - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "user": u.GetName(), - }).Infof("reading user %s", user) + l.Debugf("reading user %s", user) // send API call to capture the user u, err := database.FromContext(c).GetUserForName(ctx, user) diff --git a/api/user/get_current.go b/api/user/get_current.go index 1cd21526d..a33fab4d2 100644 --- a/api/user/get_current.go +++ b/api/user/get_current.go @@ -34,14 +34,10 @@ import ( // currently authenticated user. func GetCurrentUser(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) u := user.Retrieve(c) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "user": u.GetName(), - }).Infof("reading current user %s", u.GetName()) + l.Debugf("reading current user %s", u.GetName()) c.JSON(http.StatusOK, u) } diff --git a/api/user/get_source.go b/api/user/get_source.go index b74639f96..19b75eea3 100644 --- a/api/user/get_source.go +++ b/api/user/get_source.go @@ -42,15 +42,11 @@ import ( // GetSourceRepos represents the API handler to get a list of repos for a user. func GetSourceRepos(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) u := user.Retrieve(c) ctx := c.Request.Context() - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "user": u.GetName(), - }).Infof("reading available SCM repos for user %s", u.GetName()) + l.Debugf("reading available SCM repos for user %s", u.GetName()) // variables to capture requested data dbRepos := []*types.Repo{} diff --git a/api/user/list.go b/api/user/list.go index d4f5ad0ff..12dde536c 100644 --- a/api/user/list.go +++ b/api/user/list.go @@ -12,7 +12,6 @@ import ( "github.com/go-vela/server/api" "github.com/go-vela/server/database" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" ) @@ -67,15 +66,10 @@ import ( // ListUsers represents the API handler to get a list of users. func ListUsers(c *gin.Context) { // capture middleware values - u := user.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) ctx := c.Request.Context() - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "user": u.GetName(), - }).Info("reading lite users") + l.Debug("reading lite users") // capture page query parameter if present page, err := strconv.Atoi(c.DefaultQuery("page", "1")) diff --git a/api/user/update.go b/api/user/update.go index 9ebd37c36..f356bd956 100644 --- a/api/user/update.go +++ b/api/user/update.go @@ -11,7 +11,6 @@ import ( "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" ) @@ -61,16 +60,11 @@ import ( // UpdateUser represents the API handler to update a user. func UpdateUser(c *gin.Context) { // capture middleware values - u := user.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) user := util.PathParameter(c, "user") ctx := c.Request.Context() - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "user": u.GetName(), - }).Infof("updating user %s", user) + l.Debugf("updating user %s", user) // capture body from API request input := new(types.User) @@ -85,7 +79,7 @@ func UpdateUser(c *gin.Context) { } // send API call to capture the user - u, err = database.FromContext(c).GetUserForName(ctx, user) + u, err := database.FromContext(c).GetUserForName(ctx, user) if err != nil { retErr := fmt.Errorf("unable to get user %s: %w", user, err) diff --git a/api/user/update_current.go b/api/user/update_current.go index 3853611ec..d73bb445d 100644 --- a/api/user/update_current.go +++ b/api/user/update_current.go @@ -53,15 +53,11 @@ import ( // update the currently authenticated user. func UpdateCurrentUser(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) u := user.Retrieve(c) ctx := c.Request.Context() - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "user": u.GetName(), - }).Infof("updating current user %s", u.GetName()) + l.Debugf("updating current user %s", u.GetName()) // capture body from API request input := new(types.User) diff --git a/api/webhook/post.go b/api/webhook/post.go index ddc0a047e..e4ac32c3d 100644 --- a/api/webhook/post.go +++ b/api/webhook/post.go @@ -82,12 +82,13 @@ var baseErr = "unable to process webhook" // //nolint:funlen,gocyclo // ignore function length and cyclomatic complexity func PostWebhook(c *gin.Context) { - logrus.Info("webhook received") - // capture middleware values m := c.MustGet("metadata").(*internal.Metadata) + l := c.MustGet("logger").(*logrus.Entry) ctx := c.Request.Context() + l.Debug("webhook received") + // duplicate request so we can perform operations on the request body // // https://golang.org/pkg/net/http/#Request.Clone @@ -142,8 +143,8 @@ func PostWebhook(c *gin.Context) { h, r, b := webhook.Hook, webhook.Repo, webhook.Build - logrus.Debugf("hook generated from SCM: %v", h) - logrus.Debugf("repo generated from SCM: %v", r) + l.Debugf("hook generated from SCM: %v", h) + l.Debugf("repo generated from SCM: %v", r) // if event is repository event, handle separately and return if strings.EqualFold(h.GetEvent(), constants.EventRepository) { @@ -173,7 +174,7 @@ func PostWebhook(c *gin.Context) { return } - logrus.Debugf(`build author: %s, + l.Debugf(`build author: %s, build branch: %s, build commit: %s, build ref: %s`, @@ -191,8 +192,16 @@ func PostWebhook(c *gin.Context) { // send API call to update the webhook _, err = database.FromContext(c).UpdateHook(ctx, h) if err != nil { - logrus.Errorf("unable to update webhook %s/%d: %v", r.GetFullName(), h.GetNumber(), err) + l.Errorf("unable to update webhook %s/%d: %v", r.GetFullName(), h.GetNumber(), err) } + + l.WithFields(logrus.Fields{ + "hook": h.GetNumber(), + "hook_id": h.GetID(), + "org": r.GetOrg(), + "repo": r.GetName(), + "repo_id": r.GetID(), + }).Info("hook updated") }() // send API call to capture parsed repo from webhook @@ -261,6 +270,13 @@ func PostWebhook(c *gin.Context) { return } + l.WithFields(logrus.Fields{ + "hook": h.GetNumber(), + "hook_id": h.GetID(), + "org": repo.GetOrg(), + "repo": repo.GetName(), + }).Info("hook created") + // verify the webhook from the source control provider if c.Value("webhookvalidation").(bool) { err = scm.FromContext(c).VerifyWebhook(ctx, dupRequest, repo) @@ -371,7 +387,7 @@ func PostWebhook(c *gin.Context) { deployment.SetRepoID(repo.GetID()) deployment.SetBuilds([]*library.Build{b.ToLibrary()}) - _, err := database.FromContext(c).CreateDeployment(c, deployment) + dr, err := database.FromContext(c).CreateDeployment(c, deployment) if err != nil { retErr := fmt.Errorf("%s: failed to create deployment %s/%d: %w", baseErr, repo.GetFullName(), deployment.GetNumber(), err) util.HandleError(c, http.StatusInternalServerError, retErr) @@ -381,6 +397,14 @@ func PostWebhook(c *gin.Context) { return } + + l.WithFields(logrus.Fields{ + "deployment": dr.GetNumber(), + "deployment_id": dr.GetID(), + "org": repo.GetOrg(), + "repo": repo.GetName(), + "repo_id": repo.GetID(), + }).Info("deployment created") } else { retErr := fmt.Errorf("%s: failed to get deployment %s/%d: %w", baseErr, repo.GetFullName(), webhook.Deployment.GetNumber(), err) util.HandleError(c, http.StatusInternalServerError, retErr) @@ -405,6 +429,14 @@ func PostWebhook(c *gin.Context) { return } + + l.WithFields(logrus.Fields{ + "deployment": d.GetNumber(), + "deployment_id": d.GetID(), + "org": repo.GetOrg(), + "repo": repo.GetName(), + "repo_id": repo.GetID(), + }).Info("deployment updated") } } @@ -416,27 +448,43 @@ func PostWebhook(c *gin.Context) { // fetch pending and running builds rBs, err := database.FromContext(c).ListPendingAndRunningBuildsForRepo(c, repo) if err != nil { - logrus.Errorf("unable to fetch pending and running builds for %s: %v", repo.GetFullName(), err) + l.Errorf("unable to fetch pending and running builds for %s: %v", repo.GetFullName(), err) } + l.WithFields(logrus.Fields{ + "build": b.GetNumber(), + "build_id": b.GetID(), + "org": repo.GetOrg(), + "repo": repo.GetName(), + "repo_id": repo.GetID(), + }).Debugf("found %d pending/running builds", len(rBs)) + for _, rB := range rBs { // call auto cancel routine canceled, err := build.AutoCancel(c, b, rB, p.Metadata.AutoCancel) if err != nil { // continue cancel loop if error, but log based on type of error if canceled { - logrus.Errorf("unable to update canceled build error message: %v", err) + l.Errorf("unable to update canceled build error message: %v", err) } else { - logrus.Errorf("unable to cancel running build: %v", err) + l.Errorf("unable to cancel running build: %v", err) } } + + l.WithFields(logrus.Fields{ + "build": rB.GetNumber(), + "build_id": rB.GetID(), + "org": repo.GetOrg(), + "repo": repo.GetName(), + "repo_id": repo.GetID(), + }).Debug("auto-canceled build") } } }() // if the webhook was from a Pull event from a forked repository, verify it is allowed to run if webhook.PullRequest.IsFromFork { - logrus.Tracef("inside %s workflow for fork PR build %s/%d", repo.GetApproveBuild(), r.GetFullName(), b.GetNumber()) + l.Tracef("inside %s workflow for fork PR build %s/%d", repo.GetApproveBuild(), r.GetFullName(), b.GetNumber()) switch repo.GetApproveBuild() { case constants.ApproveForkAlways: @@ -458,7 +506,7 @@ func PostWebhook(c *gin.Context) { return } - logrus.Debugf("fork PR build %s/%d automatically running without approval", repo.GetFullName(), b.GetNumber()) + l.Debugf("fork PR build %s/%d automatically running without approval", repo.GetFullName(), b.GetNumber()) case constants.ApproveOnce: // determine if build sender is in the contributors list for the repo // @@ -482,14 +530,14 @@ func PostWebhook(c *gin.Context) { case constants.ApproveNever: fallthrough default: - logrus.Debugf("fork PR build %s/%d automatically running without approval", repo.GetFullName(), b.GetNumber()) + l.Debugf("fork PR build %s/%d automatically running without approval", repo.GetFullName(), b.GetNumber()) } } // send API call to set the status on the commit err = scm.FromContext(c).Status(ctx, repo.GetOwner(), b, repo.GetOrg(), repo.GetName()) if err != nil { - logrus.Errorf("unable to set commit status for %s/%d: %v", repo.GetFullName(), b.GetNumber(), err) + l.Errorf("unable to set commit status for %s/%d: %v", repo.GetFullName(), b.GetNumber(), err) } // publish the build to the queue @@ -505,14 +553,28 @@ func PostWebhook(c *gin.Context) { // handleRepositoryEvent is a helper function that processes repository events from the SCM and updates // the database resources with any relevant changes resulting from the event, such as name changes, transfers, etc. func handleRepositoryEvent(ctx context.Context, c *gin.Context, m *internal.Metadata, h *library.Hook, r *types.Repo) (*types.Repo, error) { - logrus.Debugf("webhook is repository event, making necessary updates to repo %s", r.GetFullName()) + l := c.MustGet("logger").(*logrus.Entry) + + l = l.WithFields(logrus.Fields{ + "event_type": h.GetEvent(), + }) + + l.Debugf("webhook is repository event, making necessary updates to repo %s", r.GetFullName()) defer func() { // send API call to update the webhook - _, err := database.FromContext(c).CreateHook(ctx, h) + hr, err := database.FromContext(c).CreateHook(ctx, h) if err != nil { - logrus.Errorf("unable to create webhook %s/%d: %v", r.GetFullName(), h.GetNumber(), err) + l.Errorf("unable to create webhook %s/%d: %v", r.GetFullName(), h.GetNumber(), err) } + + l.WithFields(logrus.Fields{ + "hook": hr.GetNumber(), + "hook_id": hr.GetID(), + "org": r.GetOrg(), + "repo": r.GetName(), + "repo_id": r.GetID(), + }).Info("hook created") }() switch h.GetEventAction() { @@ -529,7 +591,7 @@ func handleRepositoryEvent(ctx context.Context, c *gin.Context, m *internal.Meta return r, nil // if action is archived, unarchived, or edited, perform edits to relevant repo fields case "archived", "unarchived", constants.ActionEdited: - logrus.Debugf("repository action %s for %s", h.GetEventAction(), r.GetFullName()) + l.Debugf("repository action %s for %s", h.GetEventAction(), r.GetFullName()) // send call to get repository from database dbRepo, err := database.FromContext(c).GetRepoForOrg(ctx, r.GetOrg(), r.GetName()) if err != nil { @@ -585,6 +647,12 @@ func handleRepositoryEvent(ctx context.Context, c *gin.Context, m *internal.Meta return nil, err } + l.WithFields(logrus.Fields{ + "org": dbRepo.GetOrg(), + "repo": dbRepo.GetName(), + "repo_id": dbRepo.GetID(), + }).Info("repo updated") + return dbRepo, nil // all other repo event actions are skippable default: @@ -597,7 +665,13 @@ func handleRepositoryEvent(ctx context.Context, c *gin.Context, m *internal.Meta // that repo to its new name in order to preserve it. It also updates the secrets // associated with that repo as well as build links for the UI. func RenameRepository(ctx context.Context, h *library.Hook, r *types.Repo, c *gin.Context, m *internal.Metadata) (*types.Repo, error) { - logrus.Infof("renaming repository from %s to %s", r.GetPreviousName(), r.GetName()) + l := c.MustGet("logger").(*logrus.Entry) + + l = l.WithFields(logrus.Fields{ + "event_type": h.GetEvent(), + }) + + l.Debugf("renaming repository from %s to %s", r.GetPreviousName(), r.GetName()) // get any matching hook with the repo's unique webhook ID in the SCM hook, err := database.FromContext(c).GetHookByWebhookID(ctx, h.GetWebhookID()) @@ -662,6 +736,12 @@ func RenameRepository(ctx context.Context, h *library.Hook, r *types.Repo, c *gi if err != nil { return nil, fmt.Errorf("unable to update secret for repo %s/%s: %w", dbR.GetOrg(), dbR.GetName(), err) } + + l.WithFields(logrus.Fields{ + "secret_id": secret.GetID(), + "repo": secret.GetRepo(), + "org": secret.GetOrg(), + }).Info("secret updated") } // get total number of builds associated with repository @@ -694,6 +774,14 @@ func RenameRepository(ctx context.Context, h *library.Hook, r *types.Repo, c *gi if err != nil { return nil, fmt.Errorf("unable to update build for repo %s: %w", dbR.GetFullName(), err) } + + l.WithFields(logrus.Fields{ + "build_id": build.GetID(), + "build": build.GetNumber(), + "org": dbR.GetOrg(), + "repo": dbR.GetName(), + "repo_id": dbR.GetID(), + }).Info("build updated") } // update the repo name information @@ -707,7 +795,7 @@ func RenameRepository(ctx context.Context, h *library.Hook, r *types.Repo, c *gi // update the repo in the database dbR, err = database.FromContext(c).UpdateRepo(ctx, dbR) if err != nil { - retErr := fmt.Errorf("%s: failed to update repo %s/%s in database", baseErr, dbR.GetOrg(), dbR.GetName()) + retErr := fmt.Errorf("%s: failed to update repo %s/%s", baseErr, dbR.GetOrg(), dbR.GetName()) util.HandleError(c, http.StatusBadRequest, retErr) h.SetStatus(constants.StatusFailure) @@ -716,13 +804,30 @@ func RenameRepository(ctx context.Context, h *library.Hook, r *types.Repo, c *gi return nil, retErr } + l.WithFields(logrus.Fields{ + "org": dbR.GetOrg(), + "repo": dbR.GetName(), + "repo_id": dbR.GetID(), + }).Infof("repo updated in database (previous name: %s)", r.GetPreviousName()) + return dbR, nil } // gatekeepBuild is a helper function that will set the status of a build to 'pending approval' and // send a status update to the SCM. func gatekeepBuild(c *gin.Context, b *types.Build, r *types.Repo) error { - logrus.Debugf("fork PR build %s/%d waiting for approval", r.GetFullName(), b.GetNumber()) + l := c.MustGet("logger").(*logrus.Entry) + + l = l.WithFields(logrus.Fields{ + "org": r.GetOrg(), + "repo": r.GetName(), + "repo_id": r.GetID(), + "build": b.GetNumber(), + "build_id": b.GetID(), + }) + + l.Debug("fork PR build waiting for approval") + b.SetStatus(constants.StatusPendingApproval) _, err := database.FromContext(c).UpdateBuild(c, b) @@ -730,6 +835,8 @@ func gatekeepBuild(c *gin.Context, b *types.Build, r *types.Repo) error { return fmt.Errorf("unable to update build for %s/%d: %w", r.GetFullName(), b.GetNumber(), err) } + l.Info("build updated") + // update the build components to pending approval status err = build.UpdateComponentStatuses(c, b, constants.StatusPendingApproval) if err != nil { @@ -739,7 +846,7 @@ func gatekeepBuild(c *gin.Context, b *types.Build, r *types.Repo) error { // send API call to set the status on the commit err = scm.FromContext(c).Status(c, r.GetOwner(), b, r.GetOrg(), r.GetName()) if err != nil { - logrus.Errorf("unable to set commit status for %s/%d: %v", r.GetFullName(), b.GetNumber(), err) + l.Errorf("unable to set commit status for %s/%d: %v", r.GetFullName(), b.GetNumber(), err) } return nil diff --git a/api/worker/create.go b/api/worker/create.go index c8af50b5e..cfac76e54 100644 --- a/api/worker/create.go +++ b/api/worker/create.go @@ -15,7 +15,6 @@ import ( "github.com/go-vela/server/database" "github.com/go-vela/server/internal/token" "github.com/go-vela/server/router/middleware/claims" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/constants" "github.com/go-vela/types/library" @@ -59,7 +58,7 @@ import ( // create a worker. func CreateWorker(c *gin.Context) { // capture middleware values - u := user.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) cl := claims.Retrieve(c) ctx := c.Request.Context() @@ -86,15 +85,9 @@ func CreateWorker(c *gin.Context) { input.SetLastCheckedIn(time.Now().Unix()) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "user": u.GetName(), - "worker": input.GetHostname(), - }).Infof("creating new worker %s", input.GetHostname()) + l.Debugf("creating new worker %s", input.GetHostname()) - _, err = database.FromContext(c).CreateWorker(ctx, input) + w, err := database.FromContext(c).CreateWorker(ctx, input) if err != nil { retErr := fmt.Errorf("unable to create worker: %w", err) @@ -103,12 +96,18 @@ func CreateWorker(c *gin.Context) { return } + l.WithFields(logrus.Fields{ + "worker": w.GetHostname(), + "worker_id": w.GetID(), + }).Info("worker created") + switch cl.TokenType { // if symmetric token configured, send back symmetric token case constants.ServerWorkerTokenType: if secret, ok := c.Value("secret").(string); ok { tkn := new(library.Token) tkn.SetToken(secret) + c.JSON(http.StatusCreated, tkn) return diff --git a/api/worker/delete.go b/api/worker/delete.go index 84f1442c0..a31ed9d44 100644 --- a/api/worker/delete.go +++ b/api/worker/delete.go @@ -10,7 +10,6 @@ import ( "github.com/sirupsen/logrus" "github.com/go-vela/server/database" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/router/middleware/worker" "github.com/go-vela/server/util" ) @@ -55,17 +54,11 @@ import ( // DeleteWorker represents the API handler to remove a worker. func DeleteWorker(c *gin.Context) { // capture middleware values - u := user.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) w := worker.Retrieve(c) ctx := c.Request.Context() - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "user": u.GetName(), - "worker": w.GetHostname(), - }).Infof("deleting worker %s", w.GetHostname()) + l.Debugf("deleting worker %s", w.GetHostname()) // send API call to remove the step err := database.FromContext(c).DeleteWorker(ctx, w) diff --git a/api/worker/get.go b/api/worker/get.go index c7d3f5227..23af82124 100644 --- a/api/worker/get.go +++ b/api/worker/get.go @@ -11,7 +11,6 @@ import ( "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/router/middleware/worker" "github.com/go-vela/server/util" ) @@ -56,17 +55,11 @@ import ( // GetWorker represents the API handler to get a worker. func GetWorker(c *gin.Context) { // capture middleware values - u := user.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) w := worker.Retrieve(c) ctx := c.Request.Context() - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "user": u.GetName(), - "worker": w.GetHostname(), - }).Infof("reading worker %s", w.GetHostname()) + l.Debugf("reading worker %s", w.GetHostname()) rBs := []*types.Build{} diff --git a/api/worker/list.go b/api/worker/list.go index eb20d58f8..5c0584809 100644 --- a/api/worker/list.go +++ b/api/worker/list.go @@ -13,7 +13,6 @@ import ( "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" ) @@ -63,15 +62,10 @@ import ( // ListWorkers represents the API handler to get a list of workers. func ListWorkers(c *gin.Context) { // capture middleware values - u := user.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) ctx := c.Request.Context() - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "user": u.GetName(), - }).Info("reading workers") + l.Debug("reading workers") active := c.Query("active") diff --git a/api/worker/refresh.go b/api/worker/refresh.go index 5fca4b884..51098efe2 100644 --- a/api/worker/refresh.go +++ b/api/worker/refresh.go @@ -61,6 +61,7 @@ import ( // refresh the auth token for a worker. func Refresh(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) w := worker.Retrieve(c) cl := claims.Retrieve(c) ctx := c.Request.Context() @@ -69,10 +70,7 @@ func Refresh(c *gin.Context) { if !strings.EqualFold(cl.TokenType, constants.ServerWorkerTokenType) && !strings.EqualFold(cl.Subject, w.GetHostname()) { retErr := fmt.Errorf("unable to refresh worker auth: claims subject %s does not match worker hostname %s", cl.Subject, w.GetHostname()) - logrus.WithFields(logrus.Fields{ - "subject": cl.Subject, - "worker": w.GetHostname(), - }).Warnf("attempted refresh of worker %s using token from worker %s", w.GetHostname(), cl.Subject) + l.Warnf("attempted refresh of worker %s using token from worker %s", w.GetHostname(), cl.Subject) util.HandleError(c, http.StatusBadRequest, retErr) @@ -92,12 +90,9 @@ func Refresh(c *gin.Context) { return } - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "worker": w.GetHostname(), - }).Infof("refreshing worker %s authentication", w.GetHostname()) + l.Info("worker updated - check-in time updated") + + l.Debugf("refreshing worker %s authentication", w.GetHostname()) switch cl.TokenType { // if symmetric token configured, send back symmetric token @@ -105,6 +100,7 @@ func Refresh(c *gin.Context) { if secret, ok := c.Value("secret").(string); ok { tkn := new(library.Token) tkn.SetToken(secret) + c.JSON(http.StatusOK, tkn) return diff --git a/api/worker/update.go b/api/worker/update.go index b717f9838..199928349 100644 --- a/api/worker/update.go +++ b/api/worker/update.go @@ -11,7 +11,6 @@ import ( "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/router/middleware/worker" "github.com/go-vela/server/util" ) @@ -63,17 +62,11 @@ import ( // update a worker. func UpdateWorker(c *gin.Context) { // capture middleware values - u := user.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) w := worker.Retrieve(c) ctx := c.Request.Context() - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "user": u.GetName(), - "worker": w.GetHostname(), - }).Infof("updating worker %s", w.GetHostname()) + l.Debugf("updating worker %s", w.GetHostname()) // capture body from API request input := new(types.Worker) diff --git a/cmd/vela-server/metadata.go b/cmd/vela-server/metadata.go index f14d9ee12..11da44af4 100644 --- a/cmd/vela-server/metadata.go +++ b/cmd/vela-server/metadata.go @@ -13,7 +13,7 @@ import ( // helper function to setup the metadata from the CLI arguments. func setupMetadata(c *cli.Context) (*internal.Metadata, error) { - logrus.Debug("Creating metadata from CLI configuration") + logrus.Debug("creating metadata from CLI configuration") m := new(internal.Metadata) @@ -50,7 +50,7 @@ func setupMetadata(c *cli.Context) (*internal.Metadata, error) { // helper function to capture the database metadata from the CLI arguments. func metadataDatabase(c *cli.Context) (*internal.Database, error) { - logrus.Trace("Creating database metadata from CLI configuration") + logrus.Trace("creating database metadata from CLI configuration") u, err := url.Parse(c.String("database.addr")) if err != nil { @@ -65,7 +65,7 @@ func metadataDatabase(c *cli.Context) (*internal.Database, error) { // helper function to capture the queue metadata from the CLI arguments. func metadataQueue(c *cli.Context) (*internal.Queue, error) { - logrus.Trace("Creating queue metadata from CLI configuration") + logrus.Trace("creating queue metadata from CLI configuration") u, err := url.Parse(c.String("queue.addr")) if err != nil { @@ -80,7 +80,7 @@ func metadataQueue(c *cli.Context) (*internal.Queue, error) { // helper function to capture the source metadata from the CLI arguments. func metadataSource(c *cli.Context) (*internal.Source, error) { - logrus.Trace("Creating source metadata from CLI configuration") + logrus.Trace("creating source metadata from CLI configuration") u, err := url.Parse(c.String("scm.addr")) if err != nil { @@ -97,7 +97,7 @@ func metadataSource(c *cli.Context) (*internal.Source, error) { // //nolint:unparam // ignore unparam for now func metadataVela(c *cli.Context) (*internal.Vela, error) { - logrus.Trace("Creating Vela metadata from CLI configuration") + logrus.Trace("creating Vela metadata from CLI configuration") vela := new(internal.Vela) diff --git a/cmd/vela-server/schedule.go b/cmd/vela-server/schedule.go index 3709df9a8..422dcd710 100644 --- a/cmd/vela-server/schedule.go +++ b/cmd/vela-server/schedule.go @@ -122,6 +122,11 @@ func processSchedules(ctx context.Context, start time.Time, settings *settings.P continue } + logrus.WithFields(logrus.Fields{ + "schedule": schedule.GetName(), + "schedule_id": schedule.GetID(), + }).Info("schedule updated - scheduled at set") + // process the schedule and trigger a new build err = processSchedule(ctx, schedule, settings, compiler, database, metadata, queue, scm) if err != nil { @@ -141,6 +146,11 @@ func processSchedules(ctx context.Context, start time.Time, settings *settings.P continue } + + logrus.WithFields(logrus.Fields{ + "schedule": schedule.GetName(), + "schedule_id": schedule.GetID(), + }).Info("schedule updated - error message cleared") } } @@ -241,4 +251,9 @@ func handleError(ctx context.Context, database database.Interface, err error, sc if err != nil { logrus.WithError(err).Warnf("%s %s: %s", scheduleErr, schedule.GetName(), err.Error()) } + + logrus.WithFields(logrus.Fields{ + "schedule": schedule.GetName(), + "schedule_id": schedule.GetID(), + }).Info("schedule updated - error message set") } diff --git a/cmd/vela-server/scm.go b/cmd/vela-server/scm.go index 4cf76a740..c8c441442 100644 --- a/cmd/vela-server/scm.go +++ b/cmd/vela-server/scm.go @@ -11,7 +11,7 @@ import ( // helper function to setup the scm from the CLI arguments. func setupSCM(c *cli.Context) (scm.Service, error) { - logrus.Debug("Creating scm client from CLI configuration") + logrus.Debug("creating scm client from CLI configuration") // scm configuration _setup := &scm.Setup{ diff --git a/cmd/vela-server/secret.go b/cmd/vela-server/secret.go index 88312bd6d..2ca65615a 100644 --- a/cmd/vela-server/secret.go +++ b/cmd/vela-server/secret.go @@ -13,7 +13,7 @@ import ( // helper function to setup the secrets engines from the CLI arguments. func setupSecrets(c *cli.Context, d database.Interface) (map[string]secret.Service, error) { - logrus.Debug("Creating secret clients from CLI configuration") + logrus.Debug("creating secret clients from CLI configuration") secrets := make(map[string]secret.Service) diff --git a/cmd/vela-server/server.go b/cmd/vela-server/server.go index 9472e9c54..43b7a8f3c 100644 --- a/cmd/vela-server/server.go +++ b/cmd/vela-server/server.go @@ -145,6 +145,8 @@ func server(c *cli.Context) error { if err != nil { return err } + + logrus.Info("initial platform settings created") } // update any internal settings, this occurs in middleware diff --git a/cmd/vela-server/token.go b/cmd/vela-server/token.go index 525ce1518..5636d0535 100644 --- a/cmd/vela-server/token.go +++ b/cmd/vela-server/token.go @@ -14,7 +14,7 @@ import ( // helper function to setup the tokenmanager from the CLI arguments. func setupTokenManager(c *cli.Context, db database.Interface) (*token.Manager, error) { - logrus.Debug("Creating token manager from CLI configuration") + logrus.Debug("creating token manager from CLI configuration") tm := &token.Manager{ PrivateKeyHMAC: c.String("vela-server-private-key"), diff --git a/cmd/vela-server/validate.go b/cmd/vela-server/validate.go index 3ceb2b330..605e0707c 100644 --- a/cmd/vela-server/validate.go +++ b/cmd/vela-server/validate.go @@ -13,7 +13,7 @@ import ( ) func validate(c *cli.Context) error { - logrus.Debug("Validating CLI configuration") + logrus.Debug("validating CLI configuration") // validate core configuration err := validateCore(c) @@ -32,7 +32,7 @@ func validate(c *cli.Context) error { // helper function to validate the core CLI configuration. func validateCore(c *cli.Context) error { - logrus.Trace("Validating core CLI configuration") + logrus.Trace("validating core CLI configuration") if len(c.String("server-addr")) == 0 { return fmt.Errorf("server-addr (VELA_ADDR or VELA_HOST) flag is not properly configured") @@ -110,7 +110,7 @@ func validateCore(c *cli.Context) error { // helper function to validate the compiler CLI configuration. func validateCompiler(c *cli.Context) error { - logrus.Trace("Validating compiler CLI configuration") + logrus.Trace("validating compiler CLI configuration") if c.Bool("github-driver") { if len(c.String("github-url")) == 0 { diff --git a/compiler/native/native.go b/compiler/native/native.go index 93d93c5ea..63e526f2e 100644 --- a/compiler/native/native.go +++ b/compiler/native/native.go @@ -49,7 +49,7 @@ type client struct { // //nolint:revive // ignore returning unexported client func FromCLIContext(ctx *cli.Context) (*client, error) { - logrus.Debug("Creating registry clients from CLI configuration") + logrus.Debug("creating registry clients from CLI configuration") c := new(client) @@ -107,14 +107,14 @@ func FromCLIContext(ctx *cli.Context) (*client, error) { // setupGithub is a helper function to setup the // Github registry service from the CLI arguments. func setupGithub() (registry.Service, error) { - logrus.Tracef("Creating %s registry client from CLI configuration", "github") + logrus.Tracef("creating %s registry client from CLI configuration", "github") return github.New("", "") } // setupPrivateGithub is a helper function to setup the // Github registry service from the CLI arguments. func setupPrivateGithub(addr, token string) (registry.Service, error) { - logrus.Tracef("Creating private %s registry client from CLI configuration", "github") + logrus.Tracef("creating private %s registry client from CLI configuration", "github") return github.New(addr, token) } diff --git a/database/build/build.go b/database/build/build.go index 0ff9871bd..b425731f3 100644 --- a/database/build/build.go +++ b/database/build/build.go @@ -62,7 +62,7 @@ func New(opts ...EngineOpt) (*engine, error) { // check if we should skip creating build database objects if e.config.SkipCreation { - e.logger.Warning("skipping creation of builds table and indexes in the database") + e.logger.Warning("skipping creation of builds table and indexes") return e, nil } diff --git a/database/build/clean.go b/database/build/clean.go index 5c239a57e..b7d876d16 100644 --- a/database/build/clean.go +++ b/database/build/clean.go @@ -15,7 +15,7 @@ import ( // CleanBuilds updates builds to an error with a provided message with a created timestamp prior to a defined moment. func (e *engine) CleanBuilds(ctx context.Context, msg string, before int64) (int64, error) { - logrus.Tracef("cleaning pending or running builds in the database created prior to %d", before) + logrus.Tracef("cleaning pending or running builds created prior to %d", before) b := new(api.Build) b.SetStatus(constants.StatusError) diff --git a/database/build/count.go b/database/build/count.go index 02960a50d..3e86611d9 100644 --- a/database/build/count.go +++ b/database/build/count.go @@ -10,7 +10,7 @@ import ( // CountBuilds gets the count of all builds from the database. func (e *engine) CountBuilds(ctx context.Context) (int64, error) { - e.logger.Tracef("getting count of all builds from the database") + e.logger.Tracef("getting count of all builds") // variable to store query results var b int64 diff --git a/database/build/count_deployment.go b/database/build/count_deployment.go index 08cf80951..46c8170fc 100644 --- a/database/build/count_deployment.go +++ b/database/build/count_deployment.go @@ -15,7 +15,7 @@ import ( func (e *engine) CountBuildsForDeployment(ctx context.Context, d *library.Deployment, filters map[string]interface{}) (int64, error) { e.logger.WithFields(logrus.Fields{ "deployment": d.GetURL(), - }).Tracef("getting count of builds for deployment %s from the database", d.GetURL()) + }).Tracef("getting count of builds for deployment %s", d.GetURL()) // variable to store query results var b int64 diff --git a/database/build/count_org.go b/database/build/count_org.go index 2f2a93119..d9f4105ed 100644 --- a/database/build/count_org.go +++ b/database/build/count_org.go @@ -14,7 +14,7 @@ import ( func (e *engine) CountBuildsForOrg(ctx context.Context, org string, filters map[string]interface{}) (int64, error) { e.logger.WithFields(logrus.Fields{ "org": org, - }).Tracef("getting count of builds for org %s from the database", org) + }).Tracef("getting count of builds for org %s", org) // variable to store query results var b int64 diff --git a/database/build/count_repo.go b/database/build/count_repo.go index cb12e4fdc..298420caa 100644 --- a/database/build/count_repo.go +++ b/database/build/count_repo.go @@ -16,7 +16,7 @@ func (e *engine) CountBuildsForRepo(ctx context.Context, r *api.Repo, filters ma e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), - }).Tracef("getting count of builds for repo %s from the database", r.GetFullName()) + }).Tracef("getting count of builds for repo %s", r.GetFullName()) // variable to store query results var b int64 diff --git a/database/build/count_status.go b/database/build/count_status.go index e95ec8e1e..524d27d76 100644 --- a/database/build/count_status.go +++ b/database/build/count_status.go @@ -10,7 +10,7 @@ import ( // CountBuildsForStatus gets the count of builds by status from the database. func (e *engine) CountBuildsForStatus(ctx context.Context, status string, filters map[string]interface{}) (int64, error) { - e.logger.Tracef("getting count of builds for status %s from the database", status) + e.logger.Tracef("getting count of builds for status %s", status) // variable to store query results var b int64 diff --git a/database/build/create.go b/database/build/create.go index 0ba65aad5..3a3684102 100644 --- a/database/build/create.go +++ b/database/build/create.go @@ -17,7 +17,7 @@ import ( func (e *engine) CreateBuild(ctx context.Context, b *api.Build) (*api.Build, error) { e.logger.WithFields(logrus.Fields{ "build": b.GetNumber(), - }).Tracef("creating build %d in the database", b.GetNumber()) + }).Tracef("creating build %d", b.GetNumber()) build := types.BuildFromAPI(b) diff --git a/database/build/delete.go b/database/build/delete.go index b2bff7795..2bcb282e4 100644 --- a/database/build/delete.go +++ b/database/build/delete.go @@ -16,7 +16,7 @@ import ( func (e *engine) DeleteBuild(ctx context.Context, b *api.Build) error { e.logger.WithFields(logrus.Fields{ "build": b.GetNumber(), - }).Tracef("deleting build %d from the database", b.GetNumber()) + }).Tracef("deleting build %d", b.GetNumber()) build := types.BuildFromAPI(b) diff --git a/database/build/get.go b/database/build/get.go index a780b1721..caaf1fe0c 100644 --- a/database/build/get.go +++ b/database/build/get.go @@ -12,7 +12,7 @@ import ( // GetBuild gets a build by ID from the database. func (e *engine) GetBuild(ctx context.Context, id int64) (*api.Build, error) { - e.logger.Tracef("getting build %d from the database", id) + e.logger.Tracef("getting build %d", id) // variable to store query results b := new(types.Build) diff --git a/database/build/get_repo.go b/database/build/get_repo.go index 8a13009c2..b144cf432 100644 --- a/database/build/get_repo.go +++ b/database/build/get_repo.go @@ -18,7 +18,7 @@ func (e *engine) GetBuildForRepo(ctx context.Context, r *api.Repo, number int) ( "build": number, "org": r.GetOrg(), "repo": r.GetName(), - }).Tracef("getting build %s/%d from the database", r.GetFullName(), number) + }).Tracef("getting build %s/%d", r.GetFullName(), number) // variable to store query results b := new(types.Build) diff --git a/database/build/index.go b/database/build/index.go index f5bea2898..446395cc9 100644 --- a/database/build/index.go +++ b/database/build/index.go @@ -44,7 +44,7 @@ ON builds (status); // CreateBuildIndexes creates the indexes for the builds table in the database. func (e *engine) CreateBuildIndexes(ctx context.Context) error { - e.logger.Tracef("creating indexes for builds table in the database") + e.logger.Tracef("creating indexes for builds table") // create the created column index for the builds table err := e.client.Exec(CreateCreatedIndex).Error diff --git a/database/build/last_repo.go b/database/build/last_repo.go index 2795d2f47..fe04af158 100644 --- a/database/build/last_repo.go +++ b/database/build/last_repo.go @@ -19,7 +19,7 @@ func (e *engine) LastBuildForRepo(ctx context.Context, r *api.Repo, branch strin e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), - }).Tracef("getting last build for repo %s from the database", r.GetFullName()) + }).Tracef("getting last build for repo %s", r.GetFullName()) // variable to store query results b := new(types.Build) diff --git a/database/build/list.go b/database/build/list.go index 2b5176d30..9e3e45c8c 100644 --- a/database/build/list.go +++ b/database/build/list.go @@ -12,7 +12,7 @@ import ( // ListBuilds gets a list of all builds from the database. func (e *engine) ListBuilds(ctx context.Context) ([]*api.Build, error) { - e.logger.Trace("listing all builds from the database") + e.logger.Trace("listing all builds") // variables to store query results and return value count := int64(0) diff --git a/database/build/list_dashboard.go b/database/build/list_dashboard.go index 10d2c378d..8ddc6fa57 100644 --- a/database/build/list_dashboard.go +++ b/database/build/list_dashboard.go @@ -17,7 +17,7 @@ func (e *engine) ListBuildsForDashboardRepo(ctx context.Context, r *api.Repo, br e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), - }).Tracef("listing builds for repo %s from the database", r.GetFullName()) + }).Tracef("listing builds for repo %s", r.GetFullName()) // variables to store query results and return values b := new([]types.Build) diff --git a/database/build/list_org.go b/database/build/list_org.go index 0799635b4..cfaa1992d 100644 --- a/database/build/list_org.go +++ b/database/build/list_org.go @@ -18,7 +18,7 @@ import ( func (e *engine) ListBuildsForOrg(ctx context.Context, org string, filters map[string]interface{}, page, perPage int) ([]*api.Build, int64, error) { e.logger.WithFields(logrus.Fields{ "org": org, - }).Tracef("listing builds for org %s from the database", org) + }).Tracef("listing builds for org %s", org) // variables to store query results and return values count := int64(0) diff --git a/database/build/list_pending_running.go b/database/build/list_pending_running.go index ae40ece51..858b9c08e 100644 --- a/database/build/list_pending_running.go +++ b/database/build/list_pending_running.go @@ -12,7 +12,7 @@ import ( // ListPendingAndRunningBuilds gets a list of all pending and running builds in the provided timeframe from the database. func (e *engine) ListPendingAndRunningBuilds(ctx context.Context, after string) ([]*api.QueueBuild, error) { - e.logger.Trace("listing all pending and running builds from the database") + e.logger.Trace("listing all pending and running builds") // variables to store query results and return value b := new([]types.QueueBuild) diff --git a/database/build/list_pending_running_repo.go b/database/build/list_pending_running_repo.go index 6213bab29..cc8984265 100644 --- a/database/build/list_pending_running_repo.go +++ b/database/build/list_pending_running_repo.go @@ -12,7 +12,7 @@ import ( // ListPendingAndRunningBuilds gets a list of all pending and running builds in the provided timeframe from the database. func (e *engine) ListPendingAndRunningBuildsForRepo(ctx context.Context, repo *api.Repo) ([]*api.Build, error) { - e.logger.Trace("listing all pending and running builds from the database") + e.logger.Trace("listing all pending and running builds") // variables to store query results and return value b := new([]types.Build) diff --git a/database/build/list_repo.go b/database/build/list_repo.go index 753c941c2..2552c2ea3 100644 --- a/database/build/list_repo.go +++ b/database/build/list_repo.go @@ -19,7 +19,7 @@ func (e *engine) ListBuildsForRepo(ctx context.Context, r *api.Repo, filters map e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), - }).Tracef("listing builds for repo %s from the database", r.GetFullName()) + }).Tracef("listing builds for repo %s", r.GetFullName()) // variables to store query results and return values count := int64(0) diff --git a/database/build/table.go b/database/build/table.go index 8d1ca461e..8a7ae172c 100644 --- a/database/build/table.go +++ b/database/build/table.go @@ -102,7 +102,7 @@ builds ( // CreateBuildTable creates the builds table in the database. func (e *engine) CreateBuildTable(ctx context.Context, driver string) error { - e.logger.Tracef("creating builds table in the database") + e.logger.Tracef("creating builds table") // handle the driver provided to create the table switch driver { diff --git a/database/build/update.go b/database/build/update.go index 0657470aa..e8ff1f274 100644 --- a/database/build/update.go +++ b/database/build/update.go @@ -17,7 +17,7 @@ import ( func (e *engine) UpdateBuild(ctx context.Context, b *api.Build) (*api.Build, error) { e.logger.WithFields(logrus.Fields{ "build": b.GetNumber(), - }).Tracef("updating build %d in the database", b.GetNumber()) + }).Tracef("updating build %d", b.GetNumber()) build := types.BuildFromAPI(b) diff --git a/database/dashboard/create.go b/database/dashboard/create.go index 5d179e11e..1af56728a 100644 --- a/database/dashboard/create.go +++ b/database/dashboard/create.go @@ -16,7 +16,7 @@ import ( func (e *engine) CreateDashboard(ctx context.Context, d *api.Dashboard) (*api.Dashboard, error) { e.logger.WithFields(logrus.Fields{ "dashboard": d.GetName(), - }).Tracef("creating dashboard %s in the database", d.GetName()) + }).Tracef("creating dashboard %s", d.GetName()) dashboard := types.DashboardFromAPI(d) diff --git a/database/dashboard/dashboard.go b/database/dashboard/dashboard.go index 8cd70c080..b21471114 100644 --- a/database/dashboard/dashboard.go +++ b/database/dashboard/dashboard.go @@ -73,7 +73,7 @@ func New(opts ...EngineOpt) (*engine, error) { // check if we should skip creating dashboard database objects if e.config.SkipCreation { - e.logger.Warning("skipping creation of dashboards table and indexes in the database") + e.logger.Warning("skipping creation of dashboards table and indexes") return e, nil } diff --git a/database/dashboard/delete.go b/database/dashboard/delete.go index c0bf658ee..2f49cca9f 100644 --- a/database/dashboard/delete.go +++ b/database/dashboard/delete.go @@ -16,7 +16,7 @@ import ( func (e *engine) DeleteDashboard(ctx context.Context, d *api.Dashboard) error { e.logger.WithFields(logrus.Fields{ "dashboard": d.GetID(), - }).Tracef("deleting dashboard %s from the database", d.GetID()) + }).Tracef("deleting dashboard %s", d.GetID()) dashboard := types.DashboardFromAPI(d) diff --git a/database/dashboard/get.go b/database/dashboard/get.go index 1e08391f9..7c29c987f 100644 --- a/database/dashboard/get.go +++ b/database/dashboard/get.go @@ -12,7 +12,7 @@ import ( // GetDashboard gets a dashboard by UUID from the database. func (e *engine) GetDashboard(ctx context.Context, id string) (*api.Dashboard, error) { - e.logger.Tracef("getting dashboard %s from the database", id) + e.logger.Tracef("getting dashboard %s", id) // variable to store query results d := new(types.Dashboard) diff --git a/database/dashboard/table.go b/database/dashboard/table.go index 51d470a99..1cedb30c3 100644 --- a/database/dashboard/table.go +++ b/database/dashboard/table.go @@ -44,7 +44,7 @@ dashboards ( // CreateDashboardTable creates the dashboards table in the database. func (e *engine) CreateDashboardTable(ctx context.Context, driver string) error { - e.logger.Tracef("creating dashboards table in the database") + e.logger.Tracef("creating dashboards table") // handle the driver provided to create the table switch driver { diff --git a/database/dashboard/update.go b/database/dashboard/update.go index f05fe3e28..e13387cb3 100644 --- a/database/dashboard/update.go +++ b/database/dashboard/update.go @@ -16,7 +16,7 @@ import ( func (e *engine) UpdateDashboard(ctx context.Context, d *api.Dashboard) (*api.Dashboard, error) { e.logger.WithFields(logrus.Fields{ "dashboard": d.GetID(), - }).Tracef("creating dashboard %s in the database", d.GetID()) + }).Tracef("creating dashboard %s", d.GetID()) dashboard := types.DashboardFromAPI(d) diff --git a/database/deployment/count.go b/database/deployment/count.go index c83f739c5..26189cf10 100644 --- a/database/deployment/count.go +++ b/database/deployment/count.go @@ -10,7 +10,7 @@ import ( // CountDeployments gets the count of all deployments from the database. func (e *engine) CountDeployments(ctx context.Context) (int64, error) { - e.logger.Tracef("getting count of all deployments from the database") + e.logger.Tracef("getting count of all deployments") // variable to store query results var d int64 diff --git a/database/deployment/count_repo.go b/database/deployment/count_repo.go index 6b70fff8f..94ed86558 100644 --- a/database/deployment/count_repo.go +++ b/database/deployment/count_repo.go @@ -16,7 +16,7 @@ func (e *engine) CountDeploymentsForRepo(ctx context.Context, r *api.Repo) (int6 e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), - }).Tracef("getting count of deployments for repo %s from the database", r.GetFullName()) + }).Tracef("getting count of deployments for repo %s", r.GetFullName()) // variable to store query results var d int64 diff --git a/database/deployment/create.go b/database/deployment/create.go index 6ce17e9a8..c766596e8 100644 --- a/database/deployment/create.go +++ b/database/deployment/create.go @@ -16,7 +16,7 @@ import ( func (e *engine) CreateDeployment(ctx context.Context, d *library.Deployment) (*library.Deployment, error) { e.logger.WithFields(logrus.Fields{ "deployment": d.GetID(), - }).Tracef("creating deployment %d in the database", d.GetID()) + }).Tracef("creating deployment %d", d.GetID()) // cast the library type to database type deployment := database.DeploymentFromLibrary(d) diff --git a/database/deployment/delete.go b/database/deployment/delete.go index f50cb9033..606ef8262 100644 --- a/database/deployment/delete.go +++ b/database/deployment/delete.go @@ -16,7 +16,7 @@ import ( func (e *engine) DeleteDeployment(ctx context.Context, d *library.Deployment) error { e.logger.WithFields(logrus.Fields{ "deployment": d.GetID(), - }).Tracef("deleting deployment %d in the database", d.GetID()) + }).Tracef("deleting deployment %d", d.GetID()) // cast the library type to database type deployment := database.DeploymentFromLibrary(d) diff --git a/database/deployment/deployment.go b/database/deployment/deployment.go index 63f661452..cd9192438 100644 --- a/database/deployment/deployment.go +++ b/database/deployment/deployment.go @@ -60,7 +60,7 @@ func New(opts ...EngineOpt) (*engine, error) { // check if we should skip creating deployment database objects if e.config.SkipCreation { - e.logger.Warning("skipping creation of deployment table and indexes in the database") + e.logger.Warning("skipping creation of deployment table and indexes") return e, nil } diff --git a/database/deployment/get.go b/database/deployment/get.go index 9d84b958e..214dcf57f 100644 --- a/database/deployment/get.go +++ b/database/deployment/get.go @@ -13,7 +13,7 @@ import ( // GetDeployment gets a deployment by ID from the database. func (e *engine) GetDeployment(ctx context.Context, id int64) (*library.Deployment, error) { - e.logger.Tracef("getting deployment %d from the database", id) + e.logger.Tracef("getting deployment %d", id) // variable to store query results d := new(database.Deployment) diff --git a/database/deployment/get_repo.go b/database/deployment/get_repo.go index f000afcda..1558b0428 100644 --- a/database/deployment/get_repo.go +++ b/database/deployment/get_repo.go @@ -20,7 +20,7 @@ func (e *engine) GetDeploymentForRepo(ctx context.Context, r *api.Repo, number i "deployment": number, "org": r.GetOrg(), "repo": r.GetName(), - }).Tracef("getting deployment %s/%d from the database", r.GetFullName(), number) + }).Tracef("getting deployment %s/%d", r.GetFullName(), number) // variable to store query results d := new(database.Deployment) diff --git a/database/deployment/index.go b/database/deployment/index.go index 0fa2fac4c..f9b6a3419 100644 --- a/database/deployment/index.go +++ b/database/deployment/index.go @@ -17,7 +17,7 @@ ON deployments (repo_id); // CreateDeploymetsIndexes creates the indexes for the deployments table in the database. func (e *engine) CreateDeploymentIndexes(ctx context.Context) error { - e.logger.Tracef("creating indexes for deployments table in the database") + e.logger.Tracef("creating indexes for deployments table") // create the repo_id column index for the deployments table return e.client.Exec(CreateRepoIDIndex).Error diff --git a/database/deployment/list.go b/database/deployment/list.go index b3f4da509..f395f668b 100644 --- a/database/deployment/list.go +++ b/database/deployment/list.go @@ -13,7 +13,7 @@ import ( // ListDeployments gets a list of all deployments from the database. func (e *engine) ListDeployments(ctx context.Context) ([]*library.Deployment, error) { - e.logger.Trace("listing all deployments from the database") + e.logger.Trace("listing all deployments") // variables to store query results and return value d := new([]database.Deployment) diff --git a/database/deployment/list_repo.go b/database/deployment/list_repo.go index 71fe1ebe5..8f9b40eb4 100644 --- a/database/deployment/list_repo.go +++ b/database/deployment/list_repo.go @@ -19,7 +19,7 @@ func (e *engine) ListDeploymentsForRepo(ctx context.Context, r *api.Repo, page, e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), - }).Tracef("listing deployments for repo %s from the database", r.GetFullName()) + }).Tracef("listing deployments for repo %s", r.GetFullName()) // variables to store query results and return value d := new([]database.Deployment) diff --git a/database/deployment/table.go b/database/deployment/table.go index 25ac28c78..b519c8abf 100644 --- a/database/deployment/table.go +++ b/database/deployment/table.go @@ -56,7 +56,7 @@ deployments ( // CreateDeploymentTable creates the deployments table in the database. func (e *engine) CreateDeploymentTable(ctx context.Context, driver string) error { - e.logger.Tracef("creating deployments table in the database") + e.logger.Tracef("creating deployments table") // handle the driver provided to create the table switch driver { diff --git a/database/deployment/update.go b/database/deployment/update.go index 191753cbf..c2bbecff0 100644 --- a/database/deployment/update.go +++ b/database/deployment/update.go @@ -16,7 +16,7 @@ import ( func (e *engine) UpdateDeployment(ctx context.Context, d *library.Deployment) (*library.Deployment, error) { e.logger.WithFields(logrus.Fields{ "deployment": d.GetID(), - }).Tracef("updating deployment %d in the database", d.GetID()) + }).Tracef("updating deployment %d", d.GetID()) // cast the library type to database type deployment := database.DeploymentFromLibrary(d) diff --git a/database/executable/pop.go b/database/executable/pop.go index 2696e565e..62dfde193 100644 --- a/database/executable/pop.go +++ b/database/executable/pop.go @@ -14,7 +14,7 @@ import ( // PopBuildExecutable pops a build executable by build_id from the database. func (e *engine) PopBuildExecutable(ctx context.Context, id int64) (*library.BuildExecutable, error) { - e.logger.Tracef("popping build executable for build %d from the database", id) + e.logger.Tracef("popping build executable for build %d", id) // variable to store query results b := new(database.BuildExecutable) @@ -30,7 +30,6 @@ func (e *engine) PopBuildExecutable(ctx context.Context, id int64) (*library.Bui Where("build_id = ?", id). Delete(b). Error - if err != nil { return nil, err } diff --git a/database/executable/table.go b/database/executable/table.go index 82fd1002f..9a683f245 100644 --- a/database/executable/table.go +++ b/database/executable/table.go @@ -36,7 +36,7 @@ build_executables ( // CreateBuildExecutableTable creates the build executables table in the database. func (e *engine) CreateBuildExecutableTable(ctx context.Context, driver string) error { - e.logger.Tracef("creating build_executables table in the database") + e.logger.Tracef("creating build_executables table") // handle the driver provided to create the table switch driver { diff --git a/database/hook/count.go b/database/hook/count.go index 7f6d2449b..ce02e6fa0 100644 --- a/database/hook/count.go +++ b/database/hook/count.go @@ -10,7 +10,7 @@ import ( // CountHooks gets the count of all hooks from the database. func (e *engine) CountHooks(ctx context.Context) (int64, error) { - e.logger.Tracef("getting count of all hooks from the database") + e.logger.Tracef("getting count of all hooks") // variable to store query results var h int64 diff --git a/database/hook/count_repo.go b/database/hook/count_repo.go index 62bee12a4..aa794b5f1 100644 --- a/database/hook/count_repo.go +++ b/database/hook/count_repo.go @@ -16,7 +16,7 @@ func (e *engine) CountHooksForRepo(ctx context.Context, r *api.Repo) (int64, err e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), - }).Tracef("getting count of hooks for repo %s from the database", r.GetFullName()) + }).Tracef("getting count of hooks for repo %s", r.GetFullName()) // variable to store query results var h int64 diff --git a/database/hook/create.go b/database/hook/create.go index d71e89e51..c260eb2b5 100644 --- a/database/hook/create.go +++ b/database/hook/create.go @@ -16,7 +16,7 @@ import ( func (e *engine) CreateHook(ctx context.Context, h *library.Hook) (*library.Hook, error) { e.logger.WithFields(logrus.Fields{ "hook": h.GetNumber(), - }).Tracef("creating hook %d in the database", h.GetNumber()) + }).Tracef("creating hook %d", h.GetNumber()) // cast the library type to database type // diff --git a/database/hook/delete.go b/database/hook/delete.go index dca1f900e..0245477af 100644 --- a/database/hook/delete.go +++ b/database/hook/delete.go @@ -16,7 +16,7 @@ import ( func (e *engine) DeleteHook(ctx context.Context, h *library.Hook) error { e.logger.WithFields(logrus.Fields{ "hook": h.GetNumber(), - }).Tracef("deleting hook %d in the database", h.GetNumber()) + }).Tracef("deleting hook %d", h.GetNumber()) // cast the library type to database type // diff --git a/database/hook/get.go b/database/hook/get.go index 6119c0770..82e421dda 100644 --- a/database/hook/get.go +++ b/database/hook/get.go @@ -12,7 +12,7 @@ import ( // GetHook gets a hook by ID from the database. func (e *engine) GetHook(ctx context.Context, id int64) (*library.Hook, error) { - e.logger.Tracef("getting hook %d from the database", id) + e.logger.Tracef("getting hook %d", id) // variable to store query results h := new(database.Hook) diff --git a/database/hook/get_repo.go b/database/hook/get_repo.go index 26fe2c0fb..a88d593df 100644 --- a/database/hook/get_repo.go +++ b/database/hook/get_repo.go @@ -19,7 +19,7 @@ func (e *engine) GetHookForRepo(ctx context.Context, r *api.Repo, number int) (* "hook": number, "org": r.GetOrg(), "repo": r.GetName(), - }).Tracef("getting hook %s/%d from the database", r.GetFullName(), number) + }).Tracef("getting hook %s/%d", r.GetFullName(), number) // variable to store query results h := new(database.Hook) diff --git a/database/hook/get_webhook.go b/database/hook/get_webhook.go index d7108ff4c..919092fd7 100644 --- a/database/hook/get_webhook.go +++ b/database/hook/get_webhook.go @@ -12,7 +12,7 @@ import ( // GetHookByWebhookID gets a single hook with a matching webhook id in the database. func (e *engine) GetHookByWebhookID(ctx context.Context, webhookID int64) (*library.Hook, error) { - e.logger.Tracef("getting a hook with webhook id %d from the database", webhookID) + e.logger.Tracef("getting a hook with webhook id %d", webhookID) // variable to store query results h := new(database.Hook) diff --git a/database/hook/hook.go b/database/hook/hook.go index 22816ac83..283dad00a 100644 --- a/database/hook/hook.go +++ b/database/hook/hook.go @@ -60,7 +60,7 @@ func New(opts ...EngineOpt) (*engine, error) { // check if we should skip creating hook database objects if e.config.SkipCreation { - e.logger.Warning("skipping creation of hooks table and indexes in the database") + e.logger.Warning("skipping creation of hooks table and indexes") return e, nil } diff --git a/database/hook/index.go b/database/hook/index.go index 2b8d4e682..b86c9ac39 100644 --- a/database/hook/index.go +++ b/database/hook/index.go @@ -17,7 +17,7 @@ ON hooks (repo_id); // CreateHookIndexes creates the indexes for the hooks table in the database. func (e *engine) CreateHookIndexes(ctx context.Context) error { - e.logger.Tracef("creating indexes for hooks table in the database") + e.logger.Tracef("creating indexes for hooks table") // create the repo_id column index for the hooks table return e.client.Exec(CreateRepoIDIndex).Error diff --git a/database/hook/last_repo.go b/database/hook/last_repo.go index 388e8e464..710053ad8 100644 --- a/database/hook/last_repo.go +++ b/database/hook/last_repo.go @@ -20,7 +20,7 @@ func (e *engine) LastHookForRepo(ctx context.Context, r *api.Repo) (*library.Hoo e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), - }).Tracef("getting last hook for repo %s from the database", r.GetFullName()) + }).Tracef("getting last hook for repo %s", r.GetFullName()) // variable to store query results h := new(database.Hook) diff --git a/database/hook/list.go b/database/hook/list.go index 8e0949be4..fcfba1e28 100644 --- a/database/hook/list.go +++ b/database/hook/list.go @@ -12,7 +12,7 @@ import ( // ListHooks gets a list of all hooks from the database. func (e *engine) ListHooks(ctx context.Context) ([]*library.Hook, error) { - e.logger.Trace("listing all hooks from the database") + e.logger.Trace("listing all hooks") // variables to store query results and return value count := int64(0) diff --git a/database/hook/list_repo.go b/database/hook/list_repo.go index b8afd447f..28e80c03e 100644 --- a/database/hook/list_repo.go +++ b/database/hook/list_repo.go @@ -18,7 +18,7 @@ func (e *engine) ListHooksForRepo(ctx context.Context, r *api.Repo, page, perPag e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), - }).Tracef("listing hooks for repo %s from the database", r.GetFullName()) + }).Tracef("listing hooks for repo %s", r.GetFullName()) // variables to store query results and return value count := int64(0) diff --git a/database/hook/table.go b/database/hook/table.go index c9221e9f4..81ef7157f 100644 --- a/database/hook/table.go +++ b/database/hook/table.go @@ -58,7 +58,7 @@ hooks ( // CreateHookTable creates the hooks table in the database. func (e *engine) CreateHookTable(ctx context.Context, driver string) error { - e.logger.Tracef("creating hooks table in the database") + e.logger.Tracef("creating hooks table") // handle the driver provided to create the table switch driver { diff --git a/database/hook/update.go b/database/hook/update.go index 6c24bfd24..16222a6d1 100644 --- a/database/hook/update.go +++ b/database/hook/update.go @@ -16,7 +16,7 @@ import ( func (e *engine) UpdateHook(ctx context.Context, h *library.Hook) (*library.Hook, error) { e.logger.WithFields(logrus.Fields{ "hook": h.GetNumber(), - }).Tracef("updating hook %d in the database", h.GetNumber()) + }).Tracef("updating hook %d", h.GetNumber()) // cast the library type to database type // diff --git a/database/jwk/create.go b/database/jwk/create.go index 161b3ef4a..0ef8330b9 100644 --- a/database/jwk/create.go +++ b/database/jwk/create.go @@ -17,7 +17,7 @@ import ( func (e *engine) CreateJWK(_ context.Context, j jwk.RSAPublicKey) error { e.logger.WithFields(logrus.Fields{ "jwk": j.KeyID(), - }).Tracef("creating key %s in the database", j.KeyID()) + }).Tracef("creating key %s", j.KeyID()) key := types.JWKFromAPI(j) key.Active = sql.NullBool{Bool: true, Valid: true} diff --git a/database/jwk/get.go b/database/jwk/get.go index 0313b68a5..b324ae3cc 100644 --- a/database/jwk/get.go +++ b/database/jwk/get.go @@ -13,7 +13,7 @@ import ( // GetActiveJWK gets a JWK by UUID (kid) from the database if active. func (e *engine) GetActiveJWK(_ context.Context, id string) (jwk.RSAPublicKey, error) { - e.logger.Tracef("getting key %s from the database", id) + e.logger.Tracef("getting JWK key %s", id) // variable to store query results j := new(types.JWK) diff --git a/database/jwk/jwk.go b/database/jwk/jwk.go index 6b3acc33f..bcce18eb8 100644 --- a/database/jwk/jwk.go +++ b/database/jwk/jwk.go @@ -62,7 +62,7 @@ func New(opts ...EngineOpt) (*engine, error) { // check if we should skip creating key set database objects if e.config.SkipCreation { - e.logger.Warning("skipping creation of key sets table and indexes in the database") + e.logger.Warning("skipping creation of key sets table and indexes") return e, nil } diff --git a/database/jwk/list.go b/database/jwk/list.go index ed58fa36c..4c29a4c5c 100644 --- a/database/jwk/list.go +++ b/database/jwk/list.go @@ -13,7 +13,7 @@ import ( // ListJWKs gets a list of all configured JWKs from the database. func (e *engine) ListJWKs(_ context.Context) (jwk.Set, error) { - e.logger.Trace("listing all jwks from the database") + e.logger.Trace("listing all JWKs") k := new([]types.JWK) keySet := jwk.NewSet() diff --git a/database/jwk/rotate.go b/database/jwk/rotate.go index 82ff1c422..793584037 100644 --- a/database/jwk/rotate.go +++ b/database/jwk/rotate.go @@ -12,7 +12,7 @@ import ( // RotateKeys removes all inactive keys and sets active keys to inactive. func (e *engine) RotateKeys(_ context.Context) error { - e.logger.Trace("rotating jwks in the database") + e.logger.Trace("rotating jwks") k := types.JWK{} diff --git a/database/jwk/table.go b/database/jwk/table.go index 6e2108de9..b2a40c844 100644 --- a/database/jwk/table.go +++ b/database/jwk/table.go @@ -34,7 +34,7 @@ jwks ( // CreateJWKTable creates the jwks table in the database. func (e *engine) CreateJWKTable(ctx context.Context, driver string) error { - e.logger.Tracef("creating jwks table in the database") + e.logger.Tracef("creating jwks table") // handle the driver provided to create the table switch driver { diff --git a/database/log/count.go b/database/log/count.go index b26066b94..e3b38b316 100644 --- a/database/log/count.go +++ b/database/log/count.go @@ -10,7 +10,7 @@ import ( // CountLogs gets the count of all logs from the database. func (e *engine) CountLogs(ctx context.Context) (int64, error) { - e.logger.Tracef("getting count of all logs from the database") + e.logger.Tracef("getting count of all logs") // variable to store query results var l int64 diff --git a/database/log/count_build.go b/database/log/count_build.go index 75145d5e3..524ff2960 100644 --- a/database/log/count_build.go +++ b/database/log/count_build.go @@ -11,7 +11,7 @@ import ( // CountLogsForBuild gets the count of logs by build ID from the database. func (e *engine) CountLogsForBuild(ctx context.Context, b *api.Build) (int64, error) { - e.logger.Tracef("getting count of logs for build %d from the database", b.GetID()) + e.logger.Tracef("getting count of logs for build %d", b.GetID()) // variable to store query results var l int64 diff --git a/database/log/create.go b/database/log/create.go index e1c3a9212..fdabab63c 100644 --- a/database/log/create.go +++ b/database/log/create.go @@ -17,9 +17,9 @@ func (e *engine) CreateLog(ctx context.Context, l *library.Log) error { // check what the log entry is for switch { case l.GetServiceID() > 0: - e.logger.Tracef("creating log for service %d for build %d in the database", l.GetServiceID(), l.GetBuildID()) + e.logger.Tracef("creating log for service %d for build %d", l.GetServiceID(), l.GetBuildID()) case l.GetStepID() > 0: - e.logger.Tracef("creating log for step %d for build %d in the database", l.GetStepID(), l.GetBuildID()) + e.logger.Tracef("creating log for step %d for build %d", l.GetStepID(), l.GetBuildID()) } // cast the library type to database type diff --git a/database/log/delete.go b/database/log/delete.go index 7018396de..31f4ea31e 100644 --- a/database/log/delete.go +++ b/database/log/delete.go @@ -15,9 +15,9 @@ func (e *engine) DeleteLog(ctx context.Context, l *library.Log) error { // check what the log entry is for switch { case l.GetServiceID() > 0: - e.logger.Tracef("deleting log for service %d for build %d in the database", l.GetServiceID(), l.GetBuildID()) + e.logger.Tracef("deleting log for service %d for build %d", l.GetServiceID(), l.GetBuildID()) case l.GetStepID() > 0: - e.logger.Tracef("deleting log for step %d for build %d in the database", l.GetStepID(), l.GetBuildID()) + e.logger.Tracef("deleting log for step %d for build %d", l.GetStepID(), l.GetBuildID()) } // cast the library type to database type diff --git a/database/log/get.go b/database/log/get.go index be02ee968..2a825a6da 100644 --- a/database/log/get.go +++ b/database/log/get.go @@ -12,7 +12,7 @@ import ( // GetLog gets a log by ID from the database. func (e *engine) GetLog(ctx context.Context, id int64) (*library.Log, error) { - e.logger.Tracef("getting log %d from the database", id) + e.logger.Tracef("getting log %d", id) // variable to store query results l := new(database.Log) diff --git a/database/log/get_service.go b/database/log/get_service.go index 83d5f2f45..aac501801 100644 --- a/database/log/get_service.go +++ b/database/log/get_service.go @@ -13,7 +13,7 @@ import ( // GetLogForService gets a log by service ID from the database. func (e *engine) GetLogForService(ctx context.Context, s *library.Service) (*library.Log, error) { - e.logger.Tracef("getting log for service %d for build %d from the database", s.GetID(), s.GetBuildID()) + e.logger.Tracef("getting log for service %d for build %d", s.GetID(), s.GetBuildID()) // variable to store query results l := new(database.Log) diff --git a/database/log/get_step.go b/database/log/get_step.go index da6d70cf7..f2ca4a3a1 100644 --- a/database/log/get_step.go +++ b/database/log/get_step.go @@ -13,7 +13,7 @@ import ( // GetLogForStep gets a log by step ID from the database. func (e *engine) GetLogForStep(ctx context.Context, s *library.Step) (*library.Log, error) { - e.logger.Tracef("getting log for step %d for build %d from the database", s.GetID(), s.GetBuildID()) + e.logger.Tracef("getting log for step %d for build %d", s.GetID(), s.GetBuildID()) // variable to store query results l := new(database.Log) diff --git a/database/log/index.go b/database/log/index.go index c167f3825..230a10d8b 100644 --- a/database/log/index.go +++ b/database/log/index.go @@ -17,7 +17,7 @@ ON logs (build_id); // CreateLogIndexes creates the indexes for the logs table in the database. func (e *engine) CreateLogIndexes(ctx context.Context) error { - e.logger.Tracef("creating indexes for logs table in the database") + e.logger.Tracef("creating indexes for logs table") // create the build_id column index for the logs table return e.client.Exec(CreateBuildIDIndex).Error diff --git a/database/log/list.go b/database/log/list.go index ae85a451e..367d8c15e 100644 --- a/database/log/list.go +++ b/database/log/list.go @@ -12,7 +12,7 @@ import ( // ListLogs gets a list of all logs from the database. func (e *engine) ListLogs(ctx context.Context) ([]*library.Log, error) { - e.logger.Trace("listing all logs from the database") + e.logger.Trace("listing all logs") // variables to store query results and return value count := int64(0) diff --git a/database/log/list_build.go b/database/log/list_build.go index f5619d40b..43c117916 100644 --- a/database/log/list_build.go +++ b/database/log/list_build.go @@ -13,7 +13,7 @@ import ( // ListLogsForBuild gets a list of logs by build ID from the database. func (e *engine) ListLogsForBuild(ctx context.Context, b *api.Build, page, perPage int) ([]*library.Log, int64, error) { - e.logger.Tracef("listing logs for build %d from the database", b.GetID()) + e.logger.Tracef("listing logs for build %d", b.GetID()) // variables to store query results and return value count := int64(0) diff --git a/database/log/log.go b/database/log/log.go index a0fa23e5f..e95dc6d04 100644 --- a/database/log/log.go +++ b/database/log/log.go @@ -62,7 +62,7 @@ func New(opts ...EngineOpt) (*engine, error) { // check if we should skip creating log database objects if e.config.SkipCreation { - e.logger.Warning("skipping creation of logs table and indexes in the database") + e.logger.Warning("skipping creation of logs table and indexes") return e, nil } diff --git a/database/log/table.go b/database/log/table.go index aa8c87cfe..94ec398ff 100644 --- a/database/log/table.go +++ b/database/log/table.go @@ -44,7 +44,7 @@ logs ( // CreateLogTable creates the logs table in the database. func (e *engine) CreateLogTable(ctx context.Context, driver string) error { - e.logger.Tracef("creating logs table in the database") + e.logger.Tracef("creating logs table") // handle the driver provided to create the table switch driver { diff --git a/database/log/update.go b/database/log/update.go index 7929ab0fa..f7a148aae 100644 --- a/database/log/update.go +++ b/database/log/update.go @@ -17,9 +17,9 @@ func (e *engine) UpdateLog(ctx context.Context, l *library.Log) error { // check what the log entry is for switch { case l.GetServiceID() > 0: - e.logger.Tracef("updating log for service %d for build %d in the database", l.GetServiceID(), l.GetBuildID()) + e.logger.Tracef("updating log for service %d for build %d", l.GetServiceID(), l.GetBuildID()) case l.GetStepID() > 0: - e.logger.Tracef("updating log for step %d for build %d in the database", l.GetStepID(), l.GetBuildID()) + e.logger.Tracef("updating log for step %d for build %d", l.GetStepID(), l.GetBuildID()) } // cast the library type to database type diff --git a/database/pipeline/count.go b/database/pipeline/count.go index a251f571b..3252f5edd 100644 --- a/database/pipeline/count.go +++ b/database/pipeline/count.go @@ -10,7 +10,7 @@ import ( // CountPipelines gets the count of all pipelines from the database. func (e *engine) CountPipelines(ctx context.Context) (int64, error) { - e.logger.Tracef("getting count of all pipelines from the database") + e.logger.Tracef("getting count of all pipelines") // variable to store query results var p int64 diff --git a/database/pipeline/count_repo.go b/database/pipeline/count_repo.go index e2d5a2285..6adf46984 100644 --- a/database/pipeline/count_repo.go +++ b/database/pipeline/count_repo.go @@ -16,7 +16,7 @@ func (e *engine) CountPipelinesForRepo(ctx context.Context, r *api.Repo) (int64, e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), - }).Tracef("getting count of pipelines for repo %s from the database", r.GetFullName()) + }).Tracef("getting count of pipelines for repo %s", r.GetFullName()) // variable to store query results var p int64 diff --git a/database/pipeline/delete.go b/database/pipeline/delete.go index bba60b2bd..b35cdd7d3 100644 --- a/database/pipeline/delete.go +++ b/database/pipeline/delete.go @@ -16,7 +16,7 @@ import ( func (e *engine) DeletePipeline(ctx context.Context, p *library.Pipeline) error { e.logger.WithFields(logrus.Fields{ "pipeline": p.GetCommit(), - }).Tracef("deleting pipeline %s from the database", p.GetCommit()) + }).Tracef("deleting pipeline %s", p.GetCommit()) // cast the library type to database type // diff --git a/database/pipeline/get.go b/database/pipeline/get.go index 30a7f5d39..8e1c54b13 100644 --- a/database/pipeline/get.go +++ b/database/pipeline/get.go @@ -12,7 +12,7 @@ import ( // GetPipeline gets a pipeline by ID from the database. func (e *engine) GetPipeline(ctx context.Context, id int64) (*library.Pipeline, error) { - e.logger.Tracef("getting pipeline %d from the database", id) + e.logger.Tracef("getting pipeline %d", id) // variable to store query results p := new(database.Pipeline) diff --git a/database/pipeline/get_repo.go b/database/pipeline/get_repo.go index 428e1d84a..0fc493003 100644 --- a/database/pipeline/get_repo.go +++ b/database/pipeline/get_repo.go @@ -19,7 +19,7 @@ func (e *engine) GetPipelineForRepo(ctx context.Context, commit string, r *api.R "org": r.GetOrg(), "pipeline": commit, "repo": r.GetName(), - }).Tracef("getting pipeline %s/%s from the database", r.GetFullName(), commit) + }).Tracef("getting pipeline %s/%s", r.GetFullName(), commit) // variable to store query results p := new(database.Pipeline) diff --git a/database/pipeline/list.go b/database/pipeline/list.go index 2299c8f6f..fd9e077e0 100644 --- a/database/pipeline/list.go +++ b/database/pipeline/list.go @@ -12,7 +12,7 @@ import ( // ListPipelines gets a list of all pipelines from the database. func (e *engine) ListPipelines(ctx context.Context) ([]*library.Pipeline, error) { - e.logger.Trace("listing all pipelines from the database") + e.logger.Trace("listing all pipelines") // variables to store query results and return value count := int64(0) diff --git a/database/pipeline/list_repo.go b/database/pipeline/list_repo.go index 9893ee499..4f855c746 100644 --- a/database/pipeline/list_repo.go +++ b/database/pipeline/list_repo.go @@ -20,7 +20,7 @@ func (e *engine) ListPipelinesForRepo(ctx context.Context, r *api.Repo, page, pe e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), - }).Tracef("listing pipelines for repo %s from the database", r.GetFullName()) + }).Tracef("listing pipelines for repo %s", r.GetFullName()) // variables to store query results and return values count := int64(0) diff --git a/database/repo/count.go b/database/repo/count.go index c00001b9f..165bf0f0b 100644 --- a/database/repo/count.go +++ b/database/repo/count.go @@ -10,7 +10,7 @@ import ( // CountRepos gets the count of all repos from the database. func (e *engine) CountRepos(ctx context.Context) (int64, error) { - e.logger.Tracef("getting count of all repos from the database") + e.logger.Tracef("getting count of all repos") // variable to store query results var r int64 diff --git a/database/repo/count_org.go b/database/repo/count_org.go index 339dfd664..6e0ce6cb4 100644 --- a/database/repo/count_org.go +++ b/database/repo/count_org.go @@ -14,7 +14,7 @@ import ( func (e *engine) CountReposForOrg(ctx context.Context, org string, filters map[string]interface{}) (int64, error) { e.logger.WithFields(logrus.Fields{ "org": org, - }).Tracef("getting count of repos for org %s from the database", org) + }).Tracef("getting count of repos for org %s", org) // variable to store query results var r int64 diff --git a/database/repo/count_user.go b/database/repo/count_user.go index b8ba89a12..dfc002d9b 100644 --- a/database/repo/count_user.go +++ b/database/repo/count_user.go @@ -15,7 +15,7 @@ import ( func (e *engine) CountReposForUser(ctx context.Context, u *api.User, filters map[string]interface{}) (int64, error) { e.logger.WithFields(logrus.Fields{ "user": u.GetName(), - }).Tracef("getting count of repos for user %s from the database", u.GetName()) + }).Tracef("getting count of repos for user %s", u.GetName()) // variable to store query results var r int64 diff --git a/database/repo/create.go b/database/repo/create.go index 3a604348e..166362de9 100644 --- a/database/repo/create.go +++ b/database/repo/create.go @@ -19,7 +19,7 @@ func (e *engine) CreateRepo(ctx context.Context, r *api.Repo) (*api.Repo, error) e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), - }).Tracef("creating repo %s in the database", r.GetFullName()) + }).Tracef("creating repo %s", r.GetFullName()) // cast the library type to database type repo := types.RepoFromAPI(r) diff --git a/database/repo/delete.go b/database/repo/delete.go index 115e131c8..a12e2ec91 100644 --- a/database/repo/delete.go +++ b/database/repo/delete.go @@ -17,7 +17,7 @@ func (e *engine) DeleteRepo(ctx context.Context, r *api.Repo) error { e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), - }).Tracef("deleting repo %s from the database", r.GetFullName()) + }).Tracef("deleting repo %s", r.GetFullName()) // cast the library type to database type repo := types.RepoFromAPI(r) diff --git a/database/repo/get.go b/database/repo/get.go index 9d3fb7412..d29ba16c8 100644 --- a/database/repo/get.go +++ b/database/repo/get.go @@ -12,7 +12,7 @@ import ( // GetRepo gets a repo by ID from the database. func (e *engine) GetRepo(ctx context.Context, id int64) (*api.Repo, error) { - e.logger.Tracef("getting repo %d from the database", id) + e.logger.Tracef("getting repo %d", id) // variable to store query results r := new(types.Repo) diff --git a/database/repo/get_org.go b/database/repo/get_org.go index ecca4530f..e66b97b37 100644 --- a/database/repo/get_org.go +++ b/database/repo/get_org.go @@ -17,7 +17,7 @@ func (e *engine) GetRepoForOrg(ctx context.Context, org, name string) (*api.Repo e.logger.WithFields(logrus.Fields{ "org": org, "repo": name, - }).Tracef("getting repo %s/%s from the database", org, name) + }).Tracef("getting repo %s/%s", org, name) // variable to store query results r := new(types.Repo) diff --git a/database/repo/index.go b/database/repo/index.go index c2446bda9..9c97ad962 100644 --- a/database/repo/index.go +++ b/database/repo/index.go @@ -17,7 +17,7 @@ ON repos (org, name); // CreateRepoIndexes creates the indexes for the repos table in the database. func (e *engine) CreateRepoIndexes(ctx context.Context) error { - e.logger.Tracef("creating indexes for repos table in the database") + e.logger.Tracef("creating indexes for repos table") // create the org and name columns index for the repos table return e.client.Exec(CreateOrgNameIndex).Error diff --git a/database/repo/list.go b/database/repo/list.go index e50de9a21..abe27a434 100644 --- a/database/repo/list.go +++ b/database/repo/list.go @@ -12,7 +12,7 @@ import ( // ListRepos gets a list of all repos from the database. func (e *engine) ListRepos(ctx context.Context) ([]*api.Repo, error) { - e.logger.Trace("listing all repos from the database") + e.logger.Trace("listing all repos") // variables to store query results and return value count := int64(0) diff --git a/database/repo/list_org.go b/database/repo/list_org.go index bc1ee5597..016044744 100644 --- a/database/repo/list_org.go +++ b/database/repo/list_org.go @@ -18,7 +18,7 @@ import ( func (e *engine) ListReposForOrg(ctx context.Context, org, sortBy string, filters map[string]interface{}, page, perPage int) ([]*api.Repo, int64, error) { e.logger.WithFields(logrus.Fields{ "org": org, - }).Tracef("listing repos for org %s from the database", org) + }).Tracef("listing repos for org %s", org) // variables to store query results and return values count := int64(0) diff --git a/database/repo/list_user.go b/database/repo/list_user.go index 37665769a..f50374de1 100644 --- a/database/repo/list_user.go +++ b/database/repo/list_user.go @@ -18,7 +18,7 @@ import ( func (e *engine) ListReposForUser(ctx context.Context, u *api.User, sortBy string, filters map[string]interface{}, page, perPage int) ([]*api.Repo, int64, error) { e.logger.WithFields(logrus.Fields{ "user": u.GetName(), - }).Tracef("listing repos for user %s from the database", u.GetName()) + }).Tracef("listing repos for user %s", u.GetName()) // variables to store query results and return values count := int64(0) diff --git a/database/repo/repo.go b/database/repo/repo.go index 6f9edeb19..2a915192f 100644 --- a/database/repo/repo.go +++ b/database/repo/repo.go @@ -62,7 +62,7 @@ func New(opts ...EngineOpt) (*engine, error) { // check if we should skip creating repo database objects if e.config.SkipCreation { - e.logger.Warning("skipping creation of repos table and indexes in the database") + e.logger.Warning("skipping creation of repos table and indexes") return e, nil } diff --git a/database/repo/table.go b/database/repo/table.go index a7877d280..65bd21fb2 100644 --- a/database/repo/table.go +++ b/database/repo/table.go @@ -72,7 +72,7 @@ repos ( // CreateRepoTable creates the repos table in the database. func (e *engine) CreateRepoTable(ctx context.Context, driver string) error { - e.logger.Tracef("creating repos table in the database") + e.logger.Tracef("creating repos table") // handle the driver provided to create the table switch driver { diff --git a/database/repo/update.go b/database/repo/update.go index 31922068f..9a11b8010 100644 --- a/database/repo/update.go +++ b/database/repo/update.go @@ -19,7 +19,7 @@ func (e *engine) UpdateRepo(ctx context.Context, r *api.Repo) (*api.Repo, error) e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), - }).Tracef("creating repo %s in the database", r.GetFullName()) + }).Tracef("creating repo %s", r.GetFullName()) // cast the library type to database type repo := types.RepoFromAPI(r) diff --git a/database/schedule/count.go b/database/schedule/count.go index b61b6d028..8da93e69f 100644 --- a/database/schedule/count.go +++ b/database/schedule/count.go @@ -10,7 +10,7 @@ import ( // CountSchedules gets the count of all schedules from the database. func (e *engine) CountSchedules(ctx context.Context) (int64, error) { - e.logger.Tracef("getting count of all schedules from the database") + e.logger.Tracef("getting count of all schedules") // variable to store query results var s int64 diff --git a/database/schedule/count_active.go b/database/schedule/count_active.go index 6e46ee253..be2dd9b5e 100644 --- a/database/schedule/count_active.go +++ b/database/schedule/count_active.go @@ -10,7 +10,7 @@ import ( // CountActiveSchedules gets the count of all active schedules from the database. func (e *engine) CountActiveSchedules(ctx context.Context) (int64, error) { - e.logger.Tracef("getting count of all active schedules from the database") + e.logger.Tracef("getting count of all active schedules") // variable to store query results var s int64 diff --git a/database/schedule/count_repo.go b/database/schedule/count_repo.go index 80c1cd47a..724ce19b3 100644 --- a/database/schedule/count_repo.go +++ b/database/schedule/count_repo.go @@ -16,7 +16,7 @@ func (e *engine) CountSchedulesForRepo(ctx context.Context, r *api.Repo) (int64, e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), - }).Tracef("getting count of schedules for repo %s from the database", r.GetFullName()) + }).Tracef("getting count of schedules for repo %s", r.GetFullName()) // variable to store query results var s int64 diff --git a/database/schedule/get.go b/database/schedule/get.go index e8097bc51..1bcdc37cb 100644 --- a/database/schedule/get.go +++ b/database/schedule/get.go @@ -12,7 +12,7 @@ import ( // GetSchedule gets a schedule by ID from the database. func (e *engine) GetSchedule(ctx context.Context, id int64) (*api.Schedule, error) { - e.logger.Tracef("getting schedule %d from the database", id) + e.logger.Tracef("getting schedule %d", id) // variable to store query results s := new(types.Schedule) diff --git a/database/schedule/get_repo.go b/database/schedule/get_repo.go index 0af4d1f7d..e940694a4 100644 --- a/database/schedule/get_repo.go +++ b/database/schedule/get_repo.go @@ -18,7 +18,7 @@ func (e *engine) GetScheduleForRepo(ctx context.Context, r *api.Repo, name strin "org": r.GetOrg(), "repo": r.GetName(), "schedule": name, - }).Tracef("getting schedule %s/%s from the database", r.GetFullName(), name) + }).Tracef("getting schedule %s/%s", r.GetFullName(), name) // variable to store query results s := new(types.Schedule) diff --git a/database/schedule/list.go b/database/schedule/list.go index 7df0c2248..4282f554a 100644 --- a/database/schedule/list.go +++ b/database/schedule/list.go @@ -12,7 +12,7 @@ import ( // ListSchedules gets a list of all schedules from the database. func (e *engine) ListSchedules(ctx context.Context) ([]*api.Schedule, error) { - e.logger.Trace("listing all schedules from the database") + e.logger.Trace("listing all schedules") // variables to store query results and return value count := int64(0) diff --git a/database/schedule/list_active.go b/database/schedule/list_active.go index d53b8201d..84e575b1a 100644 --- a/database/schedule/list_active.go +++ b/database/schedule/list_active.go @@ -12,7 +12,7 @@ import ( // ListActiveSchedules gets a list of all active schedules from the database. func (e *engine) ListActiveSchedules(ctx context.Context) ([]*api.Schedule, error) { - e.logger.Trace("listing all active schedules from the database") + e.logger.Trace("listing all active schedules") // variables to store query results and return value count := int64(0) diff --git a/database/schedule/list_repo.go b/database/schedule/list_repo.go index d26f6a198..9ec086589 100644 --- a/database/schedule/list_repo.go +++ b/database/schedule/list_repo.go @@ -17,7 +17,7 @@ func (e *engine) ListSchedulesForRepo(ctx context.Context, r *api.Repo, page, pe e.logger.WithFields(logrus.Fields{ "org": r.GetOrg(), "repo": r.GetName(), - }).Tracef("listing schedules for repo %s from the database", r.GetFullName()) + }).Tracef("listing schedules for repo %s", r.GetFullName()) // variables to store query results and return value count := int64(0) diff --git a/database/secret/count.go b/database/secret/count.go index fd4158d8a..bf91525fa 100644 --- a/database/secret/count.go +++ b/database/secret/count.go @@ -10,7 +10,7 @@ import ( // CountSecrets gets the count of all secrets from the database. func (e *engine) CountSecrets(ctx context.Context) (int64, error) { - e.logger.Tracef("getting count of all secrets from the database") + e.logger.Tracef("getting count of all secrets") // variable to store query results var s int64 diff --git a/database/secret/count_org.go b/database/secret/count_org.go index e6fdc7fcb..9b4a8c263 100644 --- a/database/secret/count_org.go +++ b/database/secret/count_org.go @@ -15,7 +15,7 @@ func (e *engine) CountSecretsForOrg(ctx context.Context, org string, filters map e.logger.WithFields(logrus.Fields{ "org": org, "type": constants.SecretOrg, - }).Tracef("getting count of secrets for org %s from the database", org) + }).Tracef("getting count of secrets for org %s", org) // variable to store query results var s int64 diff --git a/database/secret/count_repo.go b/database/secret/count_repo.go index f734054a5..b8edddcb0 100644 --- a/database/secret/count_repo.go +++ b/database/secret/count_repo.go @@ -17,7 +17,7 @@ func (e *engine) CountSecretsForRepo(ctx context.Context, r *api.Repo, filters m "org": r.GetOrg(), "repo": r.GetName(), "type": constants.SecretRepo, - }).Tracef("getting count of secrets for repo %s from the database", r.GetFullName()) + }).Tracef("getting count of secrets for repo %s", r.GetFullName()) // variable to store query results var s int64 diff --git a/database/secret/count_team.go b/database/secret/count_team.go index 55445b504..1b5fc8361 100644 --- a/database/secret/count_team.go +++ b/database/secret/count_team.go @@ -17,7 +17,7 @@ func (e *engine) CountSecretsForTeam(ctx context.Context, org, team string, filt "org": org, "team": team, "type": constants.SecretShared, - }).Tracef("getting count of secrets for team %s/%s from the database", org, team) + }).Tracef("getting count of secrets for team %s/%s", org, team) // variable to store query results var s int64 @@ -49,7 +49,7 @@ func (e *engine) CountSecretsForTeams(ctx context.Context, org string, teams []s "org": org, "teams": teams, "type": constants.SecretShared, - }).Tracef("getting count of secrets for teams %s in org %s from the database", teams, org) + }).Tracef("getting count of secrets for teams %s in org %s", teams, org) // variable to store query results var s int64 diff --git a/database/secret/create.go b/database/secret/create.go index c8b0400d1..be409d304 100644 --- a/database/secret/create.go +++ b/database/secret/create.go @@ -24,14 +24,14 @@ func (e *engine) CreateSecret(ctx context.Context, s *library.Secret) (*library. "team": s.GetTeam(), "secret": s.GetName(), "type": s.GetType(), - }).Tracef("creating secret %s/%s/%s/%s in the database", s.GetType(), s.GetOrg(), s.GetTeam(), s.GetName()) + }).Tracef("creating secret %s/%s/%s/%s", s.GetType(), s.GetOrg(), s.GetTeam(), s.GetName()) default: e.logger.WithFields(logrus.Fields{ "org": s.GetOrg(), "repo": s.GetRepo(), "secret": s.GetName(), "type": s.GetType(), - }).Tracef("creating secret %s/%s/%s/%s in the database", s.GetType(), s.GetOrg(), s.GetRepo(), s.GetName()) + }).Tracef("creating secret %s/%s/%s/%s", s.GetType(), s.GetOrg(), s.GetRepo(), s.GetName()) } // cast the library type to database type diff --git a/database/secret/delete.go b/database/secret/delete.go index 5b3653ba1..bc3cba36f 100644 --- a/database/secret/delete.go +++ b/database/secret/delete.go @@ -24,14 +24,14 @@ func (e *engine) DeleteSecret(ctx context.Context, s *library.Secret) error { "team": s.GetTeam(), "secret": s.GetName(), "type": s.GetType(), - }).Tracef("deleting secret %s/%s/%s/%s from the database", s.GetType(), s.GetOrg(), s.GetTeam(), s.GetName()) + }).Tracef("deleting secret %s/%s/%s/%s", s.GetType(), s.GetOrg(), s.GetTeam(), s.GetName()) default: e.logger.WithFields(logrus.Fields{ "org": s.GetOrg(), "repo": s.GetRepo(), "secret": s.GetName(), "type": s.GetType(), - }).Tracef("deleting secret %s/%s/%s/%s from the database", s.GetType(), s.GetOrg(), s.GetRepo(), s.GetName()) + }).Tracef("deleting secret %s/%s/%s/%s", s.GetType(), s.GetOrg(), s.GetRepo(), s.GetName()) } // cast the library type to database type diff --git a/database/secret/get.go b/database/secret/get.go index c8cafa2df..6f5bc7bf9 100644 --- a/database/secret/get.go +++ b/database/secret/get.go @@ -12,7 +12,7 @@ import ( // GetSecret gets a secret by ID from the database. func (e *engine) GetSecret(ctx context.Context, id int64) (*library.Secret, error) { - e.logger.Tracef("getting secret %d from the database", id) + e.logger.Tracef("getting secret %d", id) // variable to store query results s := new(database.Secret) diff --git a/database/secret/get_org.go b/database/secret/get_org.go index fec7ff1ef..7d1766c88 100644 --- a/database/secret/get_org.go +++ b/database/secret/get_org.go @@ -18,7 +18,7 @@ func (e *engine) GetSecretForOrg(ctx context.Context, org, name string) (*librar "org": org, "secret": name, "type": constants.SecretOrg, - }).Tracef("getting org secret %s/%s from the database", org, name) + }).Tracef("getting org secret %s/%s", org, name) // variable to store query results s := new(database.Secret) diff --git a/database/secret/get_repo.go b/database/secret/get_repo.go index 6edacafd1..690823c08 100644 --- a/database/secret/get_repo.go +++ b/database/secret/get_repo.go @@ -20,7 +20,7 @@ func (e *engine) GetSecretForRepo(ctx context.Context, name string, r *api.Repo) "repo": r.GetName(), "secret": name, "type": constants.SecretRepo, - }).Tracef("getting repo secret %s/%s from the database", r.GetFullName(), name) + }).Tracef("getting repo secret %s/%s", r.GetFullName(), name) // variable to store query results s := new(database.Secret) diff --git a/database/secret/get_team.go b/database/secret/get_team.go index 74e4a57f9..e03845947 100644 --- a/database/secret/get_team.go +++ b/database/secret/get_team.go @@ -19,7 +19,7 @@ func (e *engine) GetSecretForTeam(ctx context.Context, org, team, name string) ( "team": team, "secret": name, "type": constants.SecretShared, - }).Tracef("getting shared secret %s/%s/%s from the database", org, team, name) + }).Tracef("getting shared secret %s/%s/%s", org, team, name) // variable to store query results s := new(database.Secret) diff --git a/database/secret/index.go b/database/secret/index.go index f0cd1837d..e045031bb 100644 --- a/database/secret/index.go +++ b/database/secret/index.go @@ -33,7 +33,7 @@ ON secrets (type, org); // CreateSecretIndexes creates the indexes for the secrets table in the database. func (e *engine) CreateSecretIndexes(ctx context.Context) error { - e.logger.Tracef("creating indexes for secrets table in the database") + e.logger.Tracef("creating indexes for secrets table") // create the type, org and repo columns index for the secrets table err := e.client.Exec(CreateTypeOrgRepo).Error diff --git a/database/secret/list.go b/database/secret/list.go index 08746332c..a61e2088f 100644 --- a/database/secret/list.go +++ b/database/secret/list.go @@ -12,7 +12,7 @@ import ( // ListSecrets gets a list of all secrets from the database. func (e *engine) ListSecrets(ctx context.Context) ([]*library.Secret, error) { - e.logger.Trace("listing all secrets from the database") + e.logger.Trace("listing all secrets") // variables to store query results and return value count := int64(0) diff --git a/database/secret/list_org.go b/database/secret/list_org.go index 63cf5f899..d8c7ced5a 100644 --- a/database/secret/list_org.go +++ b/database/secret/list_org.go @@ -19,7 +19,7 @@ func (e *engine) ListSecretsForOrg(ctx context.Context, org string, filters map[ e.logger.WithFields(logrus.Fields{ "org": org, "type": constants.SecretOrg, - }).Tracef("listing secrets for org %s from the database", org) + }).Tracef("listing secrets for org %s", org) // variables to store query results and return values count := int64(0) diff --git a/database/secret/list_repo.go b/database/secret/list_repo.go index 0be77454c..ef2fe546c 100644 --- a/database/secret/list_repo.go +++ b/database/secret/list_repo.go @@ -21,7 +21,7 @@ func (e *engine) ListSecretsForRepo(ctx context.Context, r *api.Repo, filters ma "org": r.GetOrg(), "repo": r.GetName(), "type": constants.SecretRepo, - }).Tracef("listing secrets for repo %s from the database", r.GetFullName()) + }).Tracef("listing secrets for repo %s", r.GetFullName()) // variables to store query results and return values count := int64(0) diff --git a/database/secret/list_team.go b/database/secret/list_team.go index f9a17c2fd..93a5d6db1 100644 --- a/database/secret/list_team.go +++ b/database/secret/list_team.go @@ -21,7 +21,7 @@ func (e *engine) ListSecretsForTeam(ctx context.Context, org, team string, filte "org": org, "team": team, "type": constants.SecretShared, - }).Tracef("listing secrets for team %s/%s from the database", org, team) + }).Tracef("listing secrets for team %s/%s", org, team) // variables to store query results and return values count := int64(0) @@ -97,7 +97,7 @@ func (e *engine) ListSecretsForTeams(ctx context.Context, org string, teams []st "org": org, "teams": teams, "type": constants.SecretShared, - }).Tracef("listing secrets for teams %s in org %s from the database", teams, org) + }).Tracef("listing secrets for teams %s in org %s", teams, org) // variables to store query results and return values count := int64(0) diff --git a/database/secret/secret.go b/database/secret/secret.go index 55e20b59f..4a7c772e8 100644 --- a/database/secret/secret.go +++ b/database/secret/secret.go @@ -62,7 +62,7 @@ func New(opts ...EngineOpt) (*engine, error) { // check if we should skip creating secret database objects if e.config.SkipCreation { - e.logger.Warning("skipping creation of secrets table and indexes in the database") + e.logger.Warning("skipping creation of secrets table and indexes") return e, nil } diff --git a/database/secret/table.go b/database/secret/table.go index 07b84fee8..e696409c2 100644 --- a/database/secret/table.go +++ b/database/secret/table.go @@ -62,7 +62,7 @@ secrets ( // CreateSecretTable creates the secrets table in the database. func (e *engine) CreateSecretTable(ctx context.Context, driver string) error { - e.logger.Tracef("creating secrets table in the database") + e.logger.Tracef("creating secrets table") // handle the driver provided to create the table switch driver { diff --git a/database/secret/update.go b/database/secret/update.go index 641a8a3e3..0bb713e47 100644 --- a/database/secret/update.go +++ b/database/secret/update.go @@ -24,14 +24,14 @@ func (e *engine) UpdateSecret(ctx context.Context, s *library.Secret) (*library. "team": s.GetTeam(), "secret": s.GetName(), "type": s.GetType(), - }).Tracef("updating secret %s/%s/%s/%s in the database", s.GetType(), s.GetOrg(), s.GetTeam(), s.GetName()) + }).Tracef("updating secret %s/%s/%s/%s", s.GetType(), s.GetOrg(), s.GetTeam(), s.GetName()) default: e.logger.WithFields(logrus.Fields{ "org": s.GetOrg(), "repo": s.GetRepo(), "secret": s.GetName(), "type": s.GetType(), - }).Tracef("updating secret %s/%s/%s/%s in the database", s.GetType(), s.GetOrg(), s.GetRepo(), s.GetName()) + }).Tracef("updating secret %s/%s/%s/%s", s.GetType(), s.GetOrg(), s.GetRepo(), s.GetName()) } // cast the library type to database type diff --git a/database/service/count.go b/database/service/count.go index dd1f63188..f8bee25b1 100644 --- a/database/service/count.go +++ b/database/service/count.go @@ -10,7 +10,7 @@ import ( // CountServices gets the count of all services from the database. func (e *engine) CountServices(ctx context.Context) (int64, error) { - e.logger.Tracef("getting count of all services from the database") + e.logger.Tracef("getting count of all services") // variable to store query results var s int64 diff --git a/database/service/count_build.go b/database/service/count_build.go index a15c061ff..1e84819a2 100644 --- a/database/service/count_build.go +++ b/database/service/count_build.go @@ -15,7 +15,7 @@ import ( func (e *engine) CountServicesForBuild(ctx context.Context, b *api.Build, filters map[string]interface{}) (int64, error) { e.logger.WithFields(logrus.Fields{ "build": b.GetNumber(), - }).Tracef("getting count of services for build %d from the database", b.GetNumber()) + }).Tracef("getting count of services for build %d", b.GetNumber()) // variable to store query results var s int64 diff --git a/database/service/delete.go b/database/service/delete.go index 5762fbb8d..3f0bd331e 100644 --- a/database/service/delete.go +++ b/database/service/delete.go @@ -16,7 +16,7 @@ import ( func (e *engine) DeleteService(ctx context.Context, s *library.Service) error { e.logger.WithFields(logrus.Fields{ "service": s.GetNumber(), - }).Tracef("deleting service %s from the database", s.GetName()) + }).Tracef("deleting service %s", s.GetName()) // cast the library type to database type // diff --git a/database/service/get.go b/database/service/get.go index aacda2904..eee921123 100644 --- a/database/service/get.go +++ b/database/service/get.go @@ -12,7 +12,7 @@ import ( // GetService gets a service by ID from the database. func (e *engine) GetService(ctx context.Context, id int64) (*library.Service, error) { - e.logger.Tracef("getting service %d from the database", id) + e.logger.Tracef("getting service %d", id) // variable to store query results s := new(database.Service) diff --git a/database/service/get_build.go b/database/service/get_build.go index 26b5632c8..81a95e0bc 100644 --- a/database/service/get_build.go +++ b/database/service/get_build.go @@ -18,7 +18,7 @@ func (e *engine) GetServiceForBuild(ctx context.Context, b *api.Build, number in e.logger.WithFields(logrus.Fields{ "build": b.GetNumber(), "service": number, - }).Tracef("getting service %d from the database", number) + }).Tracef("getting service %d", number) // variable to store query results s := new(database.Service) diff --git a/database/service/list.go b/database/service/list.go index 5da3a06ed..656beee10 100644 --- a/database/service/list.go +++ b/database/service/list.go @@ -12,7 +12,7 @@ import ( // ListServices gets a list of all services from the database. func (e *engine) ListServices(ctx context.Context) ([]*library.Service, error) { - e.logger.Trace("listing all services from the database") + e.logger.Trace("listing all services") // variables to store query results and return value count := int64(0) diff --git a/database/service/list_build.go b/database/service/list_build.go index 98cb70294..047aba669 100644 --- a/database/service/list_build.go +++ b/database/service/list_build.go @@ -17,7 +17,7 @@ import ( func (e *engine) ListServicesForBuild(ctx context.Context, b *api.Build, filters map[string]interface{}, page int, perPage int) ([]*library.Service, int64, error) { e.logger.WithFields(logrus.Fields{ "build": b.GetNumber(), - }).Tracef("listing services for build %d from the database", b.GetNumber()) + }).Tracef("listing services for build %d", b.GetNumber()) // variables to store query results and return value count := int64(0) diff --git a/database/service/list_image.go b/database/service/list_image.go index f5267d5da..a94447e6c 100644 --- a/database/service/list_image.go +++ b/database/service/list_image.go @@ -11,7 +11,7 @@ import ( // ListServiceImageCount gets a list of all service images and the count of their occurrence from the database. func (e *engine) ListServiceImageCount(ctx context.Context) (map[string]float64, error) { - e.logger.Tracef("getting count of all images for services from the database") + e.logger.Tracef("getting count of all images for services") // variables to store query results and return value s := []struct { diff --git a/database/service/list_status.go b/database/service/list_status.go index dde89795a..9e5f106fd 100644 --- a/database/service/list_status.go +++ b/database/service/list_status.go @@ -11,7 +11,7 @@ import ( // ListServiceStatusCount gets a list of all service statuses and the count of their occurrence from the database. func (e *engine) ListServiceStatusCount(ctx context.Context) (map[string]float64, error) { - e.logger.Tracef("getting count of all statuses for services from the database") + e.logger.Tracef("getting count of all statuses for services") // variables to store query results and return value s := []struct { diff --git a/database/service/table.go b/database/service/table.go index 7cf7561c3..56e78b249 100644 --- a/database/service/table.go +++ b/database/service/table.go @@ -60,7 +60,7 @@ services ( // CreateServiceTable creates the services table in the database. func (e *engine) CreateServiceTable(ctx context.Context, driver string) error { - e.logger.Tracef("creating services table in the database") + e.logger.Tracef("creating services table") // handle the driver provided to create the table switch driver { diff --git a/database/service/update.go b/database/service/update.go index da6417aab..6eb43a7e2 100644 --- a/database/service/update.go +++ b/database/service/update.go @@ -16,7 +16,7 @@ import ( func (e *engine) UpdateService(ctx context.Context, s *library.Service) (*library.Service, error) { e.logger.WithFields(logrus.Fields{ "service": s.GetNumber(), - }).Tracef("updating service %s in the database", s.GetName()) + }).Tracef("updating service %s", s.GetName()) // cast the library type to database type // diff --git a/database/settings/create.go b/database/settings/create.go index 7775fb4c9..8c5747320 100644 --- a/database/settings/create.go +++ b/database/settings/create.go @@ -11,7 +11,7 @@ import ( // CreateSettings creates a platform settings record in the database. func (e *engine) CreateSettings(_ context.Context, s *settings.Platform) (*settings.Platform, error) { - e.logger.Tracef("creating platform settings in the database with %v", s.String()) + e.logger.Tracef("creating platform settings with %v", s.String()) // cast the api type to database type settings := types.SettingsFromAPI(s) diff --git a/database/settings/get.go b/database/settings/get.go index 0bba2e0f4..96bc19ef1 100644 --- a/database/settings/get.go +++ b/database/settings/get.go @@ -11,7 +11,7 @@ import ( // GetSettings gets platform settings from the database. func (e *engine) GetSettings(ctx context.Context) (*settings.Platform, error) { - e.logger.Trace("getting platform settings from the database") + e.logger.Trace("getting platform settings") // variable to store query results s := new(types.Platform) diff --git a/database/settings/settings.go b/database/settings/settings.go index a673ed49d..e86ea23b1 100644 --- a/database/settings/settings.go +++ b/database/settings/settings.go @@ -62,7 +62,7 @@ func New(opts ...EngineOpt) (*engine, error) { // check if we should skip creating database objects if e.config.SkipCreation { - e.logger.Warning("skipping creation of settings table and indexes in the database") + e.logger.Warning("skipping creation of settings table and indexes") return e, nil } diff --git a/database/settings/table.go b/database/settings/table.go index a7268bc76..18a4207ab 100644 --- a/database/settings/table.go +++ b/database/settings/table.go @@ -44,7 +44,7 @@ settings ( // CreateSettingsTable creates the settings table in the database. func (e *engine) CreateSettingsTable(_ context.Context, driver string) error { - e.logger.Tracef("creating settings table in the database") + e.logger.Tracef("creating settings table") // handle the driver provided to create the table switch driver { diff --git a/database/step/count.go b/database/step/count.go index 12ef7afc4..d5c64ba34 100644 --- a/database/step/count.go +++ b/database/step/count.go @@ -10,7 +10,7 @@ import ( // CountSteps gets the count of all steps from the database. func (e *engine) CountSteps(ctx context.Context) (int64, error) { - e.logger.Tracef("getting count of all steps from the database") + e.logger.Tracef("getting count of all steps") // variable to store query results var s int64 diff --git a/database/step/count_build.go b/database/step/count_build.go index 35109fa06..6b4d63fc4 100644 --- a/database/step/count_build.go +++ b/database/step/count_build.go @@ -15,7 +15,7 @@ import ( func (e *engine) CountStepsForBuild(ctx context.Context, b *api.Build, filters map[string]interface{}) (int64, error) { e.logger.WithFields(logrus.Fields{ "build": b.GetNumber(), - }).Tracef("getting count of steps for build %d from the database", b.GetNumber()) + }).Tracef("getting count of steps for build %d", b.GetNumber()) // variable to store query results var s int64 diff --git a/database/step/delete.go b/database/step/delete.go index 98e895def..dfd2d5bfa 100644 --- a/database/step/delete.go +++ b/database/step/delete.go @@ -16,7 +16,7 @@ import ( func (e *engine) DeleteStep(ctx context.Context, s *library.Step) error { e.logger.WithFields(logrus.Fields{ "step": s.GetNumber(), - }).Tracef("deleting step %s from the database", s.GetName()) + }).Tracef("deleting step %s", s.GetName()) // cast the library type to database type // diff --git a/database/step/get.go b/database/step/get.go index d75217f58..7a4e18041 100644 --- a/database/step/get.go +++ b/database/step/get.go @@ -12,7 +12,7 @@ import ( // GetStep gets a step by ID from the database. func (e *engine) GetStep(ctx context.Context, id int64) (*library.Step, error) { - e.logger.Tracef("getting step %d from the database", id) + e.logger.Tracef("getting step %d", id) // variable to store query results s := new(database.Step) diff --git a/database/step/get_build.go b/database/step/get_build.go index 9fd8a937e..5d32ba582 100644 --- a/database/step/get_build.go +++ b/database/step/get_build.go @@ -18,7 +18,7 @@ func (e *engine) GetStepForBuild(ctx context.Context, b *api.Build, number int) e.logger.WithFields(logrus.Fields{ "build": b.GetNumber(), "step": number, - }).Tracef("getting step %d from the database", number) + }).Tracef("getting step %d", number) // variable to store query results s := new(database.Step) diff --git a/database/step/list.go b/database/step/list.go index afbb9f818..0d53297bd 100644 --- a/database/step/list.go +++ b/database/step/list.go @@ -12,7 +12,7 @@ import ( // ListSteps gets a list of all steps from the database. func (e *engine) ListSteps(ctx context.Context) ([]*library.Step, error) { - e.logger.Trace("listing all steps from the database") + e.logger.Trace("listing all steps") // variables to store query results and return value count := int64(0) diff --git a/database/step/list_build.go b/database/step/list_build.go index fce2619e8..ac0a608d1 100644 --- a/database/step/list_build.go +++ b/database/step/list_build.go @@ -17,7 +17,7 @@ import ( func (e *engine) ListStepsForBuild(ctx context.Context, b *api.Build, filters map[string]interface{}, page int, perPage int) ([]*library.Step, int64, error) { e.logger.WithFields(logrus.Fields{ "build": b.GetNumber(), - }).Tracef("listing steps for build %d from the database", b.GetNumber()) + }).Tracef("listing steps for build %d", b.GetNumber()) // variables to store query results and return value count := int64(0) diff --git a/database/step/list_image.go b/database/step/list_image.go index 7669d637a..5b0f46aec 100644 --- a/database/step/list_image.go +++ b/database/step/list_image.go @@ -11,7 +11,7 @@ import ( // ListStepImageCount gets a list of all step images and the count of their occurrence from the database. func (e *engine) ListStepImageCount(ctx context.Context) (map[string]float64, error) { - e.logger.Tracef("getting count of all images for steps from the database") + e.logger.Tracef("getting count of all images for steps") // variables to store query results and return value s := []struct { diff --git a/database/step/list_status.go b/database/step/list_status.go index d93db3c30..c74b8db3c 100644 --- a/database/step/list_status.go +++ b/database/step/list_status.go @@ -11,7 +11,7 @@ import ( // ListStepStatusCount gets a list of all step statuses and the count of their occurrence from the database. func (e *engine) ListStepStatusCount(ctx context.Context) (map[string]float64, error) { - e.logger.Tracef("getting count of all statuses for steps from the database") + e.logger.Tracef("getting count of all statuses for steps") // variables to store query results and return value s := []struct { diff --git a/database/user/count.go b/database/user/count.go index dc5554b37..c48fa00ed 100644 --- a/database/user/count.go +++ b/database/user/count.go @@ -10,7 +10,7 @@ import ( // CountUsers gets the count of all users from the database. func (e *engine) CountUsers(ctx context.Context) (int64, error) { - e.logger.Tracef("getting count of all users from the database") + e.logger.Tracef("getting count of all users") // variable to store query results var u int64 diff --git a/database/user/create.go b/database/user/create.go index b8cb1e59d..e9cf0f2c6 100644 --- a/database/user/create.go +++ b/database/user/create.go @@ -18,7 +18,7 @@ import ( func (e *engine) CreateUser(ctx context.Context, u *api.User) (*api.User, error) { e.logger.WithFields(logrus.Fields{ "user": u.GetName(), - }).Tracef("creating user %s in the database", u.GetName()) + }).Tracef("creating user %s", u.GetName()) // cast the API type to database type user := types.UserFromAPI(u) diff --git a/database/user/delete.go b/database/user/delete.go index b7a7be169..3154461e2 100644 --- a/database/user/delete.go +++ b/database/user/delete.go @@ -16,7 +16,7 @@ import ( func (e *engine) DeleteUser(ctx context.Context, u *api.User) error { e.logger.WithFields(logrus.Fields{ "user": u.GetName(), - }).Tracef("deleting user %s from the database", u.GetName()) + }).Tracef("deleting user %s", u.GetName()) // cast the API type to database type user := types.UserFromAPI(u) diff --git a/database/user/get.go b/database/user/get.go index e0f8d45d9..a2f7d8468 100644 --- a/database/user/get.go +++ b/database/user/get.go @@ -12,7 +12,7 @@ import ( // GetUser gets a user by ID from the database. func (e *engine) GetUser(ctx context.Context, id int64) (*api.User, error) { - e.logger.Tracef("getting user %d from the database", id) + e.logger.Tracef("getting user %d", id) // variable to store query results u := new(types.User) diff --git a/database/user/get_name.go b/database/user/get_name.go index f74c07166..8d3633eb8 100644 --- a/database/user/get_name.go +++ b/database/user/get_name.go @@ -16,7 +16,7 @@ import ( func (e *engine) GetUserForName(ctx context.Context, name string) (*api.User, error) { e.logger.WithFields(logrus.Fields{ "user": name, - }).Tracef("getting user %s from the database", name) + }).Tracef("getting user %s", name) // variable to store query results u := new(types.User) diff --git a/database/user/index.go b/database/user/index.go index 25c3edef3..d35e1accd 100644 --- a/database/user/index.go +++ b/database/user/index.go @@ -17,7 +17,7 @@ ON users (refresh_token); // CreateUserIndexes creates the indexes for the users table in the database. func (e *engine) CreateUserIndexes(ctx context.Context) error { - e.logger.Tracef("creating indexes for users table in the database") + e.logger.Tracef("creating indexes for users table") // create the refresh_token column index for the users table return e.client.Exec(CreateUserRefreshIndex).Error diff --git a/database/user/list.go b/database/user/list.go index 29b53f7f0..80c7f5681 100644 --- a/database/user/list.go +++ b/database/user/list.go @@ -12,7 +12,7 @@ import ( // ListUsers gets a list of all users from the database. func (e *engine) ListUsers(ctx context.Context) ([]*api.User, error) { - e.logger.Trace("listing all users from the database") + e.logger.Trace("listing all users") // variables to store query results and return value count := int64(0) diff --git a/database/user/list_lite.go b/database/user/list_lite.go index d3ca1c49a..1a5c570f9 100644 --- a/database/user/list_lite.go +++ b/database/user/list_lite.go @@ -14,7 +14,7 @@ import ( // //nolint:lll // ignore long line length due to variable names func (e *engine) ListLiteUsers(ctx context.Context, page, perPage int) ([]*api.User, int64, error) { - e.logger.Trace("listing lite users from the database") + e.logger.Trace("listing lite users") // variables to store query results and return values count := int64(0) diff --git a/database/user/table.go b/database/user/table.go index c5e4d1712..183390b43 100644 --- a/database/user/table.go +++ b/database/user/table.go @@ -46,7 +46,7 @@ users ( // CreateUserTable creates the users table in the database. func (e *engine) CreateUserTable(ctx context.Context, driver string) error { - e.logger.Tracef("creating users table in the database") + e.logger.Tracef("creating users table") // handle the driver provided to create the table switch driver { diff --git a/database/user/update.go b/database/user/update.go index b785352eb..19f653f8d 100644 --- a/database/user/update.go +++ b/database/user/update.go @@ -18,7 +18,7 @@ import ( func (e *engine) UpdateUser(ctx context.Context, u *api.User) (*api.User, error) { e.logger.WithFields(logrus.Fields{ "user": u.GetName(), - }).Tracef("updating user %s in the database", u.GetName()) + }).Tracef("updating user %s", u.GetName()) // cast the library type to database type user := types.UserFromAPI(u) diff --git a/database/user/user.go b/database/user/user.go index 23948bfb3..ad2e2bae5 100644 --- a/database/user/user.go +++ b/database/user/user.go @@ -62,7 +62,7 @@ func New(opts ...EngineOpt) (*engine, error) { // check if we should skip creating user database objects if e.config.SkipCreation { - e.logger.Warning("skipping creation of users table and indexes in the database") + e.logger.Warning("skipping creation of users table and indexes") return e, nil } diff --git a/database/worker/count.go b/database/worker/count.go index eef910c36..0d992cdca 100644 --- a/database/worker/count.go +++ b/database/worker/count.go @@ -10,7 +10,7 @@ import ( // CountWorkers gets the count of all workers from the database. func (e *engine) CountWorkers(ctx context.Context) (int64, error) { - e.logger.Tracef("getting count of all workers from the database") + e.logger.Tracef("getting count of all workers") // variable to store query results var w int64 diff --git a/database/worker/create.go b/database/worker/create.go index c566ecd0e..445669deb 100644 --- a/database/worker/create.go +++ b/database/worker/create.go @@ -16,7 +16,7 @@ import ( func (e *engine) CreateWorker(ctx context.Context, w *api.Worker) (*api.Worker, error) { e.logger.WithFields(logrus.Fields{ "worker": w.GetHostname(), - }).Tracef("creating worker %s in the database", w.GetHostname()) + }).Tracef("creating worker %s", w.GetHostname()) // cast the library type to database type // diff --git a/database/worker/delete.go b/database/worker/delete.go index 4972efc98..8df8ff5e0 100644 --- a/database/worker/delete.go +++ b/database/worker/delete.go @@ -16,7 +16,7 @@ import ( func (e *engine) DeleteWorker(ctx context.Context, w *api.Worker) error { e.logger.WithFields(logrus.Fields{ "worker": w.GetHostname(), - }).Tracef("deleting worker %s from the database", w.GetHostname()) + }).Tracef("deleting worker %s", w.GetHostname()) // cast the library type to database type // diff --git a/database/worker/get.go b/database/worker/get.go index 7aca60b76..cde920413 100644 --- a/database/worker/get.go +++ b/database/worker/get.go @@ -12,7 +12,7 @@ import ( // GetWorker gets a worker by ID from the database. func (e *engine) GetWorker(ctx context.Context, id int64) (*api.Worker, error) { - e.logger.Tracef("getting worker %d from the database", id) + e.logger.Tracef("getting worker %d", id) // variable to store query results w := new(types.Worker) diff --git a/database/worker/get_hostname.go b/database/worker/get_hostname.go index ec37b9200..1646e262e 100644 --- a/database/worker/get_hostname.go +++ b/database/worker/get_hostname.go @@ -16,7 +16,7 @@ import ( func (e *engine) GetWorkerForHostname(ctx context.Context, hostname string) (*api.Worker, error) { e.logger.WithFields(logrus.Fields{ "worker": hostname, - }).Tracef("getting worker %s from the database", hostname) + }).Tracef("getting worker %s", hostname) // variable to store query results w := new(types.Worker) diff --git a/database/worker/index.go b/database/worker/index.go index 3220d4a63..65fe7326f 100644 --- a/database/worker/index.go +++ b/database/worker/index.go @@ -17,7 +17,7 @@ ON workers (hostname, address); // CreateWorkerIndexes creates the indexes for the workers table in the database. func (e *engine) CreateWorkerIndexes(ctx context.Context) error { - e.logger.Tracef("creating indexes for workers table in the database") + e.logger.Tracef("creating indexes for workers table") // create the hostname and address columns index for the workers table return e.client.Exec(CreateHostnameAddressIndex).Error diff --git a/database/worker/list.go b/database/worker/list.go index a8adc1a79..e2af759dd 100644 --- a/database/worker/list.go +++ b/database/worker/list.go @@ -14,7 +14,7 @@ import ( // ListWorkers gets a list of all workers from the database. func (e *engine) ListWorkers(ctx context.Context, active string, before, after int64) ([]*api.Worker, error) { - e.logger.Trace("listing all workers from the database") + e.logger.Trace("listing all workers") // variables to store query results and return value results := new([]types.Worker) diff --git a/database/worker/table.go b/database/worker/table.go index 9fcfdd113..403dd5ad3 100644 --- a/database/worker/table.go +++ b/database/worker/table.go @@ -53,7 +53,7 @@ workers ( // CreateWorkerTable creates the workers table in the database. func (e *engine) CreateWorkerTable(ctx context.Context, driver string) error { - e.logger.Tracef("creating workers table in the database") + e.logger.Tracef("creating workers table") // handle the driver provided to create the table switch driver { diff --git a/database/worker/update.go b/database/worker/update.go index 996d0c0af..872d9c82d 100644 --- a/database/worker/update.go +++ b/database/worker/update.go @@ -16,7 +16,7 @@ import ( func (e *engine) UpdateWorker(ctx context.Context, w *api.Worker) (*api.Worker, error) { e.logger.WithFields(logrus.Fields{ "worker": w.GetHostname(), - }).Tracef("updating worker %s in the database", w.GetHostname()) + }).Tracef("updating worker %s", w.GetHostname()) // cast the library type to database type // diff --git a/database/worker/worker.go b/database/worker/worker.go index 18e4d90d9..655a7dd2f 100644 --- a/database/worker/worker.go +++ b/database/worker/worker.go @@ -62,7 +62,7 @@ func New(opts ...EngineOpt) (*engine, error) { // check if we should skip creating worker database objects if e.config.SkipCreation { - e.logger.Warning("skipping creation of workers table and indexes in the database") + e.logger.Warning("skipping creation of workers table and indexes") return e, nil } diff --git a/queue/queue.go b/queue/queue.go index 181ed5899..fdff9b364 100644 --- a/queue/queue.go +++ b/queue/queue.go @@ -13,7 +13,7 @@ import ( // FromCLIContext helper function to setup the queue from the CLI arguments. func FromCLIContext(c *cli.Context) (Service, error) { - logrus.Debug("Creating queue client from CLI configuration") + logrus.Debug("creating queue client from CLI configuration") // queue configuration _setup := &Setup{ diff --git a/router/admin.go b/router/admin.go index d349fd7b0..d2eb667ac 100644 --- a/router/admin.go +++ b/router/admin.go @@ -13,7 +13,6 @@ import ( // with the API handlers for admin functionality. // // GET /api/v1/admin/builds/queue -// GET /api/v1/admin/build/:id // PUT /api/v1/admin/build // PUT /api/v1/admin/clean // PUT /api/v1/admin/deployment diff --git a/router/dashboard.go b/router/dashboard.go index 57ffafddb..32e8490db 100644 --- a/router/dashboard.go +++ b/router/dashboard.go @@ -10,11 +10,14 @@ import ( ) // DashboardHandlers is a function that extends the provided base router group -// with the API handlers for resource search functionality. +// with the API handlers for dashboard functionality. // -// GET /api/v1/search/builds/:id . +// POST /api/v1/dashboards +// GET /api/v1/dashboards/:id +// PUT /api/v1/dashboards/:id +// DELETE /api/v1/dashboards/:id . func DashboardHandlers(base *gin.RouterGroup) { - // Search endpoints + // Dashboard endpoints dashboards := base.Group("/dashboards") { dashboards.POST("", dashboard.CreateDashboard) @@ -25,5 +28,5 @@ func DashboardHandlers(base *gin.RouterGroup) { d.PUT("", dashboard.UpdateDashboard) d.DELETE("", dashboard.DeleteDashboard) } - } // end of search endpoints + } // end of dashboard endpoints } diff --git a/router/hook.go b/router/hook.go index 69816fa4c..896279e66 100644 --- a/router/hook.go +++ b/router/hook.go @@ -6,6 +6,7 @@ import ( "github.com/gin-gonic/gin" "github.com/go-vela/server/api/hook" + hmiddleware "github.com/go-vela/server/router/middleware/hook" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/perm" "github.com/go-vela/server/router/middleware/repo" @@ -26,9 +27,13 @@ func HookHandlers(base *gin.RouterGroup) { { _hooks.POST("", perm.MustPlatformAdmin(), hook.CreateHook) _hooks.GET("", perm.MustRead(), hook.ListHooks) - _hooks.GET("/:hook", perm.MustRead(), hook.GetHook) - _hooks.PUT("/:hook", perm.MustPlatformAdmin(), hook.UpdateHook) - _hooks.DELETE("/:hook", perm.MustPlatformAdmin(), hook.DeleteHook) - _hooks.POST("/:hook/redeliver", perm.MustWrite(), hook.RedeliverHook) + + _hook := _hooks.Group("/:hook", hmiddleware.Establish()) + { + _hook.GET("", perm.MustRead(), hook.GetHook) + _hook.PUT("", perm.MustPlatformAdmin(), hook.UpdateHook) + _hook.DELETE("", perm.MustPlatformAdmin(), hook.DeleteHook) + _hook.POST("/redeliver", perm.MustWrite(), hook.RedeliverHook) + } } // end of hooks endpoints } diff --git a/router/middleware/build/build.go b/router/middleware/build/build.go index 06273e532..c59d85aa8 100644 --- a/router/middleware/build/build.go +++ b/router/middleware/build/build.go @@ -12,9 +12,7 @@ import ( api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" ) @@ -26,9 +24,8 @@ func Retrieve(c *gin.Context) *api.Build { // Establish sets the build in the given context. func Establish() gin.HandlerFunc { return func(c *gin.Context) { - o := org.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) r := repo.Retrieve(c) - u := user.Retrieve(c) ctx := c.Request.Context() if r == nil { @@ -54,15 +51,7 @@ func Establish() gin.HandlerFunc { return } - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "build": number, - "org": o, - "repo": r.GetName(), - "user": u.GetName(), - }).Debugf("reading build %s/%d", r.GetFullName(), number) + l.Debugf("reading build %d", number) b, err := database.FromContext(c).GetBuildForRepo(ctx, r, number) if err != nil { @@ -72,6 +61,14 @@ func Establish() gin.HandlerFunc { return } + l = l.WithFields(logrus.Fields{ + "build": b.GetNumber(), + "build_id": b.GetID(), + }) + + // update the logger with the new fields + c.Set("logger", l) + ToContext(c, b) c.Next() } diff --git a/router/middleware/build/build_test.go b/router/middleware/build/build_test.go index e95036c54..aacf14949 100644 --- a/router/middleware/build/build_test.go +++ b/router/middleware/build/build_test.go @@ -10,6 +10,7 @@ import ( "github.com/gin-gonic/gin" "github.com/google/go-cmp/cmp" + "github.com/sirupsen/logrus" api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" @@ -128,6 +129,7 @@ func TestBuild_Establish(t *testing.T) { context.Request, _ = http.NewRequest(http.MethodGet, "/foo/bar/builds/1", nil) // setup mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) engine.Use(org.Establish()) engine.Use(repo.Establish()) @@ -166,6 +168,7 @@ func TestBuild_Establish_NoRepo(t *testing.T) { context.Request, _ = http.NewRequest(http.MethodGet, "/foo/bar/builds/1", nil) // setup mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) engine.Use(Establish()) @@ -212,6 +215,7 @@ func TestBuild_Establish_NoBuildParameter(t *testing.T) { context.Request, _ = http.NewRequest(http.MethodGet, "/foo/bar/builds", nil) // setup mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) engine.Use(org.Establish()) engine.Use(repo.Establish()) @@ -263,6 +267,7 @@ func TestBuild_Establish_InvalidBuildParameter(t *testing.T) { context.Request, _ = http.NewRequest(http.MethodGet, "/foo/bar/builds/foo", nil) // setup mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) engine.Use(org.Establish()) engine.Use(repo.Establish()) @@ -311,6 +316,7 @@ func TestBuild_Establish_NoBuild(t *testing.T) { context.Request, _ = http.NewRequest(http.MethodGet, "/foo/bar/builds/1", nil) // setup mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) engine.Use(org.Establish()) engine.Use(repo.Establish()) diff --git a/router/middleware/claims/claims.go b/router/middleware/claims/claims.go index 75a30caa0..e306f9e7e 100644 --- a/router/middleware/claims/claims.go +++ b/router/middleware/claims/claims.go @@ -7,6 +7,7 @@ import ( "strings" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" "github.com/go-vela/server/internal/token" "github.com/go-vela/server/router/middleware/auth" @@ -22,7 +23,9 @@ func Retrieve(c *gin.Context) *token.Claims { // Establish sets the claims in the given context. func Establish() gin.HandlerFunc { return func(c *gin.Context) { + l := c.MustGet("logger").(*logrus.Entry) tm := c.MustGet("token-manager").(*token.Manager) + // get the access token from the request at, err := auth.RetrieveAccessToken(c.Request) if err != nil { @@ -51,6 +54,13 @@ func Establish() gin.HandlerFunc { return } + l = l.WithFields(logrus.Fields{ + "claim_subject": claims.Subject, + }) + + // update the logger with the new fields + c.Set("logger", l) + ToContext(c, claims) c.Next() } diff --git a/router/middleware/claims/claims_test.go b/router/middleware/claims/claims_test.go index fa61c773f..9d065df0f 100644 --- a/router/middleware/claims/claims_test.go +++ b/router/middleware/claims/claims_test.go @@ -14,6 +14,7 @@ import ( "github.com/gin-gonic/gin" "github.com/golang-jwt/jwt/v5" + "github.com/sirupsen/logrus" api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" @@ -198,6 +199,7 @@ func TestClaims_Establish(t *testing.T) { gin.SetMode(gin.TestMode) // setup vela mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) engine.Use(Establish()) engine.PUT(tt.Endpoint, func(c *gin.Context) { @@ -238,6 +240,7 @@ func TestClaims_Establish_NoToken(t *testing.T) { context, engine := gin.CreateTestContext(resp) context.Request, _ = http.NewRequest(http.MethodGet, "/workers/host", nil) + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) engine.Use(Establish()) @@ -290,6 +293,7 @@ func TestClaims_Establish_BadToken(t *testing.T) { context.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", tkn)) + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) engine.Use(func(c *gin.Context) { c.Set("secret", "very-secret") }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) diff --git a/router/middleware/dashboard/dashboard.go b/router/middleware/dashboard/dashboard.go index b62db4b90..e1b86335b 100644 --- a/router/middleware/dashboard/dashboard.go +++ b/router/middleware/dashboard/dashboard.go @@ -23,6 +23,7 @@ func Retrieve(c *gin.Context) *api.Dashboard { // Establish sets the build in the given context. func Establish() gin.HandlerFunc { return func(c *gin.Context) { + l := c.MustGet("logger").(*logrus.Entry) u := user.Retrieve(c) ctx := c.Request.Context() @@ -39,13 +40,7 @@ func Establish() gin.HandlerFunc { id = userBoards[0] } - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "dashboard": id, - "user": u.GetName(), - }).Debugf("reading dashboard %s", id) + l.Debugf("reading dashboard %s", id) d, err := database.FromContext(c).GetDashboard(ctx, id) if err != nil { @@ -55,6 +50,13 @@ func Establish() gin.HandlerFunc { return } + l = l.WithFields(logrus.Fields{ + "dashboard": d.GetID(), + }) + + // update the logger with the new fields + c.Set("logger", l) + ToContext(c, d) c.Next() } diff --git a/router/middleware/dashboard/dashboard_test.go b/router/middleware/dashboard/dashboard_test.go index 35509c19e..39c6b6f5f 100644 --- a/router/middleware/dashboard/dashboard_test.go +++ b/router/middleware/dashboard/dashboard_test.go @@ -10,6 +10,7 @@ import ( "testing" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" @@ -81,6 +82,7 @@ func TestDashboard_Establish(t *testing.T) { context.Request, _ = http.NewRequest(http.MethodGet, "/c8da1302-07d6-11ea-882f-4893bca275b8", nil) // setup mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) engine.Use(Establish()) engine.GET("/:dashboard", func(c *gin.Context) { @@ -117,6 +119,7 @@ func TestDashboard_Establish_NoDashboardParameter(t *testing.T) { context.Request, _ = http.NewRequest(http.MethodGet, "//test", nil) // setup mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) engine.Use(Establish()) engine.GET("/:dashboard/test", func(c *gin.Context) { @@ -147,6 +150,7 @@ func TestDashboard_Establish_NoDashboard(t *testing.T) { context.Request, _ = http.NewRequest(http.MethodGet, "/c8da1302-07d6-11ea-882f-4893bca275b8", nil) // setup mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) engine.Use(Establish()) engine.GET("/:dashboard", func(c *gin.Context) { diff --git a/router/middleware/dashboard/doc.go b/router/middleware/dashboard/doc.go new file mode 100644 index 000000000..e12e9d7d5 --- /dev/null +++ b/router/middleware/dashboard/doc.go @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: Apache-2.0 + +// Package dashboard provides the ability for inserting +// Vela dashboard resources into or extracting Vela dashboard +// resources from the middleware chain for the API. +// +// Usage: +// +// import "github.com/go-vela/server/router/middleware/dashboard" +package dashboard diff --git a/router/middleware/header.go b/router/middleware/header.go index c65a003af..a54d737f8 100644 --- a/router/middleware/header.go +++ b/router/middleware/header.go @@ -31,10 +31,12 @@ func Options(c *gin.Context) { c.Next() } else { c.Header("Access-Control-Allow-Origin", "*") + if len(m.Vela.WebAddress) > 0 { c.Header("Access-Control-Allow-Origin", m.Vela.WebAddress) c.Header("Access-Control-Allow-Credentials", "true") } + c.Header("Access-Control-Allow-Methods", "GET,POST,PUT,PATCH,DELETE,OPTIONS") c.Header("Access-Control-Allow-Headers", "authorization, origin, content-type, accept") c.Header("Access-Control-Max-Age", "86400") diff --git a/router/middleware/hook/context.go b/router/middleware/hook/context.go new file mode 100644 index 000000000..b1fa95a4c --- /dev/null +++ b/router/middleware/hook/context.go @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: Apache-2.0 + +package hook + +import ( + "context" + + "github.com/go-vela/types/library" +) + +const key = "hook" + +// Setter defines a context that enables setting values. +type Setter interface { + Set(string, interface{}) +} + +// FromContext returns the Repo associated with this context. +func FromContext(c context.Context) *library.Hook { + value := c.Value(key) + if value == nil { + return nil + } + + r, ok := value.(*library.Hook) + if !ok { + return nil + } + + return r +} + +// ToContext adds the Repo to this context if it supports +// the Setter interface. +func ToContext(c Setter, r *library.Hook) { + c.Set(key, r) +} diff --git a/router/middleware/hook/context_test.go b/router/middleware/hook/context_test.go new file mode 100644 index 000000000..316632435 --- /dev/null +++ b/router/middleware/hook/context_test.go @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: Apache-2.0 + +package hook + +import ( + "testing" + + "github.com/gin-gonic/gin" + + "github.com/go-vela/types/library" +) + +func TestHook_FromContext(t *testing.T) { + // setup types + num := int64(1) + want := &library.Hook{ID: &num} + + // setup context + gin.SetMode(gin.TestMode) + context, _ := gin.CreateTestContext(nil) + context.Set(key, want) + + // run test + got := FromContext(context) + + if got != want { + t.Errorf("FromContext is %v, want %v", got, want) + } +} + +func TestHook_FromContext_Bad(t *testing.T) { + // setup context + gin.SetMode(gin.TestMode) + context, _ := gin.CreateTestContext(nil) + context.Set(key, nil) + + // run test + got := FromContext(context) + + if got != nil { + t.Errorf("FromContext is %v, want nil", got) + } +} + +func TestHook_FromContext_WrongType(t *testing.T) { + // setup context + gin.SetMode(gin.TestMode) + context, _ := gin.CreateTestContext(nil) + context.Set(key, 1) + + // run test + got := FromContext(context) + + if got != nil { + t.Errorf("FromContext is %v, want nil", got) + } +} + +func TestHook_FromContext_Empty(t *testing.T) { + // setup context + gin.SetMode(gin.TestMode) + context, _ := gin.CreateTestContext(nil) + + // run test + got := FromContext(context) + + if got != nil { + t.Errorf("FromContext is %v, want nil", got) + } +} + +func TestHook_ToContext(t *testing.T) { + // setup types + num := int64(1) + want := &library.Hook{ID: &num} + + // setup context + gin.SetMode(gin.TestMode) + context, _ := gin.CreateTestContext(nil) + ToContext(context, want) + + // run test + got := context.Value(key) + + if got != want { + t.Errorf("ToContext is %v, want %v", got, want) + } +} diff --git a/router/middleware/hook/doc.go b/router/middleware/hook/doc.go new file mode 100644 index 000000000..0b110262c --- /dev/null +++ b/router/middleware/hook/doc.go @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: Apache-2.0 + +// Package hook provides the ability for inserting +// Vela hook resources into or extracting Vela hook +// resources from the middleware chain for the API. +// +// Usage: +// +// import "github.com/go-vela/server/router/middleware/hook" +package hook diff --git a/router/middleware/hook/hook.go b/router/middleware/hook/hook.go new file mode 100644 index 000000000..18d0c7c21 --- /dev/null +++ b/router/middleware/hook/hook.go @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: Apache-2.0 + +package hook + +import ( + "fmt" + "net/http" + "strconv" + + "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + + "github.com/go-vela/server/database" + "github.com/go-vela/server/router/middleware/org" + "github.com/go-vela/server/router/middleware/repo" + "github.com/go-vela/server/util" + "github.com/go-vela/types/library" +) + +// Retrieve gets the hook in the given context. +func Retrieve(c *gin.Context) *library.Hook { + return FromContext(c) +} + +// Establish sets the hook in the given context. +func Establish() gin.HandlerFunc { + return func(c *gin.Context) { + l := c.MustGet("logger").(*logrus.Entry) + o := org.Retrieve(c) + r := repo.Retrieve(c) + ctx := c.Request.Context() + + if r == nil { + retErr := fmt.Errorf("repo %s/%s not found", o, util.PathParameter(c, "repo")) + util.HandleError(c, http.StatusNotFound, retErr) + + return + } + + hParam := util.PathParameter(c, "hook") + if len(hParam) == 0 { + retErr := fmt.Errorf("no hook parameter provided") + util.HandleError(c, http.StatusBadRequest, retErr) + + return + } + + number, err := strconv.Atoi(hParam) + if err != nil { + retErr := fmt.Errorf("malformed hook parameter provided: %s", hParam) + util.HandleError(c, http.StatusBadRequest, retErr) + + return + } + + l.Debugf("reading hook %s/%d", r.GetFullName(), number) + + h, err := database.FromContext(c).GetHookForRepo(ctx, r, number) + if err != nil { + retErr := fmt.Errorf("unable to read hook %s/%d: %w", r.GetFullName(), number, err) + util.HandleError(c, http.StatusNotFound, retErr) + + return + } + + l = l.WithFields(logrus.Fields{ + "hook": h.GetID(), + }) + + // update the logger with the new fields + c.Set("logger", l) + + ToContext(c, h) + c.Next() + } +} diff --git a/router/middleware/hook/hook_test.go b/router/middleware/hook/hook_test.go new file mode 100644 index 000000000..fa3deef79 --- /dev/null +++ b/router/middleware/hook/hook_test.go @@ -0,0 +1,302 @@ +// SPDX-License-Identifier: Apache-2.0 + +package hook + +import ( + "context" + "net/http" + "net/http/httptest" + "reflect" + "testing" + + "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" + + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/database" + "github.com/go-vela/server/router/middleware/org" + "github.com/go-vela/server/router/middleware/repo" + "github.com/go-vela/types/library" +) + +func TestHook_Retrieve(t *testing.T) { + // setup types + want := new(library.Hook) + want.SetID(1) + + // setup context + gin.SetMode(gin.TestMode) + context, _ := gin.CreateTestContext(nil) + ToContext(context, want) + + // run test + got := Retrieve(context) + + if got != want { + t.Errorf("Retrieve is %v, want %v", got, want) + } +} + +func TestHook_Establish(t *testing.T) { + // setup types + owner := new(api.User) + owner.SetID(1) + + r := new(api.Repo) + r.SetID(1) + r.SetOwner(owner) + r.SetHash("baz") + r.SetOrg("foo") + r.SetName("bar") + r.SetFullName("foo/bar") + r.SetVisibility("public") + + want := new(library.Hook) + want.SetID(1) + want.SetRepoID(1) + want.SetBuildID(0) + want.SetNumber(1) + want.SetSourceID("ok") + want.SetStatus("") + want.SetError("") + want.SetCreated(0) + want.SetHost("") + want.SetEvent("") + want.SetEventAction("") + want.SetBranch("") + want.SetError("") + want.SetStatus("") + want.SetLink("") + want.SetWebhookID(1) + + got := new(library.Hook) + + // setup database + db, err := database.NewTest() + if err != nil { + t.Errorf("unable to create test database engine: %v", err) + } + + defer func() { + _ = db.DeleteRepo(context.TODO(), r) + _ = db.DeleteHook(context.TODO(), want) + db.Close() + }() + + _, _ = db.CreateRepo(context.TODO(), r) + _, _ = db.CreateHook(context.TODO(), want) + + // setup context + gin.SetMode(gin.TestMode) + + resp := httptest.NewRecorder() + context, engine := gin.CreateTestContext(resp) + context.Request, _ = http.NewRequest(http.MethodGet, "/hooks/foo/bar/1", nil) + + // setup mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) + engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) + engine.Use(org.Establish()) + engine.Use(repo.Establish()) + engine.Use(Establish()) + engine.GET("/hooks/:org/:repo/:hook", func(c *gin.Context) { + got = Retrieve(c) + + c.Status(http.StatusOK) + }) + + // run test + engine.ServeHTTP(context.Writer, context.Request) + + if resp.Code != http.StatusOK { + t.Errorf("Establish returned %v, want %v", resp.Code, http.StatusOK) + } + + if !reflect.DeepEqual(got, want) { + t.Errorf("Establish is %v, want %v", got, want) + } +} + +func TestHook_Establish_NoRepo(t *testing.T) { + // setup database + db, err := database.NewTest() + if err != nil { + t.Errorf("unable to create test database engine: %v", err) + } + defer db.Close() + + // setup context + gin.SetMode(gin.TestMode) + + resp := httptest.NewRecorder() + context, engine := gin.CreateTestContext(resp) + context.Request, _ = http.NewRequest(http.MethodGet, "/hooks/foo/bar/1", nil) + + // setup mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) + engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) + engine.Use(Establish()) + engine.GET("/hooks/:org/:repo/:hook", func(c *gin.Context) { + c.Status(http.StatusOK) + }) + + // run test + engine.ServeHTTP(context.Writer, context.Request) + + if resp.Code != http.StatusNotFound { + t.Errorf("Establish returned %v, want %v", resp.Code, http.StatusNotFound) + } +} + +func TestHook_Establish_NoHookParameter(t *testing.T) { + // setup types + owner := new(api.User) + owner.SetID(1) + + r := new(api.Repo) + r.SetID(1) + r.SetOwner(owner) + r.SetHash("baz") + r.SetOrg("foo") + r.SetName("bar") + r.SetFullName("foo/bar") + r.SetVisibility("public") + + // setup database + db, err := database.NewTest() + if err != nil { + t.Errorf("unable to create test database engine: %v", err) + } + + defer func() { + _ = db.DeleteRepo(context.TODO(), r) + db.Close() + }() + + _, _ = db.CreateRepo(context.TODO(), r) + + // setup context + gin.SetMode(gin.TestMode) + + resp := httptest.NewRecorder() + context, engine := gin.CreateTestContext(resp) + context.Request, _ = http.NewRequest(http.MethodGet, "/hooks/foo/bar", nil) + + // setup mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) + engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) + engine.Use(org.Establish()) + engine.Use(repo.Establish()) + engine.Use(Establish()) + engine.GET("/hooks/:org/:repo/:hook", func(c *gin.Context) { + c.Status(http.StatusOK) + }) + + // run test + engine.ServeHTTP(context.Writer, context.Request) + + if resp.Code != http.StatusBadRequest { + t.Errorf("Establish returned %v, want %v", resp.Code, http.StatusBadRequest) + } +} + +func TestHook_Establish_InvalidHookParameter(t *testing.T) { + // setup types + owner := new(api.User) + owner.SetID(1) + + r := new(api.Repo) + r.SetID(1) + r.SetOwner(owner) + r.SetHash("baz") + r.SetOrg("foo") + r.SetName("bar") + r.SetFullName("foo/bar") + r.SetVisibility("public") + + // setup database + db, err := database.NewTest() + if err != nil { + t.Errorf("unable to create test database engine: %v", err) + } + + defer func() { + _ = db.DeleteRepo(context.TODO(), r) + db.Close() + }() + + _, _ = db.CreateRepo(context.TODO(), r) + + // setup context + gin.SetMode(gin.TestMode) + + resp := httptest.NewRecorder() + context, engine := gin.CreateTestContext(resp) + context.Request, _ = http.NewRequest(http.MethodGet, "/hooks/foo/bar/foo", nil) + + // setup mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) + engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) + engine.Use(org.Establish()) + engine.Use(repo.Establish()) + engine.Use(Establish()) + engine.GET("/hooks/:org/:repo/:hook", func(c *gin.Context) { + c.Status(http.StatusOK) + }) + + // run test + engine.ServeHTTP(context.Writer, context.Request) + + if resp.Code != http.StatusBadRequest { + t.Errorf("Establish returned %v, want %v", resp.Code, http.StatusBadRequest) + } +} + +func TestHook_Establish_NoHook(t *testing.T) { + // setup types + r := new(api.Repo) + r.SetID(1) + r.GetOwner().SetID(1) + r.SetHash("baz") + r.SetOrg("foo") + r.SetName("bar") + r.SetFullName("foo/bar") + r.SetVisibility("public") + + // setup database + db, err := database.NewTest() + if err != nil { + t.Errorf("unable to create test database engine: %v", err) + } + + defer func() { + _ = db.DeleteRepo(context.TODO(), r) + db.Close() + }() + + _, _ = db.CreateRepo(context.TODO(), r) + + // setup context + gin.SetMode(gin.TestMode) + + resp := httptest.NewRecorder() + context, engine := gin.CreateTestContext(resp) + context.Request, _ = http.NewRequest(http.MethodGet, "/hooks/foo/bar/1", nil) + + // setup mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) + engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) + engine.Use(org.Establish()) + engine.Use(repo.Establish()) + engine.Use(Establish()) + engine.GET("/hooks/:org/:repo/:hook", func(c *gin.Context) { + c.Status(http.StatusOK) + }) + + // run test + engine.ServeHTTP(context.Writer, context.Request) + + if resp.Code != http.StatusNotFound { + t.Errorf("Establish returned %v, want %v", resp.Code, http.StatusNotFound) + } +} diff --git a/router/middleware/logger.go b/router/middleware/logger.go index 0f1b14c4c..5b8be89c9 100644 --- a/router/middleware/logger.go +++ b/router/middleware/logger.go @@ -9,8 +9,13 @@ import ( "github.com/sirupsen/logrus" "github.com/go-vela/server/router/middleware/build" + "github.com/go-vela/server/router/middleware/claims" + "github.com/go-vela/server/router/middleware/dashboard" + "github.com/go-vela/server/router/middleware/hook" "github.com/go-vela/server/router/middleware/org" + "github.com/go-vela/server/router/middleware/pipeline" "github.com/go-vela/server/router/middleware/repo" + "github.com/go-vela/server/router/middleware/schedule" "github.com/go-vela/server/router/middleware/service" "github.com/go-vela/server/router/middleware/step" "github.com/go-vela/server/router/middleware/user" @@ -46,11 +51,20 @@ func Logger(logger *logrus.Logger, timeFormat string) gin.HandlerFunc { // some evil middlewares modify this values path := util.EscapeValue(c.Request.URL.Path) - c.Next() + fields := logrus.Fields{ + "ip": util.EscapeValue(c.ClientIP()), + "path": path, + } + + entry := logger.WithFields(fields) + + // set the logger in the context so + // downstream handlers can use it + c.Set("logger", entry) - end := time.Now() + c.Next() - latency := end.Sub(start) + latency := time.Since(start) // prevent us from logging the health endpoint if c.Request.URL.Path != "/health" { @@ -73,6 +87,7 @@ func Logger(logger *logrus.Logger, timeFormat string) gin.HandlerFunc { build := build.Retrieve(c) if build != nil { fields["build"] = build.Number + fields["build_id"] = build.ID } org := org.Retrieve(c) @@ -80,29 +95,73 @@ func Logger(logger *logrus.Logger, timeFormat string) gin.HandlerFunc { fields["org"] = org } + pipeline := pipeline.Retrieve(c) + if pipeline != nil { + fields["pipeline_id"] = pipeline.ID + } + repo := repo.Retrieve(c) if repo != nil { fields["repo"] = repo.Name + fields["repo_id"] = repo.ID } service := service.Retrieve(c) if service != nil { fields["service"] = service.Number + fields["service_id"] = service.ID + } + + hook := hook.Retrieve(c) + if hook != nil { + fields["hook"] = hook.Number + fields["hook_id"] = hook.ID } step := step.Retrieve(c) if step != nil { fields["step"] = step.Number + fields["step_id"] = step.ID + } + + schedule := schedule.Retrieve(c) + if schedule != nil { + fields["schedule"] = schedule.Name + fields["schedule_id"] = schedule.ID + } + + dashboard := dashboard.Retrieve(c) + if dashboard != nil { + fields["dashboard"] = dashboard.Name + fields["dashboard_id"] = dashboard.ID } user := user.Retrieve(c) - if user != nil { + // we check to make sure user name is populated + // because when it's not a user token, we still + // inject an empty user object into the context + // which results in log entries with 'user: null' + if user != nil && user.GetName() != "" { fields["user"] = user.Name + fields["user_id"] = user.ID } worker := worker.Retrieve(c) if worker != nil { fields["worker"] = worker.Hostname + fields["worker_id"] = worker.ID + } + + // if there's no user or worker in the context + // of this request, we log claims subject + _, hasUser := fields["user"] + _, hasWorker := fields["worker"] + + if !hasUser && !hasWorker { + claims := claims.Retrieve(c) + if claims != nil { + fields["claims_subject"] = claims.Subject + } } entry := logger.WithFields(fields) @@ -188,7 +247,7 @@ func (f *ECSFormatter) Format(e *logrus.Entry) ([]byte, error) { } jf := logrus.JSONFormatter{ - TimestampFormat: "2006-01-02T15:04:05.000Z0700", + TimestampFormat: time.RFC3339, // same as default in logrus FieldMap: ecsFieldMap, } diff --git a/router/middleware/org/org.go b/router/middleware/org/org.go index 70efcdfc9..78ccbe708 100644 --- a/router/middleware/org/org.go +++ b/router/middleware/org/org.go @@ -7,6 +7,7 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" "github.com/go-vela/server/util" ) @@ -19,7 +20,10 @@ func Retrieve(c *gin.Context) string { // Establish used to check if org param is used only. func Establish() gin.HandlerFunc { return func(c *gin.Context) { + l := c.MustGet("logger").(*logrus.Entry) + oParam := util.PathParameter(c, "org") + if len(oParam) == 0 { retErr := fmt.Errorf("no org parameter provided") util.HandleError(c, http.StatusBadRequest, retErr) @@ -27,8 +31,14 @@ func Establish() gin.HandlerFunc { return } - ToContext(c, oParam) + l = l.WithFields(logrus.Fields{ + "org": oParam, + }) + // update the logger with the new fields + c.Set("logger", l) + + ToContext(c, oParam) c.Next() } } diff --git a/router/middleware/org/org_test.go b/router/middleware/org/org_test.go index f540a8623..2e5607ef0 100644 --- a/router/middleware/org/org_test.go +++ b/router/middleware/org/org_test.go @@ -10,6 +10,7 @@ import ( "testing" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" @@ -74,6 +75,7 @@ func TestOrg_Establish(t *testing.T) { context.Request, _ = http.NewRequest(http.MethodGet, "/foo", nil) // setup mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) engine.Use(Establish()) engine.GET("/:org", func(c *gin.Context) { @@ -110,6 +112,7 @@ func TestOrg_Establish_NoOrgParameter(t *testing.T) { context.Request, _ = http.NewRequest(http.MethodGet, "//test", nil) // setup mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) engine.Use(Establish()) engine.GET("/:org/test", func(c *gin.Context) { diff --git a/router/middleware/perm/perm.go b/router/middleware/perm/perm.go index e0f11979d..5206ea9a2 100644 --- a/router/middleware/perm/perm.go +++ b/router/middleware/perm/perm.go @@ -13,7 +13,6 @@ import ( "github.com/go-vela/server/constants" "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/claims" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" @@ -23,14 +22,10 @@ import ( // MustPlatformAdmin ensures the user has admin access to the platform. func MustPlatformAdmin() gin.HandlerFunc { return func(c *gin.Context) { + l := c.MustGet("logger").(*logrus.Entry) cl := claims.Retrieve(c) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "user": cl.Subject, - }).Debugf("verifying user %s is a platform admin", cl.Subject) + l.Debugf("verifying user %s is a platform admin", cl.Subject) switch { case cl.IsAdmin: @@ -38,11 +33,10 @@ func MustPlatformAdmin() gin.HandlerFunc { default: if strings.EqualFold(cl.TokenType, constants.WorkerBuildTokenType) { - logrus.WithFields(logrus.Fields{ - "user": cl.Subject, - "repo": cl.Repo, - "build": cl.BuildID, - }).Warnf("attempted access of admin endpoint with build token from %s", cl.Subject) + l.WithFields(logrus.Fields{ + "claims_repo": cl.Repo, + "claims_build": cl.BuildID, + }).Warnf("attempted access of admin endpoint with build token by %s", cl.Subject) } retErr := fmt.Errorf("user %s is not a platform admin", cl.Subject) @@ -56,14 +50,10 @@ func MustPlatformAdmin() gin.HandlerFunc { // MustWorkerRegisterToken ensures the token is a registration token retrieved by a platform admin. func MustWorkerRegisterToken() gin.HandlerFunc { return func(c *gin.Context) { + l := c.MustGet("logger").(*logrus.Entry) cl := claims.Retrieve(c) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "user": cl.Subject, - }).Debugf("verifying user %s has a registration token for worker", cl.Subject) + l.Debugf("verifying user %s has a registration token for worker", cl.Subject) switch cl.TokenType { case constants.WorkerRegisterTokenType: @@ -89,20 +79,14 @@ func MustWorkerRegisterToken() gin.HandlerFunc { // MustWorkerAuthToken ensures the token is a worker auth token. func MustWorkerAuthToken() gin.HandlerFunc { return func(c *gin.Context) { + l := c.MustGet("logger").(*logrus.Entry) cl := claims.Retrieve(c) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "worker": cl.Subject, - }).Debugf("verifying worker %s has a valid auth token", cl.Subject) + l.Debugf("verifying worker %s has a valid auth token", cl.Subject) // global permissions bypass if cl.IsAdmin { - logrus.WithFields(logrus.Fields{ - "user": cl.Subject, - }).Debugf("user %s has platform admin permissions", cl.Subject) + l.Debugf("user %s has platform admin permissions", cl.Subject) return } @@ -131,24 +115,18 @@ func MustWorkerAuthToken() gin.HandlerFunc { // MustBuildAccess ensures the token is a build token for the appropriate build. func MustBuildAccess() gin.HandlerFunc { return func(c *gin.Context) { + l := c.MustGet("logger").(*logrus.Entry) cl := claims.Retrieve(c) b := build.Retrieve(c) // global permissions bypass if cl.IsAdmin { - logrus.WithFields(logrus.Fields{ - "user": cl.Subject, - }).Debugf("user %s has platform admin permissions", cl.Subject) + l.Debugf("user %s has platform admin permissions", cl.Subject) return } - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "worker": cl.Subject, - }).Debugf("verifying worker %s has a valid build token", cl.Subject) + l.Debugf("verifying worker %s has a valid build token", cl.Subject) // validate token type and match build id in request with build id in token claims switch cl.TokenType { @@ -157,10 +135,9 @@ func MustBuildAccess() gin.HandlerFunc { return } - logrus.WithFields(logrus.Fields{ - "user": cl.Subject, - "repo": cl.Repo, - "build": cl.BuildID, + l.WithFields(logrus.Fields{ + "claims_repo": cl.Repo, + "claims_build": cl.BuildID, }).Warnf("build token for build %d attempted to be used for build %d by %s", cl.BuildID, b.GetID(), cl.Subject) fallthrough @@ -176,15 +153,11 @@ func MustBuildAccess() gin.HandlerFunc { // MustIDRequestToken ensures the token is a valid ID request token for the appropriate build. func MustIDRequestToken() gin.HandlerFunc { return func(c *gin.Context) { + l := c.MustGet("logger").(*logrus.Entry) cl := claims.Retrieve(c) b := build.Retrieve(c) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "repo": cl.Subject, - }).Debugf("verifying worker %s has a valid build token", cl.Subject) + logrus.Debugf("verifying worker %s has a valid build token", cl.Subject) // verify expected type if !strings.EqualFold(cl.TokenType, constants.IDRequestTokenType) { @@ -203,10 +176,9 @@ func MustIDRequestToken() gin.HandlerFunc { // verify expected build id if b.GetID() != cl.BuildID { - logrus.WithFields(logrus.Fields{ - "user": cl.Subject, - "repo": cl.Repo, - "build": cl.BuildID, + l.WithFields(logrus.Fields{ + "claims_repo": cl.Repo, + "claims_build": cl.BuildID, }).Warnf("request ID token for build %d attempted to be used for %s build %d by %s", cl.BuildID, b.GetStatus(), b.GetID(), cl.Subject) retErr := fmt.Errorf("invalid token") @@ -216,10 +188,9 @@ func MustIDRequestToken() gin.HandlerFunc { } // MustSecretAdmin ensures the user has admin access to the org, repo or team. -// -//nolint:funlen // ignore function length func MustSecretAdmin() gin.HandlerFunc { return func(c *gin.Context) { + l := c.MustGet("logger").(*logrus.Entry) cl := claims.Retrieve(c) u := user.Retrieve(c) e := util.PathParameter(c, "engine") @@ -232,29 +203,20 @@ func MustSecretAdmin() gin.HandlerFunc { // create log fields from API metadata fields := logrus.Fields{ - "engine": e, - "org": o, - "repo": n, - "type": t, - "user": u.GetName(), + "secret_engine": e, + "secret_org": o, + "secret_repo": n, + "secret_type": t, } // check if secret is a shared secret if strings.EqualFold(t, constants.SecretShared) { // update log fields from API metadata - fields = logrus.Fields{ - "engine": e, - "org": o, - "team": n, - "type": t, - "user": u.GetName(), - } + delete(fields, "repo") + fields["secret_team"] = n } - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logger := logrus.WithFields(fields) + logger := l.WithFields(fields) if u.GetAdmin() { return @@ -335,8 +297,7 @@ func MustSecretAdmin() gin.HandlerFunc { // check if user is accessing shared secrets in personal org if strings.EqualFold(o, u.GetName()) { logger.WithFields(logrus.Fields{ - "org": o, - "user": u.GetName(), + "secret_org": o, }).Debugf("skipping gathering teams for user %s with org %s", u.GetName(), o) return @@ -386,21 +347,12 @@ func MustSecretAdmin() gin.HandlerFunc { // MustAdmin ensures the user has admin access to the repo. func MustAdmin() gin.HandlerFunc { return func(c *gin.Context) { - o := org.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) r := repo.Retrieve(c) u := user.Retrieve(c) ctx := c.Request.Context() - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logger := logrus.WithFields(logrus.Fields{ - "org": o, - "repo": r.GetName(), - "user": u.GetName(), - }) - - logger.Debugf("verifying user %s has 'admin' permissions for repo %s", u.GetName(), r.GetFullName()) + l.Debugf("verifying user %s has 'admin' permissions for repo %s", u.GetName(), r.GetFullName()) if u.GetAdmin() { return @@ -415,7 +367,7 @@ func MustAdmin() gin.HandlerFunc { // https://docs.github.com/en/rest/reference/repos#get-repository-permissions-for-a-user perm, err = scm.FromContext(c).RepoAccess(ctx, u.GetName(), r.GetOwner().GetToken(), r.GetOrg(), r.GetName()) if err != nil { - logger.Errorf("unable to get user %s access level for repo %s", u.GetName(), r.GetFullName()) + l.Errorf("unable to get user %s access level for repo %s", u.GetName(), r.GetFullName()) } } @@ -436,21 +388,12 @@ func MustAdmin() gin.HandlerFunc { // MustWrite ensures the user has admin or write access to the repo. func MustWrite() gin.HandlerFunc { return func(c *gin.Context) { - o := org.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) r := repo.Retrieve(c) u := user.Retrieve(c) ctx := c.Request.Context() - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logger := logrus.WithFields(logrus.Fields{ - "org": o, - "repo": r.GetName(), - "user": u.GetName(), - }) - - logger.Debugf("verifying user %s has 'write' permissions for repo %s", u.GetName(), r.GetFullName()) + l.Debugf("verifying user %s has 'write' permissions for repo %s", u.GetName(), r.GetFullName()) if u.GetAdmin() { return @@ -465,7 +408,7 @@ func MustWrite() gin.HandlerFunc { // https://docs.github.com/en/rest/reference/repos#get-repository-permissions-for-a-user perm, err = scm.FromContext(c).RepoAccess(ctx, u.GetName(), r.GetOwner().GetToken(), r.GetOrg(), r.GetName()) if err != nil { - logger.Errorf("unable to get user %s access level for repo %s", u.GetName(), r.GetFullName()) + l.Errorf("unable to get user %s access level for repo %s", u.GetName(), r.GetFullName()) } } @@ -487,24 +430,15 @@ func MustWrite() gin.HandlerFunc { // MustRead ensures the user has admin, write or read access to the repo. func MustRead() gin.HandlerFunc { return func(c *gin.Context) { + l := c.MustGet("logger").(*logrus.Entry) cl := claims.Retrieve(c) - o := org.Retrieve(c) r := repo.Retrieve(c) u := user.Retrieve(c) ctx := c.Request.Context() - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logger := logrus.WithFields(logrus.Fields{ - "org": o, - "repo": r.GetName(), - "user": u.GetName(), - }) - // check if the repo visibility field is set to public if strings.EqualFold(r.GetVisibility(), constants.VisibilityPublic) { - logger.Debugf("skipping 'read' check for repo %s with %s visibility for user %s", r.GetFullName(), r.GetVisibility(), u.GetName()) + l.Debugf("skipping 'read' check for repo %s with %s visibility for user %s", r.GetFullName(), r.GetVisibility(), u.GetName()) return } @@ -523,7 +457,7 @@ func MustRead() gin.HandlerFunc { return } - logger.Debugf("verifying user %s has 'read' permissions for repo %s", u.GetName(), r.GetFullName()) + l.Debugf("verifying user %s has 'read' permissions for repo %s", u.GetName(), r.GetFullName()) // return if user is platform admin if u.GetAdmin() { @@ -539,7 +473,7 @@ func MustRead() gin.HandlerFunc { // https://docs.github.com/en/rest/reference/repos#get-repository-permissions-for-a-user perm, err = scm.FromContext(c).RepoAccess(ctx, u.GetName(), r.GetOwner().GetToken(), r.GetOrg(), r.GetName()) if err != nil { - logger.Errorf("unable to get user %s access level for repo %s", u.GetName(), r.GetFullName()) + l.Errorf("unable to get user %s access level for repo %s", u.GetName(), r.GetFullName()) } } diff --git a/router/middleware/perm/perm_test.go b/router/middleware/perm/perm_test.go index 772aecf14..a39c3a1b2 100644 --- a/router/middleware/perm/perm_test.go +++ b/router/middleware/perm/perm_test.go @@ -11,6 +11,7 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" api "github.com/go-vela/server/api/types" "github.com/go-vela/server/constants" @@ -83,6 +84,7 @@ func TestPerm_MustPlatformAdmin(t *testing.T) { client, _ := github.NewTest(s.URL) // setup vela mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) @@ -163,6 +165,7 @@ func TestPerm_MustPlatformAdmin_NotAdmin(t *testing.T) { client, _ := github.NewTest(s.URL) // setup vela mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) @@ -213,6 +216,7 @@ func TestPerm_MustWorkerRegisterToken(t *testing.T) { context.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", tok)) // setup vela mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) engine.Use(claims.Establish()) engine.Use(user.Establish()) @@ -276,6 +280,7 @@ func TestPerm_MustWorkerRegisterToken_PlatAdmin(t *testing.T) { context.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", tok)) // setup vela mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) engine.Use(claims.Establish()) @@ -324,6 +329,7 @@ func TestPerm_MustWorkerAuthToken(t *testing.T) { context.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", tok)) // setup vela mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) engine.Use(claims.Establish()) engine.Use(user.Establish()) @@ -364,6 +370,7 @@ func TestPerm_MustWorkerAuth_ServerWorkerToken(t *testing.T) { context.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", secret)) // setup vela mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) engine.Use(claims.Establish()) @@ -448,6 +455,7 @@ func TestPerm_MustBuildAccess(t *testing.T) { context.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", tok)) // setup vela mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) @@ -542,6 +550,7 @@ func TestPerm_MustBuildAccess_PlatAdmin(t *testing.T) { context.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", tok)) // setup vela mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) @@ -633,6 +642,7 @@ func TestPerm_MustBuildToken_WrongBuild(t *testing.T) { context.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", tok)) // setup vela mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) @@ -726,6 +736,7 @@ func TestPerm_MustIDRequestToken(t *testing.T) { context.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", tok)) // setup vela mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) @@ -824,6 +835,7 @@ func TestPerm_MustIDRequestToken_NotRunning(t *testing.T) { context.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", tok)) // setup vela mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) @@ -915,6 +927,7 @@ func TestPerm_MustIDRequestToken_WrongBuild(t *testing.T) { context.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", tok)) // setup vela mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) @@ -1003,6 +1016,7 @@ func TestPerm_MustSecretAdmin_BuildToken_Repo(t *testing.T) { context.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", tok)) // setup vela mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) @@ -1088,6 +1102,7 @@ func TestPerm_MustSecretAdmin_BuildToken_Org(t *testing.T) { context.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", tok)) // setup vela mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) @@ -1173,6 +1188,7 @@ func TestPerm_MustSecretAdmin_BuildToken_Shared(t *testing.T) { context.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", tok)) // setup vela mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) @@ -1269,6 +1285,7 @@ func TestPerm_MustAdmin(t *testing.T) { client, _ := github.NewTest(s.URL) // setup vela mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) @@ -1368,6 +1385,7 @@ func TestPerm_MustAdmin_PlatAdmin(t *testing.T) { client, _ := github.NewTest(s.URL) // setup vela mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) @@ -1467,6 +1485,7 @@ func TestPerm_MustAdmin_NotAdmin(t *testing.T) { client, _ := github.NewTest(s.URL) // setup vela mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) @@ -1566,6 +1585,7 @@ func TestPerm_MustWrite(t *testing.T) { client, _ := github.NewTest(s.URL) // setup vela mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) @@ -1665,6 +1685,7 @@ func TestPerm_MustWrite_PlatAdmin(t *testing.T) { client, _ := github.NewTest(s.URL) // setup vela mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) @@ -1764,6 +1785,7 @@ func TestPerm_MustWrite_RepoAdmin(t *testing.T) { client, _ := github.NewTest(s.URL) // setup vela mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) @@ -1863,6 +1885,7 @@ func TestPerm_MustWrite_NotWrite(t *testing.T) { client, _ := github.NewTest(s.URL) // setup vela mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) @@ -1962,6 +1985,7 @@ func TestPerm_MustRead(t *testing.T) { client, _ := github.NewTest(s.URL) // setup vela mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) @@ -2061,6 +2085,7 @@ func TestPerm_MustRead_PlatAdmin(t *testing.T) { client, _ := github.NewTest(s.URL) // setup vela mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) @@ -2149,6 +2174,7 @@ func TestPerm_MustRead_WorkerBuildToken(t *testing.T) { context.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", tok)) // setup vela mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) @@ -2248,6 +2274,7 @@ func TestPerm_MustRead_RepoAdmin(t *testing.T) { client, _ := github.NewTest(s.URL) // setup vela mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) @@ -2347,6 +2374,7 @@ func TestPerm_MustRead_RepoWrite(t *testing.T) { client, _ := github.NewTest(s.URL) // setup vela mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) @@ -2446,6 +2474,7 @@ func TestPerm_MustRead_RepoPublic(t *testing.T) { client, _ := github.NewTest(s.URL) // setup vela mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) @@ -2545,6 +2574,7 @@ func TestPerm_MustRead_NotRead(t *testing.T) { client, _ := github.NewTest(s.URL) // setup vela mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) diff --git a/router/middleware/pipeline/pipeline.go b/router/middleware/pipeline/pipeline.go index e2bf396ea..162c80ea5 100644 --- a/router/middleware/pipeline/pipeline.go +++ b/router/middleware/pipeline/pipeline.go @@ -13,7 +13,6 @@ import ( "github.com/go-vela/server/compiler" "github.com/go-vela/server/database" "github.com/go-vela/server/internal" - "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/scm" @@ -29,7 +28,7 @@ func Retrieve(c *gin.Context) *library.Pipeline { // Establish sets the pipeline in the given context. func Establish() gin.HandlerFunc { return func(c *gin.Context) { - o := org.Retrieve(c) + l := c.MustGet("logger").(*logrus.Entry) r := repo.Retrieve(c) u := user.Retrieve(c) ctx := c.Request.Context() @@ -53,15 +52,7 @@ func Establish() gin.HandlerFunc { entry := fmt.Sprintf("%s/%s", r.GetFullName(), p) - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "org": o, - "pipeline": p, - "repo": r.GetName(), - "user": u.GetName(), - }).Debugf("reading pipeline %s", entry) + l.Debugf("reading pipeline %s", entry) pipeline, err := database.FromContext(c).GetPipelineForRepo(ctx, p, r) if err != nil { // assume the pipeline doesn't exist in the database yet (before pipeline support was added) @@ -94,8 +85,15 @@ func Establish() gin.HandlerFunc { } } - ToContext(c, pipeline) + l = l.WithFields(logrus.Fields{ + "pipeline": pipeline.GetCommit(), + "pipeline_id": pipeline.GetID(), + }) + + // update the logger with the new fields + c.Set("logger", l) + ToContext(c, pipeline) c.Next() } } diff --git a/router/middleware/pipeline/pipeline_test.go b/router/middleware/pipeline/pipeline_test.go index 5a8c6d608..1408d0dea 100644 --- a/router/middleware/pipeline/pipeline_test.go +++ b/router/middleware/pipeline/pipeline_test.go @@ -13,6 +13,7 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" "github.com/urfave/cli/v2" api "github.com/go-vela/server/api/types" @@ -121,6 +122,7 @@ func TestPipeline_Establish(t *testing.T) { context.Request, _ = http.NewRequest(http.MethodGet, "/pipelines/foo/bar/48afb5bdc41ad69bf22588491333f7cf71135163", nil) // setup mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) engine.Use(org.Establish()) engine.Use(repo.Establish()) @@ -159,6 +161,7 @@ func TestPipeline_Establish_NoRepo(t *testing.T) { context.Request, _ = http.NewRequest(http.MethodGet, "/pipelines/foo/bar/48afb5bdc41ad69bf22588491333f7cf71135163", nil) // setup mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) engine.Use(Establish()) @@ -205,6 +208,7 @@ func TestPipeline_Establish_NoPipelineParameter(t *testing.T) { context.Request, _ = http.NewRequest(http.MethodGet, "/pipelines/foo/bar", nil) // setup mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) engine.Use(org.Establish()) engine.Use(repo.Establish()) @@ -325,6 +329,7 @@ func TestPipeline_Establish_NoPipeline(t *testing.T) { client, _ := github.NewTest(s.URL) // setup vela mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { c.Set("metadata", m) }) engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) diff --git a/router/middleware/repo/repo.go b/router/middleware/repo/repo.go index 448bc13ed..bbc678660 100644 --- a/router/middleware/repo/repo.go +++ b/router/middleware/repo/repo.go @@ -12,7 +12,6 @@ import ( api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/org" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" ) @@ -24,8 +23,8 @@ func Retrieve(c *gin.Context) *api.Repo { // Establish sets the repo in the given context. func Establish() gin.HandlerFunc { return func(c *gin.Context) { + l := c.MustGet("logger").(*logrus.Entry) o := org.Retrieve(c) - u := user.Retrieve(c) ctx := c.Request.Context() rParam := util.PathParameter(c, "repo") @@ -36,14 +35,7 @@ func Establish() gin.HandlerFunc { return } - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "org": o, - "repo": rParam, - "user": u.GetName(), - }).Debugf("reading repo %s/%s", o, rParam) + l.Debugf("reading repo %s", rParam) r, err := database.FromContext(c).GetRepoForOrg(ctx, o, rParam) if err != nil { @@ -53,6 +45,14 @@ func Establish() gin.HandlerFunc { return } + l = l.WithFields(logrus.Fields{ + "repo": r.GetName(), + "repo_id": r.GetID(), + }) + + // update the logger with the new fields + c.Set("logger", l) + ToContext(c, r) c.Next() } diff --git a/router/middleware/repo/repo_test.go b/router/middleware/repo/repo_test.go index d2bb0d512..c20067c62 100644 --- a/router/middleware/repo/repo_test.go +++ b/router/middleware/repo/repo_test.go @@ -10,6 +10,7 @@ import ( "testing" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" @@ -91,6 +92,7 @@ func TestRepo_Establish(t *testing.T) { context.Request, _ = http.NewRequest(http.MethodGet, "/foo/bar", nil) // setup mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) engine.Use(org.Establish()) engine.Use(Establish()) @@ -128,6 +130,7 @@ func TestRepo_Establish_NoOrgParameter(t *testing.T) { context.Request, _ = http.NewRequest(http.MethodGet, "//bar/test", nil) // setup mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) engine.Use(Establish()) engine.GET("/:org/:repo/test", func(c *gin.Context) { @@ -158,6 +161,7 @@ func TestRepo_Establish_NoRepoParameter(t *testing.T) { context.Request, _ = http.NewRequest(http.MethodGet, "/foo//test", nil) // setup mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) engine.Use(Establish()) engine.GET("/:org/:repo/test", func(c *gin.Context) { @@ -188,6 +192,7 @@ func TestRepo_Establish_NoRepo(t *testing.T) { context.Request, _ = http.NewRequest(http.MethodGet, "/foo/bar", nil) // setup mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) engine.Use(Establish()) engine.GET("/:org/:repo", func(c *gin.Context) { diff --git a/router/middleware/schedule/schedule.go b/router/middleware/schedule/schedule.go index 41864cef0..ff617bc3a 100644 --- a/router/middleware/schedule/schedule.go +++ b/router/middleware/schedule/schedule.go @@ -12,7 +12,6 @@ import ( api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" "github.com/go-vela/server/router/middleware/repo" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" ) @@ -24,8 +23,8 @@ func Retrieve(c *gin.Context) *api.Schedule { // Establish sets the schedule in the given context. func Establish() gin.HandlerFunc { return func(c *gin.Context) { + l := c.MustGet("logger").(*logrus.Entry) r := repo.Retrieve(c) - u := user.Retrieve(c) ctx := c.Request.Context() sParam := util.PathParameter(c, "schedule") @@ -36,14 +35,7 @@ func Establish() gin.HandlerFunc { return } - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "org": r.GetOrg(), - "repo": r.GetName(), - "user": u.GetName(), - }).Debugf("reading schedule %s for repo %s", sParam, r.GetFullName()) + l.Debugf("reading schedule %s", sParam) s, err := database.FromContext(c).GetScheduleForRepo(ctx, r, sParam) if err != nil { @@ -53,6 +45,14 @@ func Establish() gin.HandlerFunc { return } + l = l.WithFields(logrus.Fields{ + "schedule": s.GetName(), + "schedule_id": s.GetID(), + }) + + // update the logger with the new fields + c.Set("logger", l) + ToContext(c, s) c.Next() } diff --git a/router/middleware/service/service.go b/router/middleware/service/service.go index 32142e16b..7089e22f7 100644 --- a/router/middleware/service/service.go +++ b/router/middleware/service/service.go @@ -14,7 +14,6 @@ import ( "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/library" ) @@ -28,10 +27,10 @@ func Retrieve(c *gin.Context) *library.Service { func Establish() gin.HandlerFunc { return func(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) b := build.Retrieve(c) o := org.Retrieve(c) r := repo.Retrieve(c) - u := user.Retrieve(c) ctx := c.Request.Context() if r == nil { @@ -64,16 +63,7 @@ func Establish() gin.HandlerFunc { return } - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "build": b.GetNumber(), - "org": o, - "service": number, - "repo": r.GetName(), - "user": u.GetName(), - }).Debugf("reading service %s/%d/%d", r.GetFullName(), b.GetNumber(), number) + l.Debugf("reading service %d", number) s, err := database.FromContext(c).GetServiceForBuild(ctx, b, number) if err != nil { @@ -83,6 +73,14 @@ func Establish() gin.HandlerFunc { return } + l = l.WithFields(logrus.Fields{ + "service": s.GetName(), + "service_id": s.GetID(), + }) + + // update the logger with the new fields + c.Set("logger", l) + ToContext(c, s) c.Next() } diff --git a/router/middleware/service/service_test.go b/router/middleware/service/service_test.go index 65869cea0..681975c36 100644 --- a/router/middleware/service/service_test.go +++ b/router/middleware/service/service_test.go @@ -10,6 +10,7 @@ import ( "testing" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" @@ -100,6 +101,7 @@ func TestService_Establish(t *testing.T) { context.Request, _ = http.NewRequest(http.MethodGet, "/foo/bar/builds/1/services/1", nil) // setup mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) engine.Use(org.Establish()) engine.Use(repo.Establish()) @@ -139,6 +141,7 @@ func TestService_Establish_NoRepo(t *testing.T) { context.Request, _ = http.NewRequest(http.MethodGet, "/foo/bar/builds/1/services/1", nil) // setup mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) engine.Use(Establish()) engine.GET("/:org/:repo/builds/:build/services/:service", func(c *gin.Context) { @@ -185,6 +188,7 @@ func TestService_Establish_NoBuild(t *testing.T) { context.Request, _ = http.NewRequest(http.MethodGet, "/foo/bar/builds/1/services/1", nil) // setup mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) engine.Use(org.Establish()) engine.Use(repo.Establish()) @@ -243,6 +247,7 @@ func TestService_Establish_NoServiceParameter(t *testing.T) { context.Request, _ = http.NewRequest(http.MethodGet, "/foo/bar/builds/1/services", nil) // setup mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) engine.Use(org.Establish()) engine.Use(repo.Establish()) @@ -302,6 +307,7 @@ func TestService_Establish_InvalidServiceParameter(t *testing.T) { context.Request, _ = http.NewRequest(http.MethodGet, "/foo/bar/builds/1/services/foo", nil) // setup mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) engine.Use(org.Establish()) engine.Use(repo.Establish()) @@ -358,6 +364,7 @@ func TestService_Establish_NoService(t *testing.T) { context.Request, _ = http.NewRequest(http.MethodGet, "/foo/bar/builds/1/services/1", nil) // setup mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) engine.Use(org.Establish()) engine.Use(repo.Establish()) diff --git a/router/middleware/step/step.go b/router/middleware/step/step.go index 77a710585..c1e31cf43 100644 --- a/router/middleware/step/step.go +++ b/router/middleware/step/step.go @@ -14,7 +14,6 @@ import ( "github.com/go-vela/server/router/middleware/build" "github.com/go-vela/server/router/middleware/org" "github.com/go-vela/server/router/middleware/repo" - "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/library" ) @@ -28,10 +27,10 @@ func Retrieve(c *gin.Context) *library.Step { func Establish() gin.HandlerFunc { return func(c *gin.Context) { // capture middleware values + l := c.MustGet("logger").(*logrus.Entry) b := build.Retrieve(c) o := org.Retrieve(c) r := repo.Retrieve(c) - u := user.Retrieve(c) ctx := c.Request.Context() if r == nil { @@ -64,16 +63,7 @@ func Establish() gin.HandlerFunc { return } - // update engine logger with API metadata - // - // https://pkg.go.dev/github.com/sirupsen/logrus?tab=doc#Entry.WithFields - logrus.WithFields(logrus.Fields{ - "build": b.GetNumber(), - "org": o, - "step": number, - "repo": r.GetName(), - "user": u.GetName(), - }).Debugf("reading step %s/%d/%d", r.GetFullName(), b.GetNumber(), number) + l.Debugf("reading step %d", number) s, err := database.FromContext(c).GetStepForBuild(ctx, b, number) if err != nil { @@ -83,6 +73,14 @@ func Establish() gin.HandlerFunc { return } + l = l.WithFields(logrus.Fields{ + "step": s.GetNumber(), + "step_id": s.GetID(), + }) + + // update the logger with the new fields + c.Set("logger", l) + ToContext(c, s) c.Next() } diff --git a/router/middleware/step/step_test.go b/router/middleware/step/step_test.go index b96141e5b..120170d04 100644 --- a/router/middleware/step/step_test.go +++ b/router/middleware/step/step_test.go @@ -10,6 +10,7 @@ import ( "testing" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" @@ -103,6 +104,7 @@ func TestStep_Establish(t *testing.T) { context.Request, _ = http.NewRequest(http.MethodGet, "/foo/bar/builds/1/steps/1", nil) // setup mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) engine.Use(org.Establish()) engine.Use(repo.Establish()) @@ -142,6 +144,7 @@ func TestStep_Establish_NoRepo(t *testing.T) { context.Request, _ = http.NewRequest(http.MethodGet, "/foo/bar/builds/1/steps/1", nil) // setup mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) engine.Use(Establish()) engine.GET("/:org/:repo/builds/:build/steps/:step", func(c *gin.Context) { @@ -191,6 +194,7 @@ func TestStep_Establish_NoBuild(t *testing.T) { context.Request, _ = http.NewRequest(http.MethodGet, "/foo/bar/builds/1/steps/1", nil) // setup mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) engine.Use(org.Establish()) engine.Use(repo.Establish()) @@ -249,6 +253,7 @@ func TestStep_Establish_NoStepParameter(t *testing.T) { context.Request, _ = http.NewRequest(http.MethodGet, "/foo/bar/builds/1/steps", nil) // setup mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) engine.Use(org.Establish()) engine.Use(repo.Establish()) @@ -308,6 +313,7 @@ func TestStep_Establish_InvalidStepParameter(t *testing.T) { context.Request, _ = http.NewRequest(http.MethodGet, "/foo/bar/builds/1/steps/foo", nil) // setup mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) engine.Use(org.Establish()) engine.Use(repo.Establish()) @@ -367,6 +373,7 @@ func TestStep_Establish_NoStep(t *testing.T) { context.Request, _ = http.NewRequest(http.MethodGet, "/foo/bar/builds/1/steps/1", nil) // setup mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) engine.Use(org.Establish()) engine.Use(repo.Establish()) diff --git a/router/middleware/user/user.go b/router/middleware/user/user.go index 89b286b08..cc883fd41 100644 --- a/router/middleware/user/user.go +++ b/router/middleware/user/user.go @@ -24,6 +24,7 @@ func Retrieve(c *gin.Context) *api.User { // Establish sets the user in the given context. func Establish() gin.HandlerFunc { return func(c *gin.Context) { + l := c.MustGet("logger").(*logrus.Entry) cl := claims.Retrieve(c) ctx := c.Request.Context() @@ -37,7 +38,7 @@ func Establish() gin.HandlerFunc { return } - logrus.Debugf("parsing user access token") + l.Debugf("parsing user access token") // lookup user in claims subject in the database u, err := database.FromContext(c).GetUserForName(ctx, cl.Subject) @@ -46,6 +47,14 @@ func Establish() gin.HandlerFunc { return } + l = l.WithFields(logrus.Fields{ + "user": u.GetName(), + "user_id": u.GetID(), + }) + + // update the logger with the new fields + c.Set("logger", l) + ToContext(c, u) c.Next() } diff --git a/router/middleware/user/user_test.go b/router/middleware/user/user_test.go index 8e15f80f7..28d7f7a3d 100644 --- a/router/middleware/user/user_test.go +++ b/router/middleware/user/user_test.go @@ -12,6 +12,7 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" @@ -111,6 +112,7 @@ func TestUser_Establish(t *testing.T) { client, _ := github.NewTest(s.URL) // setup vela mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) @@ -161,6 +163,7 @@ func TestUser_Establish_NoToken(t *testing.T) { context.Request, _ = http.NewRequest(http.MethodGet, "/users/foo", nil) // setup mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) @@ -198,6 +201,7 @@ func TestUser_Establish_DiffTokenType(t *testing.T) { context.Request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", secret)) // setup vela mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) engine.Use(func(c *gin.Context) { c.Set("token-manager", tm) }) engine.Use(claims.Establish()) @@ -251,6 +255,7 @@ func TestUser_Establish_NoAuthorizeUser(t *testing.T) { client, _ := github.NewTest("") // setup vela mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) engine.Use(func(c *gin.Context) { scm.ToContext(c, client) }) @@ -313,6 +318,7 @@ func TestUser_Establish_NoUser(t *testing.T) { client, _ := github.NewTest("") // setup vela mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { c.Set("secret", secret) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) engine.Use(func(c *gin.Context) { scm.ToContext(c, client) }) diff --git a/router/middleware/worker/worker.go b/router/middleware/worker/worker.go index d46ad1a1a..628ffb9f3 100644 --- a/router/middleware/worker/worker.go +++ b/router/middleware/worker/worker.go @@ -22,6 +22,7 @@ func Retrieve(c *gin.Context) *api.Worker { // Establish sets the worker in the given context. func Establish() gin.HandlerFunc { return func(c *gin.Context) { + l := c.MustGet("logger").(*logrus.Entry) ctx := c.Request.Context() wParam := util.PathParameter(c, "worker") @@ -32,7 +33,7 @@ func Establish() gin.HandlerFunc { return } - logrus.Debugf("Reading worker %s", wParam) + l.Debugf("reading worker %s", wParam) w, err := database.FromContext(c).GetWorkerForHostname(ctx, wParam) if err != nil { @@ -42,6 +43,14 @@ func Establish() gin.HandlerFunc { return } + l = l.WithFields(logrus.Fields{ + "worker": w.GetHostname(), + "worker_id": w.GetID(), + }) + + // update the logger with the new fields + c.Set("logger", l) + ToContext(c, w) c.Next() } diff --git a/router/middleware/worker/worker_test.go b/router/middleware/worker/worker_test.go index d39d43842..6ea01df56 100644 --- a/router/middleware/worker/worker_test.go +++ b/router/middleware/worker/worker_test.go @@ -10,6 +10,7 @@ import ( "testing" "github.com/gin-gonic/gin" + "github.com/sirupsen/logrus" api "github.com/go-vela/server/api/types" "github.com/go-vela/server/database" @@ -75,6 +76,7 @@ func TestWorker_Establish(t *testing.T) { context.Request, _ = http.NewRequest(http.MethodGet, "/workers/worker_0", nil) // setup mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) engine.Use(Establish()) engine.GET("/workers/:worker", func(c *gin.Context) { @@ -111,6 +113,7 @@ func TestWorker_Establish_NoWorkerParameter(t *testing.T) { context.Request, _ = http.NewRequest(http.MethodGet, "/workers/", nil) // setup mock server + engine.Use(func(c *gin.Context) { c.Set("logger", logrus.NewEntry(logrus.StandardLogger())) }) engine.Use(func(c *gin.Context) { database.ToContext(c, db) }) engine.Use(Establish()) engine.GET("/workers/:worker", func(c *gin.Context) { diff --git a/router/queue.go b/router/queue.go index 90452c2a8..5082a4284 100644 --- a/router/queue.go +++ b/router/queue.go @@ -12,7 +12,7 @@ import ( // QueueHandlers is a function that extends the provided base router group // with the API handlers for queue registration functionality. // -// POST /api/v1/queue/register. +// GET /api/v1/queue/info . func QueueHandlers(base *gin.RouterGroup) { // Queue endpoints _queue := base.Group("/queue") diff --git a/scm/github/deployment.go b/scm/github/deployment.go index 852ca0bb2..91357afa9 100644 --- a/scm/github/deployment.go +++ b/scm/github/deployment.go @@ -158,9 +158,10 @@ func (c *client) GetDeploymentList(ctx context.Context, u *api.User, r *api.Repo // CreateDeployment creates a new deployment for the GitHub repo. func (c *client) CreateDeployment(ctx context.Context, u *api.User, r *api.Repo, d *library.Deployment) error { c.Logger.WithFields(logrus.Fields{ - "org": r.GetOrg(), - "repo": r.GetName(), - "user": u.GetName(), + "org": r.GetOrg(), + "repo": r.GetName(), + "user": u.GetName(), + "user_id": u.GetID(), }).Tracef("creating deployment for repo %s", r.GetFullName()) // create GitHub OAuth client with user's token diff --git a/scm/github/repo.go b/scm/github/repo.go index c3b7ab7c9..8c0a58457 100644 --- a/scm/github/repo.go +++ b/scm/github/repo.go @@ -25,7 +25,7 @@ func (c *client) ConfigBackoff(ctx context.Context, u *api.User, r *api.Repo, re retryLimit := 5 for i := 0; i < retryLimit; i++ { - logrus.Debugf("Fetching config file - Attempt %d", i+1) + logrus.Debugf("fetching config file - Attempt %d", i+1) // attempt to fetch the config data, err = c.Config(ctx, u, r, ref)