github-issue-tower-defence-management 2.41.0 → 2.43.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.
Files changed (24) hide show
  1. package/README.md +59 -0
  2. package/bin/adapter/entry-points/cli/index.js +92 -0
  3. package/bin/adapter/entry-points/cli/index.js.map +1 -1
  4. package/bin/adapter/entry-points/console/ui-dist/assets/index-CFS8x2a1.js +88 -0
  5. package/bin/adapter/entry-points/console/ui-dist/index.html +1 -1
  6. package/bin/adapter/repositories/RestGitHubActionsRepository.js +112 -0
  7. package/bin/adapter/repositories/RestGitHubActionsRepository.js.map +1 -0
  8. package/bin/domain/entities/DoraMetrics.js +3 -0
  9. package/bin/domain/entities/DoraMetrics.js.map +1 -0
  10. package/bin/domain/usecases/DoraMetricsWeeklyMeasureUseCase.js +105 -0
  11. package/bin/domain/usecases/DoraMetricsWeeklyMeasureUseCase.js.map +1 -0
  12. package/bin/domain/usecases/adapter-interfaces/GitHubActionsRepository.js +3 -0
  13. package/bin/domain/usecases/adapter-interfaces/GitHubActionsRepository.js.map +1 -0
  14. package/package.json +1 -1
  15. package/types/adapter/entry-points/cli/index.d.ts.map +1 -1
  16. package/types/adapter/repositories/RestGitHubActionsRepository.d.ts +12 -0
  17. package/types/adapter/repositories/RestGitHubActionsRepository.d.ts.map +1 -0
  18. package/types/domain/entities/DoraMetrics.d.ts +30 -0
  19. package/types/domain/entities/DoraMetrics.d.ts.map +1 -0
  20. package/types/domain/usecases/DoraMetricsWeeklyMeasureUseCase.d.ts +22 -0
  21. package/types/domain/usecases/DoraMetricsWeeklyMeasureUseCase.d.ts.map +1 -0
  22. package/types/domain/usecases/adapter-interfaces/GitHubActionsRepository.d.ts +7 -0
  23. package/types/domain/usecases/adapter-interfaces/GitHubActionsRepository.d.ts.map +1 -0
  24. package/bin/adapter/entry-points/console/ui-dist/assets/index-Cuq8MGJN.js +0 -88
@@ -4,7 +4,7 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>TDPM Console</title>
7
- <script type="module" crossorigin src="/assets/index-Cuq8MGJN.js"></script>
7
+ <script type="module" crossorigin src="/assets/index-CFS8x2a1.js"></script>
8
8
  <link rel="stylesheet" crossorigin href="/assets/index-C23_HNwW.css">
9
9
  </head>
