Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: GoTest and Build Docker Image Test

on:
push:
branches:
- '**'

jobs:
test:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: 1.23

- name: Cache Go modules
uses: actions/cache@v3
with:
path: |
~/.cache/go-build
~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-

- name: Install dependencies
run: go mod tidy

- name: Run unit tests
run: go test ./... -v

docker-image-build:
runs-on: ubuntu-latest
needs: test

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Build Docker image
run: |
docker build -t server-controller:latest .
docker images server-controller:latest --format "Image Size: {{.Size}}"
13 changes: 13 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FROM golang:1.23.0-alpine3.20 as builder
WORKDIR /app

COPY go.mod go.sum ./
RUN go mod download

COPY ./ ./
RUN CGO_ENABLED=0 GOOS=linux go build -o /main ./main.go

FROM alpine:3.20
WORKDIR /app

COPY --from=builder /main ./main
3 changes: 3 additions & 0 deletions app/grpc/grpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/ideagate/server-controller/domain/entrypoint"
projectrepositorysql "github.com/ideagate/server-controller/domain/project/repository/sql"
projectusecase "github.com/ideagate/server-controller/domain/project/usecase"
"github.com/ideagate/server-controller/domain/workflow"
"github.com/ideagate/server-controller/infrastructure"
"github.com/improbable-eng/grpc-web/go/grpcweb"
"github.com/urfave/cli/v2"
Expand Down Expand Up @@ -101,6 +102,7 @@ type DashboardServiceServer struct {
usecaseProject projectusecase.ProjectUsecase
usecaseApplication appusecase.ApplicationUsecase
domainEntrypoint entrypoint.Domain
domainWorkflow workflow.Domain
}

