acdev 1.0.0
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/.acdev/.env.example +13 -0
- package/README.md +231 -0
- package/bin/acdev.js +138 -0
- package/package.json +56 -0
- package/public/acdev_wordmark_logo.svg +10 -0
- package/public/app.js +3291 -0
- package/public/index.html +449 -0
- package/public/styles.css +1870 -0
- package/src/afterPrRules.js +116 -0
- package/src/agent.js +669 -0
- package/src/claude-auth.js +81 -0
- package/src/config.js +426 -0
- package/src/env.js +98 -0
- package/src/gh-auth.js +41 -0
- package/src/git.js +867 -0
- package/src/github.js +179 -0
- package/src/jira.js +418 -0
- package/src/paths.js +128 -0
- package/src/server.js +988 -0
- package/src/store.js +135 -0
- package/src/urls.js +16 -0
- package/src/usage.js +122 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Best-effort post-PR ticket rules (Jira transition / GitHub label or close).
|
|
3
|
+
* Failures must never undo a successful PR open.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { normalizeGithubRules, normalizeJiraRules } from './config.js';
|
|
7
|
+
import { addIssueLabel, closeIssue } from './github.js';
|
|
8
|
+
import { resolveJiraCredentials, transitionJiraIssue } from './jira.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @param {{
|
|
12
|
+
* job: {
|
|
13
|
+
* id: string,
|
|
14
|
+
* ticketSource?: string,
|
|
15
|
+
* jiraKey?: string,
|
|
16
|
+
* issueNumber?: number,
|
|
17
|
+
* worktreePath?: string,
|
|
18
|
+
* },
|
|
19
|
+
* config: object,
|
|
20
|
+
* repoRoot: string,
|
|
21
|
+
* appendLog: (job: object, type: string, payload: string) => object,
|
|
22
|
+
* deps?: {
|
|
23
|
+
* transitionJiraIssue?: typeof transitionJiraIssue,
|
|
24
|
+
* addIssueLabel?: typeof addIssueLabel,
|
|
25
|
+
* closeIssue?: typeof closeIssue,
|
|
26
|
+
* resolveJiraCredentials?: typeof resolveJiraCredentials,
|
|
27
|
+
* },
|
|
28
|
+
* }} params
|
|
29
|
+
* @returns {Promise<{ applied: boolean, message?: string }>}
|
|
30
|
+
*/
|
|
31
|
+
export async function applyAfterPrOpenedRules({
|
|
32
|
+
job,
|
|
33
|
+
config,
|
|
34
|
+
repoRoot,
|
|
35
|
+
appendLog,
|
|
36
|
+
deps = {},
|
|
37
|
+
}) {
|
|
38
|
+
const doTransition = deps.transitionJiraIssue || transitionJiraIssue;
|
|
39
|
+
const doAddLabel = deps.addIssueLabel || addIssueLabel;
|
|
40
|
+
const doClose = deps.closeIssue || closeIssue;
|
|
41
|
+
const doResolveCreds = deps.resolveJiraCredentials || resolveJiraCredentials;
|
|
42
|
+
|
|
43
|
+
const source = job.ticketSource === 'jira' || job.jiraKey ? 'jira' : 'github';
|
|
44
|
+
|
|
45
|
+
try {
|
|
46
|
+
if (source === 'jira') {
|
|
47
|
+
const rules = normalizeJiraRules(config.jiraRules);
|
|
48
|
+
const rule = rules.afterPrOpened;
|
|
49
|
+
if (!rule.enabled) {
|
|
50
|
+
return { applied: false };
|
|
51
|
+
}
|
|
52
|
+
if (!job.jiraKey) {
|
|
53
|
+
const msg = 'Post-PR Jira rule skipped: job has no jiraKey';
|
|
54
|
+
console.warn(`[acdev] ${msg}`);
|
|
55
|
+
appendLog(job, 'warn', msg);
|
|
56
|
+
return { applied: false, message: msg };
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const creds = doResolveCreds({ configBaseUrl: config.jiraBaseUrl });
|
|
60
|
+
if ('error' in creds) {
|
|
61
|
+
const msg = `Post-PR Jira transition failed: ${creds.error}`;
|
|
62
|
+
console.warn(`[acdev] ${msg}`);
|
|
63
|
+
appendLog(job, 'warn', msg);
|
|
64
|
+
return { applied: false, message: msg };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const result = await doTransition(job.jiraKey, rule.targetStatus, creds);
|
|
68
|
+
const msg = `Moved Jira ${result.key} to "${result.statusName}" after PR opened`;
|
|
69
|
+
appendLog(job, 'info', msg);
|
|
70
|
+
return { applied: true, message: msg };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const rules = normalizeGithubRules(config.githubRules);
|
|
74
|
+
const rule = rules.afterPrOpened;
|
|
75
|
+
if (!rule.enabled || rule.action === 'none') {
|
|
76
|
+
return { applied: false };
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (job.issueNumber == null) {
|
|
80
|
+
const msg = 'Post-PR GitHub rule skipped: job has no issueNumber';
|
|
81
|
+
console.warn(`[acdev] ${msg}`);
|
|
82
|
+
appendLog(job, 'warn', msg);
|
|
83
|
+
return { applied: false, message: msg };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const cwd = job.worktreePath || repoRoot;
|
|
87
|
+
|
|
88
|
+
if (rule.action === 'add_label') {
|
|
89
|
+
if (!rule.label) {
|
|
90
|
+
const msg = 'Post-PR GitHub rule skipped: add_label requires a label name';
|
|
91
|
+
console.warn(`[acdev] ${msg}`);
|
|
92
|
+
appendLog(job, 'warn', msg);
|
|
93
|
+
return { applied: false, message: msg };
|
|
94
|
+
}
|
|
95
|
+
await doAddLabel(job.issueNumber, rule.label, cwd);
|
|
96
|
+
const msg = `Added label "${rule.label}" to GitHub issue #${job.issueNumber} after PR opened`;
|
|
97
|
+
appendLog(job, 'info', msg);
|
|
98
|
+
return { applied: true, message: msg };
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (rule.action === 'close_issue') {
|
|
102
|
+
await doClose(job.issueNumber, cwd);
|
|
103
|
+
const msg = `Closed GitHub issue #${job.issueNumber} after PR opened`;
|
|
104
|
+
appendLog(job, 'info', msg);
|
|
105
|
+
return { applied: true, message: msg };
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return { applied: false };
|
|
109
|
+
} catch (err) {
|
|
110
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
111
|
+
const msg = `Post-PR ticket rule failed (PR still opened): ${message}`;
|
|
112
|
+
console.warn(`[acdev] ${msg}`);
|
|
113
|
+
appendLog(job, 'warn', msg);
|
|
114
|
+
return { applied: false, message: msg };
|
|
115
|
+
}
|
|
116
|
+
}
|