Skip to content

Commit

Permalink
Merge branch 'main' into feat/dashboard/poc
Browse files Browse the repository at this point in the history
  • Loading branch information
ecrupper committed Dec 19, 2023
2 parents 1f18c30 + 2dd31d6 commit c1150d7
Show file tree
Hide file tree
Showing 46 changed files with 741 additions and 154 deletions.
36 changes: 32 additions & 4 deletions .github/workflows/integration-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,19 @@ on:

# pipeline to execute
jobs:
database:
database_postgres:
runs-on: ubuntu-latest

strategy:
matrix:
# support should be n-1 here
postgres_version:
- postgres:15-alpine
- postgres:16-alpine

services:
postgres:
image: postgres:15-alpine@sha256:35ce2187f2f7fb75e8e79493e13743596c21eb3789ff41ece145ae04d06e93a5
image: ${{ matrix.postgres_version }}
env:
POSTGRES_DB: vela
POSTGRES_PASSWORD: notARealPassword12345
Expand All @@ -30,6 +37,27 @@ jobs:

env:
POSTGRES_ADDR: postgres://vela:notARealPassword12345@localhost:5432/vela

steps:
- name: clone
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4

- name: install go
uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4
with:
# use version from go.mod file
go-version-file: 'go.mod'
cache: true
check-latest: true

- name: testing with ${{ matrix.postgres_version }}
run: |
DB_DRIVER=postgres make integration-test
database_sql:
runs-on: ubuntu-latest

env:
SQLITE_ADDR: vela.db

steps:
Expand All @@ -44,6 +72,6 @@ jobs:
cache: true
check-latest: true

- name: test
- name: testing with sqlite
run: |
make integration-test
DB_DRIVER=sqlite make integration-test
27 changes: 20 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,25 @@ fix:
@echo "### Fixing Go Code"
@go fix ./...

# The `integration-test` target is intended to run all integration tests for the Go source code.
# The `integration-test` target is intended to run all database integration
# tests for the Go source code.
#
# Optionally target specific database drivers by passing a variable
# named "DB_DRIVER" to the make command. This assumes that test names
# coincide with database driver names.
#
# Example: "DB_DRIVER=postgres make integration-test"
# will only run integration tests for the postgres driver.
.PHONY: integration-test
integration-test:
@echo
@echo "### Integration Testing"
INTEGRATION=1 go test -run TestDatabase_Integration ./...
@if [ -n "$(DB_DRIVER)" ]; then \
echo "### DB Integration Testing ($(DB_DRIVER))"; \
INTEGRATION=1 go test -run TestDatabase_Integration/$(DB_DRIVER) ./...; \
else \
echo "### DB Integration Testing"; \
INTEGRATION=1 go test -run TestDatabase_Integration ./...; \
fi

# The `test` target is intended to run
# the tests for the Go source code.
Expand Down Expand Up @@ -227,7 +240,7 @@ bump-deps-full: check
pull:
@echo
@echo "### Pulling images for docker-compose stack"
@docker-compose pull
@docker compose pull

# The `compose-up` target is intended to build and create
# all containers for the local Docker compose stack.
Expand All @@ -237,7 +250,7 @@ pull:
compose-up:
@echo
@echo "### Creating containers for docker-compose stack"
@docker-compose -f docker-compose.yml up -d --build
@docker compose -f docker-compose.yml up -d --build

# The `compose-down` target is intended to destroy
# all containers for the local Docker compose stack.
Expand All @@ -247,7 +260,7 @@ compose-up:
compose-down:
@echo
@echo "### Destroying containers for docker-compose stack"
@docker-compose -f docker-compose.yml down
@docker compose -f docker-compose.yml down

# The `spec-install` target is intended to install the
# the needed dependencies to generate the api spec.
Expand Down Expand Up @@ -322,4 +335,4 @@ spec: spec-gen spec-version-update spec-validate
lint:
@echo
@echo "### Linting Go Code"
@golangci-lint run ./...
@golangci-lint run ./...
130 changes: 130 additions & 0 deletions api/build/approve.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
// SPDX-License-Identifier: Apache-2.0

