-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Implement workflow system for semaphore ui #3486
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Implement workflow system for semaphore ui #3486
Conversation
Adds workflow creation, editing, and execution. Co-authored-by: denguk <denguk@gmail.com>
|
Cursor Agent can help with this pull request. Just |
|
|
||
| // 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) |
There was a problem hiding this 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".
| 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 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 👍 / 👎.
| 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 | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 👍 / 👎.
COMPOSER 1
Adds a Workflow feature to Semaphore UI, allowing users to define and execute multi-step automation pipelines with conditional logic.