capistrano-sentry 0.4.0 → 0.5.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: 68fd747d897527e62a5ac086ebc361a5c4b166c059d7c3596b85f7b2a776374f
4
- data.tar.gz: ce63a3acb315cc6b3c96fc01a968032e8a98d4ea080d21eedfe3bc17cb42a3c2
3
+ metadata.gz: 1309178927aac5e5af01a3dd3e42ed491dd88c6915ab250d419b9ead97f630ca
4
+ data.tar.gz: 28bcd3f86fbdfacec11a91e58e98df9df216c924db5022b1138450a11de1c056
5
5
  SHA512:
6
- metadata.gz: 9b3ccae3566b22f9fa686821dae840b0ddd63aa49f9dea6a3d1eaad27802ad33933f650be0706f8ad4c2cf3f10f53035a263a859385577263ff0b6a5d338a826
7
- data.tar.gz: 5e85c1e6d80eaa6dcf43af44ec0e70f76f3de0d31028b0481ea22922501ca73ae350bfda417d1b8af152c7999398911331ad73703fb55f59cbb012af776e198f
6
+ metadata.gz: c6964c9789df72462efb1b3f6c0e90625904f7d173403277815358f38f36377ece78807766966a214d2ae4d0981d07fe7c98eda0d37f7d69f3d092b5b5cb1bd0
7
+ data.tar.gz: 8c210ac87ef38e0758f95cb5410759adf0f9abfa3b6cbc00c33c427e0aa2e312a5acac3cc09463048b29993e484665c2fcc7f18552a2ae9fa743a2ef9a01e58f
@@ -0,0 +1,43 @@
1
+ name: Test
2
+
3
+ on: [push]
4
+
5
+ jobs:
6
+ test:
7
+
8
+ runs-on: ubuntu-latest
9
+
10
+ strategy:
11
+ matrix:
12
+ ruby: [ '3.4' ]
13
+
14
+ steps:
15
+ - uses: actions/checkout@v2
16
+
17
+ - name: Set up Ruby ${{ matrix.ruby }}
18
+ uses: ruby/setup-ruby@v1
19
+ with:
20
+ ruby-version: ${{ matrix.ruby }}
21
+ bundler-cache: true
22
+
23
+ - name: Retrieve gems cache
24
+ uses: actions/cache@v5
25
+ with:
26
+ path: vendor/bundle
27
+ key: ${{ runner.os }}-${{ matrix.ruby }}-gem-${{ hashFiles('**/Gemfile.lock') }}
28
+
29
+ - name: Install gems
30
+ run: |
31
+ rm -f .ruby-version
32
+ bundle config path vendor/bundle
33
+ bundle install --jobs 4 --retry 3
34
+
35
+ - name: Run tests
36
+ run: bundle exec rake test
37
+
38
+ - name: Upload log if failure
39
+ uses: actions/upload-artifact@v6
40
+ if: failure()
41
+ with:
42
+ name: test.log
43
+ path: log/test.log
data/.rubocop.yml ADDED
@@ -0,0 +1,99 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.4
3
+
4
+ Layout/AccessModifierIndentation:
5
+ EnforcedStyle: outdent
6
+ IndentationWidth: 2
7
+
8
+ Layout/ArgumentAlignment:
9
+ EnforcedStyle: with_fixed_indentation
10
+ IndentationWidth: 2
11
+
12
+ Layout/FirstArrayElementIndentation:
13
+ EnforcedStyle: consistent
14
+
15
+ Layout/FirstHashElementIndentation:
16
+ EnforcedStyle: consistent
17
+
18
+ Layout/HashAlignment:
19
+ EnforcedHashRocketStyle: table
20
+ EnforcedColonStyle: table
21
+
22
+ Layout/MultilineMethodCallIndentation:
23
+ EnforcedStyle: indented
24
+
25
+ Layout/ParameterAlignment:
26
+ EnforcedStyle: with_fixed_indentation
27
+ IndentationWidth: 2
28
+
29
+ Lint/RaiseException:
30
+ Enabled: true
31
+
32
+ Lint/StructNewOverride:
33
+ Enabled: true
34
+
35
+ Metrics/AbcSize:
36
+ Max: 65
37
+
38
+ Metrics/BlockLength:
39
+ Max: 70
40
+
41
+ Metrics/ClassLength:
42
+ Max: 300
43
+
44
+ Metrics/CyclomaticComplexity:
45
+ Max: 10
46
+
47
+ Metrics/MethodLength:
48
+ Max: 60
49
+
50
+ Metrics/ModuleLength:
51
+ Max: 300
52
+
53
+ Metrics/PerceivedComplexity:
54
+ Max: 10
55
+
56
+ Naming/FileName:
57
+ Enabled: false
58
+
59
+ Style/AsciiComments:
60
+ Enabled: false
61
+
62
+ Style/ClassAndModuleChildren:
63
+ AutoCorrect: true
64
+
65
+ Style/ConditionalAssignment:
66
+ Enabled: false
67
+
68
+ Style/Documentation:
69
+ Enabled: false
70
+
71
+ Style/EmptyMethod:
72
+ EnforcedStyle: expanded
73
+
74
+ Style/GuardClause:
75
+ MinBodyLength: 3
76
+
77
+ Style/HashEachMethods:
78
+ Enabled: true
79
+ AutoCorrect: true
80
+
81
+ Style/HashTransformKeys:
82
+ Enabled: true
83
+ AutoCorrect: true
84
+
85
+ Style/HashTransformValues:
86
+ Enabled: true
87
+ AutoCorrect: true
88
+
89
+ Style/IfUnlessModifier:
90
+ Enabled: false
91
+
92
+ Style/MultipleComparison:
93
+ Enabled: false
94
+
95
+ Style/NumericPredicate:
96
+ Enabled: false
97
+
98
+ Style/SymbolArray:
99
+ MinSize: 7
data/Gemfile CHANGED
@@ -1,6 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
4
6
 
