class Rake::XPI::Config
Public Class Methods
new()
click to toggle source
# File lib/rake/xpi.rb, line 26 def initialize() @config = RecursiveOpenStruct.new(YAML::load_file('xpi.yml'), recurse_over_arrays: true) @timestamp = Time.now.to_i.to_s @config.to_h.keys.each{|key| self.class.send(:define_method, key) { @config[key] } } end
Public Instance Methods
add_asset(tag, is_prerelease, asset_name, content, content_type)
click to toggle source
# File lib/rake/xpi/publish/github.rb, line 32 def add_asset(tag, is_prerelease, asset_name, content, content_type) begin release = octokit.release_for_tag(@repo, tag.to_s) rescue Octokit::NotFound release = nil end if release raise "Release #{tag}: requested #{is_prerelease ? 'pre' : ''}release, found #{release.prerelease ? 'pre' : ''}release" if is_prerelease ^ release.prerelease else params = { name: tag.to_s, body: tag.to_s, } params[:target_commitish] = `git rev-list --max-parents=0 HEAD`.split(/\n/).collect{|sha| sha.strip}.first if tag.is_a?(Symbol) params[:prerelease] = true if is_prerelease release = octokit.create_release(@repo, tag.to_s, params) end # remove old version octokit.release_assets(release.url).each{|asset| next unless asset.name == asset_name octokit.delete_release_asset(asset.url) } octokit.upload_asset(release.url, content, name: asset_name, content_type: content_type) end
branch()
click to toggle source
# File lib/rake/xpi.rb, line 127 def branch if @branch.nil? if pull_request @branch = 'pull-request-' + pull_request elsif ENV['TRAVIS_BRANCH'] @branch = ENV['TRAVIS_BRANCH'] elsif ENV['CIRCLE_BRANCH'] @branch = ENV['CIRCLE_BRANCH'] else @branch = `git rev-parse --abbrev-ref HEAD`.strip end end return @branch end
bump(level=nil)
click to toggle source
# File lib/rake/xpi.rb, line 38 def bump(level=nil) level = (level || :tiny).to_sym level = :tiny if level == :patch self.release = Versionomy.parse(self.release).bump(level).to_s end
download(url, file)
click to toggle source
# File lib/rake/xpi.rb, line 112 def download(url, file) puts "Downloading #{url} to #{file}..." sh "curl -L #{url.shellescape} -o #{file.shellescape}" end
getxpis()
click to toggle source
# File lib/rake/xpi.rb, line 233 def getxpis return if ENV['OFFLINE'].to_s.downcase == 'true' return unless @config.test && @config.test.xpis && @config.test.xpis.install dir = File.expand_path(@config.test.xpis.install) FileUtils.mkdir_p(dir) installed = Dir["#{dir}/*.xpi"].collect{|f| File.basename(f) } xpis = [] conditional = {} (@config.test.xpis.download || []).each{|xpi| if xpi.is_a?(Hash) || xpi.is_a?(RecursiveOpenStruct) xpi.each_pair{|env, link| env = env.to_s next unless ENV[env.upcase] == 'true' || env == 'default' puts "Conditional XPI: #{env.inspect} => #{link}" conditional[env] ||= [] conditional[env] << link } else xpis << xpi end } conditional.delete('default') if conditional.keys.length > 1 xpis << conditional.values xpis.flatten! xpis = xpis.collect{|url| resolvexpi(url)} (installed - xpis.collect{|s| s.xpi}).each{|xpi| STDERR.puts "Removing #{xpi}" unless ENV['VERBOSE'] == 'false' File.unlink("#{dir}/#{xpi}") } xpis.reject{|s| installed.include?(s.xpi) && s.url !~ /^file:/ }.each{|s| # https://github.com/zotero/zotero/zipball/master for zotero master if s.xpi =~ /(.*)-master-.*.xpi$/ src = $1 tgt = "#{dir}/#{s.xpi}" STDERR.puts "Zipping #{s.xpi} to #{tgt}" unless ENV['VERBOSE'] == 'false' Dir.chdir(src){|path| Zip::File.open(tgt, 'w') do |zipfile| Dir["**/*"].sort.each{|file| zipfile.add(file, file) } end } else STDERR.puts "Downloading #{s.xpi}" unless ENV['VERBOSE'] == 'false' download(s.url, "#{dir}/#{s.xpi}") end } end
id()
click to toggle source
# File lib/rake/xpi.rb, line 44 def id return Nokogiri::XML(File.open('install.rdf')).at('//em:id').inner_text end
octokit()
click to toggle source
# File lib/rake/xpi/publish/github.rb, line 11 def octokit if @initialized.nil? raise "Github publishing not configured" unless @config.github && @config.github.user && @config.github.token token = ENV[@config.github.token] raise "Github publishing not configured" unless token Octokit.configure{|c| c.access_token = token } Octokit.middleware = Faraday::RackBuilder.new {|builder| builder.use Faraday::HttpCache, shared_cache: false builder.use Octokit::Response::RaiseError builder.adapter Faraday.default_adapter } Octokit.auto_paginate = true @initialized = true @repo = @config.github.user + '/' + @config.github.repo end return Octokit end
publish()
click to toggle source
# File lib/rake/xpi/publish/bintray.rb, line 20 def publish raise "Bintray publishing not configured" unless @config.bintray && @config.bintray.secret #RestClient.log = 'stdout' secret = ENV[@config.bintray.secret] client = RestClient::Resource.new('https://api.bintray.com', @config.bintray.user, secret) content = client['content'][@config.bintray.user][@config.bintray.repo] begin client['packages'][@config.bintray.user][@config.bintray.repo][@config.bintray.package]['versions']['latest'].delete rescue RestClient::ResourceNotFound # that's OK end content[@config.bintray.package][self.version][self.versioned_xpi].put(File.new(self.xpi), { content_type: 'application/x-xpinstall', x_bintray_package: @config.bintray.package, x_bintray_version: self.version, x_bintray_publish: '1' }) if release_build? update_rdf("https://bintray.com/artifact/download/#{@config.bintray.user}/#{@config.bintray.repo}/#{@config.bintray.package}/#{self.version}/#{self.versioned_xpi}"){|update| content[@config.repo.package]['update.rdf'].put(File.new(update), { content_type: 'application/rdf+xml', x_bintray_package: @config.repo.package, x_bintray_version: 'latest', x_bintray_publish: '1', x_bintray_override: '1' }) } end end
pull_request()
click to toggle source
# File lib/rake/xpi.rb, line 121 def pull_request return ENV['TRAVIS_PULL_REQUEST'] if (ENV['TRAVIS_PULL_REQUEST'] || 'false') != 'false' return ENV['CI_PULL_REQUESTS'] if (ENV['CI_PULL_REQUESTS'] || '') != '' return nil end
release()
click to toggle source
# File lib/rake/xpi.rb, line 47 def release return Nokogiri::XML(File.open('install.rdf')).at('//em:version').inner_text end
release=(rel)
click to toggle source
# File lib/rake/xpi.rb, line 50 def release=(rel) doc = Nokogiri::XML(File.open('install.rdf')) doc.at('//em:version').content = rel open('install.rdf', 'w'){|f| f.write(doc.to_xml)} end
release_build?()
click to toggle source
# File lib/rake/xpi.rb, line 142 def release_build? if @release_build.nil? commitmsg = `git log -n 1 --pretty=oneline`.strip commit = %w{CIRCLE_SHA1 TRAVIS_COMMIT}.collect{|key| ENV[key]}.compact.first commit ||= 'local' releasemsg = "#{commit} #{release_message}" if ENV['VERBOSE'] != 'false' STDERR.puts "#{self.release}" STDERR.puts " committed = #{commitmsg}" STDERR.puts " release = #{releasemsg}" STDERR.puts " branch = #{branch}" end @release_build = (commitmsg == releasemsg && branch == 'master') end return @release_build end
release_message()
click to toggle source
# File lib/rake/xpi.rb, line 117 def release_message return "release: #{self.xpi} #{self.release}" end
resolvexpi(source)
click to toggle source
# File lib/rake/xpi.rb, line 285 def resolvexpi(source) STDERR.puts "Resolving #{source}" unless ENV['VERBOSE'] == 'false' xpi = nil if source =~ /\.rdf$/ update_rdf = Nokogiri::XML(open(source)) update_rdf.remove_namespaces! url = update_rdf.at('//updateLink').inner_text elsif source =~ /^https:\/\/addons\.mozilla\.org\// page = Nokogiri::HTML(open(source)) id = page.at('//*[@data-addonid]')['data-addonid'] info = Nokogiri::XML(open("https://services.addons.mozilla.org/en-US/firefox/api/1.5/addon/#{id}")) url = info.xpath('//install').detect{|install| (install['status'] || 'Release') != 'Beta'}.inner_text elsif source =~ /^https:\/\/github\.com\/zotero\/([^\/]+)\/zipball\/master$/ url = source src = $1 Dir.chdir(src) { rev = `git log -n 1 --pretty=format:"%h"` xpi = "#{src}-master-#{rev}.xpi" } elsif source =~ /^file:/ || source =~ /\.xpi(\?|$)/ url = source else throw "Unsupported XPI source #{source}" end xpi ||= url.sub(/.*\//, '').sub(/\?.*$/, '') STDERR.puts "Resolved to #{url}" unless ENV['VERBOSE'] == 'false' return OpenStruct.new(url: url, xpi: xpi) end
sign()
click to toggle source
# File lib/rake/xpi.rb, line 163 def sign return if ENV['SIGN'] == 'false' || pull_request return unless @config.amo && @config.amo.issuer && @config.amo.secret issuer = ENV[@config.amo.issuer] secret = ENV[@config.amo.secret] return unless issuer && secret token = lambda { payload = { jti: SecureRandom.base64, iss: issuer, iat: Time.now.utc.to_i, exp: Time.now.utc.to_i + 60, } return JWT.encode(payload, secret, 'HS256') } duration = lambda{|secs| secs = secs.to_i mins = secs / 60 hours = mins / 60 days = hours / 24 if days > 0 "#{days} days and #{hours % 24} hours" elsif hours > 0 "#{hours} hours and #{mins % 60} minutes" elsif mins > 0 "#{mins} minutes and #{secs % 60} seconds" elsif secs >= 0 "#{secs} seconds" end } url = "https://addons.mozilla.org/api/v3/addons/#{self.id}/versions/#{self.version}/" wait = nil begin Dir.mktmpdir{|dir| tmp = File.join(dir, self.versioned_xpi) FileUtils.cp(self.xpi, tmp) puts "Submit #{tmp} to #{url} for signing" RestClient.put(url, {upload: File.new(tmp)}, { 'Authorization' => "JWT #{token.call}", 'Content-Type' => 'multipart/form-data' }) } wait = Time.now.to_i sleep 10 rescue RestClient::Conflict puts "#{self.xpi} already signed" wait = Time.now.to_i end status = {} (1..100).each{|attempt| status = JSON.parse(RestClient.get(url, { 'Authorization' => "JWT #{token.call}"} ).to_s) files = (status['files'] || []).length signed = (files > 0 ? status['files'][0]['signed'] : false) puts "attempt #{attempt} after #{duration.call(Time.now.to_i - wait)}, #{files} files, signed: #{signed}" break if signed sleep 5 } raise "Unexpected response: #{status['files'].inspect}" if !status['files'] || status['files'].length != 1 || !status['files'][0]['download_url'] raise "Not signed: #{status['files'][0].inspect}" unless status['files'][0]['signed'] puts "\ngetting signed XPI from #{status['files'][0]['download_url']}" File.open(self.xpi, 'wb'){|f| f.write(RestClient.get(status['files'][0]['download_url'], { 'Authorization' => "JWT #{token.call}"} ).body) } end
update_rdf() { |path| ... }
click to toggle source
# File lib/rake/xpi.rb, line 70 def update_rdf _id = self.id _release = self.release _changelog = self.changelog _link = self.xpi_url update = Nokogiri::XML::Builder.new { |xml| xml.RDF('xmlns:RDF'=>'http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'xmlns:em' => 'http://www.mozilla.org/2004/em-rdf#') { xml.parent.namespace = xml.parent.namespace_definitions.find{|ns|ns.prefix=='RDF'} xml['RDF'].Description(about: "urn:mozilla:extension:#{_id}") { xml['em'].updates { xml['RDF'].Seq { xml['RDF'].li { xml['RDF'].Description { xml['em'].version { xml.text _release } Nokogiri::XML(open('install.rdf')).xpath('//em:targetApplication/xmlns:Description').each{|target| xml['em'].targetApplication { xml['RDF'].Description { xml['em'].id { xml.text target.at('./em:id').inner_text } xml['em'].minVersion { xml.text target.at('./em:minVersion').inner_text } xml['em'].maxVersion { xml.text target.at('./em:maxVersion').inner_text } xml['em'].updateLink { xml.text _link } xml['em'].updateInfoURL { xml.text _changelog } } } } } } } } } } } Tempfile.create('update_rdf') do |tmp| tmp.write(update.to_xml) tmp.close yield tmp.path end end
update_url()
click to toggle source
# File lib/rake/xpi/publish/github.rb, line 59 def update_url return "https://github.com/#{@config.github.user}/#{@config.github.repo}/releases/download/update.rdf/update.rdf" end
version()
click to toggle source
# File lib/rake/xpi.rb, line 56 def version if release_build? return release elsif ENV['TRAVIS_BUILD_NUMBER'] return release + "-#{branch}-#{ENV['TRAVIS_BUILD_NUMBER']}" elsif ENV['CIRCLE_BUILD_NUM'] br = branch br = "br#{br}" unless br =~ /^[a-z]/i return release + "-#{br}-#{ENV['CIRCLE_BUILD_NUM']}" else return release + "-#{Socket.gethostname}-#{@timestamp}" end end
versioned_xpi(v=nil)
click to toggle source
# File lib/rake/xpi.rb, line 34 def versioned_xpi(v=nil) return File.basename(self.xpi, File.extname(self.xpi)) + '-' + (v || self.version) + File.extname(self.xpi) end
xpi_url()
click to toggle source
# File lib/rake/xpi/publish/github.rb, line 62 def xpi_url return "https://github.com/#{@config.github.user}/#{@config.github.repo}/releases/download/#{release_build? ? self.version : @@builds}/#{self.versioned_xpi}" end