@fitlab-ai/agent-infra 0.5.3 → 0.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/package.json +1 -1
- package/templates/.agents/rules/issue-pr-commands.github.en.md +25 -9
- package/templates/.agents/rules/issue-pr-commands.github.zh-CN.md +25 -9
- package/templates/.agents/rules/issue-sync.github.en.md +111 -23
- package/templates/.agents/rules/issue-sync.github.zh-CN.md +105 -17
- package/templates/.agents/rules/milestone-inference.github.en.md +13 -6
- package/templates/.agents/rules/milestone-inference.github.zh-CN.md +13 -6
- package/templates/.agents/rules/pr-sync.github.en.md +3 -1
- package/templates/.agents/rules/pr-sync.github.zh-CN.md +3 -1
- package/templates/.agents/scripts/platform-adapters/platform-sync.github.js +1080 -0
- package/templates/.agents/scripts/validate-artifact.js +51 -802
- package/templates/.agents/skills/analyze-task/SKILL.en.md +2 -2
- package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/analyze-task/config/verify.json +1 -1
- package/templates/.agents/skills/block-task/SKILL.en.md +2 -2
- package/templates/.agents/skills/block-task/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/block-task/config/verify.json +1 -1
- package/templates/.agents/skills/cancel-task/SKILL.en.md +6 -6
- package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +6 -6
- package/templates/.agents/skills/cancel-task/config/verify.json +1 -1
- package/templates/.agents/skills/commit/SKILL.en.md +14 -2
- package/templates/.agents/skills/commit/SKILL.zh-CN.md +14 -2
- package/templates/.agents/skills/commit/config/verify.json +2 -1
- package/templates/.agents/skills/commit/reference/issue-metadata-sync.en.md +23 -0
- package/templates/.agents/skills/commit/reference/issue-metadata-sync.zh-CN.md +23 -0
- package/templates/.agents/skills/complete-task/SKILL.en.md +2 -2
- package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/complete-task/config/verify.json +1 -1
- package/templates/.agents/skills/create-issue/SKILL.en.md +3 -1
- package/templates/.agents/skills/create-issue/SKILL.zh-CN.md +3 -1
- package/templates/.agents/skills/create-issue/config/verify.json +1 -1
- package/templates/.agents/skills/create-issue/reference/label-and-type.en.md +6 -1
- package/templates/.agents/skills/create-issue/reference/label-and-type.zh-CN.md +6 -1
- package/templates/.agents/skills/create-pr/SKILL.en.md +4 -4
- package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +4 -4
- package/templates/.agents/skills/create-pr/config/verify.json +1 -1
- package/templates/.agents/skills/create-pr/reference/pr-body-template.en.md +9 -5
- package/templates/.agents/skills/create-pr/reference/pr-body-template.zh-CN.md +9 -5
- package/templates/.agents/skills/create-task/config/verify.json +1 -1
- package/templates/.agents/skills/implement-task/SKILL.en.md +4 -4
- package/templates/.agents/skills/implement-task/SKILL.zh-CN.md +4 -4
- package/templates/.agents/skills/implement-task/config/verify.json +1 -2
- package/templates/.agents/skills/import-codescan/config/verify.json +1 -1
- package/templates/.agents/skills/import-dependabot/config/verify.json +1 -1
- package/templates/.agents/skills/import-issue/SKILL.en.md +1 -1
- package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/import-issue/config/verify.json +1 -1
- package/templates/.agents/skills/plan-task/SKILL.en.md +2 -2
- package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/plan-task/config/verify.json +1 -1
- package/templates/.agents/skills/refine-task/SKILL.en.md +2 -4
- package/templates/.agents/skills/refine-task/SKILL.zh-CN.md +2 -4
- package/templates/.agents/skills/refine-task/config/verify.json +1 -2
- package/templates/.agents/skills/refine-title/SKILL.en.md +5 -1
- package/templates/.agents/skills/refine-title/SKILL.zh-CN.md +5 -1
- package/templates/.agents/skills/restore-task/config/verify.json +1 -1
- package/templates/.agents/skills/review-task/SKILL.en.md +2 -2
- package/templates/.agents/skills/review-task/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/review-task/config/verify.json +1 -1
- package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +1 -1
- package/templates/.github/workflows/metadata-sync.yml +127 -0
- package/templates/.github/workflows/pr-label.yml +75 -0
- package/templates/.github/workflows/status-label.yml +12 -8
|
@@ -17,7 +17,7 @@ Import the specified GitHub Issue and create a task. Argument: issue number.
|
|
|
17
17
|
|
|
18
18
|
### 1. Retrieve Issue Information
|
|
19
19
|
|
|
20
|
-
Read `.agents/rules/issue-pr-commands.md` first,
|
|
20
|
+
Read `.agents/rules/issue-pr-commands.md` first, follow its prerequisite steps to complete authentication and code-hosting platform detection, then load the Issue data with its "Read an Issue" command.
|
|
21
21
|
|
|
22
22
|
Extract: issue number, title, description, and labels.
|
|
23
23
|
Use the Issue title as-is for the task title (preserve the Issue's original language).
|
|
@@ -17,7 +17,7 @@ description: "从 GitHub Issue 导入并创建任务"
|
|
|
17
17
|
|
|
18
18
|
### 1. 获取 Issue 信息
|
|
19
19
|
|
|
20
|
-
执行前先读取 `.agents/rules/issue-pr-commands.md
|
|
20
|
+
执行前先读取 `.agents/rules/issue-pr-commands.md`,并按其中的前置步骤完成认证和代码托管平台检测;随后按其中的 “读取 Issue” 命令获取 Issue 信息。
|
|
21
21
|
|
|
22
22
|
提取:issue 编号、标题、描述、标签。
|
|
23
23
|
任务标题直接使用 Issue 的原始标题(保持 Issue 标题的原始语言)。
|
|
@@ -97,8 +97,8 @@ Update `.agents/workspace/active/{task-id}/task.md`:
|
|
|
97
97
|
```
|
|
98
98
|
|
|
99
99
|
If task.md contains a valid `issue_number`, perform these sync actions (skip and continue on any failure):
|
|
100
|
-
- Read `.agents/rules/issue-sync.md` before syncing
|
|
101
|
-
- Set `status: pending-design-work`
|
|
100
|
+
- Read `.agents/rules/issue-sync.md` before syncing, and complete upstream repository detection plus permission detection
|
|
101
|
+
- Set `status: pending-design-work` by following issue-sync.md
|
|
102
102
|
- Publish the `{plan-artifact}` comment
|
|
103
103
|
- Create or update the `<!-- sync-issue:{task-id}:task -->` comment (follow the task.md comment sync rule in issue-sync.md)
|
|
104
104
|
|
|
@@ -97,8 +97,8 @@ date "+%Y-%m-%d %H:%M:%S%:z"
|
|
|
97
97
|
```
|
|
98
98
|
|
|
99
99
|
如果 task.md 中存在有效的 `issue_number`,执行以下同步操作(任一失败则跳过并继续):
|
|
100
|
-
- 执行前先读取 `.agents/rules/issue-sync.md
|
|
101
|
-
- 设置 `status: pending-design-work`
|
|
100
|
+
- 执行前先读取 `.agents/rules/issue-sync.md`,完成 upstream 仓库检测和权限检测
|
|
101
|
+
- 按 issue-sync.md 设置 `status: pending-design-work`
|
|
102
102
|
- 发布 `{plan-artifact}` 评论
|
|
103
103
|
- 创建或更新 `<!-- sync-issue:{task-id}:task -->` 评论(按 issue-sync.md 的 task.md 评论同步规则)
|
|
104
104
|
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"expected_action_pattern": "Technical Design \\(Round \\d+\\)",
|
|
32
32
|
"freshness_minutes": 30
|
|
33
33
|
},
|
|
34
|
-
"
|
|
34
|
+
"platform-sync": {
|
|
35
35
|
"when": "issue_number_exists",
|
|
36
36
|
"expected_status_label": "status: pending-design-work",
|
|
37
37
|
"expected_comment_marker": "<!-- sync-issue:{task-id}:{artifact-stem} -->",
|
|
@@ -60,10 +60,8 @@ Update task.md:
|
|
|
60
60
|
`- {YYYY-MM-DD HH:mm:ss±HH:MM} — **Refinement (Round {N}, for {review-artifact})** by {agent} — Fixed {n} blockers, {n} major, {n} minor issues → {refinement-artifact}`
|
|
61
61
|
|
|
62
62
|
If task.md contains a valid `issue_number`, perform these sync actions (skip and continue on any failure):
|
|
63
|
-
- Read `.agents/rules/issue-sync.md` before syncing
|
|
64
|
-
- Set `status: in-progress`
|
|
65
|
-
- Refine `in:` labels from the branch diff by following `.agents/rules/issue-sync.md` (add/remove when a mapping exists, add-only when it does not)
|
|
66
|
-
- Sync checked `## Requirements` items to the Issue body
|
|
63
|
+
- Read `.agents/rules/issue-sync.md` before syncing, and complete upstream repository detection plus permission detection
|
|
64
|
+
- Set `status: in-progress` by following issue-sync.md
|
|
67
65
|
- Publish the `{refinement-artifact}` comment
|
|
68
66
|
- Create or update the `<!-- sync-issue:{task-id}:task -->` comment (follow the task.md comment sync rule in issue-sync.md)
|
|
69
67
|
|
|
@@ -60,10 +60,8 @@ date "+%Y-%m-%d %H:%M:%S%:z"
|
|
|
60
60
|
`- {YYYY-MM-DD HH:mm:ss±HH:MM} — **Refinement (Round {N}, for {review-artifact})** by {agent} — Fixed {n} blockers, {n} major, {n} minor issues → {refinement-artifact}`
|
|
61
61
|
|
|
62
62
|
如果 task.md 中存在有效的 `issue_number`,执行以下同步操作(任一失败则跳过并继续):
|
|
63
|
-
- 执行前先读取 `.agents/rules/issue-sync.md
|
|
64
|
-
- 设置 `status: in-progress`
|
|
65
|
-
- 按 `.agents/rules/issue-sync.md` 的 `in:` label 同步规则,基于分支改动精修 `in:` label(有映射时可增可删,无映射时仅补充)
|
|
66
|
-
- 同步 `## 需求` 中已勾选项到 Issue body
|
|
63
|
+
- 执行前先读取 `.agents/rules/issue-sync.md`,完成 upstream 仓库检测和权限检测
|
|
64
|
+
- 按 issue-sync.md 设置 `status: in-progress`
|
|
67
65
|
- 发布 `{refinement-artifact}` 评论
|
|
68
66
|
- 创建或更新 `<!-- sync-issue:{task-id}:task -->` 评论(按 issue-sync.md 的 task.md 评论同步规则)
|
|
69
67
|
|
|
@@ -25,13 +25,12 @@
|
|
|
25
25
|
"expected_action_pattern": "Refinement \\(Round \\d+, for .+\\)",
|
|
26
26
|
"freshness_minutes": 30
|
|
27
27
|
},
|
|
28
|
-
"
|
|
28
|
+
"platform-sync": {
|
|
29
29
|
"when": "issue_number_exists",
|
|
30
30
|
"expected_status_label": "status: in-progress",
|
|
31
31
|
"expected_comment_marker": "<!-- sync-issue:{task-id}:{artifact-stem} -->",
|
|
32
32
|
"verify_comment_content": true,
|
|
33
33
|
"verify_task_comment_content": true,
|
|
34
|
-
"sync_checked_requirements": true,
|
|
35
34
|
"verify_issue_type": true,
|
|
36
35
|
"verify_milestone": true
|
|
37
36
|
}
|
|
@@ -11,7 +11,7 @@ Reformat the title of the specified Issue or PR to Conventional Commits format b
|
|
|
11
11
|
|
|
12
12
|
### 1. Identify Target and Fetch Information
|
|
13
13
|
|
|
14
|
-
Read `.agents/rules/issue-pr-commands.md` before this step.
|
|
14
|
+
Read `.agents/rules/issue-pr-commands.md` before this step, and follow its prerequisite steps to complete authentication and code-hosting platform detection.
|
|
15
15
|
|
|
16
16
|
Try to determine if the ID is an Issue or PR:
|
|
17
17
|
- first fetch Issue data by following the "Read an Issue" command in the rule file
|
|
@@ -58,6 +58,8 @@ If the user confirms:
|
|
|
58
58
|
- for an Issue, update the title by following the "Update Issues" command in `.agents/rules/issue-pr-commands.md`
|
|
59
59
|
- for a PR, update the title by following the "Update PRs" command in `.agents/rules/issue-pr-commands.md`
|
|
60
60
|
|
|
61
|
+
Title changes require write permission. Follow the permission-degradation rules in `.agents/rules/issue-pr-commands.md` and `.agents/rules/issue-sync.md`; if permission is unavailable, skip the change and inform the user.
|
|
62
|
+
|
|
61
63
|
### 5. Inform User
|
|
62
64
|
|
|
63
65
|
> **IMPORTANT**: All TUI command formats listed below must be output in full. Do not show only the format for the current AI agent.
|
|
@@ -66,6 +68,8 @@ If the skill updated an Issue title, explain that no extra sync command is requi
|
|
|
66
68
|
|
|
67
69
|
If the skill updated a PR title, explain that `create-pr` now publishes the reviewer summary inline, so no extra sync command is needed; continue with the workflow skill that matches the task's current stage.
|
|
68
70
|
|
|
71
|
+
If title modification was skipped due to insufficient permissions, additionally remind the user that the suggested title can still be applied manually on the code-hosting platform page.
|
|
72
|
+
|
|
69
73
|
## Advantages
|
|
70
74
|
|
|
71
75
|
This skill:
|
|
@@ -11,7 +11,7 @@ description: "重构 Issue/PR 标题为 Conventional Commits 格式"
|
|
|
11
11
|
|
|
12
12
|
### 1. 识别目标并获取信息
|
|
13
13
|
|
|
14
|
-
执行前先读取 `.agents/rules/issue-pr-commands.md
|
|
14
|
+
执行前先读取 `.agents/rules/issue-pr-commands.md`,并按其中的前置步骤完成认证和代码托管平台检测。
|
|
15
15
|
|
|
16
16
|
尝试判断 ID 是 Issue 还是 PR:
|
|
17
17
|
- 先按规则文件中的“读取 Issue”命令获取 Issue 信息
|
|
@@ -58,6 +58,8 @@ Issue/PR #{id} 分析结果:
|
|
|
58
58
|
- 对于 Issue:按 `.agents/rules/issue-pr-commands.md` 中的 “Issue 更新” 命令设置标题
|
|
59
59
|
- 对于 PR:按 `.agents/rules/issue-pr-commands.md` 中的 “PR 更新” 命令设置标题
|
|
60
60
|
|
|
61
|
+
标题修改需要写权限,按 `.agents/rules/issue-pr-commands.md` 与 `.agents/rules/issue-sync.md` 中的权限降级规则执行;无权限时跳过修改操作并告知用户。
|
|
62
|
+
|
|
61
63
|
### 5. 告知用户
|
|
62
64
|
|
|
63
65
|
> **重要**:以下「下一步」中列出的所有 TUI 命令格式必须完整输出,不要只展示当前 AI 代理对应的格式。
|
|
@@ -66,6 +68,8 @@ Issue/PR #{id} 分析结果:
|
|
|
66
68
|
|
|
67
69
|
如果修改了 PR 标题,提示 `create-pr` 已内联发布 reviewer 摘要,无需额外同步命令;后续按任务当前阶段继续执行对应工作流技能。
|
|
68
70
|
|
|
71
|
+
如果因权限不足跳过了标题修改,额外提示用户建议标题仍可手动应用到代码托管平台页面。
|
|
72
|
+
|
|
69
73
|
## 优势
|
|
70
74
|
|
|
71
75
|
本技能的优势:
|
|
@@ -54,8 +54,8 @@ Update task.md and append:
|
|
|
54
54
|
`- {YYYY-MM-DD HH:mm:ss±HH:MM} — **Code Review (Round {N})** by {agent} — Verdict: {Approved/Changes Requested/Rejected}, blockers: {n}, major: {n}, minor: {n} → {artifact-filename}`
|
|
55
55
|
|
|
56
56
|
If task.md contains a valid `issue_number`, perform these sync actions (skip and continue on any failure):
|
|
57
|
-
- Read `.agents/rules/issue-sync.md` before syncing
|
|
58
|
-
- Set `status: in-progress`
|
|
57
|
+
- Read `.agents/rules/issue-sync.md` before syncing, and complete upstream repository detection plus permission detection
|
|
58
|
+
- Set `status: in-progress` by following issue-sync.md
|
|
59
59
|
- Publish the `{review-artifact}` comment
|
|
60
60
|
- Create or update the `<!-- sync-issue:{task-id}:task -->` comment (follow the task.md comment sync rule in issue-sync.md)
|
|
61
61
|
|
|
@@ -54,8 +54,8 @@ date "+%Y-%m-%d %H:%M:%S%:z"
|
|
|
54
54
|
`- {YYYY-MM-DD HH:mm:ss±HH:MM} — **Code Review (Round {N})** by {agent} — Verdict: {Approved/Changes Requested/Rejected}, blockers: {n}, major: {n}, minor: {n} → {artifact-filename}`
|
|
55
55
|
|
|
56
56
|
如果 task.md 中存在有效的 `issue_number`,执行以下同步操作(任一失败则跳过并继续):
|
|
57
|
-
- 执行前先读取 `.agents/rules/issue-sync.md
|
|
58
|
-
- 设置 `status: in-progress`
|
|
57
|
+
- 执行前先读取 `.agents/rules/issue-sync.md`,完成 upstream 仓库检测和权限检测
|
|
58
|
+
- 按 issue-sync.md 设置 `status: in-progress`
|
|
59
59
|
- 发布 `{review-artifact}` 评论
|
|
60
60
|
- 创建或更新 `<!-- sync-issue:{task-id}:task -->` 评论(按 issue-sync.md 的 task.md 评论同步规则)
|
|
61
61
|
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"expected_action_pattern": "Code Review \\(Round \\d+\\)",
|
|
30
30
|
"freshness_minutes": 30
|
|
31
31
|
},
|
|
32
|
-
"
|
|
32
|
+
"platform-sync": {
|
|
33
33
|
"when": "issue_number_exists",
|
|
34
34
|
"expected_status_label": "status: in-progress",
|
|
35
35
|
"expected_comment_marker": "<!-- sync-issue:{task-id}:{artifact-stem} -->",
|
|
@@ -76,7 +76,7 @@ const DEFAULTS = {
|
|
|
76
76
|
}
|
|
77
77
|
};
|
|
78
78
|
|
|
79
|
-
const INSTALLER_VERSION = "v0.5.
|
|
79
|
+
const INSTALLER_VERSION = "v0.5.4";
|
|
80
80
|
const PACKAGE_NAME = '@fitlab-ai/agent-infra';
|
|
81
81
|
// Add a new identifier here only after shipping matching .{platform}. template variants.
|
|
82
82
|
const KNOWN_PLATFORMS = new Set(['github']);
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
name: Metadata Sync
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
issue_comment:
|
|
5
|
+
types: [created, edited]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
issues: write
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
sync-metadata:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
if: ${{ !github.event.issue.pull_request }}
|
|
14
|
+
steps:
|
|
15
|
+
- name: Extract metadata from task comment
|
|
16
|
+
id: metadata
|
|
17
|
+
run: |
|
|
18
|
+
body=$(jq -r '.comment.body' "$GITHUB_EVENT_PATH")
|
|
19
|
+
if ! printf '%s' "$body" | grep -qE '<!-- sync-issue:TASK-[0-9]{8}-[0-9]{6}:task -->'; then
|
|
20
|
+
printf 'is_task_comment=false\n' >> "$GITHUB_OUTPUT"
|
|
21
|
+
exit 0
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
frontmatter=$(printf '%s\n' "$body" \
|
|
25
|
+
| tr -d '\r' \
|
|
26
|
+
| awk '
|
|
27
|
+
BEGIN { capture = 0; separators = 0 }
|
|
28
|
+
$0 == "---" {
|
|
29
|
+
separators += 1
|
|
30
|
+
if (separators == 1) {
|
|
31
|
+
capture = 1
|
|
32
|
+
next
|
|
33
|
+
}
|
|
34
|
+
if (separators == 2) {
|
|
35
|
+
exit
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
capture { print }
|
|
39
|
+
')
|
|
40
|
+
|
|
41
|
+
type=$(printf '%s\n' "$frontmatter" \
|
|
42
|
+
| sed -n 's/^type:[[:space:]]*//p' \
|
|
43
|
+
| head -n 1 \
|
|
44
|
+
| sed 's/[[:space:]]*#.*$//' \
|
|
45
|
+
| sed 's/^[[:space:]]*//; s/[[:space:]]*$//' \
|
|
46
|
+
| tr '[:upper:]' '[:lower:]')
|
|
47
|
+
|
|
48
|
+
milestone=$(printf '%s\n' "$frontmatter" \
|
|
49
|
+
| sed -n 's/^milestone:[[:space:]]*//p' \
|
|
50
|
+
| head -n 1 \
|
|
51
|
+
| sed 's/^[[:space:]]*//; s/[[:space:]]*$//')
|
|
52
|
+
|
|
53
|
+
printf 'is_task_comment=true\n' >> "$GITHUB_OUTPUT"
|
|
54
|
+
printf 'type=%s\n' "$type" >> "$GITHUB_OUTPUT"
|
|
55
|
+
printf 'milestone=%s\n' "$milestone" >> "$GITHUB_OUTPUT"
|
|
56
|
+
|
|
57
|
+
- name: Sync type label
|
|
58
|
+
if: steps.metadata.outputs.is_task_comment == 'true' && steps.metadata.outputs.type != ''
|
|
59
|
+
env:
|
|
60
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
61
|
+
ISSUE_NUMBER: ${{ github.event.issue.number }}
|
|
62
|
+
TYPE: ${{ steps.metadata.outputs.type }}
|
|
63
|
+
run: |
|
|
64
|
+
case "$TYPE" in
|
|
65
|
+
bug|bugfix) TYPE_LABEL="type: bug" ;;
|
|
66
|
+
feature) TYPE_LABEL="type: feature" ;;
|
|
67
|
+
enhancement|refactor|refactoring) TYPE_LABEL="type: enhancement" ;;
|
|
68
|
+
docs|documentation) TYPE_LABEL="type: documentation" ;;
|
|
69
|
+
dependency-upgrade) TYPE_LABEL="type: dependency-upgrade" ;;
|
|
70
|
+
task|chore) TYPE_LABEL="type: task" ;;
|
|
71
|
+
*) TYPE_LABEL="" ;;
|
|
72
|
+
esac
|
|
73
|
+
|
|
74
|
+
if [ -n "$TYPE_LABEL" ]; then
|
|
75
|
+
current_type_labels=$(gh issue view "$ISSUE_NUMBER" \
|
|
76
|
+
--repo "$GITHUB_REPOSITORY" \
|
|
77
|
+
--json labels --jq '.labels[].name | select(startswith("type:"))' \
|
|
78
|
+
2>/dev/null || true)
|
|
79
|
+
|
|
80
|
+
printf '%s\n' "$current_type_labels" | while IFS= read -r label; do
|
|
81
|
+
[ -z "$label" ] && continue
|
|
82
|
+
if [ "$label" != "$TYPE_LABEL" ]; then
|
|
83
|
+
gh issue edit "$ISSUE_NUMBER" \
|
|
84
|
+
--repo "$GITHUB_REPOSITORY" \
|
|
85
|
+
--remove-label "$label" \
|
|
86
|
+
2>/dev/null || true
|
|
87
|
+
fi
|
|
88
|
+
done || true
|
|
89
|
+
|
|
90
|
+
if ! printf '%s\n' "$current_type_labels" | grep -qxF "$TYPE_LABEL"; then
|
|
91
|
+
gh issue edit "$ISSUE_NUMBER" \
|
|
92
|
+
--repo "$GITHUB_REPOSITORY" \
|
|
93
|
+
--add-label "$TYPE_LABEL" \
|
|
94
|
+
2>/dev/null || true
|
|
95
|
+
fi
|
|
96
|
+
fi
|
|
97
|
+
|
|
98
|
+
- name: Sync milestone
|
|
99
|
+
if: steps.metadata.outputs.is_task_comment == 'true' && steps.metadata.outputs.milestone != ''
|
|
100
|
+
env:
|
|
101
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
102
|
+
ISSUE_NUMBER: ${{ github.event.issue.number }}
|
|
103
|
+
MILESTONE: ${{ steps.metadata.outputs.milestone }}
|
|
104
|
+
run: |
|
|
105
|
+
gh issue edit "$ISSUE_NUMBER" \
|
|
106
|
+
--repo "$GITHUB_REPOSITORY" \
|
|
107
|
+
--milestone "$MILESTONE" \
|
|
108
|
+
2>/dev/null || true
|
|
109
|
+
|
|
110
|
+
- name: Sync issue type
|
|
111
|
+
if: steps.metadata.outputs.is_task_comment == 'true' && steps.metadata.outputs.type != ''
|
|
112
|
+
env:
|
|
113
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
114
|
+
ISSUE_NUMBER: ${{ github.event.issue.number }}
|
|
115
|
+
TYPE: ${{ steps.metadata.outputs.type }}
|
|
116
|
+
run: |
|
|
117
|
+
case "$TYPE" in
|
|
118
|
+
bug|bugfix) ISSUE_TYPE="Bug" ;;
|
|
119
|
+
feature|enhancement) ISSUE_TYPE="Feature" ;;
|
|
120
|
+
*) ISSUE_TYPE="Task" ;;
|
|
121
|
+
esac
|
|
122
|
+
|
|
123
|
+
gh api "repos/$GITHUB_REPOSITORY/issues/$ISSUE_NUMBER" \
|
|
124
|
+
-X PATCH \
|
|
125
|
+
-f type="$ISSUE_TYPE" \
|
|
126
|
+
--silent \
|
|
127
|
+
2>/dev/null || true
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
name: PR Label & Assignee
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request_target:
|
|
5
|
+
types: [opened, synchronize]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
issues: write
|
|
10
|
+
pull-requests: write
|
|
11
|
+
|
|
12
|
+
concurrency:
|
|
13
|
+
group: pr-label-${{ github.event.pull_request.number }}
|
|
14
|
+
cancel-in-progress: true
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
label-and-assign:
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
steps:
|
|
20
|
+
- name: Checkout base branch
|
|
21
|
+
uses: actions/checkout@v4
|
|
22
|
+
|
|
23
|
+
- name: Sync in-labels
|
|
24
|
+
env:
|
|
25
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
26
|
+
PR_NUMBER: ${{ github.event.pull_request.number }}
|
|
27
|
+
run: |
|
|
28
|
+
changed_files=$(gh api "repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER/files" \
|
|
29
|
+
--paginate --jq '[.[].filename]')
|
|
30
|
+
|
|
31
|
+
should_labels=$(jq -rn \
|
|
32
|
+
--argjson files "$changed_files" \
|
|
33
|
+
--argjson mapping "$(jq '.labels.in // {}' .agents/.airc.json)" \
|
|
34
|
+
'$mapping
|
|
35
|
+
| to_entries
|
|
36
|
+
| map(select(.value | any(. as $prefix | $files | any(startswith($prefix)))))
|
|
37
|
+
| map("in: " + .key)
|
|
38
|
+
| .[]?')
|
|
39
|
+
|
|
40
|
+
current_labels=$(gh pr view "$PR_NUMBER" \
|
|
41
|
+
--repo "$GITHUB_REPOSITORY" \
|
|
42
|
+
--json labels --jq '.labels[].name | select(startswith("in: "))' \
|
|
43
|
+
2>/dev/null || true)
|
|
44
|
+
|
|
45
|
+
printf '%s\n' "$should_labels" | while IFS= read -r label; do
|
|
46
|
+
[ -z "$label" ] && continue
|
|
47
|
+
if ! printf '%s\n' "$current_labels" | grep -qxF "$label"; then
|
|
48
|
+
gh pr edit "$PR_NUMBER" \
|
|
49
|
+
--repo "$GITHUB_REPOSITORY" \
|
|
50
|
+
--add-label "$label" 2>/dev/null || true
|
|
51
|
+
fi
|
|
52
|
+
done
|
|
53
|
+
|
|
54
|
+
printf '%s\n' "$current_labels" | while IFS= read -r label; do
|
|
55
|
+
[ -z "$label" ] && continue
|
|
56
|
+
if ! printf '%s\n' "$should_labels" | grep -qxF "$label"; then
|
|
57
|
+
gh pr edit "$PR_NUMBER" \
|
|
58
|
+
--repo "$GITHUB_REPOSITORY" \
|
|
59
|
+
--remove-label "$label" 2>/dev/null || true
|
|
60
|
+
fi
|
|
61
|
+
done
|
|
62
|
+
|
|
63
|
+
- name: Assign PR creator if unassigned
|
|
64
|
+
env:
|
|
65
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
66
|
+
PR_NUMBER: ${{ github.event.pull_request.number }}
|
|
67
|
+
CREATOR: ${{ github.event.pull_request.user.login }}
|
|
68
|
+
ASSIGNEES_JSON: ${{ toJSON(github.event.pull_request.assignees) }}
|
|
69
|
+
run: |
|
|
70
|
+
count=$(printf '%s' "$ASSIGNEES_JSON" | jq 'length')
|
|
71
|
+
if [ "$count" -eq 0 ]; then
|
|
72
|
+
gh pr edit "$PR_NUMBER" \
|
|
73
|
+
--repo "$GITHUB_REPOSITORY" \
|
|
74
|
+
--add-assignee "$CREATOR" 2>/dev/null || true
|
|
75
|
+
fi
|
|
@@ -40,19 +40,23 @@ jobs:
|
|
|
40
40
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
41
41
|
ISSUE_NUMBER: ${{ github.event.issue.number }}
|
|
42
42
|
run: |
|
|
43
|
-
gh issue view "$ISSUE_NUMBER" \
|
|
43
|
+
current_status_labels=$(gh issue view "$ISSUE_NUMBER" \
|
|
44
44
|
--repo "$GITHUB_REPOSITORY" \
|
|
45
45
|
--json labels --jq '.labels[].name | select(startswith("status:"))' \
|
|
46
|
-
2>/dev/null
|
|
47
|
-
| while IFS= read -r label; do
|
|
48
|
-
|
|
46
|
+
2>/dev/null || true)
|
|
47
|
+
printf '%s\n' "$current_status_labels" | while IFS= read -r label; do
|
|
48
|
+
[ -z "$label" ] && continue
|
|
49
|
+
if [ "$label" != "status: waiting-for-triage" ]; then
|
|
49
50
|
gh issue edit "$ISSUE_NUMBER" \
|
|
50
51
|
--repo "$GITHUB_REPOSITORY" \
|
|
51
52
|
--remove-label "$label"
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
fi
|
|
54
|
+
done || true
|
|
55
|
+
if ! printf '%s\n' "$current_status_labels" | grep -qxF "status: waiting-for-triage"; then
|
|
56
|
+
gh issue edit "$ISSUE_NUMBER" \
|
|
57
|
+
--repo "$GITHUB_REPOSITORY" \
|
|
58
|
+
--add-label "status: waiting-for-triage"
|
|
59
|
+
fi
|
|
56
60
|
|
|
57
61
|
- name: Clean status labels on PR merge
|
|
58
62
|
if: >-
|