Initialize the Jira API client with your Jira base URL and API token:
funcmain() { jiraClient, err := jira.New(nil, "https://your-jira-instance.atlassian.net")if err !=nil { log.Fatal(err) }// Set API token for authentication jiraClient.Auth.SetBasicAuth(mail, token)}
Step 5: Create a workflow
To create a new workflow, we need to the create the models.WorkflowPayloadScheme payload struct with the following information.
Worfklow Name.
Workflow Description.
Workflow Statuses.
Workflow Transitions.
Let's try to create a workflow with directed transitions and all-to-all transitions, something like this:
Step 5.1: Extract the status ID's
The first step to create a Jira workflow is recognize what's gonna be the statuses you want to use.
Statuses represent the different stages that an issue can go through in a workflow.
In this particular example, we're needed to use the following statuses:
Open
In Progress
QA
Waiting for approval
Escalated
Closed
Resolved
var statusesNamesAsSlice = []string{"Open", "In Progress", "QA","Waiting for approval", "Escalated","Closed", "Resolved",}var statusesAsMap =make(map[string]*models.WorkflowStatusDetailScheme)for _, statusName :=range statusesNamesAsSlice { options :=&models.WorkflowStatusSearchParams{ SearchString: statusName, } page, response, err := instance.Workflow.Status.Search(context.Background(), options, 0, 1)if err !=nil {if response !=nil { log.Println(response.Bytes.String()) log.Println(response.Code) } log.Fatal(err) }var wasFound boolfor _, status :=range page.Values {if status.Name == statusName { statusesAsMap[status.Name] = status wasFound =truebreak } }if!wasFound {// If the workflow is not found, it's required to create a new global status statusPayload :=&models.WorkflowStatusPayloadScheme{ Statuses: []*models.WorkflowStatusNodeScheme{ { Name: statusName, StatusCategory: "IN_PROGRESS", }, }, Scope: &models.WorkflowStatusScopeScheme{ Type: "GLOBAL", }, } statuses, response, err := instance.Workflow.Status.Create(context.Background(), statusPayload)if err !=nil {if response !=nil { log.Println(response.Bytes.String()) log.Println(response.Code) } log.Fatal(err) }for _, status :=range statuses {if status.Name == statusName { statusesAsMap[status.Name] = statusbreak } } }}for name, data :=range statusesAsMap { fmt.Println(name, data.ID)}
The previously code extracts the status ID's from the Jira instance and if one status is not available on the instance, it'll automatically create the statuses and append the information on the statusesAsMap variable.
With the status ID's, we can proceed with the creation of the workflow statuses payload
var workflowStatuses []*models.WorkflowTransitionScreenSchemefor _, status :=range statusesAsMap { workflowStatuses =append(workflowStatuses, &models.WorkflowTransitionScreenScheme{ ID: status.ID, Properties: nil, })}
Step 5.2: Create the workflow transitions
With the statuses id's extracted, we can create a workflow transitions. The transitions define the paths that an issue can take from one status to another.
For example: an issue in the "Open" status can transition to the "In Progress" status when work begins on it.
There're the conditional validations needed to create a valid workflow transition:
include one initial transition.
not use the same name for a global and directed transition.
have a unique name for each global transition.
have a unique 'to' status for each global transition.
have unique names for each transition from a status.
not have a 'from' status on initial and global transitions.
have a 'from' status on directed transitions.
var workflowTransitions []*models.WorkflowTransitionPayloadScheme// -----// The initial transition is required, it creates the relationship between the creation trigger with the// first status// -----workflowTransitions =append(workflowTransitions, &models.WorkflowTransitionPayloadScheme{ Name: "Create", To: "1", Type: "initial",})// -----// Create the Escalated and Waiting for approval statuses because the relationship is all-to-allworkflowTransitions =append(workflowTransitions, &models.WorkflowTransitionPayloadScheme{ Name: "Escalated", To: statusesAsMap["Escalated"].ID, Type: "global",})workflowTransitions =append(workflowTransitions, &models.WorkflowTransitionPayloadScheme{ Name: "Waiting for approval", To: statusesAsMap["Waiting for approval"].ID, Type: "global",})// -----// ----// Create the directed transitions, it's required to use the from and to statuses// Open -----------------------> In ProgressworkflowTransitions =append(workflowTransitions, &models.WorkflowTransitionPayloadScheme{ Name: "In Progress", From: []string{statusesAsMap["Open"].ID}, To: statusesAsMap["In Progress"].ID, Type: "directed",})// In Progress -----------------------> QAworkflowTransitions =append(workflowTransitions, &models.WorkflowTransitionPayloadScheme{ Name: "QA", From: []string{statusesAsMap["In Progress"].ID}, To: statusesAsMap["QA"].ID, Type: "directed",})// QA -----------------------> In ProgressworkflowTransitions =append(workflowTransitions, &models.WorkflowTransitionPayloadScheme{ Name: "QA", From: []string{statusesAsMap["QA"].ID}, To: statusesAsMap["In Progress"].ID, Type: "directed",})// QA -----------------------> ClosedworkflowTransitions =append(workflowTransitions, &models.WorkflowTransitionPayloadScheme{ Name: "Closed", From: []string{statusesAsMap["QA"].ID}, To: statusesAsMap["Closed"].ID, Type: "directed",})// QA -----------------------> ResolvedworkflowTransitions =append(workflowTransitions, &models.WorkflowTransitionPayloadScheme{ Name: "Resolved", From: []string{statusesAsMap["QA"].ID}, To: statusesAsMap["Resolved"].ID, Type: "directed",})
Step 5.3: Create the workflow
In conclusion, we can combine the statuses and transitions structs and create the workflow using the structs created on the previous steps.