plan_my_stuff 0.3.0 → 0.4.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 (83) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +10 -0
  3. data/README.md +569 -38
  4. data/app/controllers/plan_my_stuff/comments_controller.rb +5 -1
  5. data/app/controllers/plan_my_stuff/issues/approvals_controller.rb +102 -0
  6. data/app/controllers/plan_my_stuff/issues/closures_controller.rb +37 -0
  7. data/app/controllers/plan_my_stuff/issues/links_controller.rb +127 -0
  8. data/app/controllers/plan_my_stuff/issues/takes_controller.rb +88 -0
  9. data/app/controllers/plan_my_stuff/issues/viewers_controller.rb +48 -0
  10. data/app/controllers/plan_my_stuff/issues/waitings_controller.rb +47 -0
  11. data/app/controllers/plan_my_stuff/issues_controller.rb +22 -55
  12. data/app/controllers/plan_my_stuff/labels_controller.rb +4 -4
  13. data/app/controllers/plan_my_stuff/project_items/assignments_controller.rb +75 -0
  14. data/app/controllers/plan_my_stuff/project_items/statuses_controller.rb +40 -0
  15. data/app/controllers/plan_my_stuff/project_items_controller.rb +0 -75
  16. data/app/controllers/plan_my_stuff/projects_controller.rb +11 -1
  17. data/app/controllers/plan_my_stuff/testing_project_items/results_controller.rb +54 -0
  18. data/app/controllers/plan_my_stuff/testing_project_items_controller.rb +39 -0
  19. data/app/controllers/plan_my_stuff/testing_projects_controller.rb +93 -0
  20. data/app/controllers/plan_my_stuff/webhooks/aws_controller.rb +148 -0
  21. data/app/controllers/plan_my_stuff/webhooks/github_controller.rb +284 -0
  22. data/app/jobs/plan_my_stuff/application_job.rb +9 -0
  23. data/app/jobs/plan_my_stuff/reminders_sweep_job.rb +81 -0
  24. data/app/views/plan_my_stuff/comments/partials/_form.html.erb +7 -0
  25. data/app/views/plan_my_stuff/issues/partials/_approvals.html.erb +87 -0
  26. data/app/views/plan_my_stuff/issues/partials/_labels.html.erb +2 -2
  27. data/app/views/plan_my_stuff/issues/partials/_links.html.erb +70 -0
  28. data/app/views/plan_my_stuff/issues/partials/_viewers.html.erb +2 -2
  29. data/app/views/plan_my_stuff/issues/show.html.erb +46 -3
  30. data/app/views/plan_my_stuff/projects/index.html.erb +15 -1
  31. data/app/views/plan_my_stuff/projects/show.html.erb +10 -5
  32. data/app/views/plan_my_stuff/testing_project_items/new.html.erb +12 -0
  33. data/app/views/plan_my_stuff/testing_project_items/results/new.html.erb +22 -0
  34. data/app/views/plan_my_stuff/testing_projects/edit.html.erb +7 -0
  35. data/app/views/plan_my_stuff/testing_projects/new.html.erb +7 -0
  36. data/app/views/plan_my_stuff/testing_projects/partials/_form.html.erb +39 -0
  37. data/app/views/plan_my_stuff/testing_projects/partials/_item.html.erb +51 -0
  38. data/app/views/plan_my_stuff/testing_projects/partials/items/_form.html.erb +35 -0
  39. data/app/views/plan_my_stuff/testing_projects/show.html.erb +65 -0
  40. data/config/routes.rb +38 -15
  41. data/lib/generators/plan_my_stuff/install/templates/initializer.rb +138 -5
  42. data/lib/plan_my_stuff/application_record.rb +121 -0
  43. data/lib/plan_my_stuff/approval.rb +80 -0
  44. data/lib/plan_my_stuff/archive/sweep.rb +85 -0
  45. data/lib/plan_my_stuff/archive.rb +14 -0
  46. data/lib/plan_my_stuff/aws_sns_simulator.rb +110 -0
  47. data/lib/plan_my_stuff/base_project.rb +661 -0
  48. data/lib/plan_my_stuff/base_project_item.rb +562 -0
  49. data/lib/plan_my_stuff/base_project_metadata.rb +16 -0
  50. data/lib/plan_my_stuff/cache.rb +197 -0
  51. data/lib/plan_my_stuff/client.rb +7 -0
  52. data/lib/plan_my_stuff/comment.rb +171 -50
  53. data/lib/plan_my_stuff/configuration.rb +210 -10
  54. data/lib/plan_my_stuff/custom_fields.rb +31 -17
  55. data/lib/plan_my_stuff/engine.rb +0 -4
  56. data/lib/plan_my_stuff/errors.rb +49 -0
  57. data/lib/plan_my_stuff/graphql/queries.rb +392 -0
  58. data/lib/plan_my_stuff/issue.rb +1476 -175
  59. data/lib/plan_my_stuff/issue_metadata.rb +122 -0
  60. data/lib/plan_my_stuff/label.rb +82 -11
  61. data/lib/plan_my_stuff/link.rb +144 -0
  62. data/lib/plan_my_stuff/notifications.rb +142 -0
  63. data/lib/plan_my_stuff/pipeline/issue_linker.rb +62 -0
  64. data/lib/plan_my_stuff/pipeline/status.rb +44 -0
  65. data/lib/plan_my_stuff/pipeline.rb +293 -0
  66. data/lib/plan_my_stuff/project.rb +30 -693
  67. data/lib/plan_my_stuff/project_item.rb +3 -417
  68. data/lib/plan_my_stuff/project_item_metadata.rb +55 -0
  69. data/lib/plan_my_stuff/project_metadata.rb +9 -3
  70. data/lib/plan_my_stuff/reminders/closer.rb +70 -0
  71. data/lib/plan_my_stuff/reminders/fire.rb +129 -0
  72. data/lib/plan_my_stuff/reminders/sweep.rb +54 -0
  73. data/lib/plan_my_stuff/reminders.rb +16 -0
  74. data/lib/plan_my_stuff/test_helpers.rb +260 -15
  75. data/lib/plan_my_stuff/testing_project.rb +291 -0
  76. data/lib/plan_my_stuff/testing_project_item.rb +184 -0
  77. data/lib/plan_my_stuff/testing_project_metadata.rb +94 -0
  78. data/lib/plan_my_stuff/user_resolver.rb +8 -3
  79. data/lib/plan_my_stuff/version.rb +1 -1
  80. data/lib/plan_my_stuff/webhook_replayer.rb +280 -0
  81. data/lib/plan_my_stuff.rb +15 -0
  82. data/lib/tasks/plan_my_stuff.rake +163 -0
  83. metadata +50 -2