5
7
  # Specify your gem's dependencies in capistrano-sentry.gemspec
6
8
  gemspec
9
+
10
+ gem 'minitest', '~> 5.0'
11
+ gem 'rake', '>= 10'
data/README.md CHANGED
@@ -33,9 +33,10 @@ set :sentry_api_token, '0123456789abcdef0123456789abcdef'
33
33
  set :sentry_organization, 'my-org' # fetch(:application) by default
34
34
  set :sentry_project, 'my-proj' # fetch(:application) by default
35
35
  set :sentry_repo, 'my-org/my-proj' # computed from repo_url by default
36
+ set :sentry_stages, %w[production] # only these stages create releases and deploys, %w[production] by default
36
37
  ```
37
38
 
38
- If you want deployments to be published in every Rails environment, put this in `config/deploy.rb`, otherwise put it your environment-specific deploy file (i.e. `config/deploy/production.rb`):
39
+ Then hook the tasks in `config/deploy.rb`:
39
40
  ```ruby
40
41
  before 'deploy:starting', 'sentry:validate_config'
41
42
  after 'deploy:published', 'sentry:notice_deployment'
@@ -56,6 +57,8 @@ after 'deploy:published', 'sentry:notice_deployment'
56
57
 
57
58
  * `sentry_repo`: The `repository` name to be used when reporting repository details to Sentry [computed from `fetch(:repo_url)` by default -- `https://github.com/codeur/capistrano-sentry` becomes `//github.com/codeur/capistrano-sentry` and `git@github.com:codeur/capistrano-sentry.git` becomes `codeur/capistrano-sentry`]
58
59
 
60
+ * `sentry_stages`: the Capistrano stages allowed to create releases and deploys in Sentry. Both tasks are skipped for any other stage, so a staging deploy never creates a release. [`%w[production]` by default]
61
+
59
62
  * `sentry_repo_integration`: this enables/disables submission of git repo information (`release_refs` below) to Sentry [Enabled (`true`) by default].
60
63
 
61
64
  * `sentry_release_refs`: Repository details about this realease (`repository`, `commit`, `previousCommit`) to Sentry [computed from `sentry_repo`, `current_revision`, and `previous_revision`)].
data/Rakefile CHANGED
@@ -1,8 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler/gem_tasks'
2
4
  require 'rake/testtask'
3
5
 
4
6
  Rake::TestTask.new(:test) do |t|
5
7
  t.libs << 'test'
8
+ t.warning = false # capistrano itself triggers circular require warnings
6
9
  t.libs << 'lib'
7
10
  t.test_files = FileList['test/**/*_test.rb']
8
11
  end
data/bin/console CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'bundler/setup'
4
5
  require 'capistrano/sentry'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  lib = File.expand_path('lib', __dir__)
