github-issue-tower-defence-management 1.1.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 (221) hide show
  1. package/.env.example +6 -0
  2. package/.eslintrc.cjs +55 -0
  3. package/.github/CODEOWNERS +2 -0
  4. package/.github/workflows/assign-all-cards-to-owner.yml +14 -0
  5. package/.github/workflows/commit-lint.yml +54 -0
  6. package/.github/workflows/configs/commitlint.config.js +27 -0
  7. package/.github/workflows/create-pr.yml +64 -0
  8. package/.github/workflows/format.yml +25 -0
  9. package/.github/workflows/publish.yml +47 -0
  10. package/.github/workflows/test.yml +45 -0
  11. package/.github/workflows/umino-project.yml +181 -0
  12. package/.prettierignore +22 -0
  13. package/.prettierrc +5 -0
  14. package/CHANGELOG.md +49 -0
  15. package/CONTRIBUTING.md +107 -0
  16. package/README.md +108 -0
  17. package/bin/adapter/entry-points/cli/index.js +26 -0
  18. package/bin/adapter/entry-points/cli/index.js.map +1 -0
  19. package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js +142 -0
  20. package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js.map +1 -0
  21. package/bin/adapter/repositories/AxiosSlackRepository.js +124 -0
  22. package/bin/adapter/repositories/AxiosSlackRepository.js.map +1 -0
  23. package/bin/adapter/repositories/BaseGitHubRepository.js +136 -0
  24. package/bin/adapter/repositories/BaseGitHubRepository.js.map +1 -0
  25. package/bin/adapter/repositories/GoogleSpreadsheetRepository.js +123 -0
  26. package/bin/adapter/repositories/GoogleSpreadsheetRepository.js.map +1 -0
  27. package/bin/adapter/repositories/GraphqlProjectRepository.js +167 -0
  28. package/bin/adapter/repositories/GraphqlProjectRepository.js.map +1 -0
  29. package/bin/adapter/repositories/LocalStorageCacheRepository.js +46 -0
  30. package/bin/adapter/repositories/LocalStorageCacheRepository.js.map +1 -0
  31. package/bin/adapter/repositories/LocalStorageRepository.js +30 -0
  32. package/bin/adapter/repositories/LocalStorageRepository.js.map +1 -0
  33. package/bin/adapter/repositories/SystemDateRepository.js +23 -0
  34. package/bin/adapter/repositories/SystemDateRepository.js.map +1 -0
  35. package/bin/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.js +148 -0
  36. package/bin/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.js.map +1 -0
  37. package/bin/adapter/repositories/issue/ApiV3IssueRepository.js +48 -0
  38. package/bin/adapter/repositories/issue/ApiV3IssueRepository.js.map +1 -0
  39. package/bin/adapter/repositories/issue/CheerioIssueRepository.js +120 -0
  40. package/bin/adapter/repositories/issue/CheerioIssueRepository.js.map +1 -0
  41. package/bin/adapter/repositories/issue/GraphqlProjectItemRepository.js +485 -0
  42. package/bin/adapter/repositories/issue/GraphqlProjectItemRepository.js.map +1 -0
  43. package/bin/adapter/repositories/issue/InternalGraphqlIssueRepository.js +114 -0
  44. package/bin/adapter/repositories/issue/InternalGraphqlIssueRepository.js.map +1 -0
  45. package/bin/adapter/repositories/issue/RestIssueRepository.js +79 -0
  46. package/bin/adapter/repositories/issue/RestIssueRepository.js.map +1 -0
  47. package/bin/adapter/repositories/issue/issueTimelineUtils.js +38 -0
  48. package/bin/adapter/repositories/issue/issueTimelineUtils.js.map +1 -0
  49. package/bin/adapter/repositories/utils.js +45 -0
  50. package/bin/adapter/repositories/utils.js.map +1 -0
  51. package/bin/domain/entities/Issue.js +3 -0
  52. package/bin/domain/entities/Issue.js.map +1 -0
  53. package/bin/domain/entities/Member.js +3 -0
  54. package/bin/domain/entities/Member.js.map +1 -0
  55. package/bin/domain/entities/Project.js +3 -0
  56. package/bin/domain/entities/Project.js.map +1 -0
  57. package/bin/domain/entities/ProjectField.js +3 -0
  58. package/bin/domain/entities/ProjectField.js.map +1 -0
  59. package/bin/domain/entities/ProjectFieldSingleSelect.js +3 -0
  60. package/bin/domain/entities/ProjectFieldSingleSelect.js.map +1 -0
  61. package/bin/domain/entities/ProjectFieldSingleSelectOption.js +3 -0
  62. package/bin/domain/entities/ProjectFieldSingleSelectOption.js.map +1 -0
  63. package/bin/domain/entities/WorkingTime.js +3 -0
  64. package/bin/domain/entities/WorkingTime.js.map +1 -0
  65. package/bin/domain/usecases/ActionAnnouncementUseCase.js +46 -0
  66. package/bin/domain/usecases/ActionAnnouncementUseCase.js.map +1 -0
  67. package/bin/domain/usecases/AnalyzeProblemByIssueUseCase.js +116 -0
  68. package/bin/domain/usecases/AnalyzeProblemByIssueUseCase.js.map +1 -0
  69. package/bin/domain/usecases/ClearNextActionHourUseCase.js +38 -0
  70. package/bin/domain/usecases/ClearNextActionHourUseCase.js.map +1 -0
  71. package/bin/domain/usecases/GenerateWorkingTimeReportUseCase.js +180 -0
  72. package/bin/domain/usecases/GenerateWorkingTimeReportUseCase.js.map +1 -0
  73. package/bin/domain/usecases/HandleScheduledEventUseCase.js +122 -0
  74. package/bin/domain/usecases/HandleScheduledEventUseCase.js.map +1 -0
  75. package/bin/domain/usecases/SetWorkflowManagementIssueToStoryUseCase.js +35 -0
  76. package/bin/domain/usecases/SetWorkflowManagementIssueToStoryUseCase.js.map +1 -0
  77. package/bin/domain/usecases/adapter-interfaces/DateRepository.js +3 -0
  78. package/bin/domain/usecases/adapter-interfaces/DateRepository.js.map +1 -0
  79. package/bin/domain/usecases/adapter-interfaces/IssueRepository.js +3 -0
  80. package/bin/domain/usecases/adapter-interfaces/IssueRepository.js.map +1 -0
  81. package/bin/domain/usecases/adapter-interfaces/ProjectRepository.js +3 -0
  82. package/bin/domain/usecases/adapter-interfaces/ProjectRepository.js.map +1 -0
  83. package/bin/domain/usecases/adapter-interfaces/SlackRepository.js +3 -0
  84. package/bin/domain/usecases/adapter-interfaces/SlackRepository.js.map +1 -0
  85. package/bin/domain/usecases/adapter-interfaces/SpreadsheetRepository.js +3 -0
  86. package/bin/domain/usecases/adapter-interfaces/SpreadsheetRepository.js.map +1 -0
  87. package/bin/index.js +13 -0
  88. package/bin/index.js.map +1 -0
  89. package/commitlint.config.js +6 -0
  90. package/jest.config.js +19 -0
  91. package/package.json +80 -0
  92. package/renovate.json +37 -0
  93. package/src/adapter/entry-points/cli/index.test.ts +20 -0
  94. package/src/adapter/entry-points/cli/index.ts +36 -0
  95. package/src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.ts +95 -0
  96. package/src/adapter/repositories/AxiosSlackRepository.test.ts +119 -0
  97. package/src/adapter/repositories/AxiosSlackRepository.ts +184 -0
  98. package/src/adapter/repositories/BaseGitHubRepository.test.ts +95 -0
  99. package/src/adapter/repositories/BaseGitHubRepository.ts +172 -0
  100. package/src/adapter/repositories/GoogleSpreadsheetRepository.test.ts +124 -0
  101. package/src/adapter/repositories/GoogleSpreadsheetRepository.ts +151 -0
  102. package/src/adapter/repositories/GraphqlProjectRepository.test.ts +46 -0
  103. package/src/adapter/repositories/GraphqlProjectRepository.ts +236 -0
  104. package/src/adapter/repositories/LocalStorageCacheRepository.test.ts +146 -0
  105. package/src/adapter/repositories/LocalStorageCacheRepository.ts +53 -0
  106. package/src/adapter/repositories/LocalStorageRepository.integration.test.ts +142 -0
  107. package/src/adapter/repositories/LocalStorageRepository.test.ts +161 -0
  108. package/src/adapter/repositories/LocalStorageRepository.ts +21 -0
  109. package/src/adapter/repositories/SystemDateRepository.ts +20 -0
  110. package/src/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.test.ts +158 -0
  111. package/src/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.ts +274 -0
  112. package/src/adapter/repositories/issue/ApiV3IssueRepository.test.ts +26 -0
  113. package/src/adapter/repositories/issue/ApiV3IssueRepository.ts +59 -0
  114. package/src/adapter/repositories/issue/CheerioIssueRepository.test.ts +6610 -0
  115. package/src/adapter/repositories/issue/CheerioIssueRepository.ts +127 -0
  116. package/src/adapter/repositories/issue/GraphqlProjectItemRepository.test.ts +49 -0
  117. package/src/adapter/repositories/issue/GraphqlProjectItemRepository.ts +745 -0
  118. package/src/adapter/repositories/issue/InternalGraphqlIssueRepository.test.ts +71 -0
  119. package/src/adapter/repositories/issue/InternalGraphqlIssueRepository.ts +263 -0
  120. package/src/adapter/repositories/issue/RestIssueRepository.test.ts +29 -0
  121. package/src/adapter/repositories/issue/RestIssueRepository.ts +105 -0
  122. package/src/adapter/repositories/issue/issueTimelineUtils.test.ts +79 -0
  123. package/src/adapter/repositories/issue/issueTimelineUtils.ts +52 -0
  124. package/src/adapter/repositories/utils.test.ts +40 -0
  125. package/src/adapter/repositories/utils.ts +50 -0
  126. package/src/domain/entities/Issue.ts +23 -0
  127. package/src/domain/entities/Member.ts +3 -0
  128. package/src/domain/entities/Project.ts +29 -0
  129. package/src/domain/entities/ProjectField.ts +3 -0
  130. package/src/domain/entities/ProjectFieldSingleSelect.ts +8 -0
  131. package/src/domain/entities/ProjectFieldSingleSelectOption.ts +8 -0
  132. package/src/domain/entities/WorkingTime.ts +8 -0
  133. package/src/domain/usecases/ActionAnnouncementUseCase.ts +76 -0
  134. package/src/domain/usecases/AnalyzeProblemByIssueUseCase.ts +209 -0
  135. package/src/domain/usecases/ClearNextActionHourUseCase.ts +51 -0
  136. package/src/domain/usecases/GenerateWorkingTimeReportUseCase.test.ts +382 -0
  137. package/src/domain/usecases/GenerateWorkingTimeReportUseCase.ts +284 -0
  138. package/src/domain/usecases/HandleScheduledEventUseCase.test.ts +58 -0
  139. package/src/domain/usecases/HandleScheduledEventUseCase.ts +209 -0
  140. package/src/domain/usecases/SetWorkflowManagementIssueToStoryUseCase.ts +46 -0
  141. package/src/domain/usecases/adapter-interfaces/DateRepository.ts +5 -0
  142. package/src/domain/usecases/adapter-interfaces/IssueRepository.ts +44 -0
  143. package/src/domain/usecases/adapter-interfaces/ProjectRepository.ts +6 -0
  144. package/src/domain/usecases/adapter-interfaces/SlackRepository.ts +20 -0
  145. package/src/domain/usecases/adapter-interfaces/SpreadsheetRepository.ts +18 -0
  146. package/src/index.test.ts +8 -0
  147. package/src/index.ts +7 -0
  148. package/tsconfig.build.json +11 -0
  149. package/tsconfig.json +22 -0
  150. package/types/adapter/entry-points/cli/index.d.ts +3 -0
  151. package/types/adapter/entry-points/cli/index.d.ts.map +1 -0
  152. package/types/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.d.ts +11 -0
  153. package/types/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.d.ts.map +1 -0
  154. package/types/adapter/repositories/AxiosSlackRepository.d.ts +13 -0
  155. package/types/adapter/repositories/AxiosSlackRepository.d.ts.map +1 -0
  156. package/types/adapter/repositories/BaseGitHubRepository.d.ts +32 -0
  157. package/types/adapter/repositories/BaseGitHubRepository.d.ts.map +1 -0
  158. package/types/adapter/repositories/GoogleSpreadsheetRepository.d.ts +13 -0
  159. package/types/adapter/repositories/GoogleSpreadsheetRepository.d.ts.map +1 -0
  160. package/types/adapter/repositories/GraphqlProjectRepository.d.ts +13 -0
  161. package/types/adapter/repositories/GraphqlProjectRepository.d.ts.map +1 -0
  162. package/types/adapter/repositories/LocalStorageCacheRepository.d.ts +12 -0
  163. package/types/adapter/repositories/LocalStorageCacheRepository.d.ts.map +1 -0
  164. package/types/adapter/repositories/LocalStorageRepository.d.ts +7 -0
  165. package/types/adapter/repositories/LocalStorageRepository.d.ts.map +1 -0
  166. package/types/adapter/repositories/SystemDateRepository.d.ts +7 -0
  167. package/types/adapter/repositories/SystemDateRepository.d.ts.map +1 -0
  168. package/types/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.d.ts +38 -0
  169. package/types/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.d.ts.map +1 -0
  170. package/types/adapter/repositories/issue/ApiV3IssueRepository.d.ts +17 -0
  171. package/types/adapter/repositories/issue/ApiV3IssueRepository.d.ts.map +1 -0
  172. package/types/adapter/repositories/issue/CheerioIssueRepository.d.ts +31 -0
  173. package/types/adapter/repositories/issue/CheerioIssueRepository.d.ts.map +1 -0
  174. package/types/adapter/repositories/issue/GraphqlProjectItemRepository.d.ts +39 -0
  175. package/types/adapter/repositories/issue/GraphqlProjectItemRepository.d.ts.map +1 -0
  176. package/types/adapter/repositories/issue/InternalGraphqlIssueRepository.d.ts +83 -0
  177. package/types/adapter/repositories/issue/InternalGraphqlIssueRepository.d.ts.map +1 -0
  178. package/types/adapter/repositories/issue/RestIssueRepository.d.ts +16 -0
  179. package/types/adapter/repositories/issue/RestIssueRepository.d.ts.map +1 -0
  180. package/types/adapter/repositories/issue/issueTimelineUtils.d.ts +12 -0
  181. package/types/adapter/repositories/issue/issueTimelineUtils.d.ts.map +1 -0
  182. package/types/adapter/repositories/utils.d.ts +4 -0
  183. package/types/adapter/repositories/utils.d.ts.map +1 -0
  184. package/types/domain/entities/Issue.d.ts +24 -0
  185. package/types/domain/entities/Issue.d.ts.map +1 -0
  186. package/types/domain/entities/Member.d.ts +4 -0
  187. package/types/domain/entities/Member.d.ts.map +1 -0
  188. package/types/domain/entities/Project.d.ts +29 -0
  189. package/types/domain/entities/Project.d.ts.map +1 -0
  190. package/types/domain/entities/ProjectField.d.ts +3 -0
  191. package/types/domain/entities/ProjectField.d.ts.map +1 -0
  192. package/types/domain/entities/ProjectFieldSingleSelect.d.ts +8 -0
  193. package/types/domain/entities/ProjectFieldSingleSelect.d.ts.map +1 -0
  194. package/types/domain/entities/ProjectFieldSingleSelectOption.d.ts +8 -0
  195. package/types/domain/entities/ProjectFieldSingleSelectOption.d.ts.map +1 -0
  196. package/types/domain/entities/WorkingTime.d.ts +8 -0
  197. package/types/domain/entities/WorkingTime.d.ts.map +1 -0
  198. package/types/domain/usecases/ActionAnnouncementUseCase.d.ts +17 -0
  199. package/types/domain/usecases/ActionAnnouncementUseCase.d.ts.map +1 -0
  200. package/types/domain/usecases/AnalyzeProblemByIssueUseCase.d.ts +26 -0
  201. package/types/domain/usecases/AnalyzeProblemByIssueUseCase.d.ts.map +1 -0
  202. package/types/domain/usecases/ClearNextActionHourUseCase.d.ts +14 -0
  203. package/types/domain/usecases/ClearNextActionHourUseCase.d.ts.map +1 -0
  204. package/types/domain/usecases/GenerateWorkingTimeReportUseCase.d.ts +50 -0
  205. package/types/domain/usecases/GenerateWorkingTimeReportUseCase.d.ts.map +1 -0
  206. package/types/domain/usecases/HandleScheduledEventUseCase.d.ts +63 -0
  207. package/types/domain/usecases/HandleScheduledEventUseCase.d.ts.map +1 -0
  208. package/types/domain/usecases/SetWorkflowManagementIssueToStoryUseCase.d.ts +14 -0
  209. package/types/domain/usecases/SetWorkflowManagementIssueToStoryUseCase.d.ts.map +1 -0
  210. package/types/domain/usecases/adapter-interfaces/DateRepository.d.ts +6 -0
  211. package/types/domain/usecases/adapter-interfaces/DateRepository.d.ts.map +1 -0
  212. package/types/domain/usecases/adapter-interfaces/IssueRepository.d.ts +23 -0
  213. package/types/domain/usecases/adapter-interfaces/IssueRepository.d.ts.map +1 -0
  214. package/types/domain/usecases/adapter-interfaces/ProjectRepository.d.ts +6 -0
  215. package/types/domain/usecases/adapter-interfaces/ProjectRepository.d.ts.map +1 -0
  216. package/types/domain/usecases/adapter-interfaces/SlackRepository.d.ts +9 -0
  217. package/types/domain/usecases/adapter-interfaces/SlackRepository.d.ts.map +1 -0
  218. package/types/domain/usecases/adapter-interfaces/SpreadsheetRepository.d.ts +6 -0
  219. package/types/domain/usecases/adapter-interfaces/SpreadsheetRepository.d.ts.map +1 -0
  220. package/types/index.d.ts +10 -0
  221. package/types/index.d.ts.map +1 -0
