Skip to content

Conversation

@fiftin
Copy link
Collaborator

@fiftin fiftin commented Nov 25, 2025

COMPOSER 1

Adds a Workflow feature to Semaphore UI, allowing users to define and execute multi-step automation pipelines with conditional logic.


Open in Cursor Open in Web

Adds workflow creation, editing, and execution.

Co-authored-by: denguk <denguk@gmail.com>
@cursor
Copy link

cursor bot commented Nov 25, 2025

Cursor Agent can help with this pull request. Just @cursor in comments and I'll start working on changes in this branch.
Learn more about Cursor Agents


// GetWorkflow returns a workflow by ID
func GetWorkflow(w http.ResponseWriter, r *http.Request) {
project := helpers.GetFromContext(r, "project").(db.Project)
// RunWorkflow starts a workflow execution
func (e *WorkflowEngine) RunWorkflow(projectID int, workflowID int, userID *int) (*db.WorkflowRun, error) {
// Get workflow with nodes and links
workflow, err := e.store.GetWorkflow(projectID, workflowID)
newWorkflow: 'New Workflow',
editWorkflow: 'Edit Workflow',
workflowSaved: 'Workflow saved successfully',
run: 'Run',
@fiftin fiftin marked this pull request as ready for review November 25, 2025 06:08
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +13 to +22
func (d *BoltDb) GetWorkflows(projectID int) ([]db.Workflow, error) {
var workflows []db.Workflow
err := d.getObjects(projectID, "workflows", &workflows)
return workflows, err
}

func (d *BoltDb) GetWorkflow(projectID int, workflowID int) (db.Workflow, error) {
var workflow db.Workflow
err := d.getObject(projectID, "workflows", workflowID, &workflow)
if err != nil {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P0 Badge Bolt workflow store fails to compile

The new Bolt implementation calls getObjects/getObject with string literals and only three arguments (e.g., d.getObjects(projectID, "workflows", &workflows)), but the existing helpers are typed as getObjects(bucketID int, props db.ObjectProps, params db.RetrieveQueryParams, …) and require a db.ObjectProps plus the params/filter arguments. Because of the mismatched argument count and type, this file will not compile, so the Bolt build of the server is broken.

Useful? React with 👍 / 👎.

Comment on lines +233 to +285
for _, node := range payload.Nodes {
node.WorkflowID = workflow.ID
if node.ID > 0 && existingNodeMap[node.ID] {
// Update existing node
if err := store.UpdateWorkflowNode(node); err != nil {
helpers.WriteError(w, err)
return
}
} else {
// Create new node
node.ID = 0
_, err := store.CreateWorkflowNode(node)
if err != nil {
helpers.WriteError(w, err)
return
}
}
}

// Delete nodes that are no longer in the payload
for _, existingNode := range existingNodes {
found := false
for _, node := range payload.Nodes {
if node.ID == existingNode.ID {
found = true
break
}
}
if !found {
if err := store.DeleteWorkflowNode(workflow.ID, existingNode.ID); err != nil {
helpers.WriteError(w, err)
return
}
}
}

// Delete all existing links
for _, link := range existingLinks {
if err := store.DeleteWorkflowLink(workflow.ID, link.ID); err != nil {
helpers.WriteError(w, err)
return
}
}

// Create new links
for _, link := range payload.Links {
link.WorkflowID = workflow.ID
link.ID = 0
_, err := store.CreateWorkflowLink(link)
if err != nil {
helpers.WriteError(w, err)
return
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Links cannot be created to newly added workflow nodes

When updating a workflow, new nodes are inserted with node.ID set to 0 and the returned IDs are ignored, yet all existing links are deleted and recreated from the original payload IDs. Any save that introduces a new node and a link to it in the same request will therefore try to insert links that reference the old negative/zero IDs, triggering foreign‑key errors and leaving the workflow with its previous links dropped. The frontend always submits nodes and links together, so creating or wiring new nodes currently fails.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants