bugsnag-capistrano 1.1.2 → 2.0.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 +5 -5
- data/CHANGELOG.md +6 -4
- data/Gemfile +0 -4
- data/README.md +1 -2
- data/Rakefile +1 -8
- data/UPGRADING.md +27 -0
- data/VERSION +1 -1
- data/lib/bugsnag-capistrano/capistrano.rb +1 -1
- data/lib/bugsnag-capistrano/capistrano2.rb +13 -10
- data/lib/bugsnag-capistrano/release.rb +85 -0
- data/lib/bugsnag-capistrano/tasks/bugsnag.cap +12 -16
- data/spec/capistrano_spec.rb +12 -5
- data/spec/release_spec.rb +96 -0
- metadata +6 -8
- data/lib/bugsnag-capistrano/deploy.rb +0 -98
- data/lib/bugsnag-capistrano/tasks.rb +0 -2
- data/lib/bugsnag-capistrano/tasks/bugsnag-capistrano.rake +0 -85
- data/spec/deploy_spec.rb +0 -97
- data/spec/rake_spec.rb +0 -64
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d7777843eff43a04d774d3bdee4d5a88dd73d6b1
|
4
|
+
data.tar.gz: 8289fc24a6372a988304b5195458c4d5552e06db
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7aba8fdb6fa4637c860f7648d418bc94c65252b900ff780828389572df7b81bdb82a6de1ed29e6cc7f2f5500ce5b5fe2fd0e5971dbec077e919839a50e7e80e7
|
7
|
+
data.tar.gz: 30486a327c9896b6a0d0bb2756f2e35a3e2787cf33a311d5db8f44d6b57358e6a0bd448b3f369bedb47ab6020c470e274c3287c774f30dda88e26529a97bf7ad
|
data/CHANGELOG.md
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
-
##
|
1
|
+
## 2.0.0 (03-04-2018)
|
2
2
|
|
3
|
-
|
3
|
+
Major changes have been made with the 2.0.0 release. For a full list please consult the [upgrading guide](https://github.com/bugsnag/bugsnag-capistrano/blob/master/UPGRADING.md).
|
4
|
+
|
5
|
+
### Enhancements
|
4
6
|
|
5
|
-
*
|
6
|
-
|
7
|
+
* Rewritten tool to notify [Bugsnag Build API](https://docs.bugsnag.com/build-integrations/)
|
8
|
+
| [#13](https://github.com/bugsnag/bugsnag-capistrano/pull/13)
|
7
9
|
|
8
10
|
## 1.1.1 (14-12-2017)
|
9
11
|
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -16,8 +16,7 @@ capturing exceptions from your applications.
|
|
16
16
|
|
17
17
|
## Getting started
|
18
18
|
|
19
|
-
* [Integrating with Capistrano](https://docs.bugsnag.com/
|
20
|
-
* [Integrating with Rake](https://docs.bugsnag.com/api/deploy-tracking/rake/)
|
19
|
+
* [Integrating with Capistrano](https://docs.bugsnag.com/build-integrations/capistrano/)
|
21
20
|
|
22
21
|
## Contributing
|
23
22
|
|
data/Rakefile
CHANGED
@@ -25,14 +25,7 @@ end
|
|
25
25
|
require 'rspec/core'
|
26
26
|
require "rspec/core/rake_task"
|
27
27
|
|
28
|
-
tags = '--format documentation
|
29
|
-
|
30
|
-
begin
|
31
|
-
require 'bugsnag'
|
32
|
-
tags += '--tag with_notifier '
|
33
|
-
rescue LoadError
|
34
|
-
tags += '--tag without_notifier '
|
35
|
-
end
|
28
|
+
tags = '--format documentation'
|
36
29
|
|
37
30
|
RSpec::Core::RakeTask.new(:spec) do |opts|
|
38
31
|
opts.rspec_opts = tags
|
data/UPGRADING.md
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# Upgrade Guide
|
2
|
+
|
3
|
+
## 1.x to 2.x
|
4
|
+
|
5
|
+
_Our Capistrano build-integration has changed to accommodate changes to our [Build API](https://docs.bugsnag.com/build-integrations/), and there may be changes required to continue to notify of your Capistrano releases_
|
6
|
+
|
7
|
+
#### Heroku
|
8
|
+
|
9
|
+
Heroku deployment notifications have been removed from this gem. You can find information on how to set up a Heroku deploy hook at [our documentation](https://docs.bugsnag.com/build-integrations/heroku/).
|
10
|
+
|
11
|
+
#### Rake
|
12
|
+
|
13
|
+
Rake deployment notifications have been removed from this gem. While we don't have an explicit replacement for the Rake tasks, information on how to send a build notification can be found in [our Build API documentation](https://docs.bugsnag.com/build-integrations/).
|
14
|
+
|
15
|
+
#### Task names
|
16
|
+
|
17
|
+
The task `:deploy` has been renamed to `:release`. Any references to it should be renamed accordingly.
|
18
|
+
|
19
|
+
#### Configuration
|
20
|
+
|
21
|
+
- `branch` has been removed.
|
22
|
+
- `bugsnag_builder` has been added. This should be the name of the person or machine that has triggered the release. Can also be set using the environment variables `BUGSNAG_BUILDER_NAME` or `USER`. Will default to the result of the `whoami` command on the releasing machine.
|
23
|
+
- `bugsnag_auto_assign_release` has been added. Thi#s will ensure **all** event notifications received will be assigned to this release. This should only be used if you are not using the `app_version` configuration option within your application. Can be set using the environment variable `BUGSNAG_AUTO_ASSIGN_RELEASE`. Will default to `false`.
|
24
|
+
- `bugsnag_source_control_provider` has been added. This contains the type of on-premise server the application uses for source-control, and therefore should only be used if an on-premise source-control solution is used. Valid settings are: `github-enterprise`, `gitlab-onpremise`, and `bitbucket-server`. Can be set using the environment variable `BUGSNAG_SOURCE_CONTROL_PROVIDER`. Defaults to `nil`.
|
25
|
+
- `bugsnag-metadata` has been added. This should be a hash containing any additional data you wish to attach to your release notification.
|
26
|
+
|
27
|
+
A full list of configuration options can be found at the [Capistrano build-integration guide](https://docs.bugsnag.com/build-integrations/capistrano/).
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
2.0.0
|
@@ -2,25 +2,28 @@ module Bugsnag
|
|
2
2
|
module Capistrano
|
3
3
|
def self.load_into(configuration)
|
4
4
|
configuration.load do
|
5
|
-
after "deploy", "bugsnag:
|
6
|
-
after "deploy:migrations", "bugsnag:deploy"
|
5
|
+
after "deploy", "bugsnag:release"
|
7
6
|
|
8
7
|
namespace :bugsnag do
|
9
|
-
desc "Notify Bugsnag that new production code has been
|
10
|
-
task :
|
8
|
+
desc "Notify Bugsnag that new production code has been released"
|
9
|
+
task :release, :except => { :no_release => true }, :on_error => :continue do
|
11
10
|
begin
|
12
|
-
|
11
|
+
auto_assign_release_bool = ENV["BUGSNAG_AUTO_ASSIGN_RELEASE"] == 'true'
|
12
|
+
Bugsnag::Capistrano::Release.notify({
|
13
13
|
:api_key => fetch(:bugsnag_api_key, ENV["BUGSNAG_API_KEY"]),
|
14
|
+
:app_version => fetch(:app_version, ENV["BUGSNAG_APP_VERSION"]),
|
15
|
+
:auto_assign_release => fetch(:bugsnag_auto_assign_release, auto_assign_release_bool),
|
16
|
+
:builder_name => fetch(:bugsnag_builder, ENV["BUGSNAG_BUILDER_NAME"] || ENV["USER"]),
|
17
|
+
:metadata => fetch(:bugsnag_metadata, nil),
|
14
18
|
:release_stage => fetch(:bugsnag_env) || ENV["BUGSNAG_RELEASE_STAGE"] || fetch(:rails_env) || fetch(:stage) || "production",
|
15
19
|
:revision => fetch(:current_revision, ENV["BUGSNAG_REVISION"]),
|
16
20
|
:repository => fetch(:repo_url, ENV["BUGSNAG_REPOSITORY"]),
|
17
|
-
:
|
18
|
-
:
|
19
|
-
:endpoint => fetch(:bugsnag_endpoint)
|
21
|
+
:source_control_provider => fetch(:bugsnag_source_control_provider, ENV["BUGSNAG_SOURCE_CONTROL_PROVIDER"]),
|
22
|
+
:endpoint => fetch(:bugsnag_endpoint, nil)
|
20
23
|
})
|
21
|
-
logger.info "Bugsnag
|
24
|
+
logger.info "Bugsnag release notification complete."
|
22
25
|
rescue
|
23
|
-
logger.important("
|
26
|
+
logger.important("Bugsnag release notification failed, #{$!.inspect}")
|
24
27
|
end
|
25
28
|
end
|
26
29
|
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require "json"
|
2
|
+
require "net/http"
|
3
|
+
require "logger"
|
4
|
+
|
5
|
+
module Bugsnag
|
6
|
+
module Capistrano
|
7
|
+
class Release
|
8
|
+
|
9
|
+
HEADERS = {"Content-Type" => "application/json"}
|
10
|
+
DEFAULT_BUILD_ENDPOINT = "https://build.bugsnag.com/"
|
11
|
+
DEFAULT_BUILD_TOOL_NAME = "bugsnag-capistrano"
|
12
|
+
|
13
|
+
def self.notify(opts = {})
|
14
|
+
# Try and get some config from Bugsnag
|
15
|
+
begin
|
16
|
+
require 'bugsnag'
|
17
|
+
|
18
|
+
opts[:api_key] ||= Bugsnag.configuration.api_key
|
19
|
+
opts[:app_version] ||= Bugsnag.configuration.app_version
|
20
|
+
opts[:release_stage] ||= Bugsnag.configuration.release_stage
|
21
|
+
rescue LoadError
|
22
|
+
end
|
23
|
+
|
24
|
+
opts[:endpoint] ||= DEFAULT_BUILD_ENDPOINT
|
25
|
+
opts[:builder_name] ||= `whoami`
|
26
|
+
opts[:build_tool] ||= DEFAULT_BUILD_TOOL_NAME
|
27
|
+
|
28
|
+
parameters = {
|
29
|
+
"apiKey" => opts[:api_key],
|
30
|
+
"appVersion" => opts[:app_version],
|
31
|
+
"autoAssignRelease" => opts[:auto_assign_release],
|
32
|
+
"builderName" => opts[:builder_name],
|
33
|
+
"buildTool" => opts[:build_tool],
|
34
|
+
"metadata" => opts[:metadata],
|
35
|
+
"releaseStage" => opts[:release_stage],
|
36
|
+
"sourceControl" => {
|
37
|
+
"provider" => opts[:source_control_provider],
|
38
|
+
"revision" => opts[:revision],
|
39
|
+
"repository" => opts[:repository]
|
40
|
+
}
|
41
|
+
}
|
42
|
+
|
43
|
+
if parameters["apiKey"].nil?
|
44
|
+
logger.warn("Cannot deliver notification. Missing required apiKey")
|
45
|
+
elsif parameters["appVersion"].nil?
|
46
|
+
logger.warn("Cannot deliver notification. Missing required appVersion")
|
47
|
+
else
|
48
|
+
payload_string = ::JSON.dump(parameters)
|
49
|
+
self.deliver(opts[:endpoint], payload_string)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.deliver(url, body)
|
54
|
+
begin
|
55
|
+
request(url, body)
|
56
|
+
rescue StandardError => e
|
57
|
+
logger.warn("Notification to #{url} failed, #{e.inspect}")
|
58
|
+
logger.warn(e.backtrace)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.request(url, body)
|
63
|
+
uri = URI.parse(url)
|
64
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
65
|
+
http.read_timeout = 15
|
66
|
+
http.open_timeout = 15
|
67
|
+
|
68
|
+
http.use_ssl = uri.scheme == "https"
|
69
|
+
|
70
|
+
uri.path == "" ? "/" : uri.path
|
71
|
+
request = Net::HTTP::Post.new(uri, HEADERS)
|
72
|
+
request.body = body
|
73
|
+
http.request(request)
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.logger
|
77
|
+
if @logger.nil?
|
78
|
+
@logger = Logger.new(STDOUT)
|
79
|
+
@logger.level = Logger::INFO
|
80
|
+
end
|
81
|
+
@logger
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -1,46 +1,42 @@
|
|
1
1
|
namespace :load do
|
2
|
-
|
3
2
|
task :defaults do
|
4
|
-
|
5
3
|
set :bugsnag_default_hooks, ->{ true }
|
6
|
-
|
7
4
|
end
|
8
|
-
|
9
5
|
end
|
10
6
|
|
11
7
|
namespace :deploy do
|
12
|
-
|
13
8
|
before :starting, :bugsnag_hooks do
|
14
9
|
invoke 'bugsnag:add_default_hooks' if fetch(:bugsnag_default_hooks)
|
15
10
|
end
|
16
|
-
|
17
11
|
end
|
18
12
|
|
19
13
|
namespace :bugsnag do
|
20
|
-
|
21
14
|
task :add_default_hooks do
|
22
|
-
after 'deploy:published', 'bugsnag:
|
15
|
+
after 'deploy:published', 'bugsnag:release'
|
23
16
|
end
|
24
17
|
|
25
|
-
desc 'Notify Bugsnag that new production code has been
|
26
|
-
task :
|
18
|
+
desc 'Notify Bugsnag that new production code has been released'
|
19
|
+
task :release do
|
27
20
|
run_locally do
|
28
21
|
begin
|
29
|
-
|
22
|
+
auto_assign_release_bool = ENV["BUGSNAG_AUTO_ASSIGN_RELEASE"] == 'true'
|
23
|
+
Bugsnag::Capistrano::Release.notify({
|
30
24
|
:api_key => fetch(:bugsnag_api_key, ENV["BUGSNAG_API_KEY"]),
|
25
|
+
:app_version => fetch(:app_version, ENV["BUGSNAG_APP_VERSION"]),
|
26
|
+
:auto_assign_release => fetch(:bugsnag_auto_assign_release, auto_assign_release_bool),
|
27
|
+
:builder_name => fetch(:bugsnag_builder, ENV["BUGSNAG_BUILDER_NAME"] || ENV["USER"]),
|
28
|
+
:metadata => fetch(:bugsnag_metadata),
|
31
29
|
:release_stage => fetch(:bugsnag_env) || ENV["BUGSNAG_RELEASE_STAGE"] || fetch(:rails_env) || fetch(:stage) || "production",
|
32
30
|
:revision => fetch(:current_revision, ENV["BUGSNAG_REVISION"]),
|
33
31
|
:repository => fetch(:repo_url, ENV["BUGSNAG_REPOSITORY"]),
|
34
|
-
:
|
35
|
-
:app_version => fetch(:app_version, ENV["BUGSNAG_APP_VERSION"]),
|
32
|
+
:source_control_provider => fetch(:bugsnag_source_control_provider, ENV["BUGSNAG_SOURCE_CONTROL_PROVIDER"]),
|
36
33
|
:endpoint => fetch(:bugsnag_endpoint)
|
37
34
|
})
|
38
|
-
info 'Bugsnag
|
35
|
+
info 'Bugsnag release notification complete.'
|
39
36
|
rescue
|
40
|
-
error "Bugsnag
|
37
|
+
error "Bugsnag release notification failed, #{$!.inspect}"
|
41
38
|
end
|
42
39
|
end
|
43
40
|
end
|
44
|
-
|
45
41
|
end
|
46
42
|
# vi:ft=ruby
|
data/spec/capistrano_spec.rb
CHANGED
@@ -4,7 +4,7 @@ require 'rspec/mocks'
|
|
4
4
|
|
5
5
|
require 'webrick'
|
6
6
|
|
7
|
-
describe "bugsnag capistrano"
|
7
|
+
describe "bugsnag capistrano" do
|
8
8
|
|
9
9
|
server = nil
|
10
10
|
queue = Queue.new
|
@@ -29,16 +29,18 @@ describe "bugsnag capistrano", :always do
|
|
29
29
|
end
|
30
30
|
|
31
31
|
let(:request) { JSON.parse(queue.pop) }
|
32
|
-
|
32
|
+
|
33
33
|
it "sends a deploy notification to the set endpoint" do
|
34
34
|
ENV['BUGSNAG_ENDPOINT'] = "http://localhost:" + server.config[:Port].to_s + "/deploy"
|
35
|
-
|
35
|
+
ENV['BUGSNAG_APP_VERSION'] = "1"
|
36
|
+
|
36
37
|
Dir.chdir(example_path) do
|
37
38
|
system(exec_string)
|
38
39
|
end
|
39
40
|
|
40
41
|
payload = request()
|
41
42
|
expect(payload["apiKey"]).to eq('YOUR_API_KEY')
|
43
|
+
expect(payload["appVersion"]).to eq("1")
|
42
44
|
expect(payload["releaseStage"]).to eq('production')
|
43
45
|
end
|
44
46
|
|
@@ -49,6 +51,8 @@ describe "bugsnag capistrano", :always do
|
|
49
51
|
ENV['BUGSNAG_REVISION'] = "test"
|
50
52
|
ENV['BUGSNAG_APP_VERSION'] = "1"
|
51
53
|
ENV['BUGSNAG_REPOSITORY'] = "test@repo.com:test/test_repo.git"
|
54
|
+
ENV['BUGSNAG_SOURCE_CONTROL_PROVIDER'] = "github"
|
55
|
+
ENV['BUGSNAG_AUTO_ASSIGN_RELEASE'] = 'true'
|
52
56
|
|
53
57
|
Dir.chdir(example_path) do
|
54
58
|
system(exec_string)
|
@@ -57,9 +61,12 @@ describe "bugsnag capistrano", :always do
|
|
57
61
|
payload = request()
|
58
62
|
expect(payload["apiKey"]).to eq('this is a test key')
|
59
63
|
expect(payload["releaseStage"]).to eq('test')
|
60
|
-
expect(payload["repository"]).to eq("test@repo.com:test/test_repo.git")
|
61
64
|
expect(payload["appVersion"]).to eq("1")
|
62
|
-
expect(payload["
|
65
|
+
expect(payload["sourceControl"]).to_not be_nil
|
66
|
+
expect(payload["sourceControl"]["revision"]).to eq("test")
|
67
|
+
expect(payload["sourceControl"]["repository"]).to eq("test@repo.com:test/test_repo.git")
|
68
|
+
expect(payload["sourceControl"]["provider"]).to eq("github")
|
69
|
+
expect(payload["autoAssignRelease"]).to eq(true)
|
63
70
|
end
|
64
71
|
end
|
65
72
|
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'webmock/rspec'
|
2
|
+
require 'rspec/expectations'
|
3
|
+
require 'rspec/mocks'
|
4
|
+
require 'logger'
|
5
|
+
require 'json'
|
6
|
+
|
7
|
+
require 'webrick'
|
8
|
+
|
9
|
+
require 'bugsnag-capistrano/release'
|
10
|
+
|
11
|
+
module Bugsnag::Capistrano
|
12
|
+
class Release
|
13
|
+
attr_accessor :logger
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe Bugsnag::Capistrano::Release do
|
18
|
+
it "should call notify_without bugsnag" do
|
19
|
+
expect(Bugsnag::Capistrano::Release).to receive(:deliver)
|
20
|
+
Bugsnag::Capistrano::Release.notify({:api_key => "test", :app_version => "1"})
|
21
|
+
end
|
22
|
+
|
23
|
+
it "delivers a request to the given url" do
|
24
|
+
url = "http://localhost:56456"
|
25
|
+
stub_request(:post, url)
|
26
|
+
.to_return(status:200, body: "")
|
27
|
+
Bugsnag::Capistrano::Release.deliver(url, nil)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "delivers a body unmodified" do
|
31
|
+
body = ::JSON.dump({
|
32
|
+
"paramA" => 'a',
|
33
|
+
"paramB" => 'b',
|
34
|
+
"paramHash" => {
|
35
|
+
"one" => 1,
|
36
|
+
"two" => 2,
|
37
|
+
"three" => 3
|
38
|
+
}
|
39
|
+
})
|
40
|
+
url = "http://localhost:56456"
|
41
|
+
request = stub_request(:post, url)
|
42
|
+
.with(body: body, headers: { 'Content-Type' => 'application/json'})
|
43
|
+
.to_return(status:200, body: "")
|
44
|
+
Bugsnag::Capistrano::Release.deliver(url, body)
|
45
|
+
assert_requested request
|
46
|
+
end
|
47
|
+
|
48
|
+
it "cannot send without an apikey" do
|
49
|
+
expect(Bugsnag::Capistrano::Release).to_not receive(:deliver)
|
50
|
+
expect(Bugsnag::Capistrano::Release.logger).to receive(:warn).with("Cannot deliver notification. Missing required apiKey")
|
51
|
+
|
52
|
+
Bugsnag::Capistrano::Release.notify()
|
53
|
+
end
|
54
|
+
|
55
|
+
it "cannot send without an appVersion" do
|
56
|
+
expect(Bugsnag::Capistrano::Release).to_not receive(:deliver)
|
57
|
+
expect(Bugsnag::Capistrano::Release.logger).to receive(:warn).with("Cannot deliver notification. Missing required appVersion")
|
58
|
+
|
59
|
+
Bugsnag::Capistrano::Release.notify({:api_key => "test"})
|
60
|
+
end
|
61
|
+
|
62
|
+
context "with bugsnag installed" do
|
63
|
+
before do
|
64
|
+
module Kernel
|
65
|
+
alias_method :old_require, :require
|
66
|
+
def require(path)
|
67
|
+
old_require(path) unless /^bugsnag/.match(path)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
it "gets information from bugsnag configuration if available" do
|
73
|
+
config = double
|
74
|
+
allow(config).to receive(:api_key).and_return("bugsnag_api_key")
|
75
|
+
allow(config).to receive(:app_version).and_return("bugsnag_app_version")
|
76
|
+
allow(config).to receive(:release_stage).and_return("bugsnag_release_stage")
|
77
|
+
|
78
|
+
allow(Bugsnag).to receive(:configuration).and_return(config)
|
79
|
+
expect(Bugsnag::Capistrano::Release).to receive(:deliver) do |uri, body_string|
|
80
|
+
expect(uri).to eq(Bugsnag::Capistrano::Release::DEFAULT_BUILD_ENDPOINT)
|
81
|
+
body = ::JSON.parse(body_string)
|
82
|
+
expect(body["apiKey"]).to eq("bugsnag_api_key")
|
83
|
+
expect(body["appVersion"]).to eq("bugsnag_app_version")
|
84
|
+
expect(body["releaseStage"]).to eq("bugsnag_release_stage")
|
85
|
+
end
|
86
|
+
|
87
|
+
Bugsnag::Capistrano::Release.notify()
|
88
|
+
end
|
89
|
+
|
90
|
+
after do
|
91
|
+
module Kernel
|
92
|
+
alias_method :require, :old_require
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bugsnag-capistrano
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Keegan Lowenstein
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2018-
|
14
|
+
date: 2018-04-03 00:00:00.000000000 Z
|
15
15
|
dependencies: []
|
16
16
|
description: Correlate Capistrano deploys with new errors and increased error rates
|
17
17
|
in Bugsnag
|
@@ -31,18 +31,16 @@ files:
|
|
31
31
|
- LICENSE.txt
|
32
32
|
- README.md
|
33
33
|
- Rakefile
|
34
|
+
- UPGRADING.md
|
34
35
|
- VERSION
|
35
36
|
- bugsnag-capistrano.gemspec
|
36
37
|
- lib/bugsnag-capistrano.rb
|
37
38
|
- lib/bugsnag-capistrano/capistrano.rb
|
38
39
|
- lib/bugsnag-capistrano/capistrano2.rb
|
39
|
-
- lib/bugsnag-capistrano/
|
40
|
-
- lib/bugsnag-capistrano/tasks.rb
|
41
|
-
- lib/bugsnag-capistrano/tasks/bugsnag-capistrano.rake
|
40
|
+
- lib/bugsnag-capistrano/release.rb
|
42
41
|
- lib/bugsnag-capistrano/tasks/bugsnag.cap
|
43
42
|
- spec/capistrano_spec.rb
|
44
|
-
- spec/
|
45
|
-
- spec/rake_spec.rb
|
43
|
+
- spec/release_spec.rb
|
46
44
|
homepage: http://github.com/bugsnag/bugsnag-capistrano
|
47
45
|
licenses:
|
48
46
|
- MIT
|
@@ -63,7 +61,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
63
61
|
version: '0'
|
64
62
|
requirements: []
|
65
63
|
rubyforge_project:
|
66
|
-
rubygems_version: 2.
|
64
|
+
rubygems_version: 2.6.11
|
67
65
|
signing_key:
|
68
66
|
specification_version: 4
|
69
67
|
summary: Notify Bugsnag when deploying with Capistrano
|
@@ -1,98 +0,0 @@
|
|
1
|
-
require "json"
|
2
|
-
require "net/http"
|
3
|
-
require "logger"
|
4
|
-
|
5
|
-
module Bugsnag
|
6
|
-
module Capistrano
|
7
|
-
class Deploy
|
8
|
-
|
9
|
-
HEADERS = {"Content-Type" => "application/json"}
|
10
|
-
DEFAULT_DEPLOY_ENDPOINT = "https://notify.bugsnag.com/deploy"
|
11
|
-
|
12
|
-
def self.notify(opts = {})
|
13
|
-
begin
|
14
|
-
require 'bugsnag'
|
15
|
-
self.notify_using_bugsnag(opts)
|
16
|
-
rescue LoadError
|
17
|
-
self.notify_without_bugsnag(opts)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def self.notify_using_bugsnag(opts = {})
|
22
|
-
|
23
|
-
configuration = Bugsnag.configuration.dup
|
24
|
-
|
25
|
-
[:api_key, :app_version, :release_stage, :endpoint, :use_ssl,
|
26
|
-
:proxy_host, :proxy_port, :proxy_user, :proxy_password].each do |param|
|
27
|
-
unless opts[param].nil?
|
28
|
-
configuration.send :"#{param}=", opts[param]
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
if Gem::Version.new(Bugsnag::VERSION).release >= Gem::Version.new('6.0.0')
|
33
|
-
endpoint = configuration.endpoint + '/deploy'
|
34
|
-
else
|
35
|
-
endpoint = (configuration.use_ssl ? "https://" : "http://") + configuration.endpoint + '/deploy'
|
36
|
-
end
|
37
|
-
|
38
|
-
parameters = {
|
39
|
-
"apiKey" => configuration.api_key,
|
40
|
-
"releaseStage" => configuration.release_stage,
|
41
|
-
"appVersion" => configuration.app_version,
|
42
|
-
"revision" => opts[:revision],
|
43
|
-
"repository" => opts[:repository],
|
44
|
-
"branch" => opts[:branch]
|
45
|
-
}.reject {|k,v| v == nil}
|
46
|
-
|
47
|
-
raise RuntimeError.new("No API key found when notifying of deploy") if !parameters["apiKey"] || parameters["apiKey"].empty?
|
48
|
-
|
49
|
-
|
50
|
-
payload_string = ::JSON.dump(parameters)
|
51
|
-
Bugsnag::Delivery::Synchronous.deliver(endpoint, payload_string, configuration)
|
52
|
-
end
|
53
|
-
|
54
|
-
def self.notify_without_bugsnag(opts = {})
|
55
|
-
endpoint = (opts[:endpoint].nil? ? DEFAULT_DEPLOY_ENDPOINT : opts[:endpoint])
|
56
|
-
|
57
|
-
parameters = {
|
58
|
-
"apiKey" => opts[:api_key],
|
59
|
-
"releaseStage" => opts[:release_stage],
|
60
|
-
"appVersion" => opts[:app_version],
|
61
|
-
"revision" => opts[:revision],
|
62
|
-
"repository" => opts[:repository],
|
63
|
-
"branch" => opts[:branch]
|
64
|
-
}.reject {|k, v| v == nil}
|
65
|
-
|
66
|
-
raise RuntimeError.new("No API key found when notifying of deploy") if !parameters["apiKey"] || parameters["apiKey"].empty?
|
67
|
-
|
68
|
-
payload_string = ::JSON.dump(parameters)
|
69
|
-
self.deliver(endpoint, payload_string)
|
70
|
-
end
|
71
|
-
|
72
|
-
def self.deliver(url, body)
|
73
|
-
logger = Logger.new(STDOUT)
|
74
|
-
logger.level = Logger::INFO
|
75
|
-
begin
|
76
|
-
request(url, body)
|
77
|
-
rescue StandardError => e
|
78
|
-
logger.warn("Notification to #{url} failed, #{e.inspect}")
|
79
|
-
logger.warn(e.backtrace)
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
def self.request(url, body)
|
84
|
-
uri = URI.parse(url)
|
85
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
86
|
-
http.read_timeout = 15
|
87
|
-
http.open_timeout = 15
|
88
|
-
|
89
|
-
http.use_ssl = uri.scheme == "https"
|
90
|
-
|
91
|
-
uri.path == "" ? "/" : uri.path
|
92
|
-
request = Net::HTTP::Post.new(uri, HEADERS)
|
93
|
-
request.body = body
|
94
|
-
http.request(request)
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
@@ -1,85 +0,0 @@
|
|
1
|
-
require "bugsnag-capistrano/deploy"
|
2
|
-
|
3
|
-
namespace :bugsnag do
|
4
|
-
|
5
|
-
desc "Notify Bugsnag of a new deploy."
|
6
|
-
task :deploy do
|
7
|
-
api_key = ENV["BUGSNAG_API_KEY"]
|
8
|
-
release_stage = ENV["BUGSNAG_RELEASE_STAGE"]
|
9
|
-
app_version = ENV["BUGSNAG_APP_VERSION"]
|
10
|
-
revision = ENV["BUGSNAG_REVISION"]
|
11
|
-
repository = ENV["BUGSNAG_REPOSITORY"]
|
12
|
-
branch = ENV["BUGSNAG_BRANCH"]
|
13
|
-
endpoint = ENV["BUGSNAG_ENDPOINT"]
|
14
|
-
|
15
|
-
Rake::Task["load"].invoke unless api_key
|
16
|
-
|
17
|
-
Bugsnag::Capistrano::Deploy.notify({
|
18
|
-
:api_key => api_key,
|
19
|
-
:release_stage => release_stage,
|
20
|
-
:app_version => app_version,
|
21
|
-
:revision => revision,
|
22
|
-
:repository => repository,
|
23
|
-
:branch => branch,
|
24
|
-
:endpoint => endpoint,
|
25
|
-
})
|
26
|
-
end
|
27
|
-
|
28
|
-
namespace :heroku do
|
29
|
-
desc "Add a heroku deploy hook to notify Bugsnag of deploys"
|
30
|
-
task :add_deploy_hook => :load do
|
31
|
-
# Wrapper to run command safely even in bundler
|
32
|
-
run_command = lambda { |command|
|
33
|
-
defined?(Bundler.with_clean_env) ? Bundler.with_clean_env { `#{command}` } : `#{command}`
|
34
|
-
}
|
35
|
-
|
36
|
-
# Fetch heroku config settings
|
37
|
-
config_command = "heroku config --shell"
|
38
|
-
config_command += " --app #{ENV["HEROKU_APP"]}" if ENV["HEROKU_APP"]
|
39
|
-
heroku_env = run_command.call(config_command).split(/[\n\r]/).each_with_object({}) do |c, obj|
|
40
|
-
k,v = c.split("=")
|
41
|
-
obj[k] = (v.nil? || v.strip.empty?) ? nil : v
|
42
|
-
end
|
43
|
-
|
44
|
-
# Check for Bugsnag API key (required) using Bugsnag configuration only if available
|
45
|
-
begin
|
46
|
-
require 'bugsnag'
|
47
|
-
api_key = heroku_env["BUGSNAG_API_KEY"] || Bugsnag.configuration.api_key || ENV["BUGSNAG_API_KEY"]
|
48
|
-
rescue LoadError
|
49
|
-
api_key = heroku_env["BUGSNAG_API_KEY"] || ENV["BUGSNAG_API_KEY"]
|
50
|
-
end
|
51
|
-
|
52
|
-
unless api_key
|
53
|
-
puts "Error: No API key found, have you run 'heroku config:set BUGSNAG_API_KEY=your-api-key'?"
|
54
|
-
next
|
55
|
-
end
|
56
|
-
|
57
|
-
# Build the request, making use of deploy hook variables
|
58
|
-
# (https://devcenter.heroku.com/articles/deploy-hooks#customizing-messages)
|
59
|
-
params = {
|
60
|
-
:apiKey => api_key,
|
61
|
-
:branch => "master",
|
62
|
-
:revision => "{{head_long}}",
|
63
|
-
:releaseStage => heroku_env["BUGSNAG_RELEASE_STAGE"] || heroku_env["RAILS_ENV"] || ENV["RAILS_ENV"] || "production"
|
64
|
-
}
|
65
|
-
repo = `git config --get remote.origin.url`.strip
|
66
|
-
params[:repository] = repo unless repo.empty?
|
67
|
-
|
68
|
-
# Add the hook
|
69
|
-
url = "https://notify.bugsnag.com/deploy?" + params.map {|k,v| "#{k}=#{v}"}.join("&")
|
70
|
-
command = "heroku addons:add deployhooks:http --url=\"#{url}\""
|
71
|
-
command += " --app #{ENV["HEROKU_APP"]}" if ENV["HEROKU_APP"]
|
72
|
-
|
73
|
-
puts "$ #{command}"
|
74
|
-
run_command.call(command)
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
end
|
79
|
-
|
80
|
-
task :load do
|
81
|
-
begin
|
82
|
-
Rake::Task["environment"].invoke
|
83
|
-
rescue
|
84
|
-
end
|
85
|
-
end
|
data/spec/deploy_spec.rb
DELETED
@@ -1,97 +0,0 @@
|
|
1
|
-
require 'webmock/rspec'
|
2
|
-
require 'rspec/expectations'
|
3
|
-
require 'rspec/mocks'
|
4
|
-
require 'logger'
|
5
|
-
require 'json'
|
6
|
-
|
7
|
-
require 'webrick'
|
8
|
-
|
9
|
-
require 'bugsnag-capistrano/deploy'
|
10
|
-
|
11
|
-
describe Bugsnag::Capistrano::Deploy do
|
12
|
-
describe "with notifier loadable", :with_notifier do
|
13
|
-
|
14
|
-
before do
|
15
|
-
require "bugsnag"
|
16
|
-
Bugsnag.configure do |config|
|
17
|
-
config.api_key = "TEST_API_KEY"
|
18
|
-
config.release_stage = "production"
|
19
|
-
config.logger = Logger.new(StringIO.new)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
after do
|
24
|
-
Bugsnag.configuration.clear_request_data
|
25
|
-
end
|
26
|
-
|
27
|
-
it "should call notify_with_bugsnag" do
|
28
|
-
expect(Bugsnag::Delivery::Synchronous).to receive(:deliver).with(
|
29
|
-
"https://notify.bugsnag.com/deploy",
|
30
|
-
"{\"apiKey\":\"TEST_API_KEY\",\"releaseStage\":\"production\"}",
|
31
|
-
instance_of(Bugsnag::Configuration)
|
32
|
-
)
|
33
|
-
Bugsnag::Capistrano::Deploy.notify()
|
34
|
-
end
|
35
|
-
|
36
|
-
context "provide custom endpoint" do
|
37
|
-
before do
|
38
|
-
Bugsnag.configure do |config|
|
39
|
-
config.endpoint = "http://localhost:56302"
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
after do
|
44
|
-
Bugsnag.configure do |config|
|
45
|
-
config.endpoint = nil
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
it "uses the custom endpoint" do
|
50
|
-
expect(Bugsnag::Delivery::Synchronous).to receive(:deliver).with(
|
51
|
-
"http://localhost:56302/deploy",
|
52
|
-
"{\"apiKey\":\"TEST_API_KEY\",\"releaseStage\":\"production\"}",
|
53
|
-
instance_of(Bugsnag::Configuration)
|
54
|
-
)
|
55
|
-
Bugsnag::Capistrano::Deploy.notify()
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
describe "without notifier loadable", :without_notifier do
|
61
|
-
it "should call notify_without bugsnag" do
|
62
|
-
stub_request(:post, "https://notify.bugsnag.com/deploy").to_return(status:200, body: "")
|
63
|
-
expect(Bugsnag::Capistrano::Deploy).to receive(:deliver).with(
|
64
|
-
"https://notify.bugsnag.com/deploy",
|
65
|
-
"{\"apiKey\":\"test\"}"
|
66
|
-
)
|
67
|
-
Bugsnag::Capistrano::Deploy.notify({:api_key => "test"})
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
describe "the delivery function", :always do
|
72
|
-
it "delivers a request to the given url" do
|
73
|
-
url = "http://localhost:56456"
|
74
|
-
stub_request(:post, url)
|
75
|
-
.to_return(status:200, body: "")
|
76
|
-
Bugsnag::Capistrano::Deploy.deliver(url, nil)
|
77
|
-
end
|
78
|
-
|
79
|
-
it "delivers a body unmodified" do
|
80
|
-
body = ::JSON.dump({
|
81
|
-
"paramA" => 'a',
|
82
|
-
"paramB" => 'b',
|
83
|
-
"paramHash" => {
|
84
|
-
"one" => 1,
|
85
|
-
"two" => 2,
|
86
|
-
"three" => 3
|
87
|
-
}
|
88
|
-
})
|
89
|
-
url = "http://localhost:56456"
|
90
|
-
request = stub_request(:post, url)
|
91
|
-
.with(body: body, headers: { 'Content-Type' => 'application/json'})
|
92
|
-
.to_return(status:200, body: "")
|
93
|
-
Bugsnag::Capistrano::Deploy.deliver(url, body)
|
94
|
-
assert_requested request
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
data/spec/rake_spec.rb
DELETED
@@ -1,64 +0,0 @@
|
|
1
|
-
require 'webmock/rspec'
|
2
|
-
require 'rspec/expectations'
|
3
|
-
require 'rspec/mocks'
|
4
|
-
|
5
|
-
require 'webrick'
|
6
|
-
|
7
|
-
describe "bugsnag rake", :always do
|
8
|
-
|
9
|
-
server = nil
|
10
|
-
queue = Queue.new
|
11
|
-
fixture_path = '../examples/rake'
|
12
|
-
exec_string = 'bundle exec rake bugsnag:deploy'
|
13
|
-
example_path = File.join(File.dirname(__FILE__), fixture_path)
|
14
|
-
|
15
|
-
before do
|
16
|
-
server = WEBrick::HTTPServer.new :Port => 0, :Logger => WEBrick::Log.new(STDOUT), :AccessLog => []
|
17
|
-
server.mount_proc '/deploy' do |req, res|
|
18
|
-
queue.push req.body
|
19
|
-
res.status = 200
|
20
|
-
res.body = "OK\n"
|
21
|
-
end
|
22
|
-
Thread.new{ server.start }
|
23
|
-
end
|
24
|
-
|
25
|
-
after do
|
26
|
-
server.stop
|
27
|
-
queue.clear
|
28
|
-
end
|
29
|
-
|
30
|
-
let(:request) { JSON.parse(queue.pop) }
|
31
|
-
|
32
|
-
it "sends a deploy notification to the set endpoint" do
|
33
|
-
ENV['BUGSNAG_ENDPOINT'] = "http://localhost:" + server.config[:Port].to_s + "/deploy"
|
34
|
-
ENV['BUGSNAG_API_KEY'] = "YOUR_API_KEY"
|
35
|
-
|
36
|
-
Dir.chdir(example_path) do
|
37
|
-
system(exec_string)
|
38
|
-
end
|
39
|
-
|
40
|
-
payload = request()
|
41
|
-
expect(payload["apiKey"]).to eq('YOUR_API_KEY')
|
42
|
-
end
|
43
|
-
|
44
|
-
it "allows modifications of deployment characteristics" do
|
45
|
-
ENV['BUGSNAG_ENDPOINT'] = "http://localhost:" + server.config[:Port].to_s + "/deploy"
|
46
|
-
ENV['BUGSNAG_API_KEY'] = "this is a test key"
|
47
|
-
ENV['BUGSNAG_RELEASE_STAGE'] = "test"
|
48
|
-
ENV['BUGSNAG_REVISION'] = "test"
|
49
|
-
ENV['BUGSNAG_APP_VERSION'] = "1"
|
50
|
-
ENV['BUGSNAG_REPOSITORY'] = "test@repo.com:test/test_repo.git"
|
51
|
-
|
52
|
-
Dir.chdir(example_path) do
|
53
|
-
system(exec_string)
|
54
|
-
end
|
55
|
-
|
56
|
-
payload = request()
|
57
|
-
expect(payload["apiKey"]).to eq('this is a test key')
|
58
|
-
expect(payload["releaseStage"]).to eq('test')
|
59
|
-
expect(payload["repository"]).to eq("test@repo.com:test/test_repo.git")
|
60
|
-
expect(payload["appVersion"]).to eq("1")
|
61
|
-
expect(payload["revision"]).to eq("test")
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|