geordi 12.6.2 → 12.7.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: 82d19a3fa4a8f87dbabccaa717770bd143c6ed3d6f899443dd5032396112dfdf
4
- data.tar.gz: 6e2067c01c9ea400b51a4e66886bbd3626d0b21fb06412372e16333b0c810b42
3
+ metadata.gz: 1abf3be3e77c751d438bf3ee3b95a9552ba675dfce857adf796bc3885ba68804
4
+ data.tar.gz: 5118fa1fd8d510c9f34bcc7931d0e136dbb64d59dc21f557ad323d32647d873d
5
5
  SHA512:
6
- metadata.gz: bef2284d579d11de45367b3a31ea0bf15f1a850f1aa73213fb48fc969498d5282fbeb429af301dd8e3ab040fe60f1dba75a205354b200e68306dda6543dd0eeb
7
- data.tar.gz: 56aea49f59fc45cd027f381001b1ffa783021fcb15ab1c2e42e6ab770b767e4d9fee1d4b0641fd2e8574a268e26f6b5036db7899654eb9ad6304d707f81017e5
6
+ metadata.gz: dc001fe1a1d6fc826e4e0de10a950091f283771f50fcaa801e8d9376ca448b86dafc76ef6bf5612c819724c3c92ea25daea82d8740ec14520aabd654543fe2cd
7
+ data.tar.gz: c74907212b99944097fb569807824475455ec683382fbbad08920b830ef7f41019097f017fd5b0c6800e32c08e3e9f6ba990792afd5305b4e8e71f0ad65d8555
@@ -21,6 +21,8 @@ jobs:
21
21
  gemfile: Gemfile
22
22
  - ruby: 3.4.2
23
23
  gemfile: Gemfile
24
+ - ruby: 4.0.0
25
+ gemfile: Gemfile
24
26
  env:
25
27
  BUNDLE_GEMFILE: "${{ matrix.gemfile }}"
26
28
  steps:
data/CHANGELOG.md CHANGED
@@ -10,6 +10,14 @@ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html
10
10
  ### Breaking changes
11
11
 
12
12
 
13
+ ## 12.7.0 2026-07-16
14
+
15
+ ### Compatible changes
16
+ * `geordi deploy` will now consider actually *deployed* commits for moving Linear issues
17
+ * Support for Ruby 4 added
18
+ * `geordi commit`: No longer add Linear URL to commit message (breaks Linear <-> Gitlab integration)
19
+
20
+
13
21
  ## 12.6.2 2026-01-30
14
22
 
15
23
  ### Compatible changes
@@ -35,7 +43,7 @@ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html
35
43
  ## 12.5.0 2025-09-09
36
44
 
37
45
  ### Compatible changes
38
- * `geordi deploy` will now offer to move deployed issues to a new state if linear_team_ids are configured.
46
+ * `geordi deploy` will now offer to move pushed issues to a new state if linear_team_ids are configured.
39
47
 
40
48
 
41
49
  ## 12.4.0 2025-08-29
data/Gemfile CHANGED
@@ -3,10 +3,14 @@ source 'http://rubygems.org'
3
3
  # Specify your gem's dependencies in geordi.gemspec
4
4
  gemspec
5
5
 
6
- gem 'aruba', '< 1' # Drops support for Ruby 2.2-
7
- gem 'rake', '< 13' # Drops support for Ruby 2.1
6
+ # Former standard gems, see https://stdgems.org/
7
+ gem 'logger' # Dependency of aruba
8
+ gem 'abbrev' # Dependency of highline
9
+ gem 'ostruct' # Dependency of pry-byebug
10
+
11
+ gem 'aruba'
12
+ gem 'rake'
8
13
  gem 'rspec'
9
- gem 'abbrev' # Dependency of Highline
10
14
  gem 'parallel_tests'
11
15
  gem 'launchy'
12
16
  gem 'pry-byebug'
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- geordi (12.6.2)
4
+ geordi (12.7.0)
5
5
  highline
6
6
  thor (~> 1)
7
7
 
@@ -55,9 +55,11 @@ GEM
55
55
  highline (2.1.0)
56
56
  launchy (2.5.0)
57
57
  addressable (~> 2.7)
58
+ logger (1.7.0)
58
59
  method_source (1.1.0)
59
60
  mini_mime (1.1.5)
60
61
  multi_test (1.1.0)