2
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
5
  require 'capistrano/sentry/version'
@@ -8,7 +10,7 @@ Gem::Specification.new do |spec|
8
10
  spec.authors = ['Brice Texier']
9
11
  spec.email = ['brice@codeur.com']
10
12
  spec.description = 'Sentry release/deployment integration'
11
- spec.summary = 'Sentry release/deployment integration'
13
+ spec.summary = 'Push release and deployment information on Sentry on each deploy'
12
14
  spec.homepage = 'https://github.com/codeur/capistrano-sentry'
13
15
  spec.license = 'MIT'
14
16
 
@@ -23,8 +25,4 @@ Gem::Specification.new do |spec|
23
25
  spec.require_paths = ['lib']
24
26
 
25
27
  spec.add_dependency 'capistrano', '~> 3.1'
26
-
27
- spec.add_development_dependency 'bundler', '~> 1.17'
28
- spec.add_development_dependency 'minitest', '~> 5.0'
29
- spec.add_development_dependency 'rake', '~> 10.0'
30
28
  end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Capistrano
2
4
  module Sentry
3
- VERSION = '0.4.0'.freeze
5
+ VERSION = '0.5.0'
4
6
  end
5
7
  end
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  load File.expand_path('tasks/sentry.rake', __dir__)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This task will notify Sentry via their API[1][2] that you have deployed
2
4
  # a new release. It uses the commit hash as the `version` and the git ref as
3
5
  # the optional `ref` value.
@@ -13,15 +15,26 @@ module Capistrano
13
15
  end
14
16
 
15
17
  namespace :sentry do
18
+ # Only the stages listed in `:sentry_stages` (`production` by default) notify Sentry.
19
+ def sentry_stage_enabled?
20
+ Array(fetch(:sentry_stages, %w[production])).map(&:to_s).include?(fetch(:stage).to_s)
21
+ end
22
+
16
23
  desc 'Confirm configuration for notification to Sentry'
17
24
  task :validate_config do
18
25
  run_locally do
26
+ unless sentry_stage_enabled?
27
+ info "[sentry:validate_config] Skipped: stage #{fetch(:stage).inspect} is not listed in :sentry_stages"
28
+ next
29
+ end
30
+
19
31
  info '[sentry:validate_config] Validating Sentry notification config'
20
32
  api_token = ENV['SENTRY_API_TOKEN'] || fetch(:sentry_api_token)
21
33
  if api_token.nil? || api_token.empty?
22
- msg = "Missing SENTRY_API_TOKEN. Please set SENTRY_API_TOKEN environment variable or `set :sentry_api_token` in your `config/deploy.rb` file for your Rails application."
34
+ msg = 'Missing SENTRY_API_TOKEN. Please set SENTRY_API_TOKEN environment' \
35
+ ' variable or `set :sentry_api_token` in your `config/deploy.rb` file for your Rails application.'
23
36
  warn msg
24
- fail Capistrano::SentryConfigurationError, msg
37
+ raise Capistrano::SentryConfigurationError, msg
25
38
  end
26
39
  end
27
40
  end
@@ -29,6 +42,11 @@ namespace :sentry do
29
42
  desc 'Notice new deployment in Sentry'
30
43
  task :notice_deployment do
31
44
  run_locally do
45
+ unless sentry_stage_enabled?
46
+ info "[sentry:notice_deployment] Skipped: stage #{fetch(:stage).inspect} is not listed in :sentry_stages"
47
+ next
48
+ end
49
+
32
50
  require 'uri'
33
51
  require 'net/https'
34
52
  require 'json'
@@ -43,9 +61,9 @@ namespace :sentry do
43
61
  api_token = ENV['SENTRY_API_TOKEN'] || fetch(:sentry_api_token)
44
62
  repo_integration_enabled = fetch(:sentry_repo_integration, true)
45
63
  release_refs = fetch(:sentry_release_refs, [{
46
- repository: fetch(:sentry_repo) || fetch(:repo_url).split(':').last.gsub(/\.git$/, ''),
47
- commit: head_revision,
48
- previousCommit: prev_revision,
64
+ repository: fetch(:sentry_repo) || fetch(:repo_url).split(':').last.delete_suffix('.git'),
65
+ commit: head_revision,
66
+ previousCommit: prev_revision
49
67
  }])
50
68
  release_version = fetch(:sentry_release_version) || head_revision
