plan_my_stuff 0.10.2 → 0.10.4
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 +23 -0
- data/lib/plan_my_stuff/base_project_extractions/graphql_hydration.rb +3 -1
- data/lib/plan_my_stuff/base_project_item.rb +3 -0
- data/lib/plan_my_stuff/graphql/queries.rb +13 -2
- data/lib/plan_my_stuff/issue.rb +1 -10
- data/lib/plan_my_stuff/test_helpers.rb +10 -2
- data/lib/plan_my_stuff/version.rb +1 -1
- data/lib/tasks/plan_my_stuff.rake +26 -0
- metadata +6 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7050eff0771b80d52e75bf81bd9338bb19a99d319cca6e292a00e0634001cca7
|
|
4
|
+
data.tar.gz: ac99ee79695ea601cae8696c6610dffc50cda5a2ccadfd45c704f013be73f028
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b74d03033ea955d72b672ee5bef8e4a79b65fc54f849dcfaddb88b1e9b8bab8e3d6711458ebac3c120df1dc04023810b4ef420ef3898282a42260e14d1172a19
|
|
7
|
+
data.tar.gz: 356a558f9d98f26e442f0db365c4e8bb7c5503f2e60643e6bbf71743b431c03b3916c9ef4399ac1993abb6101ce8913278a37a262e1689cc5cb398707dd755a6
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.10.4
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- Internal: unit specs now use VCR cassettes against `BrandsInsurance/ubiquitous-adventure` instead of
|
|
8
|
+
`instance_double(Octokit::Client)`. No effect on consuming apps.
|
|
9
|
+
|
|
10
|
+
### Removed
|
|
11
|
+
|
|
12
|
+
- ETag caching on `Issue.list`. The cache key included `state`, `labels`, `page`, and `per_page`,
|
|
13
|
+
so an etag stored under one combo never matched a request with different params - the cache wrote
|
|
14
|
+
on every call and effectively never hit. `Issue.list` now always issues a fresh GitHub request.
|
|
15
|
+
`Comment.list` keeps ETag caching (param surface is just `issue` + `pms_only`).
|
|
16
|
+
`PlanMyStuff::Cache.read_list` / `write_list` remain available for `Comment.list`.
|
|
17
|
+
|
|
18
|
+
## 0.10.3
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
|
|
22
|
+
- `BaseProjectItem#assignees` returns the GitHub logins of users assigned to the underlying Issue,
|
|
23
|
+
PullRequest, or DraftIssue. Populated from the `FIND_PROJECT` GraphQL response (the query was extended
|
|
24
|
+
with `assignees(first: 10)` on each content fragment).
|
|
25
|
+
|
|
3
26
|
## 0.10.2
|
|
4
27
|
|
|
5
28
|
### Changed
|
|
@@ -129,6 +129,7 @@ module PlanMyStuff
|
|
|
129
129
|
content = item[:content] || {}
|
|
130
130
|
field_values = item.dig(:fieldValues, :nodes) || []
|
|
131
131
|
repo_name = content.dig(:repository, :nameWithOwner)
|
|
132
|
+
assignee_nodes = content.dig(:assignees, :nodes) || []
|
|
132
133
|
|
|
133
134
|
{
|
|
134
135
|
id: item[:id],
|
|
@@ -142,6 +143,7 @@ module PlanMyStuff
|
|
|
142
143
|
repo: repo_name.present? ? PlanMyStuff::Repo.resolve!(repo_name) : nil,
|
|
143
144
|
status: extract_item_status(field_values),
|
|
144
145
|
field_values: parse_field_values(field_values),
|
|
146
|
+
assignees: assignee_nodes.pluck(:login).compact,
|
|
145
147
|
updated_at: item[:updatedAt],
|
|
146
148
|
github_response: item,
|
|
147
149
|
}
|
|
@@ -168,7 +170,7 @@ module PlanMyStuff
|
|
|
168
170
|
field_name = fv.dig(:field, :name)
|
|
169
171
|
next unless field_name
|
|
170
172
|
|
|
171
|
-
value = fv[:name] || fv[:text]
|
|
173
|
+
value = fv[:name] || fv[:text] || fv[:date]&.to_date
|
|
172
174
|
users_node = fv[:users]
|
|
173
175
|
if users_node
|
|
174
176
|
value = (users_node[:nodes] || []).map { |u| u[:login] }
|
|
@@ -46,6 +46,8 @@ module PlanMyStuff
|
|
|
46
46
|
attribute :updated_at, :datetime
|
|
47
47
|
# @return [Hash]
|
|
48
48
|
attribute :field_values, default: -> { {} }
|
|
49
|
+
# @return [Array<String>] GitHub logins assigned to the underlying Issue, PullRequest, or DraftIssue
|
|
50
|
+
attribute :assignees, default: -> { [] }
|
|
49
51
|
# @return [PlanMyStuff::BaseProject, nil]
|
|
50
52
|
attribute :project
|
|
51
53
|
# @return [PlanMyStuff::Issue, nil] linked issue (nil for draft items)
|
|
@@ -75,6 +77,7 @@ module PlanMyStuff
|
|
|
75
77
|
status: item_hash[:status],
|
|
76
78
|
updated_at: item_hash[:updated_at],
|
|
77
79
|
field_values: item_hash[:field_values] || {},
|
|
80
|
+
assignees: item_hash[:assignees] || [],
|
|
78
81
|
project: project,
|
|
79
82
|
)
|
|
80
83
|
|
|
@@ -63,7 +63,7 @@ module PlanMyStuff
|
|
|
63
63
|
}
|
|
64
64
|
GRAPHQL
|
|
65
65
|
|
|
66
|
-
FIND_PROJECT = <<~GRAPHQL
|
|
66
|
+
FIND_PROJECT = <<~GRAPHQL.freeze
|
|
67
67
|
query($org: String!, $number: Int!, $cursor: String) {
|
|
68
68
|
organization(login: $org) {
|
|
69
69
|
projectV2(number: $number) {
|
|
@@ -95,7 +95,7 @@ module PlanMyStuff
|
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
|
-
items(first:
|
|
98
|
+
items(first: #{PlanMyStuff::BaseProject::ITEMS_PER_PAGE}, after: $cursor) {
|
|
99
99
|
pageInfo {
|
|
100
100
|
hasNextPage
|
|
101
101
|
endCursor
|
|
@@ -112,6 +112,7 @@ module PlanMyStuff
|
|
|
112
112
|
url
|
|
113
113
|
state
|
|
114
114
|
repository { nameWithOwner }
|
|
115
|
+
assignees(first: 10) { nodes { login } }
|
|
115
116
|
}
|
|
116
117
|
... on PullRequest {
|
|
117
118
|
id
|
|
@@ -120,11 +121,13 @@ module PlanMyStuff
|
|
|
120
121
|
url
|
|
121
122
|
state
|
|
122
123
|
repository { nameWithOwner }
|
|
124
|
+
assignees(first: 10) { nodes { login } }
|
|
123
125
|
}
|
|
124
126
|
... on DraftIssue {
|
|
125
127
|
id
|
|
126
128
|
title
|
|
127
129
|
body
|
|
130
|
+
assignees(first: 10) { nodes { login } }
|
|
128
131
|
}
|
|
129
132
|
}
|
|
130
133
|
fieldValues(first: 20) {
|
|
@@ -145,6 +148,14 @@ module PlanMyStuff
|
|
|
145
148
|
}
|
|
146
149
|
}
|
|
147
150
|
}
|
|
151
|
+
... on ProjectV2ItemFieldDateValue {
|
|
152
|
+
date
|
|
153
|
+
field {
|
|
154
|
+
... on ProjectV2Field {
|
|
155
|
+
name
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
148
159
|
... on ProjectV2ItemFieldUserValue {
|
|
149
160
|
users(first: 10) {
|
|
150
161
|
nodes {
|
data/lib/plan_my_stuff/issue.rb
CHANGED
|
@@ -290,17 +290,8 @@ module PlanMyStuff
|
|
|
290
290
|
params = { state: state.to_s, page: page, per_page: per_page }
|
|
291
291
|
params[:labels] = labels.sort.join(',') if labels.present?
|
|
292
292
|
|
|
293
|
-
|
|
294
|
-
request_options = cached ? params.merge(headers: { 'If-None-Match' => cached[:etag] }) : params
|
|
295
|
-
|
|
296
|
-
github_issues = client.rest(:list_issues, resolved_repo, **request_options)
|
|
297
|
-
|
|
298
|
-
if cached && not_modified?(client)
|
|
299
|
-
return cached[:body].map { |gi| build(gi, repo: resolved_repo) }
|
|
300
|
-
end
|
|
301
|
-
|
|
293
|
+
github_issues = client.rest(:list_issues, resolved_repo, **params)
|
|
302
294
|
filtered = github_issues.reject { |gi| gi.respond_to?(:pull_request) && gi.pull_request }
|
|
303
|
-
store_list_etag_to_cache(client, :issue, resolved_repo, params, filtered)
|
|
304
295
|
filtered.map { |gi| build(gi, repo: resolved_repo) }
|
|
305
296
|
end
|
|
306
297
|
|
|
@@ -3,17 +3,25 @@
|
|
|
3
3
|
require 'plan_my_stuff'
|
|
4
4
|
|
|
5
5
|
module PlanMyStuff
|
|
6
|
-
# Test support for
|
|
6
|
+
# Test support for apps that *consume* PlanMyStuff. Provides:
|
|
7
7
|
# - `PlanMyStuff.test_mode!` to stub all API calls
|
|
8
8
|
# - Factory-style builders: `build_issue`, `build_comment`, `build_project`
|
|
9
9
|
# - RSpec matchers: `expect_pms_issue_created`, `expect_pms_comment_created`, `expect_pms_item_moved`
|
|
10
10
|
#
|
|
11
|
-
# Usage:
|
|
11
|
+
# Usage (in a consuming Rails app):
|
|
12
12
|
# require 'plan_my_stuff/test_helpers'
|
|
13
13
|
#
|
|
14
14
|
# RSpec.configure do |config|
|
|
15
15
|
# config.include PlanMyStuff::TestHelpers
|
|
16
16
|
# end
|
|
17
|
+
#
|
|
18
|
+
# Not the harness for PlanMyStuff's own unit specs. Gem-internal specs go
|
|
19
|
+
# through VCR cassettes against a real GitHub sandbox (see `spec/support/vcr.rb`
|
|
20
|
+
# and the `:pms_vcr_configured` shared context). Calling `PlanMyStuff.test_mode!`
|
|
21
|
+
# inside the gem would monkey-patch the very class methods the cassettes were
|
|
22
|
+
# recorded against, defeating the VCR coverage. The builder utilities
|
|
23
|
+
# (`build_issue`, `build_comment`, `build_project`, `stub_approvals`) are safe
|
|
24
|
+
# to use inside the gem as plain factories - they don't replace any methods.
|
|
17
25
|
module TestHelpers
|
|
18
26
|
# Recorded actions during test mode, keyed by type:
|
|
19
27
|
# :issue_created, :comment_created, :item_moved
|
|
@@ -193,6 +193,32 @@ namespace :plan_my_stuff do
|
|
|
193
193
|
end
|
|
194
194
|
end
|
|
195
195
|
|
|
196
|
+
desc 'Print all GitHub primary rate-limit buckets for the configured token. ' \
|
|
197
|
+
'Note: secondary/abuse limits and content-creation limits are NOT surfaced by GitHub ' \
|
|
198
|
+
'until you hit them, so a healthy report here does not guarantee writes will succeed.'
|
|
199
|
+
task rate_limit: :environment do
|
|
200
|
+
data = PlanMyStuff.client.rest(:get, '/rate_limit').to_h
|
|
201
|
+
resources = data[:resources] || {}
|
|
202
|
+
|
|
203
|
+
width = resources.keys.map { |k| k.to_s.length }.max || 0
|
|
204
|
+
resources.sort.each do |name, bucket|
|
|
205
|
+
next if bucket[:used].zero?
|
|
206
|
+
|
|
207
|
+
reset_at = Time.at(bucket[:reset]).utc
|
|
208
|
+
reset_in = [bucket[:reset] - Time.now.to_i, 0].max
|
|
209
|
+
puts(format(
|
|
210
|
+
'%-*s used=%-5d remaining=%-5d limit=%-5d resets_at=%s (in %ds)',
|
|
211
|
+
width,
|
|
212
|
+
name,
|
|
213
|
+
bucket[:used],
|
|
214
|
+
bucket[:remaining],
|
|
215
|
+
bucket[:limit],
|
|
216
|
+
reset_at.iso8601,
|
|
217
|
+
reset_in,
|
|
218
|
+
))
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|
|
196
222
|
desc 'Verify PlanMyStuff configuration: token, org, repos, and project access'
|
|
197
223
|
task verify: :environment do
|
|
198
224
|
require 'plan_my_stuff/verifier'
|
metadata
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: plan_my_stuff
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.10.
|
|
4
|
+
version: 0.10.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Brands Insurance
|
|
8
|
+
autorequire:
|
|
8
9
|
bindir: exe
|
|
9
10
|
cert_chain: []
|
|
10
|
-
date:
|
|
11
|
+
date: 2026-05-12 00:00:00.000000000 Z
|
|
11
12
|
dependencies:
|
|
12
13
|
- !ruby/object:Gem::Dependency
|
|
13
14
|
name: rails
|
|
@@ -43,6 +44,7 @@ dependencies:
|
|
|
43
44
|
- - "~>"
|
|
44
45
|
- !ruby/object:Gem::Version
|
|
45
46
|
version: 10.0.0
|
|
47
|
+
description:
|
|
46
48
|
email:
|
|
47
49
|
- documents@brandsinsurance.com
|
|
48
50
|
executables: []
|
|
@@ -206,7 +208,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
206
208
|
- !ruby/object:Gem::Version
|
|
207
209
|
version: '0'
|
|
208
210
|
requirements: []
|
|
209
|
-
rubygems_version:
|
|
211
|
+
rubygems_version: 3.5.11
|
|
212
|
+
signing_key:
|
|
210
213
|
specification_version: 4
|
|
211
214
|
summary: Shared PMS
|
|
212
215
|
test_files: []
|