func NewDashboardServiceServer(infra *infrastructure.Infrastructure) *DashboardServiceServer {
Expand All @@ -114,6 +116,7 @@ func NewDashboardServiceServer(infra *infrastructure.Infrastructure) *DashboardS

return &DashboardServiceServer{
domainEntrypoint: entrypoint.New(infra.Postgres),
domainWorkflow: workflow.New(infra.Postgres),

// TODO: change using domain initialization like entrypoint
usecaseProject: usecaseProject,
Expand Down
118 changes: 118 additions & 0 deletions app/grpc/workflow.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package grpc

import (
"context"

"github.com/ideagate/core/utils"
"github.com/ideagate/core/utils/errors"
pbendpoint "github.com/ideagate/model/gen-go/core/endpoint"
"github.com/ideagate/model/gen-go/dashboard"
"github.com/ideagate/server-controller/domain/workflow/usecase"
)

func (s *DashboardServiceServer) GetWorkflows(ctx context.Context, req *dashboard.GetWorkflowsRequest) (*dashboard.GetWorkflowsResponse, error) {
// Request validation
if req.GetProjectId() == "" || req.GetApplicationId() == "" || req.GetEntrypointId() == "" {
return nil, errors.New("project_id, application_id, entrypoint_id are required")
}

// Check if getting a specific workflow
if req.GetVersion() != 0 {
resultWorkflow, err := s.domainWorkflow.GetWorkflow(ctx, &usecase.GetWorkflowRequest{
ProjectID: req.GetProjectId(),
ApplicationID: req.GetApplicationId(),
EntrypointID: req.GetEntrypointId(),
Version: req.GetVersion(),
})
if err != nil {
return nil, err
}

return &dashboard.GetWorkflowsResponse{
Workflows: []*pbendpoint.Workflow{resultWorkflow.Workflow},
}, nil
}

// Get list of workflows
requestWorkflows := &usecase.GetWorkflowsRequest{
ProjectID: req.GetProjectId(),
ApplicationID: req.GetApplicationId(),
EntrypointID: req.GetEntrypointId(),
}

resultWorkflows, err := s.domainWorkflow.GetWorkflows(ctx, requestWorkflows)
if err != nil {
return nil, err
}

return &dashboard.GetWorkflowsResponse{
Workflows: resultWorkflows.Workflows,
}, nil
}

func (s *DashboardServiceServer) CreateWorkflow(ctx context.Context, req *dashboard.CreateWorkflowRequest) (*dashboard.CreateWorkflowResponse, error) {
// Request validation
if req.GetProjectId() == "" || req.GetApplicationId() == "" || req.GetEntrypointId() == "" {
return nil, errors.New("project_id, application_id, entrypoint_id are required")
}

// Create workflow
requestCreate := &usecase.CreateWorkflowRequest{
ProjectID: req.GetProjectId(),
ApplicationID: req.GetApplicationId(),
EntrypointID: req.GetEntrypointId(),
}

if req.GetFromVersion() != 0 {
requestCreate.FromVersion = utils.ToPtr(req.GetFromVersion())
}

responseCreate, err := s.domainWorkflow.CreateWorkflow(ctx, requestCreate)
if err != nil {
return nil, err
}

return &dashboard.CreateWorkflowResponse{
Version: responseCreate.Version,
}, nil
}

func (s *DashboardServiceServer) UpdateWorkflow(ctx context.Context, req *dashboard.UpdateWorkflowRequest) (*dashboard.UpdateWorkflowResponse, error) {
// Request validation
workflow := req.GetWorkflow()
if workflow.GetProjectId() == "" || workflow.GetApplicationId() == "" || workflow.GetEntrypointId() == "" {
return nil, errors.New("project_id, application_id, entrypoint_id are required")
}

// Update workflow
requestUpdate := &usecase.UpdateWorkflowRequest{
Workflow: workflow,
}

if _, err := s.domainWorkflow.UpdateWorkflow(ctx, requestUpdate); err != nil {
return nil, err
}

return &dashboard.UpdateWorkflowResponse{}, nil
}

func (s *DashboardServiceServer) DeleteWorkflow(ctx context.Context, req *dashboard.DeleteWorkflowRequest) (*dashboard.DeleteWorkflowResponse, error) {
// Request validation
if req.GetProjectId() == "" || req.GetApplicationId() == "" || req.GetEntrypointId() == "" || req.GetVersion() == 0 {
return nil, errors.New("project_id, application_id, entrypoint_id and version are required")
}

// Delete workflow
requestDelete := &usecase.DeleteWorkflowRequest{
ProjectID: req.GetProjectId(),
ApplicationID: req.GetApplicationId(),
EntrypointID: req.GetEntrypointId(),
Version: req.GetVersion(),
}

if err := s.domainWorkflow.DeleteWorkflow(ctx, requestDelete); err != nil {
return nil, err
}

return &dashboard.DeleteWorkflowResponse{}, nil
}
14 changes: 0 additions & 14 deletions domain/application/model/application.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,17 +60,3 @@ type Endpoint struct {
func (e *Endpoint) TableName() string {
return "endpoint"
}

type Workflow struct {
Version int
EndpointID string
ApplicationID string
ProjectID string
CreatedAt time.Time
UpdatedAt time.Time
Data pgtype.JSONB `gorm:"type:jsonb"`
}

func (w *Workflow) TableName() string {
return "workflow"
}
10 changes: 0 additions & 10 deletions domain/entrypoint/model/error.go

This file was deleted.

11 changes: 6 additions & 5 deletions domain/entrypoint/usecase/usecase.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import (
"context"

"github.com/ideagate/core/utils"
pbEndpoint "github.com/ideagate/model/gen-go/core/endpoint"
"github.com/ideagate/server-controller/domain/entrypoint/model"
pbendpoint "github.com/ideagate/model/gen-go/core/endpoint"
modelentrypoint "github.com/ideagate/server-controller/domain/entrypoint/model"
"github.com/ideagate/server-controller/domain/entrypoint/repository/sql"
"github.com/ideagate/server-controller/model"
)

func New(repoSql sql.Repository) *Usecase {
Expand All @@ -31,14 +32,14 @@ func (u *Usecase) GetListEntrypoint(ctx context.Context, req *GetListEntrypointR
resultRepo, err := u.repoSql.GetListEntrypoint(ctx, &sql.GetListEntrypointRequest{
ProjectID: req.ProjectID,
ApplicationID: req.ApplicationID,
Type: utils.ToPtr(model.EntryPointRest.String()),
Type: utils.ToPtr(modelentrypoint.EntryPointRest.String()),
})
if err != nil {
return nil, err
}

result := &GetListEntrypointResponse{
Entrypoints: make([]*pbEndpoint.Endpoint, len(resultRepo)),
Entrypoints: make([]*pbendpoint.Endpoint, len(resultRepo)),
}

for i := 0; i < len(resultRepo); i++ {
Expand Down Expand Up @@ -94,7 +95,7 @@ func (u *Usecase) CreateEntrypoint(ctx context.Context, req *CreateEntrypointReq
}

// Create entrypoint
var entrypointData model.Entrypoint
var entrypointData modelentrypoint.Entrypoint
entrypointData.FromProto(req.Entrypoint)

if err := u.repoSql.CreateEntrypoint(ctx, &sql.CreateEntrypointRequest{
Expand Down
68 changes: 68 additions & 0 deletions domain/workflow/model/workflow.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package model

import (
"time"

pbendpoint "github.com/ideagate/model/gen-go/core/endpoint"
"google.golang.org/protobuf/types/known/timestamppb"
"gorm.io/datatypes"
"gorm.io/gorm"
)

type Workflow struct {
Version int64 `json:"version"`
EntrypointID string `json:"entrypoint_id"`
ApplicationID string `json:"application_id"`
ProjectID string `json:"project_id"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Data datatypes.JSONType[WorkflowData] `json:"data"`
}

type WorkflowData struct {
Steps []*pbendpoint.Step `json:"steps"`
Edges []*pbendpoint.Edge `json:"edges"`
}

func (w *Workflow) TableName() string {
return "workflow"
}

func (w *Workflow) BeforeCreate(_ *gorm.DB) error {
w.CreatedAt = time.Now()
w.UpdatedAt = time.Now()
return nil
}

func (w *Workflow) BeforeUpdate(_ *gorm.DB) error {
w.UpdatedAt = time.Now()
return nil
}

func (w *Workflow) ToProto() *pbendpoint.Workflow {
data := w.Data.Data()

return &pbendpoint.Workflow{
Version: w.Version,
EntrypointId: w.EntrypointID,
ApplicationId: w.ApplicationID,
ProjectId: w.ProjectID,
CreatedAt: timestamppb.New(w.CreatedAt),
UpdatedAt: timestamppb.New(w.UpdatedAt),
Steps: data.Steps,
Edges: data.Edges,
}
}

func (w *Workflow) FromProto(workflow *pbendpoint.Workflow) {
w.Version = workflow.Version
w.EntrypointID = workflow.EntrypointId
w.ApplicationID = workflow.ApplicationId
w.ProjectID = workflow.ProjectId
w.CreatedAt = workflow.CreatedAt.AsTime()
w.UpdatedAt = workflow.UpdatedAt.AsTime()
w.Data = datatypes.NewJSONType(WorkflowData{
Steps: workflow.Steps,
Edges: workflow.Edges,
})
}
Loading