@@ -0,0 +1,392 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PlanMyStuff
4
+ module GraphQL
5
+ # Consolidated GitHub GraphQL queries and mutations used by the gem.
6
+ # Strings are static (no runtime parameterization) so they live as
7
+ # frozen String constants rather than methods.
8
+ #
9
+ # Callers pass the constant straight to +PlanMyStuff.client.graphql+:
10
+ #
11
+ # PlanMyStuff.client.graphql(
12
+ # PMS::GraphQL::Queries::DELETE_PROJECT_ITEM,
13
+ # variables: { projectId: ..., itemId: ... },
14
+ # )
15
+ #
16
+ module Queries
17
+ # --- Organization / project lookup ---------------------------------
18
+
19
+ ORG_ID = <<~GRAPHQL
20
+ query($org: String!) {
21
+ organization(login: $org) {
22
+ id
23
+ }
24
+ }
25
+ GRAPHQL
26
+
27
+ PROJECT_ID = <<~GRAPHQL
28
+ query($org: String!, $number: Int!) {
29
+ organization(login: $org) {
30
+ projectV2(number: $number) {
31
+ id
32
+ }
33
+ }
34
+ }
35
+ GRAPHQL
36
+
37
+ USER_NODE_ID = <<~GRAPHQL
38
+ query($login: String!) {
39
+ user(login: $login) {
40
+ id
41
+ }
42
+ }
43
+ GRAPHQL
44
+
45
+ # --- Project list / find -------------------------------------------
46
+
47
+ LIST_PROJECTS = <<~GRAPHQL
48
+ query($org: String!) {
49
+ organization(login: $org) {
50
+ projectsV2(first: 100) {
51
+ nodes {
52
+ id
53
+ number
54
+ title
55
+ shortDescription
56
+ readme
57
+ url
58
+ closed
59
+ updatedAt
60
+ }
61
+ }
62
+ }
63
+ }
64
+ GRAPHQL
65
+
66
+ FIND_PROJECT = <<~GRAPHQL
67
+ query($org: String!, $number: Int!, $cursor: String) {
68
+ organization(login: $org) {
69
+ projectV2(number: $number) {
70
+ id
71
+ number
72
+ title
73
+ shortDescription
74
+ readme
75
+ url
76
+ closed
77
+ updatedAt
78
+ fields(first: 50) {
79
+ nodes {
80
+ ... on ProjectV2SingleSelectField {
81
+ id
82
+ name
83
+ options {
84
+ id
85
+ name
86
+ }
87
+ }
88
+ ... on ProjectV2Field {
89
+ id
90
+ name
91
+ }
92
+ ... on ProjectV2IterationField {
93
+ id
94
+ name
95
+ }
96
+ }
97
+ }
98
+ items(first: 100, after: $cursor) {
99
+ pageInfo {
100
+ hasNextPage
101
+ endCursor
102
+ }
103
+ nodes {
104
+ id
105
+ type
106
+ content {
107
+ ... on Issue {
108
+ id
109
+ title
110
+ number
111
+ url
112
+ state
113
+ repository { nameWithOwner }
114
+ }
115
+ ... on PullRequest {
116
+ id
117
+ title
118
+ number
119
+ url
120
+ state
121
+ repository { nameWithOwner }
122
+ }
123
+ ... on DraftIssue {
124
+ id
125
+ title
126
+ body
127
+ }
128
+ }
129
+ fieldValues(first: 20) {
130
+ nodes {
131
+ ... on ProjectV2ItemFieldSingleSelectValue {
132
+ name
133
+ field {
134
+ ... on ProjectV2SingleSelectField {
135
+ name
136
+ }
137
+ }
138
+ }
139
+ ... on ProjectV2ItemFieldTextValue {
140
+ text
141
+ field {
142
+ ... on ProjectV2Field {
143
+ name
144
+ }
145
+ }
146
+ }
147
+ ... on ProjectV2ItemFieldUserValue {
148
+ users(first: 10) {
149
+ nodes {
150
+ login
151
+ }
152
+ }
153
+ field {
154
+ ... on ProjectV2Field {
155
+ name
156
+ }
157
+ }
158
+ }
159
+ }
160
+ }
161
+ }
162
+ }
163
+ }
164
+ }
165
+ }
166
+ GRAPHQL
167
+
168
+ # --- Project mutations ---------------------------------------------
169
+
170
+ CREATE_PROJECT = <<~GRAPHQL
171
+ mutation($input: CreateProjectV2Input!) {
172
+ createProjectV2(input: $input) {
173
+ projectV2 {
174
+ id
175
+ number
176
+ }
177
+ }
178
+ }
179
+ GRAPHQL
180
+
181
+ COPY_PROJECT_V2 = <<~GRAPHQL
182
+ mutation($input: CopyProjectV2Input!) {
183
+ copyProjectV2(input: $input) {
184
+ projectV2 {
185
+ id
186
+ number
187
+ }
188
+ }
189
+ }
190
+ GRAPHQL
191
+
192
+ UPDATE_PROJECT = <<~GRAPHQL
193
+ mutation($input: UpdateProjectV2Input!) {
194
+ updateProjectV2(input: $input) {
195
+ projectV2 {
196
+ id
197
+ number
198
+ }
199
+ }
200
+ }
201
+ GRAPHQL
202
+
203
+ # --- Project item mutations ----------------------------------------
204
+
205
+ ADD_ITEM = <<~GRAPHQL
206
+ mutation($projectId: ID!, $contentId: ID!) {
207
+ addProjectV2ItemById(input: {
208
+ projectId: $projectId,
209
+ contentId: $contentId
210
+ }) {
211
+ item {
212
+ id
213
+ }
214
+ }
215
+ }
216
+ GRAPHQL
217
+
218
+ ADD_DRAFT_ITEM = <<~GRAPHQL
219
+ mutation($projectId: ID!, $title: String!, $body: String) {
220
+ addProjectV2DraftIssue(input: {
221
+ projectId: $projectId,
222
+ title: $title,
223
+ body: $body
224
+ }) {
225
+ projectItem {
226
+ id
227
+ content { ... on DraftIssue { id body } }
228
+ }
229
+ }
230
+ }
231
+ GRAPHQL
232
+
233
+ UPDATE_SINGLE_SELECT_FIELD = <<~GRAPHQL
234
+ mutation($projectId: ID!, $itemId: ID!, $fieldId: ID!, $optionId: String!) {
235
+ updateProjectV2ItemFieldValue(input: {
236
+ projectId: $projectId,
237
+ itemId: $itemId,
238
+ fieldId: $fieldId,
239
+ value: { singleSelectOptionId: $optionId }
240
+ }) {
241
+ projectV2Item {
242
+ id
243
+ }
244
+ }
245
+ }
246
+ GRAPHQL
247
+
248
+ UPDATE_TEXT_FIELD = <<~GRAPHQL
249
+ mutation($projectId: ID!, $itemId: ID!, $fieldId: ID!, $value: String!) {
250
+ updateProjectV2ItemFieldValue(input: {
251
+ projectId: $projectId,
252
+ itemId: $itemId,
253
+ fieldId: $fieldId,
254
+ value: { text: $value }
255
+ }) {
256
+ projectV2Item {
257
+ id
258
+ }
259
+ }
260
+ }
261
+ GRAPHQL
262
+
263
+ CREATE_PROJECT_V2_FIELD = <<~GRAPHQL
264
+ mutation($input: CreateProjectV2FieldInput!) {
265
+ createProjectV2Field(input: $input) {
266
+ projectV2Field {
267
+ ... on ProjectV2Field {
268
+ id
269
+ name
270
+ }
271
+ ... on ProjectV2SingleSelectField {
272
+ id
273
+ name
274
+ }
275
+ }
276
+ }
277
+ }
278
+ GRAPHQL
279
+
280
+ DELETE_PROJECT_V2_FIELD = <<~GRAPHQL
281
+ mutation($input: DeleteProjectV2FieldInput!) {
282
+ deleteProjectV2Field(input: $input) {
283
+ projectV2Field {
284
+ ... on ProjectV2Field {
285
+ id
286
+ }
287
+ ... on ProjectV2SingleSelectField {
288
+ id
289
+ }
290
+ }
291
+ }
292
+ }
293
+ GRAPHQL
294
+
295
+ UPDATE_DATE_FIELD = <<~GRAPHQL
296
+ mutation($projectId: ID!, $itemId: ID!, $fieldId: ID!, $date: Date!) {
297
+ updateProjectV2ItemFieldValue(input: {
298
+ projectId: $projectId,
299
+ itemId: $itemId,
300
+ fieldId: $fieldId,
301
+ value: { date: $date }
302
+ }) {
303
+ projectV2Item {
304
+ id
305
+ }
306
+ }
307
+ }
308
+ GRAPHQL
309
+
310
+ DELETE_PROJECT_ITEM = <<~GRAPHQL
311
+ mutation($projectId: ID!, $itemId: ID!) {
312
+ deleteProjectV2Item(input: {
313
+ projectId: $projectId,
314
+ itemId: $itemId
315
+ }) {
316
+ deletedItemId
317
+ }
318
+ }
319
+ GRAPHQL
320
+
321
+ ASSIGN_DRAFT = <<~GRAPHQL
322
+ mutation($draftIssueId: ID!, $assigneeIds: [ID!]) {
323
+ updateProjectV2DraftIssue(input: {
324
+ draftIssueId: $draftIssueId,
325
+ assigneeIds: $assigneeIds
326
+ }) {
327
+ draftIssue { id }
328
+ }
329
+ }
330
+ GRAPHQL
331
+
332
+ # --- Issue relationships -------------------------------------------
333
+ #
334
+ # Sub-issues (parent / sub_tickets) and issue dependencies
335
+ # (blocking / blocked_by) are both handled via REST in +Issue+:
336
+ # - +/repos/{owner}/{repo}/issues/{number}/parent+
337
+ # - +/repos/{owner}/{repo}/issues/{number}/sub_issues+
338
+ # - +/repos/{owner}/{repo}/issues/{number}/sub_issue+ (DELETE)
339
+ # - +/repos/{owner}/{repo}/issues/{number}/dependencies/{side}+
340
+ # Only +duplicate_of+ still uses GraphQL.
341
+
342
+ FETCH_DUPLICATE_OF = <<~GRAPHQL
343
+ query($owner: String!, $repo: String!, $number: Int!) {
344
+ repository(owner: $owner, name: $repo) {
345
+ issue(number: $number) {
346
+ stateReason
347
+ duplicateOf {
348
+ number
349
+ repository {
350
+ nameWithOwner
351
+ }
352
+ }
353
+ }
354
+ }
355
+ }
356
+ GRAPHQL
357
+
358
+ CLOSE_AS_DUPLICATE = <<~GRAPHQL
359
+ mutation($issueId: ID!, $duplicateIssueId: ID!) {
360
+ closeIssue(input: {
361
+ issueId: $issueId,
362
+ stateReason: DUPLICATE,
363
+ duplicateIssueId: $duplicateIssueId
364
+ }) {
365
+ issue {
366
+ number
367
+ stateReason
368
+ }
369
+ }
370
+ }
371
+ GRAPHQL
372
+
373
+ # --- Archive support -----------------------------------------------
374
+
375
+ LIST_ISSUE_PROJECT_ITEMS = <<~GRAPHQL
376
+ query($owner: String!, $repo: String!, $number: Int!, $cursor: String) {
377
+ repository(owner: $owner, name: $repo) {
378
+ issue(number: $number) {
379
+ projectItems(first: 50, after: $cursor) {
380
+ pageInfo { hasNextPage endCursor }
381
+ nodes {
382
+ id
383
+ project { id number }
384
+ }
385
+ }
386
+ }
387
+ }
388
+ }
389
+ GRAPHQL
390
+ end
391
+ end
392
+ end