capistrano-redmine-deployment 1.0.0 → 1.1.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: c60ab7f09f79a4d3b3e90a9bf6edb0da4dc66129392dd09971a2883de1413515
4
- data.tar.gz: a49b08f33c15eb4f9491c65501a85b26a33eb20c89fde872f463a29d70b56a0f
3
+ metadata.gz: d6bcb935ad7aaa01c101fa9380a958b0dc57a3d6b1b39797fafb3eff6ae03a05
4
+ data.tar.gz: adaff749719d3b3178b3f6f23e71d9605c8785ff37c773d2422eb2a76f568956
5
5
  SHA512:
6
- metadata.gz: 2cc8663317d582086c96f39be819bbd203fd118e58e5428ec9dcdfd1dcebaec273c9c4eb4ee21cdb70f370e2acf5715052a43ae6a15eacb72900f768b040a196
7
- data.tar.gz: 195c99e17cb7ebfee2d15f6d4db30f2d33003d36b4accafc7d1ddb9c504e17fb7f4abe711ec8fb08dee856a012a17387eba049fdf9699eb5130ec1f86f100a44
6
+ metadata.gz: c552022bdeac49a92283af11c3e99869efb1509be175ee68179759300c6c3fde2e502b1e096736157f20e4382e77bdd1a934ceb93c6a82a2d736bd544a3ba9c1
7
+ data.tar.gz: b3d6ae5239ac13d3042f5228ba2a6175a3a0d1b115e186196bf26418d50db3518cb3ea4da397d7c5893f4203db3047ffa3b727ead08e30cddf69f5c25227ac2d
data/.gitignore CHANGED
File without changes
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --require spec_helper
2
+ --format documentation
data/Gemfile CHANGED
@@ -6,3 +6,4 @@ source "https://rubygems.org"
6
6
  gemspec
7
7
 
8
8
  gem "rake"
9
+ gem "rspec"
File without changes
data/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # Capistrano::Redmine::Deployment
2
2
 
