Jira Automation - Remove Start and End Dates


The Request: Can we automate the removal of the start and end date from an Epic, and the Initiative when a sprint starts?
The answer my friends is yes. Now we must start with the why of it. Why would we want this to be automated? What is the end goal? How does this help us achieve our goals?
In my current key project, I am assisting with the transition from Excel based enterprise planning tools, to using a Jira Advanced Road map plan, we will call it a Plan for short.
One thing we should know about Advanced road map plans, is that the start and due date of a plan can be inferred by a child to a parent. Example: The start date of a story is hard set to Sep 24th 2025, if the start date of a parent epic is blank, and no other children of that epic are hard set then the start date for the epic will roll up or be inferred.
Now what if the story level work item does not have a start date? If it is in a sprint that has a date range set to it, regardless of if that sprint is open yet, the story will infer to its parent a start and due date based on the range of a sprint. If children of the epic are in multiple sprints, across multiple teams then the start date will be the earliest sprint start date, and the due date will be the latest sprint due date possible. This same logic applies to Initiatives/Legends, or any other hierarchal structure you may use for your work items.
Now I am not sure what your organization might do for planning but at mine, when an Initiative is created, it is given a time boxed estimate, so as to say we hard set the start and end dates. Now after a Initiative is created we assign to it relevant epics across as many projects as we might need, and from there assign the relevant work items to those epics and place them if possible into future sprints so as to get a holistic view of the work for the given time span of the epic. Then when the very first sprint is started on an epic that has a hard set date, we want to clear that start date and due date to show reflect the actual start date and due date as inferred from the sprints themselves.
This process allows us to estimate a given project time wise before all the work is broken down, and then adjust it roughly into shape based on what was actually scoped.
Note: We can see in the screen shot above that S on the start date indicates the story is inferred from the sprint. The arrow on the epic and initiative indicate that those dates are rolled up or inferred from its child as it was blank
The Automation
So then How might we actually go about this? Simple we need only make one rule in Jira Automation. and It will work something like this.
Trigger : When A Sprint is started in Project X
- The limitation here is that this only allows us to choice one board or project
Action: Look up Work Items
project = X AND sprint in openSprints() AND issuetype != Epic
I specify here that the issuetype is not an epic, even though we do not put epics in sprints just to be safe about what I am pulling.
This will grab any work items in an open sprint in Project X
Action: Look Up Work items:
key in ({{lookupIssues.parent.key.distinct}})
We then create a look up list of the parents of using the smart value
Note: When you create a second look up list it will over write the first using the smart value {{lookupIssues}} will use results from the last look up table
Branch: JQL
key in ({{lookupIssues.key}})
- we use this bit of JQL to pass in the items from the look up work items action. If you do not do this then there will not be any issue context for the branch to work with and thus it can not loop through the values.
If : Work item condition
Start Date is not Empty
- This lets us see if the parent of one of our sprint items has a hard set date
Action: Edit Work item
Start Date : Leave blank
Due Date : Leave Blank
- Leaving these items blank allows us to remove any values that would have been there
After Brach: Action: Look Up Work items
key in ({{lookupIssues.parent.key.distinct}})
- this may seem odd, but if we want to get the parent of the Epic then we just look them up like we did the parent of the stories in the sprint.
Steps 8 - 11 are the same as 4-6 You make a JQL branch and loop through the results clearing the start and end date based on if the start date has a value or not.
As Side note you can add a Action : log action at the end of your branch to log values that you pulled and worked on. I like to use this: Key = {{lookupIssues.key}} Start date = {{lookupIssues.startDate}}. This give me a list of all the keys and the start dates of those keys in two lists. Keys should have values, and Start date should have 0 values because we nulled them out.
And that is really all there is to it. I hope this has been insightful and engaging for those of you who are looking for tips on Jira automation. It is really easier than Power Automate or a Logic app workflow, if not as robust as those options. I plan to keep writing up these Automations as I build them out. If you’re interested in this sort of thing let me know!
Thanks again and I hope you have a great day!
Note: Replace X with your project ID and boardID: 103 with your board ID
{
"cloud": true,
"rules": [
{
"id": 29848990,
"clientKey": "79885060-33b7-405f-9c3b-9dd50d601703",
"name": "Project X Sprint Start Epic Start date Removal",
"state": "ENABLED",
"description": "",
"authorAccountId": "62c6dfd0e16ddfe82be0595b",
"actor": {
"type": "ACCOUNT_ID",
"value": "557058:f58131cb-b67d-43c7-b30d-6b58d40bd077"
},
"created": 1754410897893,
"updated": 1754415777472,
"trigger": {
"id": "720438838",
"component": "TRIGGER",
"parentId": null,
"conditionParentId": null,
"schemaVersion": 1,
"type": "jira.sprint.event.trigger:started",
"value": {
"boardId": 103,
"sprintNameFilter": ""
},
"children": [],
"conditions": [],
"connectionId": null
},
"components": [
{
"id": "720438839",
"component": "ACTION",
"parentId": null,
"conditionParentId": null,
"schemaVersion": 1,
"type": "jira.lookup.issues",
"value": {
"id": "_customsmartvalue_id_1754410787609",
"name": {
"type": "FREE",
"value": "lookupIssues"
},
"type": "JQL",
"query": {
"type": "SMART",
"value": "project = X AND sprint in openSprints() AND issuetype != Epic"
},
"lazy": false
},
"children": [],
"conditions": [],
"connectionId": null
},
{
"id": "720438840",
"component": "ACTION",
"parentId": null,
"conditionParentId": null,
"schemaVersion": 1,
"type": "jira.lookup.issues",
"value": {
"id": "_customsmartvalue_id_1754410787609",
"name": {
"type": "FREE",
"value": "lookupIssues"
},
"type": "JQL",
"query": {
"type": "SMART",
"value": "key in ({{lookupIssues.parent.key.distinct}})"
},
"lazy": false
},
"children": [],
"conditions": [],
"connectionId": null
},
{
"id": "720438841",
"component": "BRANCH",
"parentId": null,
"conditionParentId": null,
"schemaVersion": 1,
"type": "jira.issue.related",
"value": {
"relatedType": "jql",
"jql": "key in ({{lookupIssues.key}})",
"linkTypes": [],
"onlyUpdatedIssues": false,
"similarityLimit": 40,
"compareValue": 0
},
"children": [
{
"id": "720438842",
"component": "CONDITION",
"parentId": "720438841",
"conditionParentId": null,
"schemaVersion": 3,
"type": "jira.issue.condition",
"value": {
"selectedField": {
"type": "NAME",
"value": "Start date"
},
"selectedFieldType": "com.atlassian.jira.plugin.system.customfieldtypes:datepicker",
"comparison": "NOT_EMPTY",
"compareValue": null
},
"children": [],
"conditions": [],
"connectionId": null
},
{
"id": "720438843",
"component": "ACTION",
"parentId": "720438841",
"conditionParentId": null,
"schemaVersion": 12,
"type": "jira.issue.edit",
"value": {
"operations": [
{
"field": {
"type": "NAME",
"value": "Start date"
},
"fieldType": "com.atlassian.jira.plugin.system.customfieldtypes:datepicker",
"type": "SET",
"value": null
},
{
"field": {
"type": "ID",
"value": "duedate"
},
"fieldType": "duedate",
"type": "SET",
"value": null
}
],
"advancedFields": null,
"sendNotifications": true
},
"children": [],
"conditions": [],
"connectionId": null
},
{
"id": "720438844",
"component": "ACTION",
"parentId": "720438841",
"conditionParentId": null,
"schemaVersion": 1,
"type": "codebarrel.action.log",
"value": "Key = {{lookupIssues.key}} Start date = {{lookupIssues.startDate}}",
"children": [],
"conditions": [],
"connectionId": null
}
],
"conditions": [],
"connectionId": null
},
{
"id": "720450474",
"component": "ACTION",
"parentId": null,
"conditionParentId": null,
"schemaVersion": 1,
"type": "jira.lookup.issues",
"value": {
"id": "_customsmartvalue_id_1754410787609",
"name": {
"type": "FREE",
"value": "lookupIssues"
},
"type": "JQL",
"query": {
"type": "SMART",
"value": "key in ({{lookupIssues.parent.key.distinct}})"
},
"lazy": false
},
"children": [],
"conditions": [],
"connectionId": null
},
{
"id": "720450475",
"component": "BRANCH",
"parentId": null,
"conditionParentId": null,
"schemaVersion": 1,
"type": "jira.issue.related",
"value": {
"relatedType": "jql",
"jql": "key in ({{lookupIssues.key}})",
"linkTypes": [],
"onlyUpdatedIssues": false,
"similarityLimit": 40,
"compareValue": 0
},
"children": [
{
"id": "720450476",
"component": "CONDITION",
"parentId": "720450475",
"conditionParentId": null,
"schemaVersion": 3,
"type": "jira.issue.condition",
"value": {
"selectedField": {
"type": "NAME",
"value": "Start date"
},
"selectedFieldType": "com.atlassian.jira.plugin.system.customfieldtypes:datepicker",
"comparison": "NOT_EMPTY",
"compareValue": null
},
"children": [],
"conditions": [],
"connectionId": null
},
{
"id": "720450477",
"component": "ACTION",
"parentId": "720450475",
"conditionParentId": null,
"schemaVersion": 12,
"type": "jira.issue.edit",
"value": {
"operations": [
{
"field": {
"type": "NAME",
"value": "Start date"
},
"fieldType": "com.atlassian.jira.plugin.system.customfieldtypes:datepicker",
"type": "SET",
"value": null
},
{
"field": {
"type": "ID",
"value": "duedate"
},
"fieldType": "duedate",
"type": "SET",
"value": null
}
],
"advancedFields": null,
"sendNotifications": true
},
"children": [],
"conditions": [],
"connectionId": null
},
{
"id": "720450478",
"component": "ACTION",
"parentId": "720450475",
"conditionParentId": null,
"schemaVersion": 1,
"type": "codebarrel.action.log",
"value": "Key = {{lookupIssues.key}} Start date = {{lookupIssues.startDate}}",
"children": [],
"conditions": [],
"connectionId": null
}
],
"conditions": [],
"connectionId": null
}
],
"canOtherRuleTrigger": false,
"notifyOnError": "FIRSTERROR",
"projects": [],
"labels": [],
"tags": [
{
"id": 115681766,
"ruleIdUuid": "01987b09-d1e5-74c4-90c8-4e16c1fca5b3",
"tagType": "IS_RULE_UPDATED",
"tagValue": "true"
}
],
"ruleScope": {
"resources": [
"ari:cloud:jira::site/b60e83f7-a627-456b-8aa3-fcfd7047c278"
]
},
"ruleHome": {
"ruleLifecycleHome": {
"locationARI": "ari:cloud:jira-software::site/b60e83f7-a627-456b-8aa3-fcfd7047c278"
},
"ruleBillingHome": {
"locationARI": "ari:cloud:jira-software::site/b60e83f7-a627-456b-8aa3-fcfd7047c278"
}
},
"writeAccessType": "UNRESTRICTED",
"collaborators": [],
"billingType": "NORMAL",
"idUuid": "01987b09-d1e5-74c4-90c8-4e16c1fca5b3",
"partitionId": "79885060-33b7-405f-9c3b-9dd50d601703"
}
]
}
Subscribe to my newsletter
Read articles from michelangelo Rollf directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
