plan_my_stuff 0.1.0 → 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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +595 -0
- data/CONFIGURATION.md +487 -0
- data/README.md +612 -88
- data/app/controllers/plan_my_stuff/application_controller.rb +27 -5
- data/app/controllers/plan_my_stuff/comments_controller.rb +50 -19
- data/app/controllers/plan_my_stuff/issues/approvals_controller.rb +127 -0
- data/app/controllers/plan_my_stuff/issues/closures_controller.rb +53 -0
- data/app/controllers/plan_my_stuff/issues/links_controller.rb +129 -0
- data/app/controllers/plan_my_stuff/issues/takes_controller.rb +161 -0
- data/app/controllers/plan_my_stuff/issues/testings_controller.rb +82 -0
- data/app/controllers/plan_my_stuff/issues/viewers_controller.rb +62 -0
- data/app/controllers/plan_my_stuff/issues/waitings_controller.rb +55 -0
- data/app/controllers/plan_my_stuff/issues_controller.rb +53 -70
- data/app/controllers/plan_my_stuff/labels_controller.rb +32 -10
- data/app/controllers/plan_my_stuff/project_items/assignments_controller.rb +88 -0
- data/app/controllers/plan_my_stuff/project_items/statuses_controller.rb +44 -0
- data/app/controllers/plan_my_stuff/project_items_controller.rb +32 -69
- data/app/controllers/plan_my_stuff/projects_controller.rb +81 -3
- data/app/controllers/plan_my_stuff/testing_project_items/results_controller.rb +67 -0
- data/app/controllers/plan_my_stuff/testing_project_items_controller.rb +49 -0
- data/app/controllers/plan_my_stuff/testing_projects_controller.rb +121 -0
- data/app/controllers/plan_my_stuff/webhooks/aws_controller.rb +202 -0
- data/app/controllers/plan_my_stuff/webhooks/github_controller.rb +371 -0
- data/app/jobs/plan_my_stuff/application_job.rb +8 -0
- data/app/jobs/plan_my_stuff/reminders_sweep_job.rb +75 -0
- data/app/views/plan_my_stuff/comments/edit.html.erb +1 -3
- data/app/views/plan_my_stuff/comments/partials/_form.html.erb +8 -0
- data/app/views/plan_my_stuff/issues/edit.html.erb +2 -4
- data/app/views/plan_my_stuff/issues/index.html.erb +5 -5
- data/app/views/plan_my_stuff/issues/new.html.erb +2 -4
- data/app/views/plan_my_stuff/issues/partials/_approvals.html.erb +108 -0
- data/app/views/plan_my_stuff/issues/partials/_form.html.erb +11 -6
- data/app/views/plan_my_stuff/issues/partials/_labels.html.erb +4 -3
- data/app/views/plan_my_stuff/issues/partials/_links.html.erb +113 -0
- data/app/views/plan_my_stuff/issues/partials/_viewers.html.erb +4 -3
- data/app/views/plan_my_stuff/issues/show.html.erb +67 -6
- data/app/views/plan_my_stuff/partials/_flash.html.erb +3 -0
- data/app/views/plan_my_stuff/projects/edit.html.erb +5 -0
- data/app/views/plan_my_stuff/projects/index.html.erb +18 -2
- data/app/views/plan_my_stuff/projects/new.html.erb +5 -0
- data/app/views/plan_my_stuff/projects/partials/_form.html.erb +30 -0
- data/app/views/plan_my_stuff/projects/show.html.erb +30 -11
- data/app/views/plan_my_stuff/testing_project_items/new.html.erb +10 -0
- data/app/views/plan_my_stuff/testing_project_items/results/new.html.erb +20 -0
- data/app/views/plan_my_stuff/testing_projects/edit.html.erb +5 -0
- data/app/views/plan_my_stuff/testing_projects/new.html.erb +5 -0
- data/app/views/plan_my_stuff/testing_projects/partials/_form.html.erb +40 -0
- data/app/views/plan_my_stuff/testing_projects/partials/_item.html.erb +52 -0
- data/app/views/plan_my_stuff/testing_projects/partials/items/_form.html.erb +36 -0
- data/app/views/plan_my_stuff/testing_projects/show.html.erb +65 -0
- data/config/routes.rb +43 -15
- data/lib/generators/plan_my_stuff/install/templates/initializer.rb +302 -20
- data/lib/plan_my_stuff/application_record.rb +158 -1
- data/lib/plan_my_stuff/approval.rb +88 -0
- data/lib/plan_my_stuff/archive/sweep.rb +85 -0
- data/lib/plan_my_stuff/archive.rb +12 -0
- data/lib/plan_my_stuff/attachment.rb +83 -0
- data/lib/plan_my_stuff/attachment_uploader.rb +245 -0
- data/lib/plan_my_stuff/aws_sns_simulator.rb +116 -0
- data/lib/plan_my_stuff/base_metadata.rb +25 -28
- data/lib/plan_my_stuff/base_project.rb +502 -0
- data/lib/plan_my_stuff/base_project_extractions/graphql_hydration.rb +186 -0
- data/lib/plan_my_stuff/base_project_item.rb +588 -0
- data/lib/plan_my_stuff/base_project_metadata.rb +16 -0
- data/lib/plan_my_stuff/cache.rb +197 -0
- data/lib/plan_my_stuff/client.rb +139 -64
- data/lib/plan_my_stuff/comment.rb +225 -100
- data/lib/plan_my_stuff/comment_metadata.rb +68 -5
- data/lib/plan_my_stuff/configuration.rb +459 -28
- data/lib/plan_my_stuff/custom_fields.rb +96 -12
- data/lib/plan_my_stuff/engine.rb +14 -2
- data/lib/plan_my_stuff/errors.rb +65 -5
- data/lib/plan_my_stuff/graphql/queries.rb +454 -0
- data/lib/plan_my_stuff/issue.rb +1097 -166
- data/lib/plan_my_stuff/issue_extractions/approvals.rb +370 -0
- data/lib/plan_my_stuff/issue_extractions/links.rb +525 -0
- data/lib/plan_my_stuff/issue_extractions/viewers.rb +75 -0
- data/lib/plan_my_stuff/issue_extractions/waiting.rb +171 -0
- data/lib/plan_my_stuff/issue_field.rb +126 -0
- data/lib/plan_my_stuff/issue_field_translation.rb +67 -0
- data/lib/plan_my_stuff/issue_field_value_set.rb +68 -0
- data/lib/plan_my_stuff/issue_metadata.rb +132 -21
- data/lib/plan_my_stuff/label.rb +100 -13
- data/lib/plan_my_stuff/link.rb +144 -0
- data/lib/plan_my_stuff/markdown.rb +13 -7
- data/lib/plan_my_stuff/metadata_parser.rb +51 -12
- data/lib/plan_my_stuff/notifications.rb +148 -0
- data/lib/plan_my_stuff/pipeline/completed_sweep.rb +46 -0
- data/lib/plan_my_stuff/pipeline/issue_linker.rb +62 -0
- data/lib/plan_my_stuff/pipeline/status.rb +40 -0
- data/lib/plan_my_stuff/pipeline/testing.rb +23 -0
- data/lib/plan_my_stuff/pipeline.rb +310 -0
- data/lib/plan_my_stuff/project.rb +63 -465
- data/lib/plan_my_stuff/project_item.rb +3 -409
- data/lib/plan_my_stuff/project_item_metadata.rb +55 -0
- data/lib/plan_my_stuff/project_metadata.rb +47 -0
- data/lib/plan_my_stuff/reminders/closer.rb +70 -0
- data/lib/plan_my_stuff/reminders/fire.rb +129 -0
- data/lib/plan_my_stuff/reminders/sweep.rb +54 -0
- data/lib/plan_my_stuff/reminders.rb +12 -0
- data/lib/plan_my_stuff/repo.rb +145 -0
- data/lib/plan_my_stuff/test_helpers.rb +265 -25
- data/lib/plan_my_stuff/testing_project.rb +292 -0
- data/lib/plan_my_stuff/testing_project_item.rb +218 -0
- data/lib/plan_my_stuff/testing_project_metadata.rb +94 -0
- data/lib/plan_my_stuff/user_resolver.rb +24 -3
- data/lib/plan_my_stuff/verifier.rb +10 -0
- data/lib/plan_my_stuff/version.rb +2 -2
- data/lib/plan_my_stuff/webhook_replayer.rb +292 -0
- data/lib/plan_my_stuff.rb +55 -20
- data/lib/tasks/plan_my_stuff.rake +331 -0
- metadata +99 -4
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<h1><%= @project.title %></h1>
|
|
2
|
+
|
|
3
|
+
<p>
|
|
4
|
+
<%= link_to('Edit', plan_my_stuff.edit_testing_project_path(@project.number)) %>
|
|
5
|
+
<% if @support_user && @project.url.present? %>
|
|
6
|
+
<%= link_to('View on GitHub', @project.url, target: '_blank', rel: 'noopener') %>
|
|
7
|
+
<% end %>
|
|
8
|
+
</p>
|
|
9
|
+
|
|
10
|
+
<% if @support_user && @project.metadata.subject_urls.present? %>
|
|
11
|
+
<p>
|
|
12
|
+
<strong>Subject URLs:</strong>
|
|
13
|
+
<% @project.metadata.subject_urls.each do |url| %>
|
|
14
|
+
<%= link_to(url, url, target: '_blank', rel: 'noopener') %>
|
|
15
|
+
<% end %>
|
|
16
|
+
</p>
|
|
17
|
+
<% end %>
|
|
18
|
+
|
|
19
|
+
<% if @project.metadata.due_date.present? %>
|
|
20
|
+
<p><strong>Due:</strong> <%= @project.metadata.due_date %></p>
|
|
21
|
+
<% end %>
|
|
22
|
+
|
|
23
|
+
<% if @statuses.present? %>
|
|
24
|
+
<table>
|
|
25
|
+
<thead>
|
|
26
|
+
<tr>
|
|
27
|
+
<% @statuses.each do |status| %>
|
|
28
|
+
<th><%= status %></th>
|
|
29
|
+
<% end %>
|
|
30
|
+
</tr>
|
|
31
|
+
</thead>
|
|
32
|
+
<tbody>
|
|
33
|
+
<tr>
|
|
34
|
+
<% @statuses.each do |status| %>
|
|
35
|
+
<td>
|
|
36
|
+
<% items = @items_by_status[status] || [] %>
|
|
37
|
+
<% items.each do |item| %>
|
|
38
|
+
<%= render({
|
|
39
|
+
partial: 'plan_my_stuff/testing_projects/partials/item',
|
|
40
|
+
locals: { item: item, project: @project, statuses: @statuses },
|
|
41
|
+
}) %>
|
|
42
|
+
<% end %>
|
|
43
|
+
<% if items.empty? %>
|
|
44
|
+
<em>No items</em>
|
|
45
|
+
<% end %>
|
|
46
|
+
</td>
|
|
47
|
+
<% end %>
|
|
48
|
+
</tr>
|
|
49
|
+
</tbody>
|
|
50
|
+
</table>
|
|
51
|
+
<% else %>
|
|
52
|
+
<p>No statuses configured for this project.</p>
|
|
53
|
+
<% end %>
|
|
54
|
+
|
|
55
|
+
<h2>Add Item</h2>
|
|
56
|
+
|
|
57
|
+
<p><%= link_to('Add item with details', plan_my_stuff.new_testing_project_item_path(@project.number)) %></p>
|
|
58
|
+
|
|
59
|
+
<%= form_with(url: plan_my_stuff.testing_project_items_path(@project.number), method: :post, local: true) do |form| %>
|
|
60
|
+
<%= form.label(:title, 'Title') %>
|
|
61
|
+
<%= form.text_field(:title, required: true) %>
|
|
62
|
+
<%= form.label(:body, 'Body') %>
|
|
63
|
+
<%= form.text_area(:body) %>
|
|
64
|
+
<%= form.submit('Add Item') %>
|
|
65
|
+
<% end %>
|
data/config/routes.rb
CHANGED
|
@@ -1,24 +1,52 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
PlanMyStuff::Engine.routes.draw do
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
config = PlanMyStuff.configuration
|
|
5
|
+
mount_groups = config.mount_groups
|
|
6
|
+
|
|
7
|
+
if mount_groups.fetch(:issues, true)
|
|
8
|
+
resources :issues, except: %i[destroy], controller: config.controller_for(:issues) do
|
|
9
|
+
resource :closure, only: %i[create destroy], controller: config.controller_for(:'issues/closures')
|
|
10
|
+
resource :waiting, only: %i[create destroy], controller: config.controller_for(:'issues/waitings')
|
|
11
|
+
resources :viewers, only: %i[create destroy], controller: config.controller_for(:'issues/viewers')
|
|
12
|
+
if config.pipeline_enabled
|
|
13
|
+
resource(
|
|
14
|
+
:take,
|
|
15
|
+
only: %i[create destroy],
|
|
16
|
+
controller: config.controller_for(:'issues/takes'),
|
|
17
|
+
)
|
|
18
|
+
resource(
|
|
19
|
+
:testing,
|
|
20
|
+
only: %i[create destroy],
|
|
21
|
+
controller: config.controller_for(:'issues/testings'),
|
|
22
|
+
)
|
|
23
|
+
end
|
|
24
|
+
resources :comments, only: %i[create edit update], controller: config.controller_for(:comments)
|
|
25
|
+
resources :labels, only: %i[create destroy], controller: config.controller_for(:labels)
|
|
26
|
+
resources :links, only: %i[create destroy], controller: config.controller_for(:'issues/links')
|
|
27
|
+
resources :approvals, only: %i[create update destroy], controller: config.controller_for(:'issues/approvals')
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
if mount_groups.fetch(:webhooks, true) && config.pipeline_enabled
|
|
32
|
+
namespace :webhooks do
|
|
33
|
+
resource :github, only: %i[create], controller: config.controller_for(:'webhooks/github')
|
|
34
|
+
resource :aws, only: %i[create], controller: config.controller_for(:'webhooks/aws')
|
|
10
35
|
end
|
|
11
|
-
resources :comments, only: %i[create edit update]
|
|
12
|
-
post 'labels', to: 'labels#add_to_issue', as: :add_label
|
|
13
|
-
delete 'labels/:name', to: 'labels#remove_from_issue', as: :remove_label
|
|
14
36
|
end
|
|
15
37
|
|
|
16
|
-
|
|
17
|
-
resources :
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
38
|
+
if mount_groups.fetch(:projects, true)
|
|
39
|
+
resources :projects, except: %i[destroy], controller: config.controller_for(:projects) do
|
|
40
|
+
resources :items, only: %i[create destroy], controller: config.controller_for(:project_items) do
|
|
41
|
+
resource :status, only: %i[update], controller: config.controller_for(:'project_items/statuses')
|
|
42
|
+
resource :assignment, only: %i[update destroy], controller: config.controller_for(:'project_items/assignments')
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
resources :testing_projects, except: %i[destroy index], controller: config.controller_for(:testing_projects) do
|
|
47
|
+
resources :items, only: %i[new create], controller: config.controller_for(:testing_project_items) do
|
|
48
|
+
resource :status, only: %i[update], controller: config.controller_for(:'project_items/statuses')
|
|
49
|
+
resource :result, only: %i[new create], controller: config.controller_for(:'testing_project_items/results')
|
|
22
50
|
end
|
|
23
51
|
end
|
|
24
52
|
end
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
PlanMyStuff.configure do |config|
|
|
4
4
|
# --------------------------------------------------------------------------
|
|
5
5
|
# Authentication (required)
|
|
6
6
|
# --------------------------------------------------------------------------
|
|
7
7
|
# GitHub PAT with `repo` and `project` scopes. All API calls use this token.
|
|
8
8
|
config.access_token = Rails.application.credentials.dig(:plan_my_stuff, :github_token)
|
|
9
9
|
|
|
10
|
+
# Classic PAT (requires `repo` scope) for the Issues Import API (golden-comet-preview).
|
|
11
|
+
# Fine-grained tokens are not supported by that endpoint.
|
|
12
|
+
# config.import_access_token = Rails.application.credentials.dig(:plan_my_stuff, :github_import_token)
|
|
13
|
+
|
|
10
14
|
# --------------------------------------------------------------------------
|
|
11
15
|
# Organization (required)
|
|
12
16
|
# --------------------------------------------------------------------------
|
|
@@ -20,12 +24,34 @@ PMS.configure do |config|
|
|
|
20
24
|
# config.repos[:underwriter] = 'YourOrganization/Underwriter'
|
|
21
25
|
# config.default_repo = :element
|
|
22
26
|
|
|
27
|
+
# Human-readable prefix used as the `Issue#to_param` so URLs read
|
|
28
|
+
# `/issues/Element-1234` instead of `/issues/1234`. Missing keys fall back
|
|
29
|
+
# to `key.to_s.titleize`; only repos whose key doesn't titleize cleanly
|
|
30
|
+
# need an entry.
|
|
31
|
+
# config.repo_nicknames = { safety: 'Compliance' }
|
|
32
|
+
|
|
33
|
+
# --------------------------------------------------------------------------
|
|
34
|
+
# Attachments
|
|
35
|
+
# --------------------------------------------------------------------------
|
|
36
|
+
# Bare repo name (under `organization`) that stores uploaded attachment
|
|
37
|
+
# binaries. The repo must already exist; the uploader does not create it.
|
|
38
|
+
# Attachments commit onto `config.main_branch` under
|
|
39
|
+
# `<repo_key_or_name>/issue-<number>/<uuid>.<ext>`.
|
|
40
|
+
# config.attachment_repo = 'pms-attachments'
|
|
41
|
+
|
|
23
42
|
# --------------------------------------------------------------------------
|
|
24
43
|
# Projects
|
|
25
44
|
# --------------------------------------------------------------------------
|
|
26
45
|
# Default GitHub Projects V2 number for add_to_project calls.
|
|
27
46
|
# config.default_project_number = 14
|
|
28
47
|
|
|
48
|
+
# Template project to clone when creating new Testing Projects.
|
|
49
|
+
# When set, TestingProject.create! copies this project (preserving its
|
|
50
|
+
# custom fields and board layout) instead of bootstrapping fields from scratch.
|
|
51
|
+
# The template should be a pre-configured testing project with the correct
|
|
52
|
+
# fields and board view already set up in the GitHub UI.
|
|
53
|
+
# config.testing_template_project_number = 42
|
|
54
|
+
|
|
29
55
|
# --------------------------------------------------------------------------
|
|
30
56
|
# App identity
|
|
31
57
|
# --------------------------------------------------------------------------
|
|
@@ -49,6 +75,14 @@ PMS.configure do |config|
|
|
|
49
75
|
# config.support_method = :support?
|
|
50
76
|
# config.support_method = ->(user) { user.role.in?(%w[support admin]) }
|
|
51
77
|
|
|
78
|
+
# Map of app user id (whatever `user_id_method` returns) to GitHub login.
|
|
79
|
+
# Used by the "Take" UI flow to assign the GitHub user when a support
|
|
80
|
+
# user claims an issue.
|
|
81
|
+
# config.github_login_for = {
|
|
82
|
+
# 1 => 'some_username',
|
|
83
|
+
# 2 => 'octocat',
|
|
84
|
+
# }
|
|
85
|
+
|
|
52
86
|
# --------------------------------------------------------------------------
|
|
53
87
|
# Engine authentication
|
|
54
88
|
# --------------------------------------------------------------------------
|
|
@@ -65,31 +99,45 @@ PMS.configure do |config|
|
|
|
65
99
|
# :commonmarker (default) or :redcarpet -- the chosen gem must be in your Gemfile.
|
|
66
100
|
# config.markdown_renderer = :commonmarker
|
|
67
101
|
|
|
102
|
+
# Default options passed to the markdown renderer. Per-call options merge on top.
|
|
103
|
+
# For :commonmarker -- passed as `options:` to `Commonmarker.to_html`:
|
|
104
|
+
# config.markdown_options = { render: { hardbreaks: true } }
|
|
105
|
+
# For :redcarpet -- :render_options and :renderer are extracted for the HTML
|
|
106
|
+
# renderer; remaining keys are extensions passed to `Redcarpet::Markdown.new`:
|
|
107
|
+
# config.markdown_options = {
|
|
108
|
+
# render_options: { hard_wrap: true, no_styles: true },
|
|
109
|
+
# autolink: true,
|
|
110
|
+
# }
|
|
111
|
+
|
|
68
112
|
# --------------------------------------------------------------------------
|
|
69
113
|
# URL prefix
|
|
70
114
|
# --------------------------------------------------------------------------
|
|
71
|
-
# Prefix for building user-facing ticket URLs in your app.
|
|
72
|
-
#
|
|
115
|
+
# Prefix for building user-facing ticket URLs in your app. The issue
|
|
116
|
+
# number is appended to form `Issue#user_link`, which the gem also
|
|
117
|
+
# writes as the visible body of the GitHub issue.
|
|
118
|
+
# Recommended default:
|
|
119
|
+
# url_options = Rails.application.routes.default_url_options
|
|
120
|
+
# config.issues_url_prefix =
|
|
121
|
+
# "#{url_options[:protocol] || 'http'}://#{url_options[:host]}/issues"
|
|
73
122
|
|
|
74
123
|
# --------------------------------------------------------------------------
|
|
75
|
-
#
|
|
124
|
+
# Notification actor
|
|
76
125
|
# --------------------------------------------------------------------------
|
|
77
|
-
#
|
|
78
|
-
#
|
|
79
|
-
# config.
|
|
80
|
-
|
|
81
|
-
# Map of action type to job class name for deferred requests.
|
|
82
|
-
# config.job_classes = {
|
|
83
|
-
# create_ticket: 'PmsCreateTicketJob',
|
|
84
|
-
# post_comment: 'PmsPostCommentJob',
|
|
85
|
-
# update_status: 'PmsUpdateStatusJob'
|
|
86
|
-
# }
|
|
126
|
+
# Fallback actor for notification events (*.plan_my_stuff) when a caller
|
|
127
|
+
# does not pass an explicit user: kwarg. Proc/lambda called at event time.
|
|
128
|
+
# config.current_user = -> { Current.user }
|
|
87
129
|
|
|
88
|
-
#
|
|
89
|
-
#
|
|
90
|
-
#
|
|
91
|
-
#
|
|
92
|
-
#
|
|
130
|
+
# --------------------------------------------------------------------------
|
|
131
|
+
# Controller rescue hook
|
|
132
|
+
# --------------------------------------------------------------------------
|
|
133
|
+
# Invoked from every gem controller rescue block, after the gem logs the
|
|
134
|
+
# error class/message and stack trace via Rails.logger.error and just
|
|
135
|
+
# before the user-facing flash + redirect/render. Forwards the rescued
|
|
136
|
+
# exception so consuming apps can fire monitoring even though the rescue
|
|
137
|
+
# swallows the error. Receives the rescued exception; return value is
|
|
138
|
+
# ignored. Defaults to nil (no-op).
|
|
139
|
+
#
|
|
140
|
+
# config.controller_rescue = ->(error) { MonitoringService.notice_error(error) }
|
|
93
141
|
|
|
94
142
|
# --------------------------------------------------------------------------
|
|
95
143
|
# Custom fields
|
|
@@ -100,7 +148,241 @@ PMS.configure do |config|
|
|
|
100
148
|
# Supported types: :string, :integer, :boolean, :array, :hash
|
|
101
149
|
# required: true means the key must be present (value can be nil, [], etc.)
|
|
102
150
|
#
|
|
151
|
+
# Shared fields (available on both issues and comments):
|
|
103
152
|
config.custom_fields = {
|
|
104
|
-
notification_recipients: { type: :array, required: true },
|
|
153
|
+
# notification_recipients: { type: :array, required: true },
|
|
105
154
|
}
|
|
155
|
+
|
|
156
|
+
# Issue-only fields (merged on top of shared, context wins on conflicts):
|
|
157
|
+
# config.issue_custom_fields = {
|
|
158
|
+
# ticket_type: { type: :string, required: true },
|
|
159
|
+
# }
|
|
160
|
+
|
|
161
|
+
# Comment-only fields (merged on top of shared, context wins on conflicts):
|
|
162
|
+
# config.comment_custom_fields = {}
|
|
163
|
+
|
|
164
|
+
# Project-only fields (merged on top of shared, context wins on conflicts):
|
|
165
|
+
# config.project_custom_fields = {}
|
|
166
|
+
|
|
167
|
+
# Testing-project-only fields (merged on top of shared, context wins on conflicts):
|
|
168
|
+
# config.testing_custom_fields = {}
|
|
169
|
+
|
|
170
|
+
# --------------------------------------------------------------------------
|
|
171
|
+
# Issue types (org-side renames)
|
|
172
|
+
# --------------------------------------------------------------------------
|
|
173
|
+
# The gem speaks in canonical type names: 'Bug', 'Feature',
|
|
174
|
+
# 'IT Issue / Hardware', 'Other', 'Performance', 'Question', 'Task'.
|
|
175
|
+
# Symbol shortcuts (`:bug`, `:feature`, `:it_issue`, `:other`, `:performance`,
|
|
176
|
+
# `:question`, `:task`) resolve to those canonical names automatically.
|
|
177
|
+
# If your GitHub org uses different names for any of them, map the
|
|
178
|
+
# canonical name to your org's name here and PMS will translate on
|
|
179
|
+
# write. Missing keys pass through unchanged.
|
|
180
|
+
#
|
|
181
|
+
# config.issue_types = {
|
|
182
|
+
# 'Bug' => 'User Bug',
|
|
183
|
+
# 'Feature' => 'Enhancement',
|
|
184
|
+
# }
|
|
185
|
+
|
|
186
|
+
# --------------------------------------------------------------------------
|
|
187
|
+
# Issue Fields (public preview)
|
|
188
|
+
# --------------------------------------------------------------------------
|
|
189
|
+
# GitHub Issue Fields is a per-org public preview. Default is true (opt-out).
|
|
190
|
+
# Flip to false if your org has not been admitted to the preview - read paths
|
|
191
|
+
# return an empty set and write paths raise IssueFieldsNotEnabledError instead
|
|
192
|
+
# of letting a raw GraphQL error bubble.
|
|
193
|
+
#
|
|
194
|
+
# config.issue_fields_enabled = false
|
|
195
|
+
|
|
196
|
+
# Rename the native Issue Fields the gem refers to internally to whatever your
|
|
197
|
+
# org actually calls them. Keys are the gem's canonical names; values are your
|
|
198
|
+
# org's field names. Applied on reads, writes, and filters; unmapped names pass
|
|
199
|
+
# through unchanged.
|
|
200
|
+
# config.issue_field_names = {
|
|
201
|
+
# 'Issue Status' => 'Status',
|
|
202
|
+
# 'Priority' => 'Prio',
|
|
203
|
+
# }
|
|
204
|
+
|
|
205
|
+
# Rename single-select option labels, nested by canonical field name. Keys are
|
|
206
|
+
# the gem's canonical values; values are your org's option labels. Unmapped
|
|
207
|
+
# fields / values pass through unchanged.
|
|
208
|
+
# config.issue_field_values = {
|
|
209
|
+
# 'Issue Status' => {
|
|
210
|
+
# 'Submitted' => 'Triaged',
|
|
211
|
+
# 'Waiting on Reply' => 'Awaiting Customer',
|
|
212
|
+
# 'Open' => 'Open',
|
|
213
|
+
# 'Reopened' => 'Reopened',
|
|
214
|
+
# },
|
|
215
|
+
# }
|
|
216
|
+
|
|
217
|
+
# --------------------------------------------------------------------------
|
|
218
|
+
# Boot behavior
|
|
219
|
+
# --------------------------------------------------------------------------
|
|
220
|
+
# Eager-load the engine's controllers in after_initialize so that
|
|
221
|
+
# `defined?(PlanMyStuff::SomeController)` resolves without first referencing
|
|
222
|
+
# the constant. Opt in if the host app probes engine controllers via
|
|
223
|
+
# `defined?` in dev mode.
|
|
224
|
+
#
|
|
225
|
+
# config.eager_load_controllers_on_boot = true
|
|
226
|
+
|
|
227
|
+
# --------------------------------------------------------------------------
|
|
228
|
+
# Release pipeline
|
|
229
|
+
# --------------------------------------------------------------------------
|
|
230
|
+
# config.pipeline_enabled = true
|
|
231
|
+
# config.pipeline_project_number = 14
|
|
232
|
+
|
|
233
|
+
# GitHub webhook HMAC-SHA256 secret (required when webhook routes are mounted).
|
|
234
|
+
# config.webhook_secret = Rails.application.credentials.dig(:plan_my_stuff, :webhook_secret)
|
|
235
|
+
|
|
236
|
+
# Configurable display aliases for pipeline statuses.
|
|
237
|
+
# config.pipeline_statuses = {
|
|
238
|
+
# 'Submitted' => 'Triaged',
|
|
239
|
+
# 'Completed' => 'Done',
|
|
240
|
+
# }
|
|
241
|
+
|
|
242
|
+
# Display name for the Testing single-select field on the pipeline project.
|
|
243
|
+
# config.pipeline_testing_field_name = 'Testing'
|
|
244
|
+
|
|
245
|
+
# Display labels for the canonical Testing field option keys.
|
|
246
|
+
# config.pipeline_testing_values = {
|
|
247
|
+
# active: 'Testing',
|
|
248
|
+
# inactive: 'Not testing',
|
|
249
|
+
# }
|
|
250
|
+
|
|
251
|
+
# Whether the pipeline sweep removes aged-out Completed items.
|
|
252
|
+
# config.pipeline_completion_purge_enabled = true
|
|
253
|
+
|
|
254
|
+
# Hours after a project item's last update at which the sweep removes it
|
|
255
|
+
# from the pipeline if its status is Completed.
|
|
256
|
+
# config.pipeline_completion_ttl_hours = 24
|
|
257
|
+
|
|
258
|
+
# config.main_branch = 'main'
|
|
259
|
+
# config.production_branch = 'production'
|
|
260
|
+
|
|
261
|
+
# --------------------------------------------------------------------------
|
|
262
|
+
# Follow-up reminders
|
|
263
|
+
# --------------------------------------------------------------------------
|
|
264
|
+
# Daily sweep that fires `issue_reminder_due.plan_my_stuff` events on
|
|
265
|
+
# waiting issues and auto-closes issues that exceed the inactivity
|
|
266
|
+
# ceiling. Consuming app is responsible for the initial enqueue:
|
|
267
|
+
#
|
|
268
|
+
# # Enqueue one sweep job per configured repo:
|
|
269
|
+
# rake plan_my_stuff:reminders:sweep
|
|
270
|
+
#
|
|
271
|
+
# # Or a single repo:
|
|
272
|
+
# rake plan_my_stuff:reminders:sweep REPO=element
|
|
273
|
+
#
|
|
274
|
+
# Each job self-requeues after perform (default: 6:30am ET next day);
|
|
275
|
+
# running the rake task once on app boot is enough. Override
|
|
276
|
+
# `RemindersSweepJob.next_run` on a subclass to change the cadence.
|
|
277
|
+
#
|
|
278
|
+
# config.reminders_enabled = true
|
|
279
|
+
#
|
|
280
|
+
# Days-since-waiting at which reminders fire. Per-issue override via
|
|
281
|
+
# `issue.metadata.reminder_days = [...]`.
|
|
282
|
+
# config.reminder_days = [1, 3, 7, 10, 14, 18]
|
|
283
|
+
#
|
|
284
|
+
# Days of continuous waiting before the sweep auto-closes the issue
|
|
285
|
+
# (emits `issue.closed_inactive` instead of the regular `issue.closed`).
|
|
286
|
+
# config.inactivity_close_days = 30
|
|
287
|
+
#
|
|
288
|
+
# Label names the gem creates and manages on waiting/inactive issues.
|
|
289
|
+
# config.waiting_on_user_label = 'waiting-on-user'
|
|
290
|
+
# config.waiting_on_approval_label = 'waiting-on-approval'
|
|
291
|
+
# config.user_inactive_label = 'user-inactive'
|
|
292
|
+
|
|
293
|
+
# --------------------------------------------------------------------------
|
|
294
|
+
# Auto-archiving of aged-closed issues
|
|
295
|
+
# --------------------------------------------------------------------------
|
|
296
|
+
# Piggybacks the RemindersSweepJob. For every issue closed more than
|
|
297
|
+
# `archive_closed_after_days` ago (based on GitHub's `closed_at`) the
|
|
298
|
+
# sweep: adds the configured label, locks the conversation, removes
|
|
299
|
+
# the issue from every Projects V2 board, stamps `metadata.archived_at`,
|
|
300
|
+
# and emits `issue_archived.plan_my_stuff` with `reason: :aged_closed`.
|
|
301
|
+
# Issues auto-closed by the inactivity sweep (closed_by_inactivity) are
|
|
302
|
+
# excluded. Non-PMS issues are excluded.
|
|
303
|
+
#
|
|
304
|
+
# config.archiving_enabled = true
|
|
305
|
+
# config.archive_closed_after_days = 90
|
|
306
|
+
# config.archived_label = 'archived'
|
|
307
|
+
|
|
308
|
+
# --------------------------------------------------------------------------
|
|
309
|
+
# AWS webhook (ECS deployments via SNS)
|
|
310
|
+
# --------------------------------------------------------------------------
|
|
311
|
+
# Expected SNS topic ARN for webhook validation.
|
|
312
|
+
# config.sns_topic_arn = 'arn:aws:sns:us-east-1:123456:ecs-deploy-topic'
|
|
313
|
+
|
|
314
|
+
# ECS service identifier - suffix matched against resource ARNs in events.
|
|
315
|
+
# config.aws_service_identifier = 'myapp-production-web'
|
|
316
|
+
|
|
317
|
+
# Commit hash of the currently deploying build. Prefix-matched against
|
|
318
|
+
# issue metadata commit_sha on SERVICE_DEPLOYMENT_COMPLETED events.
|
|
319
|
+
# config.production_commit_sha = Rails.configuration.x.image_tag
|
|
320
|
+
|
|
321
|
+
# Toggle for processing AWS webhook events (default: Rails.env.production?).
|
|
322
|
+
# config.process_aws_webhooks = Rails.env.production?
|
|
323
|
+
|
|
324
|
+
# SNS signature verifier (default: Aws::SNS::MessageVerifier). Must respond
|
|
325
|
+
# to authenticate!(raw_body). Provide aws-sdk-sns in your Gemfile.
|
|
326
|
+
# config.sns_verifier_class = Aws::SNS::MessageVerifier
|
|
327
|
+
# config.sns_verifier_error = Aws::SNS::MessageVerifier::VerificationError
|
|
328
|
+
|
|
329
|
+
# --------------------------------------------------------------------------
|
|
330
|
+
# Caching
|
|
331
|
+
# --------------------------------------------------------------------------
|
|
332
|
+
# ETag-based HTTP caching of GitHub reads via Rails.cache. Defaults to true.
|
|
333
|
+
# config.cache_enabled = true
|
|
334
|
+
|
|
335
|
+
# Opaque version string baked into every PMS cache key. Bump it to invalidate
|
|
336
|
+
# all cached entries from the consuming app's side (e.g. after a deploy).
|
|
337
|
+
# config.cache_version = Rails.configuration.x.image_tag
|
|
338
|
+
|
|
339
|
+
# --------------------------------------------------------------------------
|
|
340
|
+
# Route mounting
|
|
341
|
+
# --------------------------------------------------------------------------
|
|
342
|
+
# Per-group toggles for which engine route groups to mount.
|
|
343
|
+
# config.mount_groups = { webhooks: true, issues: true, projects: true }
|
|
344
|
+
|
|
345
|
+
# --------------------------------------------------------------------------
|
|
346
|
+
# Controller overrides (Devise-style)
|
|
347
|
+
# --------------------------------------------------------------------------
|
|
348
|
+
# Swap in your own controller for any mounted route group. Typical use is
|
|
349
|
+
# to subclass the gem controller and slot the subclass in here:
|
|
350
|
+
#
|
|
351
|
+
# # app/controllers/issues_controller.rb
|
|
352
|
+
# class IssuesController < PlanMyStuff::IssuesController
|
|
353
|
+
# before_action :require_admin
|
|
354
|
+
# end
|
|
355
|
+
#
|
|
356
|
+
# # config/initializers/plan_my_stuff.rb
|
|
357
|
+
# config.controllers = { issues: 'issues' }
|
|
358
|
+
#
|
|
359
|
+
# Unset keys fall back to the gem default.
|
|
360
|
+
#
|
|
361
|
+
# Controllable keys (with gem defaults):
|
|
362
|
+
# :issues => 'plan_my_stuff/issues'
|
|
363
|
+
# :comments => 'plan_my_stuff/comments'
|
|
364
|
+
# :labels => 'plan_my_stuff/labels'
|
|
365
|
+
# :projects => 'plan_my_stuff/projects'
|
|
366
|
+
# :project_items => 'plan_my_stuff/project_items'
|
|
367
|
+
# :testing_projects => 'plan_my_stuff/testing_projects'
|
|
368
|
+
# :testing_project_items => 'plan_my_stuff/testing_project_items'
|
|
369
|
+
# :'issues/closures' => 'plan_my_stuff/issues/closures'
|
|
370
|
+
# :'issues/viewers' => 'plan_my_stuff/issues/viewers'
|
|
371
|
+
# :'issues/takes' => 'plan_my_stuff/issues/takes'
|
|
372
|
+
# :'issues/testings' => 'plan_my_stuff/issues/testings'
|
|
373
|
+
# :'issues/waitings' => 'plan_my_stuff/issues/waitings'
|
|
374
|
+
# :'issues/links' => 'plan_my_stuff/issues/links'
|
|
375
|
+
# :'issues/approvals' => 'plan_my_stuff/issues/approvals'
|
|
376
|
+
# :'project_items/statuses' => 'plan_my_stuff/project_items/statuses'
|
|
377
|
+
# :'project_items/assignments' => 'plan_my_stuff/project_items/assignments'
|
|
378
|
+
# :'testing_project_items/results' => 'plan_my_stuff/testing_project_items/results'
|
|
379
|
+
# :'webhooks/github' => 'plan_my_stuff/webhooks/github'
|
|
380
|
+
# :'webhooks/aws' => 'plan_my_stuff/webhooks/aws'
|
|
381
|
+
|
|
382
|
+
# --------------------------------------------------------------------------
|
|
383
|
+
# Parent controller
|
|
384
|
+
# --------------------------------------------------------------------------
|
|
385
|
+
# Parent class for PlanMyStuff::ApplicationController. Override when the
|
|
386
|
+
# consuming app does not use the `ApplicationController` name.
|
|
387
|
+
# config.parent_controller = 'MyOtherApplicationController'
|
|
106
388
|
end
|