Skip to content

Commit 766ae00

Browse files
committed
Feature: Workflows
Allow basic CRUD of workflows and stages, linking to projects and moving tasks around. Only a minimum set of fields are exposed since the API is not public available yet.
1 parent 5244813 commit 766ae00

14 files changed

Lines changed: 2239 additions & 0 deletions

projects/main_test.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ var testResources struct {
2727
MilestoneID int64
2828
TagID int64
2929
MessageID int64
30+
WorkflowID int64
31+
WorkflowStageID int64
3032
}
3133

3234
func TestMain(m *testing.M) {
@@ -154,6 +156,41 @@ func TestMain(m *testing.M) {
154156
defer messageCleanup()
155157
testResources.MessageID = messageID
156158

159+
workflowID, workflowCleanup, err := createWorkflow(testEngine)
160+
if err != nil {
161+
logger.Error("Failed to create workflow for tests",
162+
slog.String("error", err.Error()),
163+
)
164+
exitCode = 1
165+
return
166+
}
167+
defer workflowCleanup()
168+
testResources.WorkflowID = workflowID
169+
170+
_, err = projects.WorkflowProjectLink(
171+
testEngine.Context(),
172+
engine,
173+
projects.NewWorkflowProjectLinkRequest(workflowID, projectID),
174+
)
175+
if err != nil {
176+
logger.Error("Failed to link project to workflow for tests",
177+
slog.String("error", err.Error()),
178+
)
179+
exitCode = 1
180+
return
181+
}
182+
183+
workflowStageID, workflowStageCleanup, err := createWorkflowStage(testEngine, workflowID)
184+
if err != nil {
185+
logger.Error("Failed to create workflow stage for tests",
186+
slog.String("error", err.Error()),
187+
)
188+
exitCode = 1
189+
return
190+
}
191+
defer workflowStageCleanup()
192+
testResources.WorkflowStageID = workflowStageID
193+
157194
exitCode = m.Run()
158195
}
159196

@@ -570,6 +607,41 @@ func createMessageReply(t testEngine, messageID int64) (int64, func(), error) {
570607
}, nil
571608
}
572609

610+
func createWorkflow(t testEngine) (int64, func(), error) {
611+
workflow, err := projects.WorkflowCreate(t.Context(), engine, projects.NewWorkflowCreateRequest(
612+
fmt.Sprintf("test%d%d", time.Now().UnixNano(), rand.Intn(100)),
613+
))
614+
if err != nil {
615+
return 0, nil, fmt.Errorf("failed to create workflow for test: %w", err)
616+
}
617+
id := workflow.Workflow.ID
618+
return id, func() {
619+
ctx := context.Background() // t.Context is always canceled in cleanup
620+
_, err := projects.WorkflowDelete(ctx, engine, projects.NewWorkflowDeleteRequest(id))
621+
if err != nil {
622+
t.Errorf("failed to delete workflow after test: %s", err)
623+
}
624+
}, nil
625+
}
626+
627+
func createWorkflowStage(t testEngine, workflowID int64) (int64, func(), error) {
628+
stage, err := projects.WorkflowStageCreate(t.Context(), engine, projects.NewWorkflowStageCreateRequest(
629+
workflowID,
630+
fmt.Sprintf("test%d%d", time.Now().UnixNano(), rand.Intn(100)),
631+
))
632+
if err != nil {
633+
return 0, nil, fmt.Errorf("failed to create workflow stage for test: %w", err)
634+
}
635+
id := stage.Stage.ID
636+
return id, func() {
637+
ctx := context.Background() // t.Context is always canceled in cleanup
638+
_, err := projects.WorkflowStageDelete(ctx, engine, projects.NewWorkflowStageDeleteRequest(workflowID, id))
639+
if err != nil {
640+
t.Errorf("failed to delete workflow stage after test: %s", err)
641+
}
642+
}, nil
643+
}
644+
573645
type testEngine interface {
574646
Context() context.Context
575647
Errorf(string, ...any)

projects/task.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ type Task struct {
8585
// can be started or completed.
8686
Predecessors []twapi.Relationship `json:"predecessors"`
8787

88+
// WorkflowStages is the list of workflow stages associated with this task.
89+
WorkflowStages []TaskWorkflowStage `json:"workflowStages"`
90+
8891
// CreatedBy is the ID of the user who created the task.
8992
CreatedBy *int64 `json:"createdBy"`
9093

@@ -146,6 +149,19 @@ type TaskPredecessor struct {
146149
Type TaskPredecessorType `json:"type"`
147150
}
148151

152+
// TaskWorkflowStage represents the workflow stage associated with a task. This
153+
// is used when creating or updating a task to set the workflow stage of the
154+
// task.
155+
type TaskWorkflowStage struct {
156+
// WorkflowID is the unique identifier of the workflow associated with the
157+
// task.
158+
WorkflowID *int64 `json:"workflowId"`
159+
160+
// StageID is the unique identifier of the workflow stage associated with the
161+
// task.
162+
StageID *int64 `json:"stageId"`
163+
}
164+
149165
// TaskUpdateRequestPath contains the path parameters for creating a
150166
// task.
151167
type TaskCreateRequestPath struct {

0 commit comments

Comments
 (0)