Jira Sprint冲刺计划时如何设置自动分配任务?

博主园园 阅读 36

在用Jira做Sprint计划时,每次手动分配任务给团队成员好麻烦,有没有办法根据成员负载自动分配?

之前试过用Jira自带的工作量图表估算,但手动拖拽太耗时间。查了Jira市场发现AutoAssign插件要额外付费,而且评论说准确率不高。有人推荐用API写自动化脚本,但不太清楚怎么获取成员当前负载数据…

尝试用JQL写过查询语句:assignee in (members()) AND Sprint = current sprint(),但不知道如何结合Velocity数据计算负载率。用Postman调过/rest/api/2/user接口但没找到工作量字段,是不是需要连接其他工具?

我来解答 赞 10 收藏
二维码
手机扫码查看
2 条解答
康平 ☘︎
这个问题的关键是 Jira 原生不提供基于负载的自动任务分配功能,所谓的“自动分配”必须你自己定义规则并集成外部逻辑。JQL 和 REST API 只能查数据,不能直接算负载或做智能分配。你看到的 AutoAssign 插件不准,是因为它通常只看指派数量,不考虑任务复杂度或剩余工时。

真正的解决方案是:用 Jira 的 REST API 拉取成员在当前 Sprint 的所有任务,计算每人已分配的预估时间(或故事点),再根据团队约定的容量规则,把新任务分给负载最低的人。这需要你写一个自动化脚本,跑在 Sprint 规划时触发。

第一步,你要确认团队是否统一使用 timeoriginalestimate 字段(单位秒)或者 customfield_10016(通常是故事点)。建议用故事点更稳定,因为预估时间经常不准。假设你们用的是“Story Points”字段,ID 是 customfield_10016

第二步,获取当前 Sprint 所有成员的任务负载。Jira 不直接暴露“负载率”,得你自己算。你需要调:

/rest/agile/1.0/sprint/{sprintId}/issue 拿到该冲刺下所有 issue
然后遍历每个 issue,提取 assignee 和 story points

第三步,统计每个成员的总 points,再对比他们的可用容量。比如每人每 sprint 最多承担 8 点,超过就算超载。

第四步,新任务创建或进入规划状态时,调 API 把 assignee 设为当前负载最小的人。

下面是一个 Python 脚本示例,用 requests 实现:

import requests
from collections import defaultdict

# 配置
JIRA_BASE = "https://your-domain.atlassian.net"
EMAIL = "your-email@example.com"
API_TOKEN = "your-api-token" # 在 atlassian 账户里生成
SPRINT_ID = 123 # 从 URL 或 /rest/agile/1.0/board 取
STORY_POINTS_FIELD = "customfield_10016"
MAX_CAPACITY = 8 # 每人最大容量

headers = {
"Accept": "application/json",
"Content-Type": "application/json"
}

# HTTP Basic Auth
auth = (EMAIL, API_TOKEN)

def get_sprint_issues(sprint_id):
url = f"{JIRA_BASE}/rest/agile/1.0/sprint/{sprint_id}/issue"
response = requests.get(url, headers=headers, auth=auth)
response.raise_for_status()
return response.json()["issues"]

def get_user_load(issues):
# 统计每个用户已分配的 story points
load = defaultdict(float)
for issue in issues:
assignee = issue["fields"]["assignee"]
if not assignee:
continue # 未指派人跳过
username = assignee["displayName"] # 或 accountId 更稳定
points = issue["fields"].get(STORY_POINTS_FIELD) or 0
load[username] += float(points) if points else 0
return load

def find_least_busy_member(team_members, current_load):
# 找出当前负载最低的成员
member_load = {m: current_load.get(m, 0) for m in team_members}
return min(member_load, key=member_load.get)

def assign_issue(issue_key, assignee_name):
# 先通过 displayName 查 accountId,因为 assign 接口要用 account ID
url = f"{JIRA_BASE}/rest/api/2/user/search"
params = {"query": assignee_name}
response = requests.get(url, headers=headers, auth=auth)
users = response.json()
# 尽量匹配全名,简单起见取第一个
account_id = users[0]["accountId"] if users else None
if not account_id:
print(f"找不到用户: {assignee_name}")
return False

