plan_my_stuff 0.27.0 → 0.29.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f4162f792a9b4fbc7cced8a9a91721c21d15010189cf38021b87d20d53dbcb56
4
- data.tar.gz: 72c6220c9be50c083360357ba28f1cb7225c784ed9c8813430e24e9e27736f04
3
+ metadata.gz: 98cbaeb499aa1b3b22018b7145d2d8e0bd86051a237230d1b5cac3e884109e10
4
+ data.tar.gz: a66aa1aec786adca0853eed340e1f35e2639c7aca6aafae88a421b4cc2136b5d
5
5
  SHA512:
6
- metadata.gz: af715bae691caff87d81935e140a3bc2d4af7ef49780686f85b8f145ce9e7a6ff32a6ea689c697a4bc6d193ca0612ff7147a850ea5088876282c4a6bf284ab26
7
- data.tar.gz: 94d67d34bc302ceb3ec4fa815d5420f60323a9be1c6b4003af4948675861328d5c0ae74c7cd71031a9102c30af7e63a7586d72b64136263c865b7f3cdd46d8ce
6
+ metadata.gz: 8f4e1995d828ae83edfc94a9d2d0805b5787165e28f062bd0100f586de2c19e49fb6f9167ac0ee0ea88be5001012ffab5371315d2dcaee4b081a13e6be53a993
7
+ data.tar.gz: 95474b37f6f2bbd4c6074f3049086b1d643617c7c0a6dbf8562e9e0c29f9ad7bcbcabcedfda29f8e55cfcf12d5f0024a41cd69d0c9527dff91948a83e8dcde46
data/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.29.0
4
+
5
+ ### Changed
6
+
7
+ - `Pipeline.complete_deployment!` now sets the linked issue's `Issue Status` field to `Fixed` on the auto-complete
8
+ success path (alongside moving the item to `Completed`). Gated on `config.issue_fields_enabled`, so completion still
9
+ succeeds when issue fields are disabled. The auto-complete-off early return is unchanged (closes #96).
10
+
11
+ ## 0.28.0
12
+
13
+ ### Added
14
+
15
+ - `Issue.list_page_info(...)` returns a `PlanMyStuff::Issue::PageInfo` value object exposing `.issues`, `.page`,
16
+ `.per_page`, `.has_next?`, and `.has_prev?`. `Issue.list` now delegates to it; return type unchanged
17
+ (`Array<Issue>`). Closes #63.
18
+
3
19
  ## 0.27.0
4
20
 
5
21
  ### Added
@@ -23,10 +23,11 @@ module PlanMyStuff
23
23
  return
24
24
  end
25
25
 
26
- issue = PlanMyStuff::Issue.find(params[:issue_id])
27
- issue.request_approvals!(user_ids: user_ids, user: pms_current_user)
26
+ find_issue
28
27
 
29
- yield(issue) if block_given?
28
+ @issue.request_approvals!(user_ids: user_ids, user: pms_current_user)
29
+
30
+ yield(@issue) if block_given?
30
31
  return if performed?
31
32
 
32
33
  flash[:success] = 'Approvers were successfully added.'
@@ -47,7 +48,7 @@ module PlanMyStuff
47
48
  return
48
49
  end
49
50
 
50
- issue = PlanMyStuff::Issue.find(params[:issue_id])
51
+ find_issue
51
52
  caller_id = pms_current_user.present? ? PlanMyStuff::UserResolver.user_id(pms_current_user) : nil
52
53
 
53
54
  case status
@@ -56,25 +57,25 @@ module PlanMyStuff
56
57
  redirect_to_unauthorized(show_path)
57
58
  return
58
59
  end
59
- issue.approve!(user: pms_current_user)
60
+ @issue.approve!(user: pms_current_user)
60
61
  flash[:success] = 'Approval recorded.'
61
62
  when 'rejected'
62
63
  unless caller_id == target_id
63
64
  redirect_to_unauthorized(show_path)
64
65
  return
65
66
  end
66
- issue.reject!(user: pms_current_user)
67
+ @issue.reject!(user: pms_current_user)
67
68
  flash[:success] = 'Rejection recorded.'
68
69
  else
69
70
  if caller_id != target_id && !support_user?
70
71
  redirect_to_unauthorized(show_path)
71
72
  return
72
73
  end
73
- issue.revoke_approval!(user: pms_current_user, target_user_id: target_id)
74
+ @issue.revoke_approval!(user: pms_current_user, target_user_id: target_id)
74
75
  flash[:success] = 'Response revoked.'
75
76
  end
76
77
 
77
- yield(issue) if block_given?
78
+ yield(@issue) if block_given?
78
79
  return if performed?
79
80
 
80
81
  redirect_to(show_path)
@@ -91,10 +92,10 @@ module PlanMyStuff
91
92
  return
92
93
  end
93
94
 
94
- issue = PlanMyStuff::Issue.find(params[:issue_id])
95
- issue.remove_approvers!(user_ids: [params[:id].to_i], user: pms_current_user)
95
+ find_issue
96
+ @issue.remove_approvers!(user_ids: [params[:id].to_i], user: pms_current_user)
96
97
 
97
- yield(issue) if block_given?
98
+ yield(@issue) if block_given?
98
99
  return if performed?
99
100
 
100
101
  flash[:success] = 'Approver was successfully removed.'
@@ -112,9 +113,14 @@ module PlanMyStuff
112
113
  params.fetch(:approval, {}).permit(:status, :user_ids)
113
114
  end
114
115
 
116
+ # :nodoc:
117
+ def find_issue
118
+ @issue = PlanMyStuff::Issue.find(params[:issue_id])
119
+ end
120
+
115
121
  # @return [String]
116
122
  def show_path
117
- plan_my_stuff.issue_path(params[:issue_id])
123
+ plan_my_stuff.issue_path(@issue || params[:issue_id])
118
124
  end
119
125
  end
120
126
  end
@@ -16,7 +16,7 @@ module PlanMyStuff
16
16
  if loader.respond_to?(:eager_load_dir)
17
17
  loader.eager_load_dir(controllers_dir)
18
18
  else
19
- Dir.glob(File.join(controllers_dir, '**/*.rb')).sort.each { |path| require path }
19
+ Dir.glob(File.join(controllers_dir, '**/*.rb')).each { |path| require path }
20
20
  end
21
21
  end
22
22
  end
@@ -9,6 +9,21 @@ module PlanMyStuff
9
9
  # - `Issue.create!` / `Issue.find` / `Issue.list` return persisted instances
10
10
  # - `issue.save!` / `issue.update!` / `issue.reload` for persistence
11
11
  class Issue < PlanMyStuff::ApplicationRecord
12
+ # Value object returned by +Issue.list_page_info+: the fetched issues plus pagination metadata read from the
13
+ # +Link+ header of the +list_issues+ response. +:total_pages+ is intentionally absent -- GitHub's issues endpoint
14
+ # is cursor-paginated and never advertises +rel="last"+.
15
+ #
16
+ # @!attribute [r] issues
17
+ # @return [Array<PlanMyStuff::Issue>]
18
+ # @!attribute [r] page
19
+ # @return [Integer] echo of the requested page
20
+ # @!attribute [r] per_page
21
+ # @return [Integer] echo of the requested per_page
22
+ PageInfo = Data.define(:issues, :page, :per_page, :has_next, :has_prev) do
23
+ alias_method :has_next?, :has_next
24
+ alias_method :has_prev?, :has_prev
25
+ end
26
+
12
27
  include PlanMyStuff::IssueExtractions::Approvals
13
28
  include PlanMyStuff::IssueExtractions::Links
14
29
  include PlanMyStuff::IssueExtractions::Viewers
@@ -332,7 +347,38 @@ module PlanMyStuff
332
347
  #
333
348
  # @return [Array<PlanMyStuff::Issue>]
334
349
  #
335
- def list(
350
+ def list(**)
351
+ list_page_info(**).issues
352
+ end
353
+
354
+ # Lists GitHub issues like +.list+, but returns a +PageInfo+ value object carrying the issues plus pagination
355
+ # metadata read from the response's +Link+ header in the same request. Use this over +.list+ when a caller needs
356
+ # to know whether more pages exist (e.g. to render "Next"/"Prev" controls) without an optimistic +page + 1+
357
+ # probe.
358
+ #
359
+ # Shares the entire parameter surface, filtering, and PR-rejection behavior of +.list+; see it for semantics.
360
+ #
361
+ # Note the PR-filter wart: +per_page+ caps GitHub's raw item count (issues + PRs), but PRs are stripped
362
+ # client-side afterward, so +page_info.issues.length+ may be smaller than +per_page+. +has_next?+ comes straight
363
+ # from the +Link+ header, so it reflects raw items too -- a page can report +has_next? == true+ while showing
364
+ # fewer than +per_page+ issues.
365
+ #
366
+ # @raise [ArgumentError] when +priority_list: false+ is passed, or when +issue_type:+ is an Array
367
+ # @raise [PlanMyStuff::IssueFieldsNotEnabledError] when +issue_fields:+ is passed and
368
+ # +config.issue_fields_enabled+ is +false+
369
+ #
370
+ # @param repo [Symbol, String, nil] defaults to config.default_repo
371
+ # @param state [Symbol] :open, :closed, or :all
372
+ # @param labels [Array<String>]
373
+ # @param issue_type [String, Symbol, nil] a single GitHub issue type name
374
+ # @param issue_fields [Hash{String,Symbol => Object,Range,nil}, nil] GitHub Issue Field equality / range filters
375
+ # @param priority_list [Boolean, nil] when +true+, restricts to +Priority List+ +Yes+ issues
376
+ # @param page [Integer]
377
+ # @param per_page [Integer]
378
+ #
379
+ # @return [PlanMyStuff::Issue::PageInfo]
380
+ #
381
+ def list_page_info(
336
382
  repo: nil,
337
383
  state: :open,
338
384
  labels: [],
@@ -366,8 +412,16 @@ module PlanMyStuff
366
412
  params[:issue_field_values] = field_pairs.join(',') if field_pairs.present?
367
413
 
368
414
  github_issues = client.rest(:list_issues, resolved_repo, **params)
415
+ rels = client.last_response&.rels || {}
369
416
  filtered = github_issues.reject { |gi| gi.respond_to?(:pull_request) && gi.pull_request }
370
- filtered.map { |gi| build(gi, repo: resolved_repo) }
417
+
418
+ PageInfo.new(
419
+ issues: filtered.map { |gi| build(gi, repo: resolved_repo) },
420
+ page: page,
421
+ per_page: per_page,
422
+ has_next: rels[:next].present?,
423
+ has_prev: rels[:prev].present?,
424
+ )
371
425
  end
372
426
 
373
427
  # Convenience shortcut for +list(priority_list: true, ...)+. See +.list+ for parameter semantics.
@@ -273,8 +273,10 @@ module PlanMyStuff
273
273
  items
274
274
  end
275
275
 
276
- # Moves a project item to "Completed" if the linked issue has +auto_complete+ enabled. Returns +nil+ when
277
- # auto-complete is off (item stays at "Release in Progress").
276
+ # Moves a project item to "Completed" if the linked issue has +auto_complete+ enabled, and sets the linked issue's
277
+ # "Issue Status" field to "Fixed". Returns +nil+ when auto-complete is off (item stays at "Release in Progress" and
278
+ # no field is touched). The "Issue Status" update is skipped when +config.issue_fields_enabled+ is +false+ so
279
+ # completion still succeeds.
278
280
  #
279
281
  # @param project_item [PlanMyStuff::ProjectItem]
280
282
  # @param deployment_id [String, nil]
@@ -288,6 +290,8 @@ module PlanMyStuff
288
290
  status = resolve_status_name(PlanMyStuff::Pipeline::Status::COMPLETED)
289
291
  result = project_item.move_to!(status)
290
292
 
293
+ issue.set_issue_fields!('Issue Status' => 'Fixed') if PlanMyStuff.configuration.issue_fields_enabled
294
+
291
295
  instrument(PlanMyStuff::Pipeline::Status::COMPLETED, project_item, deployment_id: deployment_id)
292
296
  result
293
297
  end
@@ -3,7 +3,7 @@
3
3
  module PlanMyStuff
4
4
  module VERSION
5
5
  MAJOR = 0
6
- MINOR = 27
6
+ MINOR = 29
7
7
  TINY = 0
8
8
 
9
9
  # Set PRE to nil unless it's a pre-release (beta, rc, etc.)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: plan_my_stuff
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.27.0
4
+ version: 0.29.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brands Insurance
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-05-26 00:00:00.000000000 Z
11
+ date: 2026-05-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails