Closed DhruvBarot closed 3 months ago
Hello @DhruvBarot, and thanks for you interest in the Serverless Workflow DSL.
There are a couple of use cases that are not possible with the current spec
Unless I'm missing something from your use case, it is actually totally feasible with the current version of the DSL. As far I understand it, you could even achieve your goals in a plethora of different ways.
Here follows a sample workflow that does what you are asking, AFAIK:
document:
dsl: '1.0.0'
namespace: default
name: manage-github-issues
version: '0.1.0'
schedule:
on:
one:
with:
type: com.github.events.issues.opened.v1
data: ${ .data.author.team == "QA" }
do:
- initialize: #use to pull up data from the trigger event
set:
issue: ${ $workflow.input.events[0].data }
export:
as: .issue
- awaitForDevWork:
do:
- assign: #not required, it's only used to provide additional contextual data and set custom status
set:
issue:
assignedTo: DevTeam
status: inProgress
- notify: #can be replaced with an API call
emit:
event:
with:
source: https://serverlessworkflow.io
type: com.github.events.issues.assignedToDevTeam.v1
data:
issue: ${ .issue }
- await:
listen:
to:
one:
with:
type: com.github.events.issues.devWorkCompleted.v1
export:
as: '$context + { issue: ($context.issue + { action: .data.nextAction, dev: .data.dev }) }'
then: evaluateDevWorkOutcome
- evaluateDevWorkOutcome:
switch:
- review:
when: $context.issue.action == "review"
then: reviewIssue
- requestDetails:
when: $context.issue.action == "requestDetails"
then: awaitDetailsFromQA
- default:
then: raiseUnsupportedActionError
- awaitDetailsFromQA:
do:
- assign: #not required, it's only used to provide additional contextual data and set custom status
set:
issue:
assignedTo: QA
status: awaitingDetails
assignTo: ${ $context.issue.author }
- notify: #can be replaced with an API call
emit:
event:
with:
source: https://serverlessworkflow.io
type: com.github.events.issues.assignedToQATeam.v1
data:
issue: ${ $context.issue }
- await:
listen:
to:
one:
with:
type: com.github.events.issues.detailsProvided.v1
export:
as: '$context + { issue: ($context.issue + { action: .data.nextAction }) }'
then: awaitForDevWork
- reviewIssue:
do:
- assign: #not required, it's only used to provide additional contextual data and set custom status
set:
issue:
assignedTo: DevTeam
status: reviewing
- notify: #can be replaced with an API call
emit:
event:
with:
source: https://serverlessworkflow.io
type: com.github.events.issues.pendingReview.v1
data:
issue: ${ $context.issue }
review:
exclude: ${ $context.issue.dev }
- await:
listen:
to:
one:
with:
type: com.github.events.issues.reviewed.v1
export:
as: '$context + { issue: ($context.issue + { reviewer: .data.reviewer }) }'
- validateReview:
switch:
- reviewerIsNotAssignedDev:
when: $context.issue.reviewer != $context.issue.dev
then: evaluateReview
- reviewerIsAssignedDev:
then: raiseAssignedDevCannotBeReviewer
- evaluateReview:
do:
- assign: #not required, it's only used to provide additional contextual data and set custom status
set:
issue:
assignedTo: QA
status: evaluating
- notify: #can be replaced with an API call
emit:
event:
with:
source: https://serverlessworkflow.io
type: com.github.events.issues.evaluateReview.v1
data:
issue: ${ $context.issue }
assignTo: ${ $context.issue.author }
- await:
listen:
to:
one:
with:
type: com.github.events.issues.evaluated.v1
export:
as: '$context + { issue: ($context.issue + { action: .data.nextAction }) }'
- evaluate:
switch:
- closeIssue:
when: $context.issue.action == "close"
then: closeIssue
- default:
then: exit
- closeIssue:
do:
- initialize: #the only purpose of this step is to pull up data at top level so it can be used in URI interpolation without having to rely on expressions
set:
organization: ${ $context.issue.repository.organization }
repository: ${ $context.issue.repository.name }
issueNumber: ${ $context.issue.number }
- closeIssueOnGithub:
call: http
with:
endpoint: https://api.github.com/repos/{organization}/{repository}/issues/{issueNumber} #here we are using URI interpolation thanks to the top level data pulled up by initialize
method: patch
body:
state: closed
- setIssueInfo: #not required, it's only used to provide additional contextual data and set custom status
set:
issue:
status: closed
- notify: #can be replaced with an API call
emit:
event:
with:
source: https://serverlessworkflow.io
type: com.github.events.issues.closed.v1
data:
issue: ${ $context.issue }
then: end
then: awaitForDevWork
- raiseUnsupportedActionError:
raise:
error:
type: https://serverlessworkflow.io/spec/1.0.0/errors/runtime
status: 400
title: Unsupported Action
detail: The specified action is not supported in this context
then: end
- raiseAssignedDevCannotBeReviewer:
raise:
error:
type: https://serverlessworkflow.io/spec/1.0.0/errors/runtime
status: 400
title: Invalid Reviewer
detail: The developper that has performed the work associated with the issue cannot be the reviewer of its own work
then: end
Here's a small summary of what the above workflow does:
Issue Initialization:
Assigning the Issue to Dev Team:
inProgress
. The system sends a notification that the issue is now assigned to the Dev team.Evaluating Dev Work Outcome:
Requesting Details from QA:
awaitingDetails
. The workflow waits for the QA team to provide the requested information, after which the issue is reassigned to the Dev team for further work.Reviewing the Issue:
reviewing
.Evaluating the Review:
evaluating
.Handling Errors:
Unsupported Action
error.Invalid Reviewer
error.inProgress
, awaitingDetails
, reviewing
, and evaluating
to track the progress of the issue.Here's the graph of the workflow, as rendered by Synapse:
P.S.1: In the future, please try to stick to the supplied issue templates, as this greatly facilitates book keeping 😉
P.S.2: I see that you are a .NET developper. As such, you might be interested in Synapse, instead of factoring your own runtime. If that's not the case, however, and if you want/need to develop your own runtime, we warmly invite you to open an issue asking to advertize it as a ServerlessWorkflow runtime/implementation. In the same spirit, and as we are aiming for incubation, it would be greatly appreciated if your organisation would advertize SW adoption. If that's the case, please open a PR with your org's description and logo, so that we can add it to the website and the readme.
P.S.3: If not already done, please do star the project, it helps us gain visibility. Additionally, you can also follow us on LinkedIn and/or X 😉
@cdavernas : Thanks for your detailed explanation, I will try to based on your input, If there is any problem then I will update it on the same issue or create a new issue based on templates.
P.S.2 : We already have temporal as a workflow engine, so we are just creating a bridge between serverless workflow DSL and temporal.
@DhruvBarot hi! Even if it's just a bridge, we would appreciate it if you could add it to the adoption section of our website once you understand the project helped your team. Thank you!
@cdavernas / @ricardozanini : Can you please help me with the Synapse version? I was not able to get a diagram from the workflow, which is created by me as I tried the workflow definition shared by you, For both getting some errors and the diagram is not rendered.
P.S I am using the latest docker for running Synapse.
@DhruvBarot Are you using Synapse 1.0.0-alpha1?
What is the error(s) you are facing?
Are you using Synapse 1.0.0-alpha1?
I am using the latest docker image from Synapase, Do I need to build the solution and run from the 1.0.0-alpha1 branch?
What is the error(s) you are facing?
There is no error on the UI.
I am using the latest docker image from Synapse, Do I need to build the solution and run from the 1.0.0-alpha1 branch?
You need to build version 1.0.0-alpha1
, it hasn't been released yet. You can check the wiki (docker-compose dev install) on how to get started. Please be aware that links in the docs are pointing to the main branch, but you should use the the alpha one instead until it is being released (probably by the end of this week).
@DhruvBarot Can I close the issue as completed? I believe your initial question has been answered, right?
If you have problems with Synapse or the workflow I gave as example, please don't hesistate to open new issues in related repositories.
@DhruvBarot Closing as I believe the initial question has been answered.
As said above, though, don't hesitate to open new issues in adequate repositories, if need be 😉
@cdavernas : Thanks for the detail response, and yes initial question has been answered.
Hello Team, We are reading the specifications and it's very detailed documents that achieve most of the use cases, I would like thanks to the team, We are trying to build a workflow engine in our organization based on the serverless workflow specification.
There are a couple of use cases that are not possible with the current spec. kindly help us with how we can achieve those. Let's assume we want to build a workflow to manage GitHub issues,
With this use case, we are looking to have the support of multiple "then" with configuration of who can take which "then" action, Also, there is a fixed status of the workflow, How We can set the custom status of the workflow based on the current stage workflow?