datadog-ci 0.3.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ce3b4502404f6faa6b05421763ced6582071c9ad025937219b59ba8c63c39175
4
- data.tar.gz: 7a341aa75161299cb04a29f745e172ef5ca4fec3a24f536ec96e08119de11a97
3
+ metadata.gz: ce9361bb71547db2fcf5e1798e5a7d2984bdad921b966b25a0ca593707a6a416
4
+ data.tar.gz: a4459f627e99c32d6bd90291dde6d02a7b7101bf7557a5848b0e007e2c42b649
5
5
  SHA512:
6
- metadata.gz: 6058fbf497f43040a588018a2104055a303849d5616d063412dae4dab1e5247098e9ecd1b0b718776a51bc090f137d2bcf19cc78d252c7968c9cd6e4723ad902
7
- data.tar.gz: 3c8d8eb9a34266a690a0dd5103d344b80df5175c703a414b1bc8255dc3c2732d723960e786765f2686fdcaaff5f009b675942c5e39dbd4a6fc9e58a38653051e
6
+ metadata.gz: 458b2167df9899f700d0c64b107f96aa65108f5baa184b1d28cfd43ecd942b0a5669d84f376cdae00f4b6a2c0d86d54512d67325252197d9d7820a11de2c4e0f
7
+ data.tar.gz: 1f9fbcae386aaea7459ea15c66f30fbb9a3f4b9dbcc2e626d632f33e53fe634595669770d6b6bf0acfa6b5c84b652716071c438ad6214252836ba58298aa0727
data/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.4.1] - 2023-11-22
4
+
5
+ ### Fixed
6
+
7
+ * disable 128-bit trace id generation in CI mode ([#70][])
8
+
9
+ ## [0.4.0] - 2023-11-21
10
+
11
+ ### Added
12
+
13
+ * Public API for manual test instrumentation ([#64][]) ([#61][])
14
+
15
+ ### Changed
16
+
17
+ * fix tracing instrumentation example in readme ([#60][])
18
+
19
+ ### Fixed
20
+
21
+ * Remove user credentials from ssh URLs and from GITHUB_REPO_URL environment variable ([#66][])
22
+
23
+ ### Removed
24
+
25
+ * Remove _dd.measured tag from spans ([#65][])
26
+
3
27
  ## [0.3.0] - 2023-10-25
4
28
 
5
29
  ### Added
@@ -47,7 +71,9 @@
47
71
 
48
72
  * Ruby versions < 2.7 no longer supported ([#8][])
49
73
 
50
- [Unreleased]: https://github.com/DataDog/datadog-ci-rb/compare/v0.3.0...main
74
+ [Unreleased]: https://github.com/DataDog/datadog-ci-rb/compare/v0.4.1...main
75
+ [0.4.1]: https://github.com/DataDog/datadog-ci-rb/compare/v0.4.0...v0.4.1
76
+ [0.4.0]: https://github.com/DataDog/datadog-ci-rb/compare/v0.3.0...v0.4.0
51
77
  [0.3.0]: https://github.com/DataDog/datadog-ci-rb/compare/v0.2.0...v0.3.0
52
78
  [0.2.0]: https://github.com/DataDog/datadog-ci-rb/compare/v0.1.1...v0.2.0
53
79
  [0.1.1]: https://github.com/DataDog/datadog-ci-rb/compare/v0.1.0...v0.1.1
@@ -66,3 +92,9 @@
66
92
  [#49]: https://github.com/DataDog/datadog-ci-rb/issues/49
67
93
  [#51]: https://github.com/DataDog/datadog-ci-rb/issues/51
68
94
  [#54]: https://github.com/DataDog/datadog-ci-rb/issues/54
95
+ [#60]: https://github.com/DataDog/datadog-ci-rb/issues/60
96
+ [#61]: https://github.com/DataDog/datadog-ci-rb/issues/61
97
+ [#64]: https://github.com/DataDog/datadog-ci-rb/issues/64
98
+ [#65]: https://github.com/DataDog/datadog-ci-rb/issues/65
99
+ [#66]: https://github.com/DataDog/datadog-ci-rb/issues/66
100
+ [#70]: https://github.com/DataDog/datadog-ci-rb/issues/70
data/README.md CHANGED
@@ -30,18 +30,18 @@ To activate `RSpec` integration, add this to the `spec_helper.rb` file:
30
30
  require 'rspec'
31
31
  require 'datadog/ci'
32
32
 
33
- Datadog.configure do |c|
34
- # Only activates test instrumentation on CI
35
- c.tracing.enabled = (ENV["DD_ENV"] == "ci")
36
-
37
- # Configures the tracer to ensure results delivery
38
- c.ci.enabled = true
39
-
40
- # The name of the service or library under test
41
- c.service = 'my-ruby-app'
42
-
43
- # Enables the RSpec instrumentation
44
- c.ci.instrument :rspec, **options
33
+ # Only activates test instrumentation on CI
34
+ if ENV["DD_ENV"] == "ci"
35
+ Datadog.configure do |c|
36
+ # Configures the tracer to ensure results delivery
37
+ c.ci.enabled = true
38
+
39
+ # The name of the service or library under test
40
+ c.service = 'my-ruby-app'
41
+
42
+ # Enables the RSpec instrumentation
43
+ c.ci.instrument :rspec, **options
44
+ end
45
45
  end
46
46
  ```
47
47
 
@@ -51,7 +51,7 @@ end
51
51
  | --- | ----------- | ------- |
52
52
  | `enabled` | Defines whether RSpec tests should be traced. Useful for temporarily disabling tracing. `true` or `false` | `true` |
53
53
  | `service_name` | Service name used for `rspec` instrumentation. | `'rspec'` |
54
- | `operation_name` | Operation name used for `rspec` instrumentation. Useful if you want rename automatic trace metrics e.g. `trace.#{operation_name}.errors`. | `'rspec.example'` |
54
+ | `operation_name` | Operation name used for `rspec` instrumentation. | `'rspec.example'` |
55
55
 
56
56
  ### Minitest
57
57
 
@@ -63,18 +63,18 @@ To activate your integration, use the `Datadog.configure` method:
63
63
  require 'minitest'
64
64
  require 'datadog/ci'
65
65
 
66
+ # Only activates test instrumentation on CI
67
+ if ENV["DD_ENV"] == "ci"
66
68
  # Configure default Minitest integration
67
- Datadog.configure do |c|
68
- # Only activates test instrumentation on CI
69
- c.tracing.enabled = (ENV["DD_ENV"] == "ci")
70
-
71
- # Configures the tracer to ensure results delivery
72
- c.ci.enabled = true
69
+ Datadog.configure do |c|
70
+ # Configures the tracer to ensure results delivery
71
+ c.ci.enabled = true
73
72
 
74
- # The name of the service or library under test
75
- c.service = 'my-ruby-app'
73
+ # The name of the service or library under test
74
+ c.service = 'my-ruby-app'
76
75
 
77
- c.ci.instrument :minitest, **options
76
+ c.ci.instrument :minitest, **options
77
+ end
78
78
  end
79
79
  ```
80
80
 
@@ -84,7 +84,7 @@ end
84
84
  | --- | ----------- | ------- |
85
85
  | `enabled` | Defines whether Minitest tests should be traced. Useful for temporarily disabling tracing. `true` or `false` | `true` |
86
86
  | `service_name` | Service name used for `minitest` instrumentation. | `'minitest'` |
87
- | `operation_name` | Operation name used for `minitest` instrumentation. Useful if you want rename automatic trace metrics e.g. `trace.#{operation_name}.errors`. | `'minitest.test'` |
87
+ | `operation_name` | Operation name used for `minitest` instrumentation. | `'minitest.test'` |
88
88
 
89
89
  ### Cucumber
90
90
 
@@ -94,18 +94,18 @@ Activate `Cucumber` integration with configuration
94
94
  require 'cucumber'
95
95
  require 'datadog/ci'
96
96
 
97
- Datadog.configure do |c|
98
- # Only activates test instrumentation on CI
99
- c.tracing.enabled = (ENV["DD_ENV"] == "ci")
100
-
101
- # Configures the tracer to ensure results delivery
102
- c.ci.enabled = true
97
+ # Only activates test instrumentation on CI
98
+ if ENV["DD_ENV"] == "ci"
99
+ Datadog.configure do |c|
100
+ # Configures the tracer to ensure results delivery
101
+ c.ci.enabled = true
103
102
 
104
- # The name of the service or library under test
105
- c.service = 'my-ruby-app'
103
+ # The name of the service or library under test
104
+ c.service = 'my-ruby-app'
106
105
 
107
- # Enables the Cucumber instrumentation
108
- c.ci.instrument :cucumber, **options
106
+ # Enables the Cucumber instrumentation
107
+ c.ci.instrument :cucumber, **options
108
+ end
109
109
  end
110
110
  ```
111
111
 
@@ -115,7 +115,7 @@ end
115
115
  | --- | ----------- | ------- |
116
116
  | `enabled` | Defines whether Cucumber tests should be traced. Useful for temporarily disabling tracing. `true` or `false` | `true` |
117
117
  | `service_name` | Service name used for `cucumber` instrumentation. | `'cucumber'` |
118
- | `operation_name` | Operation name used for `cucumber` instrumentation. Useful if you want rename automatic trace metrics e.g. `trace.#{operation_name}.errors`. | `'cucumber.test'` |
118
+ | `operation_name` | Operation name used for `cucumber` instrumentation. | `'cucumber.test'` |
119
119
 
120
120
  ## Agentless mode
121
121
 
@@ -145,8 +145,8 @@ In order to achieve this you can configure ddtrace instrumentations in your conf
145
145
  ```ruby
146
146
  Datadog.configure do |c|
147
147
  # ... ci configs and instrumentation here ...
148
- c.instrument :redis
149
- c.instrument :pg
148
+ c.tracing.instrument :redis
149
+ c.tracing.instrument :pg
150
150
  end
151
151
  ```
152
152
 
@@ -7,12 +7,15 @@ require_relative "../ext/transport"
7
7
  require_relative "../test_visibility/flush"
8
8
  require_relative "../test_visibility/transport"
9
9
  require_relative "../transport/api/builder"
10
+ require_relative "../recorder"
10
11
 
11
12
  module Datadog
12
13
  module CI
13
14
  module Configuration
14
15
  # Adds CI behavior to Datadog trace components
15
16
  module Components
17
+ attr_reader :ci_recorder
18
+
16
19
  def initialize(settings)
17
20
  # Activate CI mode if enabled
18
21
  activate_ci!(settings) if settings.ci.enabled
@@ -37,6 +40,10 @@ module Datadog
37
40
  # Deactivate remote configuration
38
41
  settings.remote.enabled = false
39
42
 
43
+ # do not use 128-bit trace ids for CI visibility
44
+ # they are used for OTEL compatibility in Datadog tracer
45
+ settings.tracing.trace_id_128_bit_generation_enabled = false
46
+
40
47
  # Activate underlying tracing test mode
41
48
  settings.tracing.test_mode.enabled = true
42
49
 
@@ -52,6 +59,8 @@ module Datadog
52
59
  end
53
60
 
54
61
  settings.tracing.test_mode.writer_options = writer_options
62
+
63
+ @ci_recorder = Recorder.new
55
64
  end
56
65
 
57
66
  def can_use_evp_proxy?(settings, agent_settings)
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module CI
5
+ module Context
6
+ class Local
7
+ def initialize
8
+ @key = :datadog_ci_active_test
9
+
10
+ self.active_test = nil
11
+ end
12
+
13
+ def activate_test!(test)
14
+ raise "Nested tests are not supported. Currently active test: #{active_test}" unless active_test.nil?
15
+
16
+ if block_given?
17
+ begin
18
+ self.active_test = test
19
+ yield
20
+ ensure
21
+ self.active_test = nil
22
+ end
23
+ else
24
+ self.active_test = test
25
+ end
26
+ end
27
+
28
+ def deactivate_test!(test)
29
+ return if active_test.nil?
30
+
31
+ if active_test == test
32
+ self.active_test = nil
33
+ else
34
+ raise "Trying to deactivate test #{test}, but currently active test is #{active_test}"
35
+ end
36
+ end
37
+
38
+ def active_test
39
+ Thread.current[@key]
40
+ end
41
+
42
+ private
43
+
44
+ def active_test=(test)
45
+ Thread.current[@key] = test
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../../recorder"
4
3
  require_relative "../../ext/test"
5
4
  require_relative "ext"
6
5
 
@@ -28,56 +27,51 @@ module Datadog
28
27
  end
29
28
 
30
29
  def on_test_case_started(event)
31
- @current_feature_span = CI::Recorder.trace(
32
- configuration[:operation_name],
33
- {
34
- span_options: {
35
- resource: event.test_case.name,
36
- service: configuration[:service_name]
37
- },
38
- framework: Ext::FRAMEWORK,
39
- framework_version: CI::Contrib::Cucumber::Integration.version.to_s,
40
- test_name: event.test_case.name,
41
- test_suite: event.test_case.location.file,
42
- test_type: Ext::TEST_TYPE
43
- }
30
+ CI.start_test(
31
+ event.test_case.name,
32
+ tags: {
33
+ CI::Ext::Test::TAG_FRAMEWORK => Ext::FRAMEWORK,
34
+ CI::Ext::Test::TAG_FRAMEWORK_VERSION => CI::Contrib::Cucumber::Integration.version.to_s,
35
+ CI::Ext::Test::TAG_TYPE => Ext::TEST_TYPE,
36
+ CI::Ext::Test::TAG_SUITE => event.test_case.location.file
37
+ },
38
+ service_name: configuration[:service_name],
39
+ operation_name: configuration[:operation_name]
44
40
  )
45
41
  end
46
42
 
47
43
  def on_test_case_finished(event)
48
- return if @current_feature_span.nil?
44
+ test_span = CI.active_test
45
+ return if test_span.nil?
49
46
 
50
47
  if event.result.skipped?
51
- CI::Recorder.skipped!(@current_feature_span)
48
+ test_span.skipped!
52
49
  elsif event.result.ok?
53
- CI::Recorder.passed!(@current_feature_span)
50
+ test_span.passed!
54
51
  elsif event.result.failed?
55
- CI::Recorder.failed!(@current_feature_span)
52
+ test_span.failed!
56
53
  end
57
54
 
58
- @current_feature_span.finish
55
+ test_span.finish
59
56
  end
60
57
 
61
58
  def on_test_step_started(event)
62
- trace_options = {
63
- resource: event.test_step.to_s,
64
- span_type: Ext::STEP_SPAN_TYPE
65
- }
66
- @current_step_span = Tracing.trace(Ext::STEP_SPAN_TYPE, **trace_options)
59
+ CI.trace(Ext::STEP_SPAN_TYPE, event.test_step.to_s)
67
60
  end
68
61
 
69
62
  def on_test_step_finished(event)
70
- return if @current_step_span.nil?
63
+ current_step_span = CI.active_span(Ext::STEP_SPAN_TYPE)
64
+ return if current_step_span.nil?
71
65
 
72
66
  if event.result.skipped?
73
- CI::Recorder.skipped!(@current_step_span, event.result.exception)
67
+ current_step_span.skipped!
74
68
  elsif event.result.ok?
75
- CI::Recorder.passed!(@current_step_span)
69
+ current_step_span.passed!
76
70
  elsif event.result.failed?
77
- CI::Recorder.failed!(@current_step_span, event.result.exception)
71
+ current_step_span.failed!(exception: event.result.exception)
78
72
  end
79
73
 
80
- @current_step_span.finish
74
+ current_step_span.finish
81
75
  end
82
76
 
83
77
  private
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../../recorder"
4
3
  require_relative "../../ext/test"
5
4
  require_relative "ext"
6
5
 
@@ -19,41 +18,33 @@ module Datadog
19
18
  path, = method(name).source_location
20
19
  test_suite = Pathname.new(path.to_s).relative_path_from(Pathname.pwd).to_s
21
20
 
22
- span = CI::Recorder.trace(
23
- configuration[:operation_name],
24
- {
25
- span_options: {
26
- resource: test_name,
27
- service: configuration[:service_name]
28
- },
29
- framework: Ext::FRAMEWORK,
30
- framework_version: CI::Contrib::Minitest::Integration.version.to_s,
31
- test_name: test_name,
32
- test_suite: test_suite,
33
- test_type: Ext::TEST_TYPE
34
- }
21
+ CI.start_test(
22
+ test_name,
23
+ tags: {
24
+ CI::Ext::Test::TAG_FRAMEWORK => Ext::FRAMEWORK,
25
+ CI::Ext::Test::TAG_FRAMEWORK_VERSION => CI::Contrib::Minitest::Integration.version.to_s,
26
+ CI::Ext::Test::TAG_TYPE => Ext::TEST_TYPE,
27
+ CI::Ext::Test::TAG_SUITE => test_suite
28
+ },
29
+ service_name: configuration[:service_name],
30
+ operation_name: configuration[:operation_name]
35
31
  )
36
-
37
- Thread.current[:_datadog_test_span] = span
38
32
  end
39
33
 
40
34
  def after_teardown
41
- span = Thread.current[:_datadog_test_span]
42
- return super unless span
43
-
44
- Thread.current[:_datadog_test_span] = nil
35
+ test_span = CI.active_test
36
+ return super unless test_span
45
37
 
46
38
  case result_code
47
39
  when "."
48
- CI::Recorder.passed!(span)
40
+ test_span.passed!
49
41
  when "E", "F"
50
- CI::Recorder.failed!(span, failure)
42
+ test_span.failed!(exception: failure)
51
43
  when "S"
52
- CI::Recorder.skipped!(span)
53
- span.set_tag(CI::Ext::Test::TAG_SKIP_REASON, failure.message)
44
+ test_span.skipped!(reason: failure.message)
54
45
  end
55
46
 
56
- span.finish
47
+ test_span.finish
57
48
 
58
49
  super
59
50
  end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../../recorder"
4
3
  require_relative "../../ext/test"
5
4
  require_relative "ext"
6
5
 
@@ -25,29 +24,26 @@ module Datadog
25
24
  test_name += " #{description}"
26
25
  end
27
26
 
28
- CI::Recorder.trace(
29
- configuration[:operation_name],
30
- {
31
- span_options: {
32
- resource: test_name,
33
- service: configuration[:service_name]
34
- },
35
- framework: Ext::FRAMEWORK,
36
- framework_version: CI::Contrib::RSpec::Integration.version.to_s,
37
- test_name: test_name,
38
- test_suite: metadata[:example_group][:file_path],
39
- test_type: Ext::TEST_TYPE
40
- }
41
- ) do |span|
27
+ CI.trace_test(
28
+ test_name,
29
+ tags: {
30
+ CI::Ext::Test::TAG_FRAMEWORK => Ext::FRAMEWORK,
31
+ CI::Ext::Test::TAG_FRAMEWORK_VERSION => CI::Contrib::RSpec::Integration.version.to_s,
32
+ CI::Ext::Test::TAG_TYPE => Ext::TEST_TYPE,
33
+ CI::Ext::Test::TAG_SUITE => metadata[:example_group][:file_path]
34
+ },
35
+ service_name: configuration[:service_name],
36
+ operation_name: configuration[:operation_name]
37
+ ) do |test_span|
42
38
  result = super
43
39
 
44
40
  case execution_result.status
45
41
  when :passed
46
- CI::Recorder.passed!(span)
42
+ test_span.passed!
47
43
  when :failed
48
- CI::Recorder.failed!(span, execution_result.exception)
44
+ test_span.failed!(exception: execution_result.exception)
49
45
  else
50
- CI::Recorder.skipped!(span, execution_result.exception) if execution_result.example_skipped?
46
+ test_span.skipped!(exception: execution_result.exception) if execution_result.example_skipped?
51
47
  end
52
48
 
53
49
  result
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative "../git"
4
4
  require_relative "../../utils/git"
5
+ require_relative "../../utils/url"
5
6
  require_relative "providers"
6
7
 
7
8
  module Datadog
@@ -68,14 +69,14 @@ module Datadog
68
69
 
69
70
  def normalize_git!
70
71
  branch_ref = @tags[Git::TAG_BRANCH]
71
- if Datadog::CI::Utils::Git.is_git_tag?(branch_ref)
72
+ if Utils::Git.is_git_tag?(branch_ref)
72
73
  @tags[Git::TAG_TAG] = branch_ref
73
74
  @tags.delete(Git::TAG_BRANCH)
74
75
  end
75
76
 
76
- @tags[Git::TAG_TAG] = Datadog::CI::Utils::Git.normalize_ref(@tags[Git::TAG_TAG])
77
- @tags[Git::TAG_BRANCH] = Datadog::CI::Utils::Git.normalize_ref(@tags[Git::TAG_BRANCH])
78
- @tags[Git::TAG_REPOSITORY_URL] = filter_sensitive_info(
77
+ @tags[Git::TAG_TAG] = Utils::Git.normalize_ref(@tags[Git::TAG_TAG])
78
+ @tags[Git::TAG_BRANCH] = Utils::Git.normalize_ref(@tags[Git::TAG_BRANCH])
79
+ @tags[Git::TAG_REPOSITORY_URL] = Utils::Url.filter_sensitive_info(
79
80
  @tags[Git::TAG_REPOSITORY_URL]
80
81
  )
81
82
  end
@@ -87,12 +88,6 @@ module Datadog
87
88
  @tags[TAG_WORKSPACE_PATH] = File.expand_path(workspace_path)
88
89
  end
89
90
  end
90
-
91
- def filter_sensitive_info(url)
92
- return nil if url.nil?
93
-
94
- url.gsub(%r{(https?://)[^/]*@}, '\1')
95
- end
96
91
  end
97
92
  end
98
93
  end
@@ -3,6 +3,7 @@
3
3
  require "json"
4
4
 
5
5
  require_relative "base"
6
+ require_relative "../../../utils/url"
6
7
 
7
8
  module Datadog
8
9
  module CI
@@ -25,7 +26,7 @@ module Datadog
25
26
  end
26
27
 
27
28
  def job_url
28
- "#{env["GITHUB_SERVER_URL"]}/#{env["GITHUB_REPOSITORY"]}/commit/#{env["GITHUB_SHA"]}/checks"
29
+ "#{github_server_url}/#{env["GITHUB_REPOSITORY"]}/commit/#{env["GITHUB_SHA"]}/checks"
29
30
  end
30
31
 
31
32
  def pipeline_id
@@ -41,7 +42,7 @@ module Datadog
41
42
  end
42
43
 
43
44
  def pipeline_url
44
- res = "#{env["GITHUB_SERVER_URL"]}/#{env["GITHUB_REPOSITORY"]}/actions/runs/#{env["GITHUB_RUN_ID"]}"
45
+ res = "#{github_server_url}/#{env["GITHUB_REPOSITORY"]}/actions/runs/#{env["GITHUB_RUN_ID"]}"
45
46
  res = "#{res}/attempts/#{env["GITHUB_RUN_ATTEMPT"]}" if env["GITHUB_RUN_ATTEMPT"]
46
47
  res
47
48
  end
@@ -51,7 +52,7 @@ module Datadog
51
52
  end
52
53
 
53
54
  def git_repository_url
54
- "#{env["GITHUB_SERVER_URL"]}/#{env["GITHUB_REPOSITORY"]}.git"
55
+ "#{github_server_url}/#{env["GITHUB_REPOSITORY"]}.git"
55
56
  end
56
57
 
57
58
  def git_commit_sha
@@ -66,12 +67,20 @@ module Datadog
66
67
 
67
68
  def ci_env_vars
68
69
  {
69
- "GITHUB_SERVER_URL" => env["GITHUB_SERVER_URL"],
70
+ "GITHUB_SERVER_URL" => github_server_url,
70
71
  "GITHUB_REPOSITORY" => env["GITHUB_REPOSITORY"],
71
72
  "GITHUB_RUN_ID" => env["GITHUB_RUN_ID"],
72
73
  "GITHUB_RUN_ATTEMPT" => env["GITHUB_RUN_ATTEMPT"]
73
74
  }.reject { |_, v| v.nil? }.to_json
74
75
  end
76
+
77
+ private
78
+
79
+ def github_server_url
80
+ return @github_server_url if defined?(@github_server_url)
81
+
82
+ @github_server_url ||= Utils::Url.filter_sensitive_info(env["GITHUB_SERVER_URL"])
83
+ end
75
84
  end
76
85
  end
77
86
  end