51
69
  deploy_name = fetch(:sentry_deploy_name) || "#{release_version}-#{fetch(:release_timestamp)}"
@@ -55,24 +73,27 @@ namespace :sentry do
55
73
  http.use_ssl = true
56
74
 
57
75
  headers = {
58
- 'Content-Type' => 'application/json',
59
- 'Authorization' => 'Bearer ' + api_token.to_s,
76
+ 'Content-Type' => 'application/json',
77
+ 'Authorization' => 'Bearer ' + api_token.to_s
60
78
  }
61
79
 
62
80
  req = Net::HTTP::Post.new("/api/0/organizations/#{organization_slug}/releases/", headers)
63
81
  body = {
64
- version: release_version,
65
- projects: [project],
82
+ version: release_version,
83
+ projects: [project]
66
84
  }
67
85
  body[:refs] = release_refs if repo_integration_enabled
68
86
  req.body = JSON.generate(body)
69
87
  response = http.request(req)
70
88
  if response.is_a? Net::HTTPSuccess
71
89
  info "Notified Sentry of new release: #{release_version}"
72
- req = Net::HTTP::Post.new("/api/0/organizations/#{organization_slug}/releases/#{release_version}/deploys/", headers)
90
+ req = Net::HTTP::Post.new(
91
+ "/api/0/organizations/#{organization_slug}/releases/#{release_version}/deploys/",
92
+ headers
93
+ )
73
94
  req.body = JSON.generate(
74
95
  environment: environment,
75
- name: deploy_name,
96
+ name: deploy_name
76
97
  )
77
98
  response = http.request(req)
78
99
  if response.is_a? Net::HTTPSuccess
@@ -1,11 +1,56 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
- class Capistrano::SentryTest < Minitest::Test
4
- def test_that_it_has_a_version_number
5
- refute_nil ::Capistrano::Sentry::VERSION
6
- end
5
+ module Capistrano
6
+ class SentryTest < TestCase
7
+ def test_production_creates_a_release_and_a_deploy
8
+ set :stage, :production
9
+ run_task :notice_deployment
10
+
11
+ assert_equal 2, @http.requests.size
12
+ release, deploy = @http.requests
13
+ assert_equal '/api/0/organizations/my-app/releases/', release.path
14
+ assert_equal 'Bearer secret', release['Authorization']
15
+ body = JSON.parse(release.body)
16
+ assert_equal 'abc123', body['version']
17
+ assert_equal ['my-app'], body['projects']
18
+ assert_equal 'my-org/my-app', body['refs'].first['repository']
19
+ assert_equal '/api/0/organizations/my-app/releases/abc123/deploys/', deploy.path
20
+ assert_equal({ 'environment' => 'production', 'name' => 'abc123-20260910120000' }, JSON.parse(deploy.body))
21
+ assert_includes log, 'Notified Sentry of new deployment'
22
+ end
23
+
24
+ def test_other_stages_do_not_notify_sentry
25
+ set :stage, :staging
26
+ run_task :notice_deployment
27
+
28
+ assert_empty @http.requests
29
+ assert_includes log, 'Skipped: stage :staging is not listed in :sentry_stages'
30
+ end
31
+
32
+ def test_sentry_stages_can_enable_other_stages
33
+ set :stage, :staging
34
+ set :sentry_stages, %w[staging production]
35
+ run_task :notice_deployment
36
+
37
+ assert_equal 2, @http.requests.size
38
+ assert_equal 'staging', JSON.parse(@http.requests.last.body)['environment']
39
+ end
40
+
41
+ def test_validate_config_requires_a_token_on_enabled_stages
42
+ set :stage, :production
43
+ set :sentry_api_token, nil
44
+
45
+ assert_raises(Capistrano::SentryConfigurationError) { run_task :validate_config }
46
+ end
47
+
48
+ def test_validate_config_is_skipped_on_other_stages
49
+ set :stage, :staging
50
+ set :sentry_api_token, nil
7
51
 
8
- def test_it_does_something_useful
9
- assert false
52
+ run_task :validate_config
53
+ assert_includes log, 'Skipped: stage :staging is not listed in :sentry_stages'
54
+ end
10
55
  end
11
56
  end
data/test/test_helper.rb CHANGED
@@ -1,4 +1,62 @@
1
+ # frozen_string_literal: true
2
+
1
3
  $LOAD_PATH.unshift File.expand_path('../lib', __dir__)