10
10
  <body>
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.RestGitHubActionsRepository = void 0;
7
+ const ky_1 = __importDefault(require("ky"));
8
+ class RestGitHubActionsRepository {
9
+ constructor(defaultGhToken, tokenOverrides = {}) {
10
+ this.defaultGhToken = defaultGhToken;
11
+ this.tokenOverrides = tokenOverrides;
12
+ this.getToken = (owner) => {
13
+ return this.tokenOverrides[owner] ?? this.defaultGhToken;
14
+ };
15
+ this.getWorkflowRuns = async (owner, repo, workflowFile, branch, since, until) => {
16
+ const allRuns = [];
17
+ for (let page = 1;; page++) {
18
+ const searchParams = {
19
+ per_page: '100',
20
+ page: String(page),
21
+ };
22
+ if (branch)
23
+ searchParams['branch'] = branch;
24
+ const response = await ky_1.default
25
+ .get(`https://api.github.com/repos/${owner}/${repo}/actions/workflows/${workflowFile}/runs`, {
26
+ searchParams,
27
+ headers: { Authorization: `token ${this.getToken(owner)}` },
28
+ })
29
+ .json();
30
+ allRuns.push(...response.workflow_runs);
31
+ if (response.workflow_runs.length < 100)
32
+ break;
33
+ }
34
+ return allRuns
35
+ .filter((run) => {
36
+ const createdAt = new Date(run.created_at);
37
+ return createdAt >= since && createdAt <= until;
38
+ })
39
+ .map((run) => ({
40
+ conclusion: run.conclusion === 'success' || run.conclusion === 'failure'
41
+ ? run.conclusion
42
+ : null,
43
+ createdAt: new Date(run.created_at),
44
+ updatedAt: new Date(run.updated_at),
45
+ }));
46
+ };
47
+ this.getMergedPullRequests = async (owner, repo, baseBranch, since, until) => {
48
+ const allPrs = [];
49
+ for (let page = 1;; page++) {
50
+ const searchParams = {
51
+ state: 'closed',
52
+ per_page: '100',
53
+ page: String(page),
54
+ };
55
+ if (baseBranch)
56
+ searchParams['base'] = baseBranch;
57
+ const prs = await ky_1.default
58
+ .get(`https://api.github.com/repos/${owner}/${repo}/pulls`, {
59
+ searchParams,
60
+ headers: { Authorization: `token ${this.getToken(owner)}` },
61
+ })
62
+ .json();
63
+ allPrs.push(...prs);
64
+ if (prs.length < 100)
65
+ break;
66
+ }
67
+ const isMergedInWindow = (pr) => {
68
+ if (pr.merged_at === null)
69
+ return false;
70
+ const mergedAt = new Date(pr.merged_at);
71
+ return mergedAt >= since && mergedAt <= until;
72
+ };
73
+ return allPrs.filter(isMergedInWindow).map((pr) => ({
74
+ mergedAt: new Date(pr.merged_at),
75
+ createdAt: new Date(pr.created_at),
76
+ }));
77
+ };
78
+ this.getClosedItemsByLabels = async (owner, repo, labels, since, until) => {
79
+ if (labels.length === 0)
80
+ return [];
81
+ const allItems = [];
82
+ for (let page = 1;; page++) {
83
+ const items = await ky_1.default
84
+ .get(`https://api.github.com/repos/${owner}/${repo}/issues`, {
85
+ searchParams: {
86
+ state: 'closed',
87
+ labels: labels.join(','),
88
+ per_page: '100',
89
+ page: String(page),
90
+ },
91
+ headers: { Authorization: `token ${this.getToken(owner)}` },
92
+ })
93
+ .json();
94
+ allItems.push(...items);
95
+ if (items.length < 100)
96
+ break;
97
+ }
98
+ const isClosedInWindow = (item) => {
99
+ if (item.closed_at === null)
100
+ return false;
101
+ const closedAt = new Date(item.closed_at);
102
+ return closedAt >= since && closedAt <= until;
103
+ };
104
+ return allItems.filter(isClosedInWindow).map((item) => ({
105
+ createdAt: new Date(item.created_at),
106
+ closedAt: new Date(item.closed_at),
107
+ }));
108
+ };
109
+ }
110
+ }
111
+ exports.RestGitHubActionsRepository = RestGitHubActionsRepository;
112
+ //# sourceMappingURL=RestGitHubActionsRepository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RestGitHubActionsRepository.js","sourceRoot":"","sources":["../../../src/adapter/repositories/RestGitHubActionsRepository.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=DoraMetrics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DoraMetrics.js","sourceRoot":"","sources":["../../../src/domain/entities/DoraMetrics.ts"],"names":[],"mappings":""}
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DoraMetricsWeeklyMeasureUseCase = void 0;
4
+ class DoraMetricsWeeklyMeasureUseCase {
5
+ constructor(githubActionsRepository, createNewIssue) {
6
+ this.githubActionsRepository = githubActionsRepository;
7
+ this.createNewIssue = createNewIssue;
8
+ this.run = async (params) => {
9
+ const metrics = [];
10
+ for (const project of params.projects) {
11
+ const projectMetrics = await this.measureProject(project, params.since, params.until);
12
+ metrics.push(projectMetrics);
13
+ }
14
+ const reportTitle = `DORAメトリクス週次レポート ${this.formatDate(params.until)}`;
15
+ const reportBody = this.buildReportBody(metrics, params.since, params.until);
16
+ await this.createNewIssue(params.reportOwner, params.reportRepo, reportTitle, reportBody, [], []);
17
+ };
18
+ this.measureProject = async (config, since, until) => {
19
+ const allRuns = [];
20
+ for (const workflowFile of config.deployWorkflowFiles) {
21
+ const runs = await this.githubActionsRepository.getWorkflowRuns(config.owner, config.repo, workflowFile, config.deployBranch, since, until);
22
+ allRuns.push(...runs);
23
+ }
24
+ const mergedPRs = await this.githubActionsRepository.getMergedPullRequests(config.owner, config.repo, config.prBaseBranch, since, until);
25
+ const deployFrequency = config.deployWorkflowFiles.length > 0 ? allRuns.length : mergedPRs.length;
26
+ const changeFailureRate = config.deployWorkflowFiles.length > 0 && deployFrequency > 0
27
+ ? allRuns.filter((r) => r.conclusion === 'failure').length /
28
+ deployFrequency
29
+ : null;
30
+ const changeLeadTimeHours = config.deployWorkflowFiles.length > 0 && allRuns.length === 0
31
+ ? null
32
+ : this.calculateChangeLeadTime(mergedPRs, allRuns);
33
+ const hotfixItems = await this.githubActionsRepository.getClosedItemsByLabels(config.owner, config.repo, config.mttrLabels, since, until);
34
+ const mttrHours = this.calculateMttr(hotfixItems);
35
+ return {
36
+ projectName: config.name,
37
+ deployFrequency,
38
+ changeFailureRate,
39
+ changeLeadTimeHours,
40
+ mttrHours,
41
+ };
42
+ };
43
+ this.calculateChangeLeadTime = (prs, runs) => {
44
+ if (prs.length === 0)
45
+ return null;
46
+ if (runs.length > 0) {
47
+ const sortedRuns = [...runs].sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
48
+ const matched = prs.flatMap((pr) => {
49
+ const nextRun = sortedRuns.find((r) => r.createdAt >= pr.mergedAt);
50
+ if (!nextRun)
51
+ return [];
52
+ return [
53
+ (nextRun.updatedAt.getTime() - pr.mergedAt.getTime()) / 3600000,
54
+ ];
55
+ });
56
+ return matched.length > 0
57
+ ? matched.reduce((a, b) => a + b, 0) / matched.length
58
+ : null;
59
+ }
60
+ const totalHours = prs.reduce((sum, pr) => sum + (pr.mergedAt.getTime() - pr.createdAt.getTime()) / 3600000, 0);
61
+ return totalHours / prs.length;
62
+ };
63
+ this.calculateMttr = (items) => {
64
+ if (items.length === 0)
65
+ return null;
66
+ const totalHours = items.reduce((sum, item) => sum + (item.closedAt.getTime() - item.createdAt.getTime()) / 3600000, 0);
67
+ return totalHours / items.length;
68
+ };
69
+ this.formatDate = (date) => {
70
+ const y = date.getUTCFullYear();
71
+ const m = String(date.getUTCMonth() + 1).padStart(2, '0');
72
+ const d = String(date.getUTCDate()).padStart(2, '0');
73
+ return `${y}-${m}-${d}`;
74
+ };
75
+ this.buildReportBody = (metrics, since, until) => {
76
+ const sinceStr = this.formatDate(since);
77
+ const untilStr = this.formatDate(until);
78
+ const rows = metrics.map((m) => {
79
+ const failRate = m.changeFailureRate !== null
80
+ ? `${(m.changeFailureRate * 100).toFixed(1)}%`
81
+ : 'N/A';
82
+ const leadTime = m.changeLeadTimeHours !== null
83
+ ? m.changeLeadTimeHours.toFixed(1)
84
+ : 'N/A';
85
+ const mttr = m.mttrHours !== null ? m.mttrHours.toFixed(1) : 'N/A';
86
+ return `| ${m.projectName} | ${m.deployFrequency} | ${failRate} | ${leadTime} | ${mttr} |`;
87
+ });
88
+ return [
89
+ `## DORAメトリクス週次レポート(${untilStr}週)`,
90
+ '',
91
+ `計測期間: ${sinceStr} 〜 ${untilStr}`,
92
+ '',
93
+ '| プロジェクト | デプロイ頻度(回) | 変更失敗率 | 変更リードタイム(時間) | MTTR(時間) |',
94
+ '|---|---|---|---|---|',
95
+ ...rows,
96
+ '',
97
+ '---',
98
+ '',
99
+ '詳細はワークフローログを参照。',
100
+ ].join('\n');
101
+ };
102
+ }
103
+ }
104
+ exports.DoraMetricsWeeklyMeasureUseCase = DoraMetricsWeeklyMeasureUseCase;
105
+ //# sourceMappingURL=DoraMetricsWeeklyMeasureUseCase.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DoraMetricsWeeklyMeasureUseCase.js","sourceRoot":"","sources":["../../../src/domain/usecases/DoraMetricsWeeklyMeasureUseCase.ts"],"names":[],"mappings":";;;AAkBA,MAAa,+BAA+B;IAC1C,YACmB,uBAAgD,EAChD,cAA8B;QAD9B,4BAAuB,GAAvB,uBAAuB,CAAyB;QAChD,mBAAc,GAAd,cAAc,CAAgB;QAGjD,QAAG,GAAG,KAAK,EAAE,MAMZ,EAAiB,EAAE;YAClB,MAAM,OAAO,GAAyB,EAAE,CAAC;YAEzC,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;gBACtC,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,cAAc,CAC9C,OAAO,EACP,MAAM,CAAC,KAAK,EACZ,MAAM,CAAC,KAAK,CACb,CAAC;gBACF,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAC/B,CAAC;YAED,MAAM,WAAW,GAAG,mBAAmB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YACvE,MAAM,UAAU,GAAG,IAAI,CAAC,eAAe,CACrC,OAAO,EACP,MAAM,CAAC,KAAK,EACZ,MAAM,CAAC,KAAK,CACb,CAAC;YAEF,MAAM,IAAI,CAAC,cAAc,CACvB,MAAM,CAAC,WAAW,EAClB,MAAM,CAAC,UAAU,EACjB,WAAW,EACX,UAAU,EACV,EAAE,EACF,EAAE,CACH,CAAC;QACJ,CAAC,CAAC;QAEM,mBAAc,GAAG,KAAK,EAC5B,MAAyB,EACzB,KAAW,EACX,KAAW,EACkB,EAAE;YAC/B,MAAM,OAAO,GAAkB,EAAE,CAAC;YAClC,KAAK,MAAM,YAAY,IAAI,MAAM,CAAC,mBAAmB,EAAE,CAAC;gBACtD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,uBAAuB,CAAC,eAAe,CAC7D,MAAM,CAAC,KAAK,EACZ,MAAM,CAAC,IAAI,EACX,YAAY,EACZ,MAAM,CAAC,YAAY,EACnB,KAAK,EACL,KAAK,CACN,CAAC;gBACF,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;YACxB,CAAC;YAED,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,uBAAuB,CAAC,qBAAqB,CACxE,MAAM,CAAC,KAAK,EACZ,MAAM,CAAC,IAAI,EACX,MAAM,CAAC,YAAY,EACnB,KAAK,EACL,KAAK,CACN,CAAC;YAEF,MAAM,eAAe,GACnB,MAAM,CAAC,mBAAmB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC;YAC5E,MAAM,iBAAiB,GACrB,MAAM,CAAC,mBAAmB,CAAC,MAAM,GAAG,CAAC,IAAI,eAAe,GAAG,CAAC;gBAC1D,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,MAAM;oBACxD,eAAe;gBACjB,CAAC,CAAC,IAAI,CAAC;YAEX,MAAM,mBAAmB,GACvB,MAAM,CAAC,mBAAmB,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;gBAC3D,CAAC,CAAC,IAAI;gBACN,CAAC,CAAC,IAAI,CAAC,uBAAuB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YAEvD,MAAM,WAAW,GACf,MAAM,IAAI,CAAC,uBAAuB,CAAC,sBAAsB,CACvD,MAAM,CAAC,KAAK,EACZ,MAAM,CAAC,IAAI,EACX,MAAM,CAAC,UAAU,EACjB,KAAK,EACL,KAAK,CACN,CAAC;YAEJ,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;YAElD,OAAO;gBACL,WAAW,EAAE,MAAM,CAAC,IAAI;gBACxB,eAAe;gBACf,iBAAiB;gBACjB,mBAAmB;gBACnB,SAAS;aACV,CAAC;QACJ,CAAC,CAAC;QAEM,4BAAuB,GAAG,CAChC,GAAwB,EACxB,IAAmB,EACJ,EAAE;YACjB,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,IAAI,CAAC;YAElC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACpB,MAAM,UAAU,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,CAC/B,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,CACxD,CAAC;gBACF,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE;oBACjC,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,IAAI,EAAE,CAAC,QAAQ,CAAC,CAAC;oBACnE,IAAI,CAAC,OAAO;wBAAE,OAAO,EAAE,CAAC;oBACxB,OAAO;wBACL,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,GAAG,OAAO;qBAChE,CAAC;gBACJ,CAAC,CAAC,CAAC;gBACH,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC;oBACvB,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM;oBACrD,CAAC,CAAC,IAAI,CAAC;YACX,CAAC;YAED,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,CAC3B,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,CACV,GAAG,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,GAAG,OAAO,EAClE,CAAC,CACF,CAAC;YACF,OAAO,UAAU,GAAG,GAAG,CAAC,MAAM,CAAC;QACjC,CAAC,CAAC;QAEM,kBAAa,GAAG,CAAC,KAAmB,EAAiB,EAAE;YAC7D,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,IAAI,CAAC;YACpC,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAC7B,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CACZ,GAAG,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,GAAG,OAAO,EACtE,CAAC,CACF,CAAC;YACF,OAAO,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC;QACnC,CAAC,CAAC;QAEM,eAAU,GAAG,CAAC,IAAU,EAAU,EAAE;YAC1C,MAAM,CAAC,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;YAChC,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;YAC1D,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;YACrD,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1B,CAAC,CAAC;QAEM,oBAAe,GAAG,CACxB,OAA6B,EAC7B,KAAW,EACX,KAAW,EACH,EAAE;YACV,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YAExC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;gBAC7B,MAAM,QAAQ,GACZ,CAAC,CAAC,iBAAiB,KAAK,IAAI;oBAC1B,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,iBAAiB,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG;oBAC9C,CAAC,CAAC,KAAK,CAAC;gBACZ,MAAM,QAAQ,GACZ,CAAC,CAAC,mBAAmB,KAAK,IAAI;oBAC5B,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC;oBAClC,CAAC,CAAC,KAAK,CAAC;gBACZ,MAAM,IAAI,GAAG,CAAC,CAAC,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;gBACnE,OAAO,KAAK,CAAC,CAAC,WAAW,MAAM,CAAC,CAAC,eAAe,MAAM,QAAQ,MAAM,QAAQ,MAAM,IAAI,IAAI,CAAC;YAC7F,CAAC,CAAC,CAAC;YAEH,OAAO;gBACL,sBAAsB,QAAQ,IAAI;gBAClC,EAAE;gBACF,SAAS,QAAQ,MAAM,QAAQ,EAAE;gBACjC,EAAE;gBACF,0DAA0D;gBAC1D,uBAAuB;gBACvB,GAAG,IAAI;gBACP,EAAE;gBACF,KAAK;gBACL,EAAE;gBACF,iBAAiB;aAClB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACf,CAAC,CAAC;IAjLC,CAAC;CAkLL;AAtLD,0EAsLC"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=GitHubActionsRepository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GitHubActionsRepository.js","sourceRoot":"","sources":["../../../../src/domain/usecases/adapter-interfaces/GitHubActionsRepository.ts"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "github-issue-tower-defence-management",
3
- "version": "2.41.0",
3
+ "version": "2.43.0",
4
4
  "description": "",