package/.env.example ADDED
@@ -0,0 +1,6 @@
1
+ GH_TOKEN=
2
+ GOOGLE_SERVICE_ACCOUNT_KEY=
3
+ SLACK_USER_TOKEN=
4
+ GH_USER_NAME=
5
+ GH_USER_PASSWORD=
6
+ GH_AUTHENTICATOR_KEY=
package/.eslintrc.cjs ADDED
@@ -0,0 +1,55 @@
1
+ const fs = require('fs');
2
+
3
+ module.exports = {
4
+ extends: [
5
+ 'eslint:recommended',
6
+ 'plugin:@typescript-eslint/recommended',
7
+ 'plugin:@typescript-eslint/recommended-requiring-type-checking',
8
+ 'plugin:import/typescript',
9
+ ],
10
+ parser: '@typescript-eslint/parser',
11
+ parserOptions: {
12
+ ecmaVersion: 2020,
13
+ project: ['tsconfig.json'],
14
+ sourceType: 'module',
15
+ },
16
+ plugins: [
17
+ '@typescript-eslint',
18
+ 'no-type-assertion',
19
+ 'import',
20
+ 'unused-imports',
21
+ ],
22
+ root: true,
23
+ ignorePatterns: fs.readFileSync('.gitignore', 'utf8').split('\n'),
24
+ rules: {
25
+ '@typescript-eslint/require-await': 'off',
26
+ '@typescript-eslint/no-non-null-assertion': 'error',
27
+ 'no-type-assertion/no-type-assertion': 'error',
28
+ '@typescript-eslint/no-unused-vars': [
29
+ 'error',
30
+ {
31
+ argsIgnorePattern: '^_',
32
+ },
33
+ ],
34
+ 'import/no-restricted-paths': [
35
+ 'error',
36
+ {
37
+ zones: [
38
+ {
39
+ target: './src/domain',
40
+ from: './src/adapter',
41
+ },
42
+ {
43
+ target: './src/domain/entities',
44
+ from: './src/domain/usecases',
45
+ },
46
+ {
47
+ target: './src/adapter/repositories',
48
+ from: './src/adapter/entry-points',
49
+ },
50
+ ],
51
+ },
52
+ ],
53
+ 'unused-imports/no-unused-imports-ts': 'error',
54
+ },
55
+ };
@@ -0,0 +1,2 @@
1
+ * @HiromiShikata
2
+ * @renovate
@@ -0,0 +1,14 @@
1
+ name: Issue Assigner
2
+
3
+ on:
4
+ issues:
5
+ types: [opened]
6
+
7
+ jobs:
8
+ auto-assign:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: pozil/auto-assign-issue@v2.0.1
12
+ with:
13
+ assignees: HiromiShikata
14
+ repo-token: ${{ secrets.GH_TOKEN }}
@@ -0,0 +1,54 @@
1
+ name: Lint Commit Messages
2
+ on:
3
+ pull_request:
4
+ types:
5
+ - opened
6
+ - edited
7
+ - reopened
8
+ - synchronize
9
+
10
+ concurrency:
11
+ group: commitlint-${{ github.ref }}
12
+ cancel-in-progress: true
13
+
14
+ jobs:
15
+ commit-lint:
16
+ runs-on: ubuntu-latest
17
+ permissions:
18
+ issues: read
19
+ pull-requests: write
20
+ contents: read
21
+ steps:
22
+ - name: Checkout code
23
+ uses: actions/checkout@v4
24
+ with:
25
+ fetch-depth: 0
26
+
27
+ - name: Use Node.js
28
+ uses: actions/setup-node@v4
29
+
30
+ - name: Check for DONTMERGE
31
+ run: |
32
+ result=$(find . \
33
+ -type f \
34
+ ! -path './.github/workflows/commit-lint.yml' \
35
+ ! -name '*.snap' \
36
+ -exec grep -Hn 'DONTMERGE' {} \;)
37
+ if [[ ! -z "$result" ]]; then
38
+ echo "$result"
39
+ exit 1
40
+ fi
41
+ - uses: nearform-actions/github-action-check-linked-issues@v1
42
+ id: check-linked-issues
43
+ if: false
44
+ with:
45
+ exclude-branches: 'release/**, dependabot/**, project-common/**'
46
+ loose-matching: true
47
+
48
+ - name: Install commitlint
49
+ run: |
50
+ npm install --save-dev @commitlint/{config-conventional,cli}
51
+
52
+ - name: Lint commits
53
+ run: |
54
+ npx commitlint --from=origin/main --to=HEAD --config ./.github/workflows/configs/commitlint.config.js
@@ -0,0 +1,27 @@
1
+ module.exports = {
2
+ extends: ['@commitlint/config-conventional'],
3
+ rules: {
4
+ 'type-enum': [
5
+ 2,
6
+ 'always',
7
+ [
8
+ 'build',
9
+ 'chore',
10
+ 'ci',
11
+ 'docs',
12
+ 'feat',
13
+ 'fix',
14
+ 'perf',
15
+ 'refactor',
16
+ 'revert',
17
+ 'style',
18
+ 'test',
19
+ 'autogen',
20
+ 'prep',
21
+ 'adapt',
22
+ ],
23
+ ],
24
+ 'header-max-length': [0],
25
+ 'body-max-line-length': [0],
26
+ },
27
+ };
@@ -0,0 +1,64 @@
1
+ name: Create PR
2
+
3
+ on:
4
+ push:
5
+ branches-ignore:
6
+ - main
7
+
8
+ jobs:
9
+ create_and_enable_automerge:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - name: Checkout repository
13
+ uses: actions/checkout@v4
14
+
15
+ - name: Set branch name as output
16
+ id: branch_name
17
+ run: echo "::set-output name=branch::${GITHUB_REF#refs/heads/}"
18
+
19
+ - name: Create Pull Request
20
+ id: create_pr
21
+ uses: repo-sync/pull-request@v2
22
+ with:
23
+ github_token: ${{ secrets.GH_TOKEN }}
24
+ destination_branch: 'main'
25
+ source_branch: ''
26
+ pr_title: '${{ steps.branch_name.outputs.branch }}'
27
+ pr_body: 'This is an auto-create PR.'
28
+ draft: false
29
+
30
+ - name: Assign PR to author
31
+ if: steps.create_pr.outputs.pr_number
32
+ run: |
33
+ curl -s -X POST \
34
+ -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
35
+ -H "Accept: application/vnd.github.v3+json" \
36
+ -d '{"assignees":["${{ github.actor }}"]}' \
37
+ "https://api.github.com/repos/${{ github.repository }}/issues/${{ steps.create_pr.outputs.pr_number }}/assignees"
38
+
39
+ - name: Get PR Node ID
40
+ if: steps.create_pr.outputs.pr_number
41
+ id: get_pr_id
42
+ run: |
43
+ PR_DATA=$(curl -s -H "Authorization: token ${{ secrets.GH_TOKEN }}" -H "Accept: application/vnd.github.v3+json" "https://api.github.com/repos/${{ github.repository }}/pulls/${{ steps.create_pr.outputs.pr_number }}")
44
+ PR_ID=$(echo "$PR_DATA" | jq -r '.node_id')
45
+ echo "::set-output name=node_id::$PR_ID"
46
+
47
+ - name: Enable Auto Merge for PR
48
+ if: steps.create_pr.outputs.pr_number
49
+ run: |
50
+ RESPONSE=$(curl -s -X POST \
51
+ -H "Authorization: bearer ${{ secrets.GH_TOKEN }}" \
52
+ -H "Content-Type: application/json" \
53
+ -d '{
54
+ "query": "mutation($id: ID!) { enablePullRequestAutoMerge(input: { pullRequestId: $id }) { clientMutationId } }",
55
+ "variables": {
56
+ "id": "'"${{ steps.get_pr_id.outputs.node_id }}"'"
57
+ }
58
+ }' \
59
+ "https://api.github.com/graphql")
60
+ echo "$RESPONSE"
61
+ if echo "$RESPONSE" | jq -e '.errors' >/dev/null; then
62
+ echo "Failed to enable auto merge"
63
+ exit 1
64
+ fi
@@ -0,0 +1,25 @@
1
+ name: 'Format'
2
+
3
+ on:
4
+ push:
5
+ branches-ignore:
6
+ - main
7
+
8
+ jobs:
9
+ format:
10
+ runs-on: ubuntu-latest
11
+ permissions:
12
+ contents: write
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+ with:
16
+ token: ${{ secrets.GH_TOKEN }}
17
+ - uses: actions/setup-node@v4
18
+ with:
19
+ node-version: 22
20
+ - run: git pull
21
+ - run: npm ci
22
+ - run: npm run fmt && git --no-pager diff
23
+ - uses: stefanzweifel/git-auto-commit-action@v5
24
+ with:
25
+ commit_message: 'style: `npm run fmt`'
@@ -0,0 +1,47 @@
1
+ name: Publish
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+
8
+ env:
9
+ RELEASE_APP_ID: 795363
10
+ RELEASE_APP_PRIVATE_KEY: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
11
+ PJ_GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
12
+
13
+ jobs:
14
+ publish:
15
+ runs-on: ubuntu-latest
16
+ steps:
17
+ - uses: actions/create-github-app-token@v1
18
+ id: app-token
19
+ with:
20
+ app-id: ${{ env.RELEASE_APP_ID }}
21
+ private-key: ${{ env.RELEASE_APP_PRIVATE_KEY }}
22
+ - uses: actions/checkout@v4
23
+ with:
24
+ token: ${{ steps.app-token.outputs.token }}
25
+
26
+ - uses: actions/setup-node@v4
27
+ with:
28
+ node-version: 22
29
+
30
+ - run: npm ci
31
+ - run: npm run build
32
+ - run: git config --global user.email "gh-actions"
33
+ - run: git config --global user.name "gh-actions"
34
+
35
+ - run: npx semantic-release
36
+ env:
37
+ NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
38
+ - run: |
39
+ git status
40
+ git add -A
41
+ - run: |
42
+ if git diff --staged --quiet; then
43
+ echo "No changes to commit"
44
+ else
45
+ git commit -m "autogen: release"
46
+ git push --force origin main
47
+ fi
@@ -0,0 +1,45 @@
1
+ name: Test
2
+
3
+ on:
4
+ push:
5
+
6
+ jobs:
7
+ test:
8
+ runs-on: ubuntu-latest
9
+
10
+ steps:
11
+ - name: Checkout repository
12
+ uses: actions/checkout@v4
13
+ with:
14
+ fetch-depth: 0
15
+
16
+ - uses: actions/setup-node@v4
17
+ with:
18
+ node-version: 22
19
+ - name: Install dependencies
20
+ run: npm ci
21
+
22
+ - name: Build
23
+ run: npm run build
24
+
25
+ - name: Run tests
26
+ run: npm run test
27
+ env:
28
+ GH_TOKEN: ${{ secrets.TEST_GH_TOKEN }}
29
+ GOOGLE_SERVICE_ACCOUNT_KEY: ${{ secrets.TEST_GOOGLE_SERVICE_ACCOUNT_KEY }}
30
+ SLACK_USER_TOKEN: ${{ secrets.TEST_SLACK_USER_TOKEN }}
31
+ GH_USER_NAME: ${{ secrets.TEST_GH_USER_NAME }}
32
+ GH_USER_PASSWORD: ${{ secrets.TEST_GH_USER_PASSWORD }}
33
+ GH_AUTHENTICATOR_KEY: ${{ secrets.TEST_GH_AUTHENTICATOR_KEY }}
34
+
35
+ - name: Upload test results
36
+ uses: actions/upload-artifact@v4
37
+ with:
38
+ name: jest-junit-report
39
+ path: reports/jest-junit
40
+
41
+ - name: Upload artifacts
42
+ uses: actions/upload-artifact@v4
43
+ with:
44
+ name: reports
45
+ path: reports
@@ -0,0 +1,181 @@
1
+ name: UMINO Project
2
+ on:
3
+ issues:
4
+ types:
5
+ - opened
6
+ - reopened
7
+ - assigned
8
+ - unassigned
9
+ - labeled
10
+ pull_request:
11
+ types:
12
+ - opened
13
+ - reopened
14
+ - review_requested
15
+ - assigned
16
+ - unassigned
17
+ - labeled
18
+ - opened
19
+ - edited
20
+ - reopened
21
+ - synchronize
22
+ issue_comment:
23
+ types:
24
+ - created
25
+ pull_request_target:
26
+ types:
27
+ - opened
28
+ - edited
29
+ - reopened
30
+ - synchronize
31
+
32
+ env:
33
+ unread: Unread
34
+ in_progress: In Progress
35
+ gh_project_token: ${{ secrets.GH_TOKEN }}
36
+ user: HiromiShikata
37
+ project_id: 48
38
+ project_v2_id: PVT_kwHOAGJHa84AFWnr
39
+ field_id: PVTF_lAHOAGJHa84AFWnrzgIk_H0
40
+
41
+ jobs:
42
+ umino-job:
43
+ name: opened_or_reopened
44
+ runs-on: ubuntu-latest
45
+ steps:
46
+ - name: Move issue to ${{ env.unread }}
47
+ uses: leonsteinhaeuser/project-beta-automations@v2.2.1
48
+ with:
49
+ gh_token: ${{ env.gh_project_token }}
50
+ user: ${{ env.user }}
51
+ project_id: ${{ env.project_id }}
52
+ resource_node_id: ${{ github.event.pull_request.node_id || github.event.issue.node_id }}
53
+ status_value: ${{ env.unread }}
54
+ if: >-
55
+ (github.event_name == 'issues' && github.event.issue.state == 'open') ||
56
+ (github.event_name == 'pull_request' && github.event.pull_request.state == 'open') &&
57
+ (github.event.action == 'opened' || github.event.action == 'reopened' ||
58
+ github.event.action == 'assigned' || github.event.action == 'unassigned')
59
+ - run: |
60
+ OWNER=$(echo ${{ github.repository }} | cut -d '/' -f 1)
61
+ REPO=$(echo ${{ github.repository }} | cut -d '/' -f 2)
62
+ ENTITY_TYPE=$(echo ${{ github.event_name }} | grep -q "pull_request" && echo "pullRequest" || echo "issue")
63
+ NUMBER=$(echo ${{ github.event_name }} | grep -q "pull_request" && echo ${{ github.event.pull_request.number }} || echo ${{ github.event.issue.number }})
64
+
65
+ QUERY_DATA='{ "query": "query { repository(owner: \"'$OWNER'\", name: \"'$REPO'\") { '${ENTITY_TYPE}'(number: '$NUMBER') { projectItems(first: 10) { nodes { id } } } } }" }'
66
+ RESPONSE=$(curl -X POST -H "Authorization: bearer ${{ secrets.GH_TOKEN }}" -H "Content-Type: application/json" --data "$QUERY_DATA" https://api.github.com/graphql)
67
+
68
+ if echo $RESPONSE | grep -q "errors"; then
69
+ echo "Error in GraphQL query"
70
+ echo "GraphQL Response: $RESPONSE"
71
+ exit 1
72
+ fi
73
+
74
+ if [ "$ENTITY_TYPE" = "pullRequest" ]; then
75
+ ITEM_ID=$(echo $RESPONSE | jq -r '.data.repository.pullRequest.projectItems.nodes[0].id')
76
+ else
77
+ ITEM_ID=$(echo $RESPONSE | jq -r '.data.repository.issue.projectItems.nodes[0].id')
78
+ fi
79
+
80
+ if [ "$ITEM_ID" = "null" ] || [ -z "$ITEM_ID" ]; then
81
+ echo "No valid item ID found, cannot proceed"
82
+ exit 1
83
+ fi
84
+
85
+ CLEAR_FIELD_DATA="{\"query\":\"mutation { clearProjectV2ItemFieldValue(input: {projectId: \\\"${{ env.project_v2_id }}\\\", fieldId: \\\"${{ env.field_id }}\\\", itemId: \\\"$ITEM_ID\\\"}) { clientMutationId }}\"}"
86
+ CLEAR_RESPONSE=$(curl --request POST \
87
+ --url https://api.github.com/graphql \
88
+ --header "Authorization: Bearer ${{ env.gh_project_token }}" \
89
+ --header "Content-Type: application/json" \
90
+ --data "$CLEAR_FIELD_DATA")
91
+
92
+ if echo $CLEAR_RESPONSE | grep -q "errors"; then
93
+ echo "Error in clearing field"
94
+ echo "Clear Field Response: $CLEAR_RESPONSE"
95
+ exit 1
96
+ fi
97
+ if: >-
98
+ ((github.event_name == 'issues' && github.event.issue.state == 'open') ||
99
+ (github.event_name == 'pull_request' && github.event.pull_request.state == 'open')) &&
100
+ (github.event.action == 'opened' || github.event.action == 'reopened' ||
101
+ github.event.action == 'assigned' || github.event.action == 'unassigned')
102
+
103
+ - name: Create Issue
104
+ if: ${{ github.event_name == 'issue_comment' && github.event.action == 'created' && contains(github.event.comment.body, '/createissue') }}
105
+ uses: actions/github-script@v7
106
+ with:
107
+ github-token: ${{secrets.GH_TOKEN}}
108
+ script: |
109
+ const commentBody = context.payload.comment.body;
110
+ const createIssueIndex = commentBody.indexOf('/createissue');
111
+ const issueTitle = commentBody.slice(createIssueIndex + 12).split('\n')[0].trim();
112
+ const issueNumber = context.issue.number;
113
+ const commentId = context.payload.comment.id;
114
+ const commentLink = `https://github.com/${context.repo.owner}/${context.repo.repo}/issues/${issueNumber}#issuecomment-${commentId}`;
115
+ const issueBody = `
116
+ ${commentBody.slice(createIssueIndex + 12).trim()}
117
+ Created from a comment: ${commentLink}
118
+ `;
119
+ const newIssue = await github.rest.issues.create({
120
+ owner: context.repo.owner,
121
+ repo: context.repo.repo,
122
+ title: issueTitle,
123
+ body: issueBody,
124
+ assignees: ['HiromiShikata']
125
+ });
126
+ - name: Close Issue
127
+ if: ${{ github.event_name == 'issue_comment' && github.event.action == 'created' && (contains(github.event.comment.body, '/close') || contains(github.event.comment.body, '/done')) }}
128
+ uses: actions/github-script@v7
129
+ with:
130
+ github-token: ${{secrets.GH_TOKEN}}
131
+ script: |
132
+ await github.rest.issues.update({
133
+ owner: context.repo.owner,
134
+ repo: context.repo.repo,
135
+ issue_number: context.issue.number,
136
+ state: 'closed'
137
+ });
138
+ - name: Update Date Field
139
+ if: ${{ github.event_name == 'issue_comment' && github.event.action == 'created' && contains(github.event.comment.body, '/movenextactiondateto') }}
140
+ run: |
141
+ DATE_STRING=$(echo "${{ github.event.comment.body }}" | grep -oP '(?<=/movenextactiondateto )\d{8}')
142
+ OWNER=$(echo ${{ github.repository }} | cut -d '/' -f 1)
143
+ REPO=$(echo ${{ github.repository }} | cut -d '/' -f 2)
144
+ ITEM_ID=$(curl -X POST -H "Authorization: bearer ${{ secrets.GH_TOKEN }}" -H "Content-Type: application/json" --data '{ "query": "query { repository(owner: \"'$OWNER'\", name: \"'$REPO'\") { issue(number: '${{ github.event.issue.number }}') { projectItems(first: 10) { nodes { id } } } } }" }' https://api.github.com/graphql | jq -r '.data.repository.issue.projectItems.nodes[0].id')
145
+ UPDATE_FIELD_DATA="{\"query\":\"mutation { updateProjectV2ItemFieldValue(input: {projectId: \\\"${{ env.project_v2_id }}\\\", fieldId: \\\"${{ env.field_id }}\\\", itemId: \\\"$ITEM_ID\\\", value: { date: \\\"$DATE_STRING\\\" }}) { clientMutationId }}\"}"
146
+ curl --request POST \
147
+ -f \
148
+ --url https://api.github.com/graphql \
149
+ --header "Authorization: Bearer ${{ env.gh_project_token }}" \
150
+ --header "Content-Type: application/json" \
151
+ --data "$UPDATE_FIELD_DATA"
152
+ - name: Change Assignee
153
+ if: ${{ github.event_name == 'issue_comment' && github.event.action == 'created' && contains(github.event.comment.body, '/changeassignee ') }}
154
+ uses: actions/github-script@v7
155
+ with:
156
+ github-token: ${{secrets.GH_TOKEN}}
157
+ script: |
158
+ const commentBody = context.payload.comment.body;
159
+ const assigneeIndex = commentBody.indexOf('/changeassignee ') + 16;
160
+ const assigneeName = commentBody.slice(assigneeIndex).split(' ')[0].trim();
161
+ await github.rest.issues.update({
162
+ owner: context.repo.owner,
163
+ repo: context.repo.repo,
164
+ issue_number: context.issue.number,
165
+ assignees: [assigneeName]
166
+ });
167
+
168
+ check_pull_requests_to_link_issues:
169
+ runs-on: ubuntu-latest
170
+ name: Check linked issues in pull requests
171
+ if: >-
172
+ (github.event_name == 'pull_request')
173
+ steps:
174
+ - uses: nearform-actions/github-action-check-linked-issues@v1
175
+ id: check-linked-issues
176
+ with:
177
+ exclude-branches: 'release/**, dependabot/**, project-common/**, renovate/**'
178
+ github-token: ${{ secrets.GH_TOKEN }}
179
+ loose-matching: true
180
+ - name: Get the output
181
+ run: echo "How many linked issues? ${{ steps.check-linked-issues.outputs.linked_issues_count }}"
@@ -0,0 +1,22 @@
1
+ *.xml
2
+ .gitignore
3
+ .prettierignore
4
+ .gitkeep
5
+
6
+
7
+ .idea
8
+ reports
9
+ dist
10
+ bin
11
+ .npmignore
12
+ *.map
13
+ CHANGELOG.md
14
+ .env
15
+ .env.example
16
+ LICENSE
17
+ *.txt
18
+ *.orig
19
+ *.rej
20
+ *.diff
21
+ *.log
22
+ CODEOWNERS
package/.prettierrc ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "trailingComma": "all",
3
+ "printWidth": 80,
4
+ "singleQuote": true
5
+ }
package/CHANGELOG.md ADDED
@@ -0,0 +1,49 @@
1
+ # [1.1.0](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/compare/v1.0.0...v1.1.0) (2024-12-08)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * avoid to use comma for warning to keep csv format ([ab98722](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/ab987220d770101b270c20cb2482b7868a934e01))
7
+ * change time to run ClearNextActionHourUseCase ([58c754e](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/58c754ecbf227694aece38746d306598957a252a))
8
+ * create sheet if not exists in GoogleSpreadsheetRepository ([eed58d4](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/eed58d496556f911cee8308bfe819324a6007dad))
9
+ * decrare types ([41cae9d](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/41cae9de84bd13350ae290b38c77fe0573245499))
10
+ * failed to get cookie correctly ([2e21889](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/2e2188963edd5a665455f60dad2395338e962b16))
11
+ * failed to get ids in GraphqlProjectItemRepository ([ca04065](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/ca04065d2742f713295f30bfba1e5d610d292955))
12
+ * failed to get project number correctly in GraphqlProjectRepository ([d888325](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/d8883255efd3234015d5e8cba08987fdf4f3d3d2))
13
+ * failed to get status by classic view ([1d9f478](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/1d9f4786372bc945cef2be9dd74e6d725eff655b))
14
+ * failed to load data from file ([e02931c](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/e02931c18dfb716038e63571a31a894aec426149))
15
+ * failed to render label on issue ([dffa281](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/dffa2813966f4046c14b87dff6d69f65813ad5c4))
16
+ * failed to save file if parent dir is not exists ([ab590e1](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/ab590e1469f9b5012fa916b03702924c93f6de60))
17
+ * get cookie from credential ([133416f](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/133416f4743dab56beeab8f9a5226a6c865f56f9))
18
+ * hide log from axios ([b6cf9b3](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/b6cf9b3194168d51465f16b40a8709879b22bd61))
19
+ * remove decimals before duration calcuration in issueTimelineUrilts ([4d2654f](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/4d2654fddbc26600449708a4f44c4d4c7fc3b1b1))
20
+ * remove octokit to avoid ems error ([cbf30d7](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/cbf30d7549b1fae247d8ab28e334669261e851a2))
21
+ * run for every minutes ([b7ae179](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/b7ae179e62de563a32bcbc43d316161005267e34))
22
+ * save raw working report data to spredsheet at once ([9eb89f9](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/9eb89f9db7b517171779bb46fef0e7b61c176860))
23
+ * separate process pr or issue to get timeline ([6641705](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/6641705f8e0478b86a8cc1316152c727fac15ab5))
24
+ * set datetime after collecting issues ([dd85d6c](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/dd85d6c6d99a8e4bae4387ba9a28375388595366))
25
+ * sleep to avoid 429 on slack api ([98aa47c](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/98aa47cd5fb1a320421c1dac1e523493adf1a68c))
26
+ * updated wrong lastExecutionDate ([c0c900a](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/c0c900a5eaaab5e1e34a9b225c540dcc1ae83d87))
27
+ * wait 2sec after created issue ([b4bd107](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/b4bd107bb74025ff322ef495cf7fdc6179a5fc63))
28
+ * wait 2sec after upload image in AxiusSlackRepository ([06ff9f5](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/06ff9f569246d21e3b07727467066acdf32874da))
29
+ * wait 5sec after change story ([721bdc1](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/721bdc1f786d83378354aa52fd9e529469147bc4))
30
+ * wait 5sec to create announcement issue ([1d6c7b6](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/1d6c7b67bc622aeab06c9561469ad7b8a5f50637))
31
+ * wait 5sec to create working time report issue ([664c503](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/664c50310b0a11a2e08ad303ba6c3238efaf1f97))
32
+ * wrong updateStory parameter in ApiV3CheerioRestIssueRepository ([46d3f74](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/46d3f7495120e6d40fc9a34a906ad9a844a8a9f5))
33
+
34
+
35
+ ### Features
36
+
37
+ * add raw log to spreadsheet in GenerateWorkingTimeReportUseCase ([8f3bda7](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/8f3bda7585e9e6ab0afa77534eba45faf0029c4b))
38
+ * export function interface ([0ec4a28](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/0ec4a28e84215b37c3aa3a2306eab71f9e917153))
39
+ * implement task for scheduler ([6415aad](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/6415aad41d754a95f0167a463544b2776ceb55a9))
40
+ * report via issue when error happen in GenerateWorkingTimeReportUseCase ([464fd36](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/464fd3604e658b303bf82b93ed22c496d9cf303d))
41
+ * show labels in daily report ([f8ec5d3](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/f8ec5d3b0ae3b8ef636cbe86864cd5e0e53c67d8))
42
+ * use cache if there is for issues ([9a6ec9d](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/9a6ec9dadfdcecbc33e28745889302f949bcef29))
43
+ * use clearNextActionHourUseCase and analyzeProblemByIssueUseCase ([9046ed7](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/9046ed7c8235ac4f69f155363a762ac6370747a6))
44
+ * use codeblock for total time in working report ([b51f43a](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/b51f43a495b0918faa6bc5b6d09c54be8a5ecaf4))
45
+
46
+
47
+ ### Performance Improvements
48
+
49
+ * get timeline and issue data from 1 request in CheerioIssueRepository ([d61c35c](https://github.com/HiromiShikata/npm-cli-github-issue-tower-defence-management/commit/d61c35c41505d51387400ac1b15436bd2f0790fd))