url = f"{JIRA_BASE}/rest/api/2/issue/{issue_key}/assignee"
payload = {"accountId": account_id}
response = requests.put(url, json=payload, headers=headers, auth=auth)
if response.status_code == 204:
print(f"任务 {issue_key} 已分配给 {assignee_name}")
return True
else:
print("分配失败:", response.text)
return False

# 主流程
if __name__ == "__main__":
# 假设你的团队成员名单
team = ["张三", "李四", "王五"]

issues = get_sprint_issues(SPRINT_ID)
current_load = get_user_load(issues)
print("当前负载:", dict(current_load))

# 新加入的任务 key,比如从 webhook 或手动输入
new_issue_key = "PROJ-123"

best_member = find_least_busy_member(team, current_load)
assign_issue(new_issue_key, best_member)


这个脚本能跑通的前提是你已经配置好 API 权限,并且所有成员都能通过 search API 查到。

为什么不用 Velocity?因为 Velocity 是历史数据,反映的是过去速度,不适合用于实时分配。而且 Jira 的模板引擎不开放给外部脚本调用。

如果你想更智能,可以加权考虑:
- 成员擅长的组件(用 Component 字段)
- 任务类型匹配(Bug 给测试,Feature 给开发)
- 近期活跃度(用 last login 或更新频率)

但别搞太复杂,先实现基础版本,再迭代。

最后提醒:不要在生产环境直接跑这个脚本。先用 dry-run 模式打印建议,确认逻辑正确后再打开真实 assign。不然一不小心把任务全分给实习生就炸了。

如果你不想自己搭服务,可以用 Zapier + Jira Webhook 触发这个脚本,部署在 AWS Lambda 或 GitHub Actions 定时运行。核心还是这套逻辑。
点赞 2
2026-02-10 14:09
若溪 Dev
Jira自带功能确实没法直接实现自动分配,付费插件又不太靠谱。可以用API写个脚本,虽然有点麻烦但效果可控。

思路是这样的:
1. 通过/rest/agile/1.0/sprint/{sprintId}/issue获取当前Sprint的所有任务
2. 调用/rest/api/2/user?username={username}获取每个成员的已分配任务数
3. 根据Velocity数据估算每个人的工作量上限
4. 把未分配的任务按顺序分配给负载最低的人

给你一个Python示例代码,改一下就行:
import requests
from requests.auth import HTTPBasicAuth

jira_url = "https://your-jira-domain.com"
auth = HTTPBasicAuth("email@example.com", "api_token")

# 获取当前Sprint的任务列表
def get_sprint_issues(sprint_id):
url = f"{jira_url}/rest/agile/1.0/sprint/{sprint_id}/issue"
return requests.get(url, auth=auth).json()

# 获取某人的已分配任务数
def get_user_task_count(username):
url = f"{jira_url}/rest/api/2/search?jql=assignee={username} AND Sprint=currentSprint()"
return len(requests.get(url, auth=auth).json()['issues'])

# 自动分配任务
def auto_assign_tasks(sprint_id):
issues = get_sprint_issues(sprint_id)
members = ["user1", "user2", "user3"] # 团队成员列表
load = {m: get_user_task_count(m) for m in members}

for issue in issues:
if not issue['fields']['assignee']:
min_load_member = min(load, key=load.get)
assign_issue(issue['key'], min_load_member)
load[min_load_member] += 1

# 分配单个任务
def assign_issue(issue_key, username):
url = f"{jira_url}/rest/api/2/issue/{issue_key}/assignee"
data = {"name": username}
requests.put(url, json=data, auth=auth)

auto_assign_tasks(123) # 替换为实际的Sprint ID


注意要先生成API Token,具体看Atlassian文档。这个脚本可能需要根据你们的实际需求调整,比如加一些日志输出或者异常处理。

说实话Jira的API有时候挺反人类的,不过好在能折腾出想要的效果。
点赞 8
2026-02-01 03:16