5
5
  "main": "bin/index.js",
6
6
  "scripts": {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/cli/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,cAAc,EACd,YAAY,EACZ,wBAAwB,GACzB,MAAM,iBAAiB,CAAC;AAqPzB,eAAO,MAAM,OAAO,SAAgB,CAAC;AAqoCrC,eAAO,MAAM,uBAAuB,GAAI,OAAO,OAAO,KAAG,IAGxD,CAAC;AAuCF,eAAO,MAAM,aAAa,GACxB,MAAM,MAAM,EAAE,EACd,kBAAkB,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,KACzC,OAAO,CAAC,IAAI,CAqCd,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/cli/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,cAAc,EACd,YAAY,EACZ,wBAAwB,GACzB,MAAM,iBAAiB,CAAC;AA6PzB,eAAO,MAAM,OAAO,SAAgB,CAAC;AAmxCrC,eAAO,MAAM,uBAAuB,GAAI,OAAO,OAAO,KAAG,IAGxD,CAAC;AAuCF,eAAO,MAAM,aAAa,GACxB,MAAM,MAAM,EAAE,EACd,kBAAkB,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,KACzC,OAAO,CAAC,IAAI,CAqCd,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { ClosedItem, MergedPullRequest, WorkflowRun } from '../../domain/entities/DoraMetrics';
2
+ import { GitHubActionsRepository } from '../../domain/usecases/adapter-interfaces/GitHubActionsRepository';
3
+ export declare class RestGitHubActionsRepository implements GitHubActionsRepository {
4
+ private readonly defaultGhToken;
5
+ private readonly tokenOverrides;
6
+ constructor(defaultGhToken: string, tokenOverrides?: Record<string, string>);
7
+ private getToken;
8
+ getWorkflowRuns: (owner: string, repo: string, workflowFile: string, branch: string | null, since: Date, until: Date) => Promise<WorkflowRun[]>;
9
+ getMergedPullRequests: (owner: string, repo: string, baseBranch: string | null, since: Date, until: Date) => Promise<MergedPullRequest[]>;
10
+ getClosedItemsByLabels: (owner: string, repo: string, labels: string[], since: Date, until: Date) => Promise<ClosedItem[]>;
11
+ }
12
+ //# sourceMappingURL=RestGitHubActionsRepository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RestGitHubActionsRepository.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/RestGitHubActionsRepository.ts"],"names":[],"mappings":"AACA,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,WAAW,EACZ,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,uBAAuB,EAAE,MAAM,kEAAkE,CAAC;AAgC3G,qBAAa,2BAA4B,YAAW,uBAAuB;IAEvE,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,cAAc;gBADd,cAAc,EAAE,MAAM,EACtB,cAAc,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM;IAG9D,OAAO,CAAC,QAAQ,CAEd;IAEF,eAAe,GACb,OAAO,MAAM,EACb,MAAM,MAAM,EACZ,cAAc,MAAM,EACpB,QAAQ,MAAM,GAAG,IAAI,EACrB,OAAO,IAAI,EACX,OAAO,IAAI,KACV,OAAO,CAAC,WAAW,EAAE,CAAC,CAoCvB;IAEF,qBAAqB,GACnB,OAAO,MAAM,EACb,MAAM,MAAM,EACZ,YAAY,MAAM,GAAG,IAAI,EACzB,OAAO,IAAI,EACX,OAAO,IAAI,KACV,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAiC7B;IAEF,sBAAsB,GACpB,OAAO,MAAM,EACb,MAAM,MAAM,EACZ,QAAQ,MAAM,EAAE,EAChB,OAAO,IAAI,EACX,OAAO,IAAI,KACV,OAAO,CAAC,UAAU,EAAE,CAAC,CAiCtB;CACH"}
@@ -0,0 +1,30 @@
1
+ export type WorkflowRun = {
2
+ conclusion: 'success' | 'failure' | null;
3
+ createdAt: Date;
4
+ updatedAt: Date;
5
+ };
6
+ export type MergedPullRequest = {
7
+ mergedAt: Date;
8
+ createdAt: Date;
9
+ };
10
+ export type ClosedItem = {
11
+ createdAt: Date;
12
+ closedAt: Date;
13
+ };
14
+ export type ProjectDoraConfig = {
15
+ name: string;
16
+ owner: string;
17
+ repo: string;
18
+ deployWorkflowFiles: string[];
19
+ deployBranch: string | null;
20
+ prBaseBranch: string | null;
21
+ mttrLabels: string[];
22
+ };
23
+ export type ProjectDoraMetrics = {
24
+ projectName: string;
25
+ deployFrequency: number;
26
+ changeFailureRate: number | null;
27
+ changeLeadTimeHours: number | null;
28
+ mttrHours: number | null;
29
+ };
30
+ //# sourceMappingURL=DoraMetrics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DoraMetrics.d.ts","sourceRoot":"","sources":["../../../src/domain/entities/DoraMetrics.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG;IACxB,UAAU,EAAE,SAAS,GAAG,SAAS,GAAG,IAAI,CAAC;IACzC,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,EAAE,IAAI,CAAC;IACf,SAAS,EAAE,IAAI,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,SAAS,EAAE,IAAI,CAAC;IAChB,QAAQ,EAAE,IAAI,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { ProjectDoraConfig } from '../entities/DoraMetrics';
2
+ import { GitHubActionsRepository } from './adapter-interfaces/GitHubActionsRepository';
3
+ type CreateNewIssue = (owner: string, repo: string, title: string, body: string, assignees: string[], labels: string[]) => Promise<number>;
4
+ export declare class DoraMetricsWeeklyMeasureUseCase {
5
+ private readonly githubActionsRepository;
6
+ private readonly createNewIssue;
7
+ constructor(githubActionsRepository: GitHubActionsRepository, createNewIssue: CreateNewIssue);
8
+ run: (params: {
9
+ projects: ProjectDoraConfig[];
10
+ reportOwner: string;
11
+ reportRepo: string;
12
+ since: Date;
13
+ until: Date;
14
+ }) => Promise<void>;
15
+ private measureProject;
16
+ private calculateChangeLeadTime;
17
+ private calculateMttr;
18
+ private formatDate;
19
+ private buildReportBody;
20
+ }
21
+ export {};
22
+ //# sourceMappingURL=DoraMetricsWeeklyMeasureUseCase.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DoraMetricsWeeklyMeasureUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/DoraMetricsWeeklyMeasureUseCase.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,iBAAiB,EAGlB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,uBAAuB,EAAE,MAAM,8CAA8C,CAAC;AAEvF,KAAK,cAAc,GAAG,CACpB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EAAE,EACnB,MAAM,EAAE,MAAM,EAAE,KACb,OAAO,CAAC,MAAM,CAAC,CAAC;AAErB,qBAAa,+BAA+B;IAExC,OAAO,CAAC,QAAQ,CAAC,uBAAuB;IACxC,OAAO,CAAC,QAAQ,CAAC,cAAc;gBADd,uBAAuB,EAAE,uBAAuB,EAChD,cAAc,EAAE,cAAc;IAGjD,GAAG,GAAU,QAAQ;QACnB,QAAQ,EAAE,iBAAiB,EAAE,CAAC;QAC9B,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,IAAI,CAAC;QACZ,KAAK,EAAE,IAAI,CAAC;KACb,KAAG,OAAO,CAAC,IAAI,CAAC,CA2Bf;IAEF,OAAO,CAAC,cAAc,CAyDpB;IAEF,OAAO,CAAC,uBAAuB,CA4B7B;IAEF,OAAO,CAAC,aAAa,CAQnB;IAEF,OAAO,CAAC,UAAU,CAKhB;IAEF,OAAO,CAAC,eAAe,CAkCrB;CACH"}
@@ -0,0 +1,7 @@
1
+ import { ClosedItem, MergedPullRequest, WorkflowRun } from '../../entities/DoraMetrics';
2
+ export interface GitHubActionsRepository {
3
+ getWorkflowRuns: (owner: string, repo: string, workflowFile: string, branch: string | null, since: Date, until: Date) => Promise<WorkflowRun[]>;
4
+ getMergedPullRequests: (owner: string, repo: string, baseBranch: string | null, since: Date, until: Date) => Promise<MergedPullRequest[]>;
5
+ getClosedItemsByLabels: (owner: string, repo: string, labels: string[], since: Date, until: Date) => Promise<ClosedItem[]>;
6
+ }
7
+ //# sourceMappingURL=GitHubActionsRepository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GitHubActionsRepository.d.ts","sourceRoot":"","sources":["../../../../src/domain/usecases/adapter-interfaces/GitHubActionsRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,WAAW,EACZ,MAAM,4BAA4B,CAAC;AAEpC,MAAM,WAAW,uBAAuB;IACtC,eAAe,EAAE,CACf,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,KAAK,EAAE,IAAI,EACX,KAAK,EAAE,IAAI,KACR,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAC5B,qBAAqB,EAAE,CACrB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,GAAG,IAAI,EACzB,KAAK,EAAE,IAAI,EACX,KAAK,EAAE,IAAI,KACR,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;IAClC,sBAAsB,EAAE,CACtB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EAAE,EAChB,KAAK,EAAE,IAAI,EACX,KAAK,EAAE,IAAI,KACR,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;CAC5B"}