62
+ ostruct (0.6.3)
61
63
  parallel (1.19.2)
62
64
  parallel_tests (4.7.1)
63
65
  parallel
@@ -91,13 +93,15 @@ PLATFORMS
91
93
 
92
94
  DEPENDENCIES
93
95
  abbrev
94
- aruba (< 1)
96
+ aruba
95
97
  cucumber (~> 9)
96
98
  geordi!
97
99
  launchy
100
+ logger
101
+ ostruct
98
102
  parallel_tests
99
103
  pry-byebug
100
- rake (< 13)
104
+ rake
101
105
  rspec
102
106
 
103
107
  BUNDLED WITH
data/README.md CHANGED
@@ -170,7 +170,21 @@ Finds available Capistrano stages by their prefix, e.g. `geordi deploy p` will
170
170
  deploy production, `geordi deploy mak` will deploy a `makandra` stage if there
171
171
  is a file config/deploy/makandra.rb.
172
172
 
173
- If Linear team ids are configured (see `geordi commit`), will offer to move deployed issues to a new state. Disable this with "skip".
173
+ If Linear team ids are configured (see `geordi commit`), will offer to move deployed issues to a new state.
174
+ Disable this with "skip".
175
+ By default, Geordi will only consider issues it pushes itself during deploy.
176
+ To consider all new commits deployed to the server, add this Capistrano task to your project:
177
+
178
+ namespace :app do
179
+ desc 'Show current revision'
180
+ task :revision do
181
+ on roles :app do
182
+ within current_path do
183
+ info "REVISION: #{capture(:cat, 'REVISION')}"
184
+ end
185
+ end
186
+ end
187
+ end
174
188
 
175
189
  If your project is running Capistrano 2, Geordi will use `cap deploy:migrations` by default. Skip migrations by passing the -M option: `geordi deploy -M staging`.
176
190
 
@@ -51,6 +51,19 @@ module Geordi
51
51
  'bash --login'
52
52
  end
53
53
 
54
+ def self.current_app_revisions(target_stage)
55
+ return ['a76fdd46e5319a202f7daa3f0fbdadb0c6f44408'] if Util.testing?
56
+ output = `cap #{target_stage} app:revision`
57
+
58
+ # git revisions are in SHA-1 format => 40-byte hexadecimal string
59
+ output.scan(/[a-f0-9]{40}/).uniq
60
+ end
61
+
62
+ def self.task_defined?(task_name)
63
+ return true if Util.testing?
64
+ `cap -T`.split.include?(task_name)
65
+ end
66
+
54
67
  private
55
68
 
56
69
  attr_accessor :deploy_info, :stage
@@ -22,10 +22,9 @@ def commit(*git_args)
22
22
 
23
23
  issue = linear_client.issue_from_branch || linear_client.choose_issue
24
24
  title = "[#{issue['identifier']}] #{issue['title']}"
25
- description = "Issue: #{issue['url']}"
26
25
  extra = highline.ask("\nAdd an optional message").strip
27
26
  title << ' - ' << extra if extra != ''
28
- Util.run!(['git', 'commit', '--allow-empty', '-m', title, '-m', description, *git_args])
27
+ Util.run!(['git', 'commit', '--allow-empty', '-m', title, *git_args])
29
28
 
