appsignal-sourcemap 1.2.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 7d2fe58d1cb99d73781c8cd4c78f96521fc579a2ad65c3a22b93d514db32db26
4
+ data.tar.gz: b8e192b02d922890abb3b0d50994aa9ee4a9e26445d50b4beaf89310c6aef8b2
5
+ SHA512:
6
+ metadata.gz: fba417e39238ebcd339d60cf892b654bd71952bde0a76ab81b22e32ab5d98f3a48e6640422d7e16ed1442d9fca7aae06fdfcbddcbdfb80d97d05edf85796093c
7
+ data.tar.gz: fd9d1a66896f5880af43c5948b52f25aad637f03934db008b7754481de2075da5fa7c32cc72d78a21f4eec7dfd45894d937d562b2227977886dccdc3d45375da
data/README.md ADDED
@@ -0,0 +1,30 @@
1
+ # Appsignal Sourcemaps
2
+ This ruby gem uploads (private) sourcemaps to Appsignal using the [Sourcemaps API](https://docs.appsignal.com/api/sourcemaps.html).
3
+
4
+ ## Installation
5
+ To start using this gem, add it to the `Gemfile` of your application:
6
+ ```ruby
7
+ source 'https://rubygems.pkg.github.com/drieam' do
8
+ gem 'appsignal-sourcemap'
9
+ end
10
+ ```
11
+ After running `bundle install` you should enable the gem by adding `upload_sourcemaps: true` to your `config/appsignal.yml` file:
12
+
13
+ ```yaml
14
+ default:
15
+ upload_sourcemaps: true
16
+ ```
17
+
18
+ Also ensure that your `Rails.application.config.asset_host` is setup correctly since that is used to define the full URL of the assets.
19
+ The gem then uploads the sourcemaps after the `assets:precompile` rake task.
20
+ It searches for all `.map` files within the `Rails.public_path` directory.
21
+
22
+ ### Heroku
23
+ When building on heroku, make sure you set the revision based on the `SOURCE_VERSION` environment variable. This variable is set during the build phase and will be equal to the `HEROKU_SLUG_COMMIT` revision on runtime. Note that you should have [heroku dyno metadata](https://devcenter.heroku.com/articles/dyno-metadata) enabled.
24
+ ```yaml
25
+ default:
26
+ revision: "<%= ENV['SOURCE_VERSION'] || ENV.fetch('HEROKU_SLUG_COMMIT', 'unknown') %>"
27
+ ```
28
+
29
+ ## Publishing a new version
30
+ The [publish workflow](.github/workflows/publish.yml) listens to a new release in GitHub.
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "appsignal/hooks"
4
+
5
+ module Appsignal
6
+ module Sourcemap
7
+ class SourcemapHook < Appsignal::Hooks::Hook
8
+ register :sourcemap
9
+
10
+ def dependencies_present?
11
+ defined?(::Rails) &&
12
+ defined?(::Rake::Task) &&
13
+ Rake::Task.task_defined?("assets:precompile") &&
14
+ Appsignal.config &&
15
+ Appsignal.config[:upload_sourcemaps]
16
+ end
17
+
18
+ def install
19
+ require "appsignal/sourcemap/supervisor"
20
+
21
+ Rake::Task["assets:precompile"].enhance do
22
+ Appsignal::Sourcemap::Supervisor.start
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "parallel"
4
+ require "appsignal/sourcemap/uploader"
5
+
6
+ module Appsignal
7
+ module Sourcemap
8
+ class Supervisor
9
+ PARALLEL_THREADS = 10
10
+
11
+ def self.start
12
+ new.start
13
+ end
14
+
15
+ def start
16
+ return if invalid_preconditions
17
+
18
+ Rails.logger.info("Starting sourcemaps upload")
19
+
20
+ Parallel.each(source_map_paths, in_threads: PARALLEL_THREADS) do |source_map_path|
21
+ Uploader.upload(source_map_path)
22
+ end
23
+
24
+ Rails.logger.info("Finished sourcemaps upload")
25
+ end
26
+
27
+ private
28
+
29
+ def invalid_preconditions
30
+ unless Appsignal.config.valid?
31
+ return Rails.logger.error("Skipping sourcemaps upload since Appsignal config is invalid")
32
+ end
33
+ if asset_host.blank?
34
+ return Rails.logger.error("Skipping sourcemaps upload since Rails asset_host is not set")
35
+ end
36
+ return Rails.logger.info("Skipping sourcemaps upload since no javascript maps are found") if source_map_paths.empty?
37
+
38
+ false
39
+ end
40
+
41
+ def asset_host
42
+ Rails.application.config.asset_host
43
+ end
44
+
45
+ def source_map_paths
46
+ Dir.glob("**/*.map", base: Rails.public_path)
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Appsignal
4
+ module Sourcemap
5
+ class Uploader
6
+ UPLOAD_URI = URI("https://appsignal.com/api/sourcemaps")
7
+
8
+ def self.upload(sourcemap_path)
9
+ new(sourcemap_path).upload
10
+ end
11
+
12
+ def initialize(sourcemap_path)
13
+ @sourcemap_path = sourcemap_path
14
+ end
15
+
16
+ def upload
17
+ Rails.logger.debug("Starting sourcemap upload '#{@sourcemap_path}' with parameters: #{request_form_data}")
18
+
19
+ response = Net::HTTP.start(UPLOAD_URI.hostname, UPLOAD_URI.port, use_ssl: true) do |http|
20
+ http.request(request)
21
+ end
22
+
23
+ if response.is_a?(Net::HTTPSuccess)
24
+ Rails.logger.debug("Finished sourcemap upload '#{@sourcemap_path}'")
25
+ File.delete(sourcemap_full_path)
26
+ return
27
+ end
28
+
29
+ Rails.logger.error <<~MESSAGE
30
+ Uploading sourcemap #{@sourcemap_path} failed with message '#{response.message}'.
31
+ Response: #{response.body}
32
+ MESSAGE
33
+ end
34
+
35
+ private
36
+
37
+ def sourcemap_full_path
38
+ Rails.public_path.join(@sourcemap_path)
39
+ end
40
+
41
+ def request
42
+ Net::HTTP::Post.new(UPLOAD_URI).tap do |request|
43
+ request.set_form request_form_data, "multipart/form-data"
44
+ end
45
+ end
46
+
47
+ def request_form_data
48
+ [
49
+ ["push_api_key", Appsignal.config[:push_api_key]],
50
+ ["app_name", Appsignal.config[:name]],
51
+ ["revision", Appsignal.config[:revision]],
52
+ ["environment", Appsignal.config.env],
53
+ ["name[]", source_url],
54
+ ["file", sourcemap_content]
55
+ ]
56
+ end
57
+
58
+ def sourcemap_content
59
+ File.open(Rails.public_path.join(@sourcemap_path))
60
+ end
61
+
62
+ def source_url
63
+ "#{asset_host}/#{js_path}"
64
+ end
65
+
66
+ def js_path
67
+ @sourcemap_path.delete_suffix(".map")
68
+ end
69
+
70
+ def asset_host
71
+ Rails.application.config.asset_host
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Appsignal
4
+ module Sourcemap
5
+ VERSION = "1.2.0"
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "appsignal/sourcemap/hook"
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: appsignal-sourcemap
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Drieam
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2025-12-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '6.1'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '9.0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '6.1'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '9.0'
33
+ - !ruby/object:Gem::Dependency
34
+ name: appsignal
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "<"
38
+ - !ruby/object:Gem::Version
39
+ version: '5.0'
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "<"
45
+ - !ruby/object:Gem::Version
46
+ version: '5.0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: parallel
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '1.0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '1.0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: standard
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ description:
76
+ email:
77
+ - dev@drieam.com
78
+ executables: []
79
+ extensions: []
80
+ extra_rdoc_files: []
81
+ files:
82
+ - README.md
83
+ - lib/appsignal-sourcemap.rb
84
+ - lib/appsignal/sourcemap/hook.rb
85
+ - lib/appsignal/sourcemap/supervisor.rb
86
+ - lib/appsignal/sourcemap/uploader.rb
87
+ - lib/appsignal/sourcemap/version.rb
88
+ homepage: https://github.com/drieam/appsignal-sourcemap
89
+ licenses: []
90
+ metadata:
91
+ allowed_push_host: https://rubygems.org
92
+ rubygems_mfa_required: 'true'
93
+ post_install_message:
94
+ rdoc_options: []
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '3.1'
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubygems_version: 3.5.11
109
+ signing_key:
110
+ specification_version: 4
111
+ summary: Upload private sourcemaps to appsignal
112
+ test_files: []