module Fastlane module Actions class UploadSymbolsToSentryAction < Action def self.run(params) # Warning about usinging new plugin UI.important("It's recommended to use the official Sentry Fastlane plugin") UI.important("GitHub: https://github.com/getsentry/fastlane-plugin-sentry") UI.important("Installation: fastlane add_plugin sentry") Actions.verify_gem!('rest-client') require 'rest-client' # Params - API host = params[:api_host] api_key = params[:api_key] auth_token = params[:auth_token] org = params[:org_slug] project = params[:project_slug] # Params - dSYM dsym_path = params[:dsym_path] dsym_paths = params[:dsym_paths] || [] has_api_key = !api_key.to_s.empty? has_auth_token = !auth_token.to_s.empty? # Will fail if none or both authentication methods are provided if !has_api_key && !has_auth_token UI.user_error!("No API key or authentication token found for SentryAction given, pass using `api_key: 'key'` or `auth_token: 'token'`") elsif has_api_key && has_auth_token UI.user_error!("Both API key and authentication token found for SentryAction given, please only give one") end # Url to post dSYMs to url = "#{host}/projects/#{org}/#{project}/files/dsyms/" if has_api_key resource = RestClient::Resource.new(url, api_key, '') else resource = RestClient::Resource.new(url, headers: { Authorization: "Bearer #{auth_token}" }) end UI.message("Will upload dSYM(s) to #{url}") # Upload dsym(s) dsym_paths += [dsym_path] uploaded_paths = dsym_paths.compact.map do |dsym| upload_dsym(resource, dsym) end # Return uplaoded dSYM paths uploaded_paths end def self.upload_dsym(resource, dsym) UI.message("Uploading... #{dsym}") resource.post(file: File.new(dsym, 'rb')) unless Helper.test? UI.success('dSYM successfully uploaded to Sentry!') dsym rescue UI.user_error!('Error while trying to upload dSYM to Sentry') end ##################################################### # @!group Documentation ##################################################### def self.description "Upload dSYM symbolication files to Sentry" end def self.details [ "This action allows you to upload symbolication files to Sentry.", "It's extra useful if you use it to download the latest dSYM files from Apple when you", "use Bitcode" ].join(" ") end def self.available_options [ FastlaneCore::ConfigItem.new(key: :api_host, env_name: "SENTRY_HOST", description: "API host url for Sentry", is_string: true, default_value: "https://app.getsentry.com/api/0", optional: true), FastlaneCore::ConfigItem.new(key: :api_key, env_name: "SENTRY_API_KEY", description: "API key for Sentry", sensitive: true, optional: true), FastlaneCore::ConfigItem.new(key: :auth_token, env_name: "SENTRY_AUTH_TOKEN", description: "Authentication token for Sentry", sensitive: true, optional: true), FastlaneCore::ConfigItem.new(key: :org_slug, env_name: "SENTRY_ORG_SLUG", description: "Organization slug for Sentry project", verify_block: proc do |value| UI.user_error!("No organization slug for SentryAction given, pass using `org_slug: 'org'`") unless value and !value.empty? end), FastlaneCore::ConfigItem.new(key: :project_slug, env_name: "SENTRY_PROJECT_SLUG", description: "Project slug for Sentry", verify_block: proc do |value| UI.user_error!("No project slug for SentryAction given, pass using `project_slug: 'project'`") unless value and !value.empty? end), FastlaneCore::ConfigItem.new(key: :dsym_path, env_name: "SENTRY_DSYM_PATH", description: "Path to your symbols file. For iOS and Mac provide path to app.dSYM.zip", default_value: Actions.lane_context[SharedValues::DSYM_OUTPUT_PATH], optional: true, verify_block: proc do |value| # validation is done in the action end), FastlaneCore::ConfigItem.new(key: :dsym_paths, env_name: "SENTRY_DSYM_PATHS", description: "Path to an array of your symbols file. For iOS and Mac provide path to app.dSYM.zip", default_value: Actions.lane_context[SharedValues::DSYM_PATHS], is_string: false, optional: true, verify_block: proc do |value| # validation is done in the action end) ] end def self.return_value "The uploaded dSYM path(s)" end def self.authors ["joshdholtz"] end def self.is_supported?(platform) platform == :ios end def self.example_code [ 'upload_symbols_to_sentry( auth_token: "...", org_slug: "...", project_slug: "...", dsym_path: "./App.dSYM.zip" )' ] end def self.category :deprecated end def self.deprecated_notes "Please use the `sentry` plugin instead.\n" \ "Install using `fastlane add_plugin sentry`.\n" \ "Replace `upload_symbols_to_sentry` with `sentry_upload_dsym`" end end end end