30
29
  Hint.did_you_know [
31
30
  :branch,
@@ -28,7 +28,21 @@ Finds available Capistrano stages by their prefix, e.g. `geordi deploy p` will
28
28
  deploy production, `geordi deploy mak` will deploy a `makandra` stage if there
29
29
  is a file config/deploy/makandra.rb.
30
30
 
31
- If Linear team ids are configured (see `geordi commit`), will offer to move deployed issues to a new state. Disable this with "skip".
31
+ If Linear team ids are configured (see `geordi commit`), will offer to move deployed issues to a new state.
32
+ Disable this with "skip".
33
+ By default, Geordi will only consider issues it pushes itself during deploy.
34
+ To consider all new commits deployed to the server, add this Capistrano task to your project:
35
+
36
+ namespace :app do
37
+ desc 'Show current revision'
38
+ task :revision do
39
+ on roles :app do
40
+ within current_path do
41
+ info "REVISION: \#{capture(:cat, 'REVISION')}"
42
+ end
43
+ end
44
+ end
45
+ end
32
46
 
33
47
  If your project is running Capistrano 2, Geordi will use `cap deploy:migrations` by default. Skip migrations by passing the -M option: `geordi deploy -M staging`.
34
48
  LONGDESC
@@ -84,12 +98,7 @@ def deploy(target_stage = nil)
84
98
 
85
99
  merge_needed = (source_branch != target_branch)
86
100
  push_needed = merge_needed || `git cherry -v | wc -l`.strip.to_i > 0
87
- linear_issue_ids = []
88
- if push_needed
89
- commit_messages = Git.commits_between(source_branch, target_branch)
90
- linear_issue_ids = LinearClient.extract_issue_ids(commit_messages)
91
- end
92
- move_issues = !linear_issue_ids.empty? && target_state && !target_state.empty?
101
+ move_issues = target_state && !target_state.empty?
93
102
 
94
103
  # Checks #####################################################################
95
104
  Interaction.note "Checking whether your #{source_branch} branch is ready"
@@ -117,9 +126,11 @@ def deploy(target_stage = nil)
117
126
  Interaction.note "From current branch #{source_branch}" if options.current_branch
118
127
 
119
128
  if move_issues
120
- relevant_commits = linear_client.filter_by_issue_ids(commit_messages, linear_issue_ids)
121
- Interaction.note("Move these Linear issues to state \"#{target_state}\":")
122
- puts relevant_commits.join("\n")
129
+ linear_issue_ids, relevant_commits = Util.determine_issues_to_move(source_branch, target_branch, target_stage, linear_client: linear_client)
130
+ if relevant_commits.any?
131
+ Interaction.note("Move these Linear issues to state \"#{target_state}\":")
132
+ puts relevant_commits.uniq.join("\n")
133
+ end
123
134
  end
124
135
 
125
136
  # Execute ####################################################################
@@ -142,7 +153,7 @@ def deploy(target_stage = nil)
142
153
 
143
154
  Util.run!(capistrano_call, show_cmd: true)
144
155
 
145
- if move_issues
156
+ if move_issues && !linear_issue_ids.empty?
146
157
  linear_client.move_issues_to_state(linear_issue_ids, target_state)
147
158
  settings.persist_linear_state_after_deploy(target_stage, target_state)
148
159
  end
data/lib/geordi/git.rb CHANGED
@@ -41,10 +41,10 @@ module Geordi
41
41
  default_branch || 'master'
42
42
  end
43
43
 
44
- def commits_between(source_branch, target_branch)
44
+ def commits_between(source, target)
45
45
  return [ENV['GEORDI_TESTING_GIT_COMMIT']] if Util.testing?
46
46
 
47
- commits = `git --no-pager log --pretty=format:%s origin/#{target_branch}..#{source_branch}`
47
+ commits = `git --no-pager log --pretty=format:%s #{source}..#{target}`
48
48
 
49
49
  commits&.split("\n")
50
50
  end
@@ -25,6 +25,12 @@ module Geordi
25
25
  found_ids.map { |id| id.delete('[]') } # [W-365] => W-365
26
26
  end
27
27
 
28
+ def self.filter_by_issue_ids(list_of_strings, issue_ids)
29
+ list_of_strings.select do |message|
30
+ issue_ids.any? { |id| message.start_with?("[#{id}]") }
31
+ end
32
+ end
33
+
28
34
  def initialize
29
35
  self.highline = HighLine.new
30
36
  self.settings = Settings.new
@@ -67,16 +73,28 @@ module Geordi
67
73
  nil
68
74
  end
69
75
 
76
+ def filter_existing_issue_ids(identifiers)
77
+ return identifiers if Util.testing?
78
+ issues = fetch_linear_issues
79
+ identifiers.select { |id| issues.any? { |i| i['identifier'] == id } }
80
+ end
81
+
70
82
  def move_issues_to_state(issue_identifiers, state)
71
83
  return if Util.testing?
72
84
 
73
85
  issues = fetch_linear_issues # This only retrieves issues for the configured linear team ids
74
- state_ids_by_team_id = state_ids_by_team_id(state)
75
86
 
76
- issue_identifiers.each do |identifier|
77
- issue = issues.find { |i| i['identifier'] == identifier }
87
+ # Only look up states for teams that actually have issues being moved
88
+ # This avoids warning about missing states in teams with no relevant issues.
89
+ relevant_issues = issue_identifiers.filter_map { |id| issues.find { |i| i['identifier'] == id } }
90
+ return if relevant_issues.empty?
78
91
 
79
- next unless issue && (state_id = state_ids_by_team_id[issue.dig('team', 'id')])
92
+ relevant_team_ids = relevant_issues.map { |i| i.dig('team', 'id') }.uniq
93
+
94
+ state_ids_by_team_id = state_ids_by_team_id(state, team_ids: relevant_team_ids)
95
+
96
+ relevant_issues.each do |issue|
97
+ next unless (state_id = state_ids_by_team_id[issue.dig('team', 'id')])
80
98
 
81
99
  update_issue_state(issue['id'], state_id)
82
100
  end
@@ -101,12 +119,6 @@ module Geordi
101
119
  end
102
120
  end
103
121
 
104
- def filter_by_issue_ids(list_of_strings, issue_ids)
105
- list_of_strings.select do |message|
106
- issue_ids.any? { |id| message.start_with?("[#{id}]") }
107
- end
108
- end
109
-
110
122
  private
111
123
 
112
124
  attr_accessor :highline, :settings
@@ -167,10 +179,9 @@ module Geordi
167
179
  end
168
180
  end
169
181
 
170
- def state_ids_by_team_id(state_name)
182
+ def state_ids_by_team_id(state_name, team_ids: settings.linear_team_ids)
171
183
  result = {}
172
184
 
173
- team_ids = settings.linear_team_ids
174
185
  filter = {
175
186
  "team": {
176
187
  "id": {
data/lib/geordi/util.rb CHANGED
@@ -220,6 +220,32 @@ module Geordi
220
220
  %r{(^|\/)spec|_spec\.rb($|:)}.match?(path)
221
221
  end
222
222
 
223
+ def determine_issues_to_move(source_branch, target_branch, target_stage, linear_client: LinearClient.new)
224
+ commit_messages = []
225
+ if CapistranoConfig.task_defined?('app:revision')
226
+ revision = CapistranoConfig.current_app_revisions(target_stage)
227
+
228
+ if revision.empty?
229
+ Interaction.fail 'Could not read a server revision from app:revision output.'
230
+ elsif revision.size > 1
231
+ Interaction.warn 'Currently deployed revision differs on servers.'
232
+ Interaction.confirm_or_cancel('Continue deployment without moving Linear issues?')
233
+ else
234
+ # there is one consistent revision deployed across all target servers => Linear issues can be moved
235
+ commit_messages = Git.commits_between(revision.first, source_branch)
236
+ end
237
+ else
238
+ Interaction.warn 'Missing Capistrano task "app:revision". See `geordi help deploy`.'
239
+ puts 'Without it, Geordi can only consider pushed commits for moving Linear issues.'
240
+ commit_messages = Git.commits_between("origin/#{target_branch}", source_branch)
241
+ end
242
+
243
+ linear_issue_ids = LinearClient.extract_issue_ids(commit_messages)
244
+ linear_issue_ids = linear_client.filter_existing_issue_ids(linear_issue_ids)
245
+ relevant_commits = LinearClient.filter_by_issue_ids(commit_messages, linear_issue_ids)
246
+ [linear_issue_ids, relevant_commits]
247
+ end
248
+
223
249
  end
224
250
  end
225
251
  end
@@ -1,3 +1,3 @@
1
1
  module Geordi
2
- VERSION = '12.6.2'.freeze
2
+ VERSION = '12.7.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: geordi
3
3
  version: !ruby/object:Gem::Version
4
- version: 12.6.2
4
+ version: 12.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Henning Koch
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2026-01-30 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: thor
@@ -124,7 +123,6 @@ metadata:
124
123
  bug_tracker_uri: https://github.com/makandra/geordi/issues
125
124
  changelog_uri: https://github.com/makandra/geordi/blob/master/CHANGELOG.md
126
125
  rubygems_mfa_required: 'true'
127
- post_install_message:
128
126
  rdoc_options: []
129
127
  require_paths:
130
128
  - lib
@@ -139,8 +137,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
139
137
  - !ruby/object:Gem::Version
140
138
  version: '0'
141
139
  requirements: []
142
- rubygems_version: 3.1.6
143
- signing_key:
140
+ rubygems_version: 4.0.6
144
141
  specification_version: 4
145
142
  summary: Collection of command line tools we use in our daily work with Ruby, Rails
146
143
  and Linux at makandra.