2
- require 'capistrano/sentry'
3
4
 
5
+ require 'capistrano/all'
6
+ Rake.application.options.trace = false # re-enabled by capistrano/all
4
7
  require 'minitest/autorun'
8
+ require 'stringio'
9
+ require 'net/http'
10
+ require 'json'
11
+
12
+ include Capistrano::DSL # rubocop:disable Style/MixinUsage
13
+
14
+ require 'capistrano/sentry'
15
+
16
+ module Capistrano
17
+ # Runs Capistrano tasks against a fresh configuration, with SSHKit output captured
18
+ # and Sentry's HTTP API replaced by a recorder.
19
+ class TestCase < Minitest::Test
20
+ class FakeHTTP
21
+ attr_reader :requests
22
+
23
+ def initialize
24
+ @requests = []
25
+ end
26
+
27
+ def use_ssl=(_value); end
28
+
29
+ def request(req)
30
+ @requests << req
31
+ Net::HTTPCreated.new('1.1', '201', 'Created').tap do |response|
32
+ response.instance_variable_set(:@body, '{}')
33
+ response.instance_variable_set(:@read, true)
34
+ end
35
+ end
36
+ end
37
+
38
+ def setup
39
+ Capistrano::Configuration.reset!
40
+ @log = StringIO.new
41
+ SSHKit.config.output = SSHKit::Formatter::Pretty.new(@log)
42
+ SSHKit.config.output_verbosity = :debug
43
+ @http = FakeHTTP.new
44
+ set :application, 'my-app'
45
+ set :repo_url, 'git@github.com:my-org/my-app.git'
46
+ set :sentry_api_token, 'secret'
47
+ set :current_revision, 'abc123'
48
+ set :previous_revision, 'def456'
49
+ set :release_timestamp, '20260910120000'
50
+ end
51
+
52
+ def run_task(name)
53
+ task = Rake::Task["sentry:#{name}"]
54
+ task.reenable
55
+ Net::HTTP.stub(:new, @http) { task.invoke }
56
+ end
57
+
58
+ def log
59
+ @log.string
60
+ end
61
+ end
62
+ end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capistrano-sentry
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brice Texier
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2019-05-03 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: capistrano
@@ -24,48 +23,6 @@ dependencies:
24
23
  - - "~>"
25
24
  - !ruby/object:Gem::Version
26
25
  version: '3.1'
27
- - !ruby/object:Gem::Dependency
28
- name: bundler
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '1.17'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '1.17'
41
- - !ruby/object:Gem::Dependency
42
- name: minitest
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '5.0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '5.0'
55
- - !ruby/object:Gem::Dependency
56
- name: rake
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '10.0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: '10.0'
69
26
  description: Sentry release/deployment integration
70
27
  email:
71
28
  - brice@codeur.com
@@ -73,8 +30,9 @@ executables: []
73
30
  extensions: []
74
31
  extra_rdoc_files: []
75
32
  files:
33
+ - ".github/workflows/test.yml"
76
34
  - ".gitignore"
77
- - ".travis.yml"
35
+ - ".rubocop.yml"
78
36
  - CODE_OF_CONDUCT.md
79
37
  - Gemfile
80
38
  - LICENSE.txt
@@ -93,7 +51,6 @@ homepage: https://github.com/codeur/capistrano-sentry
93
51
  licenses:
94
52
  - MIT
95
53
  metadata: {}
96
- post_install_message:
97
54
  rdoc_options: []
98
55
  require_paths:
99
56
  - lib
@@ -108,11 +65,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
108
65
  - !ruby/object:Gem::Version
109
66
  version: '0'
110
67
  requirements: []
111
- rubyforge_project:
112
- rubygems_version: 2.7.6
113
- signing_key:
68
+ rubygems_version: 3.6.9
114
69
  specification_version: 4
115
- summary: Sentry release/deployment integration
70
+ summary: Push release and deployment information on Sentry on each deploy
116
71
  test_files:
117
72
  - test/capistrano/sentry_test.rb
118
73
  - test/test_helper.rb
data/.travis.yml DELETED
@@ -1,7 +0,0 @@
1
- ---
2
- sudo: false
3
- language: ruby
4
- cache: bundler
5
- rvm:
6
- - 2.5.1
7
- before_install: gem install bundler -v 1.17.1