3
- [![GitHub](https://img.shields.io/badge/github-ruby--smart/capistrano-redmine-deployment-blue.svg)](http://github.com/ruby-smart/capistrano-redmine-deployment)
3
+ [![GitHub](https://img.shields.io/badge/github-ruby--smart/capistrano--redmine--deployment-blue.svg)](http://github.com/ruby-smart/capistrano-redmine-deployment)
4
4
  [![Documentation](https://img.shields.io/badge/docs-rdoc.info-blue.svg)](http://rubydoc.info/gems/capistrano-redmine-deployment)
5
5
 
6
6
  [![Gem Version](https://badge.fury.io/rb/capistrano-redmine-deployment.svg?kill_cache=1)](https://badge.fury.io/rb/capistrano-redmine-deployment)
7
- [![License](https://img.shields.io/github/license/ruby-smart/capistrano-redmine-deployment)](docs/LICENSE.txt)
7
+ [![License](https://img.shields.io/badge/license-MIT-green)](LICENSE.txt)
8
8
 
9
9
  Redmine Deployment Tracking (for redmine_deployment plugin)
10
10
 
@@ -29,22 +29,64 @@ Or install it yourself as:
29
29
 
30
30
  $ gem install capistrano-redmine-deployment
31
31
 
32
- Configure redmine credentials within your `config/deploy.rb`.
32
+ ## Setup
33
+
34
+ Require deployment tasks within your `Capfile`
35
+
36
+ require 'capistrano/redmine/deployment/receipts'
37
+
38
+ -----
39
+
40
+ ## Configuration
41
+
42
+ ### Shared configuration
43
+ Configure shared redmine credentials within your `config/deploy.rb`.
33
44
  ```ruby
34
45
  # redmine deployment credentials (without api_key)
35
46
  set(:redmine_host, "https://your-redmine-host")
36
47
  set(:redmine_project, "target-redmine-project-identifier")
37
48
  set(:redmine_repository, "target-redmine-repository-identifier")
49
+
50
+ # in case of `SSL` issues that are caused by *CRL* (i.e. by LetsEncrypt certificates)
51
+ set(:redmine_host_verification, false)
52
+
53
+ # alternatively, for instances with a custom CA, point to a CA bundle instead of
54
+ # disabling verification entirely (preferred over :redmine_host_verification)
55
+ set(:redmine_ca_file, "/path/to/ca-bundle.pem")
38
56
  ```
39
57
 
40
- Setup redmine API-KEY through rake-task:
58
+ ### User-specific credentials
41
59
 
42
- $ rake capistrano:redmine:deploy:setup
60
+ The `api_key` is resolved from the following sources, **later ones win**:
43
61
 
62
+ 1. capistrano variables: `:redmine_api_key`, or `:redmine_api_key_command` (its stdout is used as the key) as fallback
63
+ 2. `.redmine` file in the current directory (`$PWD`) or `$HOME`
64
+ 3. the `REDMINE_API_KEY` ENV variable
44
65
 
45
- Require deployment tasks within your `Capfile`
66
+ #### Option A: macOS Keychain (recommended)
67
+
68
+ Store the key once per developer in the keychain (use a dedicated entry):
69
+
70
+ $ security add-generic-password -s ri-redmine-deploy -a "$USER" -w 'YOUR_KEY'
71
+
72
+ Then point capistrano at a command that reads it, in your `config/deploy.rb`:
73
+
74
+ ```ruby
75
+ set :redmine_api_key_command, 'security find-generic-password -s ri-redmine-deploy -w'
76
+ ```
77
+
78
+ No secret ends up in `deploy.rb` or your SCM — only the command. Once every developer
79
+ has switched over, the `.redmine` file can be removed entirely (it stays supported as a
80
+ fallback).
81
+
82
+ > Use a **dedicated** keychain entry (e.g. `ri-redmine-deploy`).
83
+
84
+ #### Option B: `.redmine` file via rake-task
85
+
86
+ Setup redmine `API-KEY` through rake-task:
87
+
88
+ $ rake capistrano:redmine:deployment:setup
46
89
 
47
- require 'capistrano/redmine/deployment/receipts'
48
90
 
49
91
  ## Redmine requirements
50
92
 
@@ -61,14 +103,14 @@ Install the plugin `redmine_deployment`.
61
103
 
62
104
  ## Contributing
63
105
 
64
- Bug reports and pull requests are welcome on [GitHub](https://github.com/ruby-smart/support).
106
+ Bug reports and pull requests are welcome on [GitHub](https://github.com/ruby-smart/capistrano-redmine-deployment).
65
107
  This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](docs/CODE_OF_CONDUCT.md).
66
108
 
67
109
  ## License
68
110
 
69
111
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
70
112
 
71
- A copy of the [LICENSE](docs/LICENSE.md) can be found @ the docs.
113
+ A copy of the [LICENSE](LICENSE.txt) can be found @ the docs.
72
114
 
73
115
  ## Code of Conduct
74
116
 
data/Rakefile CHANGED
File without changes
File without changes
data/docs/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Capistrano::Redmine::Deployment - CHANGELOG
2
2
 
3
+ ## [1.1.0] - 2026-07-10
4
+ * **[add]** ENV layer for config (`REDMINE_API_KEY`, `REDMINE_HOST`, `REDMINE_PROJECT`, `REDMINE_REPOSITORY`, `REDMINE_CA_FILE`)
5
+ * **[add]** `:redmine_api_key` capistrano variable, with `:redmine_api_key_command` (command stdout, e.g. macOS keychain) as fallback
6
+ * **[add]** `:redmine_ca_file` config (and `REDMINE_CA_FILE` ENV) as a safe alternative to disabling host verification
7
+ * **[add]** rspec test suite for `Config.resolve` layer precedence
8
+ * **[ref]** config resolution order: capistrano is the base, then `.redmine` files, then ENV win over it
9
+ * **[fix]** enable SSL by URI scheme (`https`) instead of only port 443, so HTTPS on non-standard ports works
10
+
11
+ ## [1.0.1] - 2025-10-24
12
+ * **[add]** config for `host_verification` to skip issues with OpenSSL / CRL issues
13
+ * **[add]** warning message during deployment while host verification is disabled
14
+ * **[ref]** setup task for better configuration
15
+ * **[ref]** logging messages for successfully / error deployment
16
+ * **[fix]** host verification SSL/CRL issues
17
+
3
18
  ## [1.0.0] - 2024-10-01
4
19
  * **[add]** config, client & receipts
5
20
  * **[add]** rake task for setup
File without changes
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'net/http'
4
4
  require 'json'
5
+ require 'openssl'
5
6
 
6
7
  module Capistrano
7
8
  module Redmine
@@ -25,7 +26,7 @@ module Capistrano
25
26
  end
26
27
 
27
28
  def initialize(config, logging: true)
28
- @config = config
29
+ @config = config
29
30
  @logging = logging
30
31
  end
31
32
 
@@ -56,15 +57,21 @@ module Capistrano
56
57
  private
57
58
 
58
59
  def send_deployment(deployment)
59
- uri = URI("#{config.host}/projects/#{config.project}/deploy/#{config.repository}.json")
60
+ uri = URI("#{config.host}/projects/#{config.project}/deploy/#{config.repository}.json")
60
61
 
61
62
  http = Net::HTTP.new(uri.host, uri.port)
62
- http.use_ssl = true if uri.port == 443
63
+ http.use_ssl = true if uri.scheme == 'https'
63
64
 
64
- request = Net::HTTP::Post.new(uri.request_uri)
65
- request["Content-Type"] = "application/json"
65
+ if config.ca_file
66
+ http.ca_file = config.ca_file
67
+ elsif config.host_verification == false
68
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
69
+ end
70
+
71
+ request = Net::HTTP::Post.new(uri.request_uri)
72
+ request["Content-Type"] = "application/json"
66
73
  request['X-Redmine-API-Key'] = config.api_key
67
- request.body = { deployment: deployment }.to_json
74
+ request.body = { deployment: deployment }.to_json
68
75
 
69
76
  response = http.request(request)
70
77
 
@@ -77,16 +84,20 @@ module Capistrano
77
84
 
78
85
  def log_deploy(deployment)
79
86
  puts "Sending deployment information to #{config.host} (project: '#{config.project}' | repo: '#{config.repository}')"
80
-
87
+ puts "\e[33m Using custom CA file: #{config.ca_file}\e[0m" if config.ca_file
88
+ puts "\e[33m WARNING: Host verification disabled!\e[0m" if config.ca_file.nil? && config.host_verification == false
89
+ puts ""
81
90
  puts " Commits......: #{deployment[:from_revision]} ... #{deployment[:to_revision]}"
82
91
  puts " Environment..: #{deployment[:environment] || '-'}"
83
92
  puts " Branch.......: #{deployment[:branch] || '-'}"
84
93
  puts " Server(s)....: #{deployment[:servers]}"
85
94
  puts " Result.......: #{deployment[:result]}"
95
+ puts ""
86
96
  end
87
97
 
88
98
  def log_deploy_done(response)
89
99
  puts "\e[32mSuccessfully created deployment ##{response['deployment']['id']}\e[0m"
100
+ puts ""
90
101
  end
91
102
 
92
103
  def log_deploy_errors(response)
@@ -95,7 +106,7 @@ module Capistrano
95
106
  else
96
107
  puts "\e[31mFailed to created deployment: #{response.inspect}\e[0m"
97
108
  end
98
-
109
+ puts ""
99
110
  end
100
111
  end
101
112
  end
@@ -14,7 +14,7 @@ module Capistrano
14
14
  # build new empty config
15
15
  config = new
16
16
 
17
- # try to resolve from capistrano
17
+ # capistrano is the base - files and ENV win over it
18
18
  config.assign!(config_from_capistrano(capistrano)) if capistrano
19
19
 
20
20
  # try to resolve from current PWD
@@ -22,32 +22,68 @@ module Capistrano
22
22
  config.assign!(config_from_file(File.join(ENV['HOME'], '.redmine')))
23
23
  config.assign!(config_from_file(file)) if file
24
24
 
25
+ # ENV wins over files and capistrano
26
+ config.assign!(config_from_env)
27
+
25
28
  config
26
29
  end
27
30
 
28
31
  def config_from_capistrano(capistrano)
29
32
  config = {
30
- host: capistrano.fetch(:redmine_host),
31
- project: capistrano.fetch(:redmine_project) || capistrano.fetch(:redmine_project_id),
32
- repository: capistrano.fetch(:redmine_repository)
33
+ api_key: capistrano.fetch(:redmine_api_key) || api_key_from_command(capistrano),
34
+ host: capistrano.fetch(:redmine_host),
35
+ project: capistrano.fetch(:redmine_project) || capistrano.fetch(:redmine_project_id),
36
+ repository: capistrano.fetch(:redmine_repository),
37
+ host_verification: capistrano.fetch(:redmine_host_verification),
38
+ ca_file: capistrano.fetch(:redmine_ca_file)
33
39
  }
34
40
 
35
41
  new(config)
36
42
  end
37
43
 
44
+ # Resolves config from ENV variables. Values are filtered by `assign!`,
45
+ # so unset (nil/empty) variables never overwrite an existing value.
46
+ def config_from_env
47
+ new({
48
+ api_key: ENV['REDMINE_API_KEY'],
49
+ host: ENV['REDMINE_HOST'],
50
+ project: ENV['REDMINE_PROJECT'],
51
+ repository: ENV['REDMINE_REPOSITORY'],
52
+ ca_file: ENV['REDMINE_CA_FILE']
53
+ })
54
+ end
55
+
38
56
  def config_from_file(file)
39
57
  new(file: file)
40
58
  end
59
+
60
+ private
61
+
62
+ # Resolves the api_key by running the `:redmine_api_key_command` capistrano
63
+ # variable (if set) and taking its stdout. This keeps the secret out of
64
+ # `deploy.rb` - only the command (e.g. a keychain lookup) lives there.
65
+ #
66
+ # On any failure (non-zero exit or empty stdout) nil is returned so the
67
+ # file/ENV fallback still applies.
68
+ def api_key_from_command(capistrano)
69
+ cmd = capistrano.fetch(:redmine_api_key_command)
70
+ return nil unless cmd && cmd != ''
71
+
72
+ key = `#{cmd}`.strip
73
+ return nil unless $?.success? && !key.empty?
74
+
75
+ key
76
+ end
41
77
  end
42
78
 
43
79
  def initialize(config = {}, file: nil)
44
80
  @config = config
45
- @file = file
81
+ @file = file
46
82
  load
47
83
  end
48
84
 
49
85
  def set(key, value)
50
- if value && value != ''
86
+ if value != nil && value != ''
51
87
  @config[key.to_sym] = value
52
88
  else
53
89
  @config.delete(key.to_sym)
@@ -66,7 +102,7 @@ module Capistrano
66
102
  return unless other
67
103
 
68
104
  other.to_h.each do |key, value|
69
- next if !value || value == ''
105
+ next if value == nil || value == ''
70
106
 
71
107
  set(key, value)
72
108
  end
@@ -10,7 +10,7 @@ module Capistrano
10
10
 
11
11
  module VERSION
12
12
  MAJOR = 1
13
- MINOR = 0
13
+ MINOR = 1
14
14
  TINY = 0
15
15
  PRE = nil
16
16
 
File without changes
File without changes
@@ -8,34 +8,77 @@ Configure the redmine credentials for deployment.
8
8
  task :setup do
9
9
  require 'capistrano/redmine/deployment/config'
10
10
 
11
+ # resolve configs
12
+ config = Capistrano::Redmine::Deployment::Config.config_from_file(File.join(Dir.pwd, '.redmine'))
13
+
11
14
  puts "******************************************************************************************************"
12
15
  puts "== Capistrano::Redmine::Deployment - setup =="
13
16
  puts "******************************************************************************************************"
14
17
  puts ""
15
18
  puts " This task creates a '.redmine' file in your current application folder (pwd)."
19
+ puts " Define credentials with this task (e.g. api_key)."
20
+ puts ""
16
21
  puts " This file must NOT be exposed and should be EXCLUDED by your scm."
17
- puts " Define application-related settings within your 'config/deploy.rb' (e.g. host, project, repository)."
18
- puts " Define authentication-related settings with this task (e.g. api_key)."
22
+ puts " Define shared settings within your 'config/deploy.rb' (e.g. host, project, repository)."
23
+ puts " Define credentials with this task (e.g. api_key)."
24
+ puts ""
25
+ puts " > HINT: Keep configs empty to prevent to overwrite existing configs."
26
+ puts ""
27
+ puts " > ALTERNATIVE (recommended): the api_key can also be provided without this file"
28
+ puts " via the ENV variable 'REDMINE_API_KEY' or the capistrano variable"
29
+ puts " ':redmine_api_key_command' (e.g. a macOS keychain lookup). Both win over"
30
+ puts " the '.redmine' file. See the README for details."
19
31
  puts ""
20
32
  puts "******************************************************************************************************"
21
- print "REDMINE API-KEY (required) > "
33
+ puts ""
34
+ puts ""
35
+
36
+ # -- BEGIN over here ...
37
+
38
+ if config.get(:api_key)
39
+ print "API-KEY (already done)..................> "
40
+ else
41
+ print "API-KEY (optional)......................> "
42
+ end
22
43
  redmine_api_key = STDIN.gets.strip
23
- print "REDMINE HOST (optional) > "
44
+
45
+ if config.get(:host)
46
+ print "HOST (already done).....................> "
47
+ else
48
+ print "HOST (optional).........................> "
49
+ end
24
50
  redmine_host = STDIN.gets.strip
25
- print "REDMINE PROJECT (optional) > "
51
+
52
+ if config.get(:project)
53
+ print "PROJECT (already done)..................> "
54
+ else
55
+ print "PROJECT (optional)......................> "
56
+ end
26
57
  redmine_project = STDIN.gets.strip
27
- print "REDMINE REPOSITORY (optional) > "
58
+
59
+ if config.get(:repository)
60
+ print "REPOSITORY (already done)...............> "
61
+ else
62
+ print "REPOSITORY (optional)...................> "
63
+ end
28
64
  redmine_repository = STDIN.gets.strip
65
+
66
+ if config.get(:host_verification) != nil
67
+ print "DISABLE HOST VERIFICATION (already done)........> "
68
+ else
69
+ print "DISABLE HOST VERIFICATION (y / n)...............> "
70
+ end
71
+ redmine_host_verification = STDIN.gets.strip
72
+
29
73
  puts ""
30
74
 
31
- # build config
32
- config = Capistrano::Redmine::Deployment::Config.config_from_file(File.join(Dir.pwd, '.redmine'))
33
75
 
34
76
  # force set to overwrite possible existing keys
35
- config.set(:api_key, redmine_api_key)
36
- config.set(:host, redmine_host)
37
- config.set(:project, redmine_project)
38
- config.set(:repository, redmine_repository)
77
+ config.set(:api_key, redmine_api_key) if redmine_api_key != ''
78
+ config.set(:host, redmine_host) if redmine_host != ''
79
+ config.set(:project, redmine_project) if redmine_project != ''
80
+ config.set(:repository, redmine_repository) if redmine_repository != ''
81
+ config.set(:host_verification, redmine_host_verification.downcase != 'y') if redmine_host_verification != ''
39
82
 
40
83
  if config.save
41
84
  puts "Successfully stored config @ #{config.file}"
File without changes
File without changes
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capistrano-redmine-deployment
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tobias Gonsior
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-10-01 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies: []
13
12
  description: |
14
13
  'capistrano-redmine-deployment' is a capistrano task to log deployments to any related redmine repository.
@@ -20,7 +19,9 @@ extensions: []
20
19
  extra_rdoc_files: []
21
20
  files:
22
21
  - ".gitignore"
22
+ - ".rspec"
23
23
  - Gemfile
24
+ - LICENSE.txt
24
25
  - README.md
25
26
  - Rakefile
26
27
  - bin/console
@@ -28,7 +29,6 @@ files:
28
29
  - capistrano-redmine-deployment.gemspec
29
30
  - docs/CHANGELOG.md
30
31
  - docs/CODE_OF_CONDUCT.md
31
- - docs/LICENSE.md
32
32
  - lib/capistrano-redmine-deployment.rb
33
33
  - lib/capistrano/redmine/deployment/client.rb
34
34
  - lib/capistrano/redmine/deployment/config.rb
@@ -46,7 +46,6 @@ metadata:
46
46
  documentation_uri: https://rubydoc.info/gems/capistrano-redmine-deployment
47
47
  changelog_uri: https://github.com/ruby-smart/capistrano-redmine-deployment/blob/main/docs/CHANGELOG.md
48
48
  allowed_push_host: https://rubygems.org
49
- post_install_message:
50
49
  rdoc_options: []
51
50
  require_paths:
52
51
  - lib
@@ -61,8 +60,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
61
60
  - !ruby/object:Gem::Version
62
61
  version: '0'
63
62
  requirements: []
64
- rubygems_version: 3.3.22
65
- signing_key:
63
+ rubygems_version: 3.6.9
66
64
  specification_version: 4
67
65
  summary: Redmine Deployment Tracking (for redmine_deployment plugin)
68
66
  test_files: []