package build

import (
"fmt"
"net/http"
"strings"
"time"

"github.com/gin-gonic/gin"
"github.com/go-vela/server/database"
"github.com/go-vela/server/queue"
"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/sirupsen/logrus"
)

// swagger:operation POST /api/v1/repos/{org}/{repo}/builds/{build}/approve builds ApproveBuild
//
// Sign off on a build to run from an outside contributor
//
// ---
// produces:
// - application/json
// parameters:
// - in: path
// name: org
// description: Name of the org
// required: true
// type: string
// - in: path
// name: repo
// description: Name of the repo
// required: true
// type: string
// - in: path
// name: build
// description: Build number to retrieve
// required: true
// type: integer
// security:
// - ApiKeyAuth: []
// responses:
// '200':
// 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
// schema:
// "$ref": "#/definitions/Error"
// '404':
// description: Unable to create the build
// schema:
// "$ref": "#/definitions/Error"
// '500':
// description: Unable to create the build
// schema:
// "$ref": "#/definitions/Error"

// CreateBuild 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)
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(),
})

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)

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())
if err != nil {
retErr := fmt.Errorf("unable to get owner for %s: %w", r.GetFullName(), err)

util.HandleError(c, http.StatusBadRequest, retErr)

return
}

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)
if err != nil {
logrus.Errorf("Failed to update build %d during publish to queue for %s: %v", b.GetNumber(), r.GetFullName(), err)
}

// publish the build to the queue
go PublishToQueue(
ctx,
queue.FromGinContext(c),
database.FromContext(c),
b,
r,
u,
b.GetHost(),
)

c.JSON(http.StatusOK, fmt.Sprintf("Successfully approved build %s/%d", r.GetFullName(), b.GetNumber()))
}
3 changes: 2 additions & 1 deletion api/build/cancel.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ func CancelBuild(c *gin.Context) {
return
}
}
case constants.StatusPending:
case constants.StatusPending, constants.StatusPendingApproval:
break

default:
Expand All @@ -198,6 +198,7 @@ func CancelBuild(c *gin.Context) {
// build has been abandoned
// update the status in the build table
b.SetStatus(constants.StatusCanceled)
b.SetError(fmt.Sprintf("build was canceled by %s", user.GetName()))

b, err := database.FromContext(c).UpdateBuild(ctx, b)
if err != nil {
Expand Down
24 changes: 23 additions & 1 deletion api/build/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -348,15 +348,37 @@ func CreateBuild(c *gin.Context) {
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)
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
}

// publish the build to the queue
go PublishToQueue(
ctx,
queue.FromGinContext(c),
database.FromContext(c),
p,
input,
r,
u,
route,
)
}

Expand Down
37 changes: 37 additions & 0 deletions api/build/executable.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
package build

import (
"context"
"encoding/json"
"fmt"
"net/http"

Expand All @@ -13,6 +15,8 @@ import (
"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"
"github.com/go-vela/types/pipeline"
"github.com/sirupsen/logrus"
)

Expand Down Expand Up @@ -91,3 +95,36 @@ func GetBuildExecutable(c *gin.Context) {

c.JSON(http.StatusOK, bExecutable)
}

// 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 {
// 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)

// error out the build
CleanBuild(ctx, db, b, nil, nil, err)

return err
}

// create build executable to push to database
bExecutable := new(library.BuildExecutable)
bExecutable.SetBuildID(b.GetID())
bExecutable.SetData(byteExecutable)

// 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)

// error out the build
CleanBuild(ctx, db, b, nil, nil, err)

return err
}

return nil
}
2 changes: 1 addition & 1 deletion api/build/get_id.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ func GetBuildByID(c *gin.Context) {

// 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, u.GetToken(), r.GetOrg(), r.GetName())
perm, err := scm.FromContext(c).RepoAccess(ctx, u.GetName(), u.GetToken(), r.GetOrg(), r.GetName())
if err != nil {
logrus.Errorf("unable to get user %s access level for repo %s", u.GetName(), r.GetFullName())
}
Expand Down
Loading

0 comments on commit c1150d7

Please sign in to comment.