rake-xpi 0.0.4
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 +7 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +81 -0
- data/Rakefile +41 -0
- data/lib/rake/xpi.rb +370 -0
- data/lib/rake/xpi/bintray.rb +57 -0
- data/lib/rake/xpi/github.rb +81 -0
- data/lib/rake/xpi/s3.rb +83 -0
- data/lib/rake/xpi/sourceforge.rb +81 -0
- data/rake-xpi.gemspec +33 -0
- metadata +207 -0
    
        checksums.yaml
    ADDED
    
    | @@ -0,0 +1,7 @@ | |
| 1 | 
            +
            ---
         | 
| 2 | 
            +
            SHA1:
         | 
| 3 | 
            +
              metadata.gz: 4fbcc44fc0cbe55a24febb2258bf4a48b90c9d0d
         | 
| 4 | 
            +
              data.tar.gz: 07946ac497e0a0859530b73e2bf0b0d86b20b90e
         | 
| 5 | 
            +
            SHA512:
         | 
| 6 | 
            +
              metadata.gz: 8cbf3067a6e13c0d09f06da122ac17fbb090ee8997535f5e5218072057cb9289419351ded35d49fd30e1c205129a6b46dd504a3f24149339a86c9f10a8d02733
         | 
| 7 | 
            +
              data.tar.gz: 13058ade3c32bb5d02ac5035162a5c2c49ee1e0f0542a95fbc8a2c2d86bce9fb406acf2d174db85fdfd994a0f946ae3c68ce319fb3f86eb7e06c114f612764d0
         | 
    
        data/Gemfile
    ADDED
    
    
    
        data/Gemfile.lock
    ADDED
    
    | @@ -0,0 +1,81 @@ | |
| 1 | 
            +
            PATH
         | 
| 2 | 
            +
              remote: .
         | 
| 3 | 
            +
              specs:
         | 
| 4 | 
            +
                rake-xpi (0.0.4)
         | 
| 5 | 
            +
                  aws-sdk
         | 
| 6 | 
            +
                  github_api
         | 
| 7 | 
            +
                  jwt
         | 
| 8 | 
            +
                  multipart-post
         | 
| 9 | 
            +
                  nokogiri
         | 
| 10 | 
            +
                  rake
         | 
| 11 | 
            +
                  recursive-open-struct
         | 
| 12 | 
            +
                  rest-client
         | 
| 13 | 
            +
                  rubyzip (>= 1.0.0)
         | 
| 14 | 
            +
                  zip-zip
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            GEM
         | 
| 17 | 
            +
              remote: https://rubygems.org/
         | 
| 18 | 
            +
              specs:
         | 
| 19 | 
            +
                addressable (2.4.0)
         | 
| 20 | 
            +
                aws-sdk (2.2.30)
         | 
| 21 | 
            +
                  aws-sdk-resources (= 2.2.30)
         | 
| 22 | 
            +
                aws-sdk-core (2.2.30)
         | 
| 23 | 
            +
                  jmespath (~> 1.0)
         | 
| 24 | 
            +
                aws-sdk-resources (2.2.30)
         | 
| 25 | 
            +
                  aws-sdk-core (= 2.2.30)
         | 
| 26 | 
            +
                descendants_tracker (0.0.4)
         | 
| 27 | 
            +
                  thread_safe (~> 0.3, >= 0.3.1)
         | 
| 28 | 
            +
                domain_name (0.5.20160310)
         | 
| 29 | 
            +
                  unf (>= 0.0.5, < 1.0.0)
         | 
| 30 | 
            +
                faraday (0.9.2)
         | 
| 31 | 
            +
                  multipart-post (>= 1.2, < 3)
         | 
| 32 | 
            +
                github_api (0.13.1)
         | 
| 33 | 
            +
                  addressable (~> 2.4.0)
         | 
| 34 | 
            +
                  descendants_tracker (~> 0.0.4)
         | 
| 35 | 
            +
                  faraday (~> 0.8, < 0.10)
         | 
| 36 | 
            +
                  hashie (>= 3.4)
         | 
| 37 | 
            +
                  multi_json (>= 1.7.5, < 2.0)
         | 
| 38 | 
            +
                  oauth2
         | 
| 39 | 
            +
                hashie (3.4.3)
         | 
| 40 | 
            +
                http-cookie (1.0.2)
         | 
| 41 | 
            +
                  domain_name (~> 0.5)
         | 
| 42 | 
            +
                jmespath (1.1.3)
         | 
| 43 | 
            +
                jwt (1.5.1)
         | 
| 44 | 
            +
                mime-types (2.99.1)
         | 
| 45 | 
            +
                mini_portile2 (2.0.0)
         | 
| 46 | 
            +
                multi_json (1.11.2)
         | 
| 47 | 
            +
                multi_xml (0.5.5)
         | 
| 48 | 
            +
                multipart-post (2.0.0)
         | 
| 49 | 
            +
                netrc (0.11.0)
         | 
| 50 | 
            +
                nokogiri (1.6.7.2)
         | 
| 51 | 
            +
                  mini_portile2 (~> 2.0.0.rc2)
         | 
| 52 | 
            +
                oauth2 (1.1.0)
         | 
| 53 | 
            +
                  faraday (>= 0.8, < 0.10)
         | 
| 54 | 
            +
                  jwt (~> 1.0, < 1.5.2)
         | 
| 55 | 
            +
                  multi_json (~> 1.3)
         | 
| 56 | 
            +
                  multi_xml (~> 0.5)
         | 
| 57 | 
            +
                  rack (>= 1.2, < 3)
         | 
| 58 | 
            +
                rack (1.6.4)
         | 
| 59 | 
            +
                rake (11.1.2)
         | 
| 60 | 
            +
                recursive-open-struct (1.0.1)
         | 
| 61 | 
            +
                rest-client (1.8.0)
         | 
| 62 | 
            +
                  http-cookie (>= 1.0.2, < 2.0)
         | 
| 63 | 
            +
                  mime-types (>= 1.16, < 3.0)
         | 
| 64 | 
            +
                  netrc (~> 0.7)
         | 
| 65 | 
            +
                rubyzip (1.2.0)
         | 
| 66 | 
            +
                thread_safe (0.3.5)
         | 
| 67 | 
            +
                unf (0.1.4)
         | 
| 68 | 
            +
                  unf_ext
         | 
| 69 | 
            +
                unf_ext (0.0.7.2)
         | 
| 70 | 
            +
                zip-zip (0.3)
         | 
| 71 | 
            +
                  rubyzip (>= 1.0.0)
         | 
| 72 | 
            +
             | 
| 73 | 
            +
            PLATFORMS
         | 
| 74 | 
            +
              ruby
         | 
| 75 | 
            +
             | 
| 76 | 
            +
            DEPENDENCIES
         | 
| 77 | 
            +
              bundler (~> 1.3)
         | 
| 78 | 
            +
              rake-xpi!
         | 
| 79 | 
            +
             | 
| 80 | 
            +
            BUNDLED WITH
         | 
| 81 | 
            +
               1.11.2
         | 
    
        data/Rakefile
    ADDED
    
    | @@ -0,0 +1,41 @@ | |
| 1 | 
            +
            require 'bundler/gem_tasks'
         | 
| 2 | 
            +
            require 'fileutils'
         | 
| 3 | 
            +
            require 'yaml'
         | 
| 4 | 
            +
            require 'pp'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            task :default => :build
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            task :bump do
         | 
| 9 | 
            +
              gemspec = []
         | 
| 10 | 
            +
              bumped = false
         | 
| 11 | 
            +
              IO.readlines('rake-xpi.gemspec').each{|line|
         | 
| 12 | 
            +
                if line =~ /spec.version *= *'([0-9\.]+)'/
         | 
| 13 | 
            +
                  bumped = true
         | 
| 14 | 
            +
                  old = $1
         | 
| 15 | 
            +
                  new = old.split('.').collect{|n| Integer(n)}
         | 
| 16 | 
            +
                  new[-1] += 1
         | 
| 17 | 
            +
                  new = new.collect{|n| n.to_s}.join('.')
         | 
| 18 | 
            +
                  line = line.sub(old, new)
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
                gemspec << line
         | 
| 21 | 
            +
              }
         | 
| 22 | 
            +
              gemspec = gemspec.join('')
         | 
| 23 | 
            +
             | 
| 24 | 
            +
              File.open('rake-xpi.gemspec', 'w'){|f| f.write(gemspec) }
         | 
| 25 | 
            +
              puts `git add rake-xpi.gemspec Gemfile Gemfile.lock`
         | 
| 26 | 
            +
            end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            task :publish do
         | 
| 29 | 
            +
              version = nil
         | 
| 30 | 
            +
              IO.readlines('rake-xpi.gemspec').each{|line|
         | 
| 31 | 
            +
                version = $1 if line =~ /spec.version *= *'([0-9\.]+)'/
         | 
| 32 | 
            +
              }
         | 
| 33 | 
            +
              raise "No version found" unless version
         | 
| 34 | 
            +
              sh "git add ."
         | 
| 35 | 
            +
              sh "git commit -m #{version}"
         | 
| 36 | 
            +
              sh "git tag #{version}"
         | 
| 37 | 
            +
              Dir['pkg/*.gem'].each{|f| File.unlink(f)}
         | 
| 38 | 
            +
              Rake::Task["build"].invoke
         | 
| 39 | 
            +
              sh "gem push #{Dir['pkg/*.gem'].join(' ')}"
         | 
| 40 | 
            +
              sh "git push"
         | 
| 41 | 
            +
            end
         | 
    
        data/lib/rake/xpi.rb
    ADDED
    
    | @@ -0,0 +1,370 @@ | |
| 1 | 
            +
            require 'aws-sdk'
         | 
| 2 | 
            +
            require 'fileutils'
         | 
| 3 | 
            +
            require 'jwt'
         | 
| 4 | 
            +
            require 'nokogiri'
         | 
| 5 | 
            +
            require 'open-uri'
         | 
| 6 | 
            +
            require 'ostruct'
         | 
| 7 | 
            +
            require 'rake'
         | 
| 8 | 
            +
            require 'recursive-open-struct'
         | 
| 9 | 
            +
            require 'rest-client'
         | 
| 10 | 
            +
            require 'securerandom'
         | 
| 11 | 
            +
            require 'socket'
         | 
| 12 | 
            +
            require 'tempfile'
         | 
| 13 | 
            +
            require 'uri'
         | 
| 14 | 
            +
            require 'yaml'
         | 
| 15 | 
            +
            require 'zip'
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            module Rake
         | 
| 18 | 
            +
              module XPI
         | 
| 19 | 
            +
                class Config
         | 
| 20 | 
            +
                  include Rake::DSL
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  def initialize()
         | 
| 23 | 
            +
                    @config = RecursiveOpenStruct.new(YAML::load_file('xpi.yml'), recurse_over_arrays: true)
         | 
| 24 | 
            +
                    @timestamp = Time.now.to_i.to_s
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                    @config.to_h.keys.each{|key|
         | 
| 27 | 
            +
                      self.class.send(:define_method, key) { @config[key] }
         | 
| 28 | 
            +
                    }
         | 
| 29 | 
            +
                  end
         | 
| 30 | 
            +
                  def versioned_xpi(v=nil)
         | 
| 31 | 
            +
                    return File.basename(self.xpi, File.extname(self.xpi)) + '-' + (v || self.version) + File.extname(self.xpi)
         | 
| 32 | 
            +
                  end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                  def bump(level=nil)
         | 
| 35 | 
            +
                    r = release.split('.').collect{|n| Integer(n)}
         | 
| 36 | 
            +
                    r = case (level || 'patch').intern
         | 
| 37 | 
            +
                        when :major then [r[0] + 1, 0, 0]
         | 
| 38 | 
            +
                        when :minor then [r[0], r[1] + 1, 0]
         | 
| 39 | 
            +
                        when :patch then [r[0], r[1], r[2] + 1]
         | 
| 40 | 
            +
                        else raise "Unexpected release increase #{level.inspect}"
         | 
| 41 | 
            +
                        end
         | 
| 42 | 
            +
                    self.release = r.collect{|n| n.to_s}.join('.')
         | 
| 43 | 
            +
                  end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                  def id
         | 
| 46 | 
            +
                    return Nokogiri::XML(File.open('install.rdf')).at('//em:id').inner_text
         | 
| 47 | 
            +
                  end
         | 
| 48 | 
            +
                  def release
         | 
| 49 | 
            +
                    return Nokogiri::XML(File.open('install.rdf')).at('//em:version').inner_text
         | 
| 50 | 
            +
                  end
         | 
| 51 | 
            +
                  def release=(rel)
         | 
| 52 | 
            +
                    doc = Nokogiri::XML(File.open('install.rdf'))
         | 
| 53 | 
            +
                    doc.at('//em:version').content = rel
         | 
| 54 | 
            +
                    open('install.rdf', 'w'){|f| f.write(doc.to_xml)}
         | 
| 55 | 
            +
                  end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                  def version
         | 
| 58 | 
            +
                    b = "-#{branch}"
         | 
| 59 | 
            +
                    b = '' if b == '-master'
         | 
| 60 | 
            +
                    if release_build?
         | 
| 61 | 
            +
                      return release
         | 
| 62 | 
            +
                    elsif ENV['TRAVIS_BUILD_NUMBER']
         | 
| 63 | 
            +
                      return release + "-travis#{b}-#{ENV['TRAVIS_BUILD_NUMBER']}"
         | 
| 64 | 
            +
                    elsif ENV['CIRCLE_BUILD_NUM']
         | 
| 65 | 
            +
                      return release + "-circle#{b}-#{ENV['CIRCLE_BUILD_NUM']}"
         | 
| 66 | 
            +
                    else
         | 
| 67 | 
            +
                      return release + "-#{Socket.gethostname}#{b}-#{@timestamp}"
         | 
| 68 | 
            +
                    end
         | 
| 69 | 
            +
                  end
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                  def update_rdf(link)
         | 
| 72 | 
            +
                    _id = self.id
         | 
| 73 | 
            +
                    _release = self.release
         | 
| 74 | 
            +
                    _changelog = self.changelog
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                    update = Nokogiri::XML::Builder.new { |xml|
         | 
| 77 | 
            +
                      xml.RDF('xmlns:RDF'=>'http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'xmlns:em' =>
         | 
| 78 | 
            +
                      'http://www.mozilla.org/2004/em-rdf#') {
         | 
| 79 | 
            +
                        xml.parent.namespace = xml.parent.namespace_definitions.find{|ns|ns.prefix=='RDF'}
         | 
| 80 | 
            +
                        xml['RDF'].Description(about: "urn:mozilla:extension:#{_id}") {
         | 
| 81 | 
            +
                          xml['em'].updates {
         | 
| 82 | 
            +
                            xml['RDF'].Seq {
         | 
| 83 | 
            +
                              xml['RDF'].li {
         | 
| 84 | 
            +
                                xml['RDF'].Description {
         | 
| 85 | 
            +
                                  xml['em'].version { xml.text _release }
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                                  Nokogiri::XML(open('install.rdf')).xpath('//em:targetApplication/xmlns:Description').each{|target|
         | 
| 88 | 
            +
                                    xml['em'].targetApplication {
         | 
| 89 | 
            +
                                      xml['RDF'].Description {
         | 
| 90 | 
            +
                                        xml['em'].id { xml.text target.at('./em:id').inner_text }
         | 
| 91 | 
            +
                                        xml['em'].minVersion { xml.text target.at('./em:minVersion').inner_text }
         | 
| 92 | 
            +
                                        xml['em'].maxVersion { xml.text target.at('./em:maxVersion').inner_text }
         | 
| 93 | 
            +
                                        xml['em'].updateLink { xml.text link }
         | 
| 94 | 
            +
                                        xml['em'].updateInfoURL { xml.text _changelog }
         | 
| 95 | 
            +
                                      }
         | 
| 96 | 
            +
                                    }
         | 
| 97 | 
            +
                                  }
         | 
| 98 | 
            +
                                }
         | 
| 99 | 
            +
                              }
         | 
| 100 | 
            +
                            }
         | 
| 101 | 
            +
                          }
         | 
| 102 | 
            +
                        }
         | 
| 103 | 
            +
                      }
         | 
| 104 | 
            +
                    }
         | 
| 105 | 
            +
                    Tempfile.create('update_rdf') do |tmp|
         | 
| 106 | 
            +
                      tmp.write(update.to_xml)
         | 
| 107 | 
            +
                      tmp.close
         | 
| 108 | 
            +
                      yield tmp.path
         | 
| 109 | 
            +
                    end
         | 
| 110 | 
            +
                  end
         | 
| 111 | 
            +
             | 
| 112 | 
            +
                  def download(url, file)
         | 
| 113 | 
            +
                    puts "Downloading #{url} to #{file}..."
         | 
| 114 | 
            +
                    sh "curl -L #{url.shellescape} -o #{file.shellescape}"
         | 
| 115 | 
            +
                  end
         | 
| 116 | 
            +
             | 
| 117 | 
            +
                  def release_message
         | 
| 118 | 
            +
                    return "release: #{self.xpi} #{self.release}"
         | 
| 119 | 
            +
                  end
         | 
| 120 | 
            +
             | 
| 121 | 
            +
                  def pull_request
         | 
| 122 | 
            +
                    return ENV['TRAVIS_PULL_REQUEST'] if (ENV['TRAVIS_PULL_REQUEST'] || 'false') != 'false'
         | 
| 123 | 
            +
                    return ENV['CI_PULL_REQUESTS'] if (ENV['CI_PULL_REQUESTS'] || '') != ''
         | 
| 124 | 
            +
                    return nil
         | 
| 125 | 
            +
                  end
         | 
| 126 | 
            +
             | 
| 127 | 
            +
                  def branch
         | 
| 128 | 
            +
                    if @branch.nil?
         | 
| 129 | 
            +
                      if pull_request
         | 
| 130 | 
            +
                        @branch = 'pull-request-' + pull_request
         | 
| 131 | 
            +
                      elsif ENV['TRAVIS_BRANCH']
         | 
| 132 | 
            +
                        @branch = ENV['TRAVIS_BRANCH']
         | 
| 133 | 
            +
                      elsif ENV['CIRCLE_BRANCH']
         | 
| 134 | 
            +
                        @branch = ENV['CIRCLE_BRANCH']
         | 
| 135 | 
            +
                      else
         | 
| 136 | 
            +
                        @branch = `git rev-parse --abbrev-ref HEAD`.strip
         | 
| 137 | 
            +
                      end
         | 
| 138 | 
            +
                    end
         | 
| 139 | 
            +
                    return @branch
         | 
| 140 | 
            +
                  end
         | 
| 141 | 
            +
             | 
| 142 | 
            +
                  def release_build?
         | 
| 143 | 
            +
                    if @release_build.nil?
         | 
| 144 | 
            +
                      commitmsg = `git log -n 1 --pretty=oneline`.strip
         | 
| 145 | 
            +
                      commit = %w{CIRCLE_SHA1 TRAVIS_COMMIT}.collect{|key| ENV[key]}.compact.first
         | 
| 146 | 
            +
                      commit ||= 'local'
         | 
| 147 | 
            +
             | 
| 148 | 
            +
                      releasemsg = "#{commit} #{release_message}"
         | 
| 149 | 
            +
             | 
| 150 | 
            +
                      STDERR.puts "#{self.release}"
         | 
| 151 | 
            +
                      STDERR.puts "  committed = #{commitmsg}"
         | 
| 152 | 
            +
                      STDERR.puts "  release   = #{releasemsg}"
         | 
| 153 | 
            +
                      STDERR.puts "  branch    = #{branch}"
         | 
| 154 | 
            +
             | 
| 155 | 
            +
                      @release_build = (commitmsg == releasemsg && branch == 'master')
         | 
| 156 | 
            +
                    end
         | 
| 157 | 
            +
             | 
| 158 | 
            +
                    return @release_build
         | 
| 159 | 
            +
                  end
         | 
| 160 | 
            +
             | 
| 161 | 
            +
                  def sign
         | 
| 162 | 
            +
                    return if ENV['SIGN'] == 'false'
         | 
| 163 | 
            +
                    return unless @config.amo && @config.amo.issuer && @config.amo.secret
         | 
| 164 | 
            +
                    issuer = ENV[@config.amo.issuer]
         | 
| 165 | 
            +
                    secret = ENV[@config.amo.secret]
         | 
| 166 | 
            +
                    return unless issuer && secret
         | 
| 167 | 
            +
             | 
| 168 | 
            +
                    token = lambda {
         | 
| 169 | 
            +
                      payload = {
         | 
| 170 | 
            +
                        jti: SecureRandom.base64,
         | 
| 171 | 
            +
                        iss: issuer,
         | 
| 172 | 
            +
                        iat: Time.now.utc.to_i,
         | 
| 173 | 
            +
                        exp: Time.now.utc.to_i + 60,
         | 
| 174 | 
            +
                      }
         | 
| 175 | 
            +
                      return JWT.encode(payload, secret, 'HS256')
         | 
| 176 | 
            +
                    }
         | 
| 177 | 
            +
             | 
| 178 | 
            +
                    duration = lambda{|secs|
         | 
| 179 | 
            +
                      secs = secs.to_i
         | 
| 180 | 
            +
                      mins  = secs / 60
         | 
| 181 | 
            +
                      hours = mins / 60
         | 
| 182 | 
            +
                      days  = hours / 24
         | 
| 183 | 
            +
             | 
| 184 | 
            +
                      if days > 0
         | 
| 185 | 
            +
                        "#{days} days and #{hours % 24} hours"
         | 
| 186 | 
            +
                      elsif hours > 0
         | 
| 187 | 
            +
                        "#{hours} hours and #{mins % 60} minutes"
         | 
| 188 | 
            +
                      elsif mins > 0
         | 
| 189 | 
            +
                        "#{mins} minutes and #{secs % 60} seconds"
         | 
| 190 | 
            +
                      elsif secs >= 0
         | 
| 191 | 
            +
                        "#{secs} seconds"
         | 
| 192 | 
            +
                      end
         | 
| 193 | 
            +
                    }
         | 
| 194 | 
            +
             | 
| 195 | 
            +
                    url = "https://addons.mozilla.org/api/v3/addons/#{self.id}/versions/#{self.version}/"
         | 
| 196 | 
            +
             | 
| 197 | 
            +
                    wait = nil
         | 
| 198 | 
            +
                    begin
         | 
| 199 | 
            +
                      Dir.mktmpdir{|dir|
         | 
| 200 | 
            +
                        tmp = File.join(dir, self.versioned_xpi)
         | 
| 201 | 
            +
                        FileUtils.cp(self.xpi, tmp)
         | 
| 202 | 
            +
                        puts "Submit #{tmp} to #{url} for signing"
         | 
| 203 | 
            +
                        RestClient.put(url, {upload: File.new(tmp)}, { 'Authorization' => "JWT #{token.call}", 'Content-Type' => 'multipart/form-data' })
         | 
| 204 | 
            +
                      }
         | 
| 205 | 
            +
                      wait = Time.now.to_i
         | 
| 206 | 
            +
                      sleep 10
         | 
| 207 | 
            +
                    rescue RestClient::Conflict
         | 
| 208 | 
            +
                      puts "#{self.xpi} already signed"
         | 
| 209 | 
            +
                      wait = Time.now.to_i
         | 
| 210 | 
            +
                    end
         | 
| 211 | 
            +
             | 
| 212 | 
            +
                    status = {}
         | 
| 213 | 
            +
                    (1..100).each{|attempt|
         | 
| 214 | 
            +
                      status = JSON.parse(RestClient.get(url, { 'Authorization' => "JWT #{token.call}"} ).to_s)
         | 
| 215 | 
            +
                      files = (status['files'] || []).length
         | 
| 216 | 
            +
                      signed = (files > 0 ? status['files'][0]['signed'] : false)
         | 
| 217 | 
            +
                      puts "attempt #{attempt} after #{duration.call(Time.now.to_i - wait)}, #{files} files, signed: #{signed}"
         | 
| 218 | 
            +
                      break if signed
         | 
| 219 | 
            +
                      sleep 5
         | 
| 220 | 
            +
                    }
         | 
| 221 | 
            +
             | 
| 222 | 
            +
                    raise "Unexpected response: #{status['files'].inspect}" if !status['files'] || status['files'].length != 1 || !status['files'][0]['download_url']
         | 
| 223 | 
            +
                    raise "Not signed: #{status['files'][0].inspect}" unless status['files'][0]['signed']
         | 
| 224 | 
            +
             | 
| 225 | 
            +
                    puts "\ngetting signed XPI from #{status['files'][0]['download_url']}"
         | 
| 226 | 
            +
                    File.open(self.xpi, 'wb'){|f|
         | 
| 227 | 
            +
                      f.write(RestClient.get(status['files'][0]['download_url'], { 'Authorization' => "JWT #{token.call}"} ).body)
         | 
| 228 | 
            +
                    }
         | 
| 229 | 
            +
                  end
         | 
| 230 | 
            +
             | 
| 231 | 
            +
                  def getxpis
         | 
| 232 | 
            +
                    return if ENV['OFFLINE'].to_s.downcase == 'true'
         | 
| 233 | 
            +
                    return unless @config.test && @config.test.xpis && @config.test.xpis.install
         | 
| 234 | 
            +
             | 
| 235 | 
            +
                    dir = File.expand_path(@config.test.xpis.install)
         | 
| 236 | 
            +
                    FileUtils.mkdir_p(dir)
         | 
| 237 | 
            +
                    installed = Dir["#{dir}/*.xpi"].collect{|f| File.basename(f) }
         | 
| 238 | 
            +
             | 
| 239 | 
            +
                    sources = (@config.test.xpis.download || []).collect{|s| resolvexpi(s) }
         | 
| 240 | 
            +
             | 
| 241 | 
            +
                    (installed - sources.collect{|s| s.xpi}).each{|xpi|
         | 
| 242 | 
            +
                      STDERR.puts "Removing #{xpi}"
         | 
| 243 | 
            +
                      File.unlink("#{dir}/#{xpi}")
         | 
| 244 | 
            +
                    }
         | 
| 245 | 
            +
                    sources.reject{|s| installed.include?(s.xpi) && s.url !~ /^file:/ }.each{|s|
         | 
| 246 | 
            +
                      # https://github.com/zotero/zotero/zipball/master for zotero master
         | 
| 247 | 
            +
                      if s.xpi =~ /(.*)-master-.*.xpi$/
         | 
| 248 | 
            +
                        src = $1
         | 
| 249 | 
            +
                        tgt = "#{dir}/#{s.xpi}"
         | 
| 250 | 
            +
                        STDERR.puts "Zipping #{s.xpi} to #{tgt}"
         | 
| 251 | 
            +
                        Dir.chdir(src){|path|
         | 
| 252 | 
            +
                          Zip::File.open(tgt, 'w') do |zipfile|
         | 
| 253 | 
            +
                            Dir["**/*"].sort.each{|file|
         | 
| 254 | 
            +
                              zipfile.add(file, file)
         | 
| 255 | 
            +
                            }
         | 
| 256 | 
            +
                          end
         | 
| 257 | 
            +
                        }
         | 
| 258 | 
            +
                      else
         | 
| 259 | 
            +
                        STDERR.puts "Downloading #{s.xpi}"
         | 
| 260 | 
            +
                        download(s.url, "#{dir}/#{s.xpi}")
         | 
| 261 | 
            +
                      end
         | 
| 262 | 
            +
                    }
         | 
| 263 | 
            +
                  end
         | 
| 264 | 
            +
             | 
| 265 | 
            +
                  def resolvexpi(source)
         | 
| 266 | 
            +
                    STDERR.puts "Resolving #{source}"
         | 
| 267 | 
            +
             | 
| 268 | 
            +
                    xpi = nil
         | 
| 269 | 
            +
             | 
| 270 | 
            +
                    if source =~ /update\.rdf$/
         | 
| 271 | 
            +
                      update_rdf = Nokogiri::XML(open(source))
         | 
| 272 | 
            +
                      update_rdf.remove_namespaces!
         | 
| 273 | 
            +
                      url = update_rdf.at('//updateLink').inner_text
         | 
| 274 | 
            +
                    elsif source =~ /^https:\/\/addons\.mozilla\.org\//
         | 
| 275 | 
            +
                      page = open(source).read
         | 
| 276 | 
            +
                      page = Nokogiri::HTML(page)
         | 
| 277 | 
            +
                      url = page.at_css('p.install-button').at_css('a')['href']
         | 
| 278 | 
            +
             | 
| 279 | 
            +
                      url = URI.join(source, url ).to_s if url !~ /^http/
         | 
| 280 | 
            +
             | 
| 281 | 
            +
                      return resolvexpi(url) if url =~ /\/contribute\/roadblock\//
         | 
| 282 | 
            +
             | 
| 283 | 
            +
                      # AMO uses redirects, so I can't write the file to the final name just yet
         | 
| 284 | 
            +
                      final_uri = nil
         | 
| 285 | 
            +
                      open(url) do |h|
         | 
| 286 | 
            +
                        final_uri = h.base_uri
         | 
| 287 | 
            +
                      end
         | 
| 288 | 
            +
                      url = final_uri.to_s
         | 
| 289 | 
            +
                    elsif source =~ /^https:\/\/github\.com\/zotero\/([^\/]+)\/zipball\/master$/
         | 
| 290 | 
            +
                      url = source
         | 
| 291 | 
            +
                      src = $1
         | 
| 292 | 
            +
                      Dir.chdir(src) {
         | 
| 293 | 
            +
                        rev = `git log -n 1 --pretty=format:"%h"`
         | 
| 294 | 
            +
                        xpi = "#{src}-master-#{rev}.xpi"
         | 
| 295 | 
            +
                      }
         | 
| 296 | 
            +
                    elsif source =~ /^file:/ || source =~ /\.xpi(\?|$)/
         | 
| 297 | 
            +
                      url = source
         | 
| 298 | 
            +
                    else
         | 
| 299 | 
            +
                      throw "Unsupported XPI source #{source}"
         | 
| 300 | 
            +
                    end
         | 
| 301 | 
            +
             | 
| 302 | 
            +
                    xpi ||= url.sub(/.*\//, '').sub(/\?.*$/, '')
         | 
| 303 | 
            +
                    STDERR.puts "Resolved to #{url}"
         | 
| 304 | 
            +
                    return OpenStruct.new(url: url, xpi: xpi)
         | 
| 305 | 
            +
                  end
         | 
| 306 | 
            +
             | 
| 307 | 
            +
                end
         | 
| 308 | 
            +
              end
         | 
| 309 | 
            +
            end
         | 
| 310 | 
            +
             | 
| 311 | 
            +
            XPI = Rake::XPI::Config.new
         | 
| 312 | 
            +
            NODEBIN="node_modules/.bin"
         | 
| 313 | 
            +
             | 
| 314 | 
            +
            task :default => XPI.xpi do
         | 
| 315 | 
            +
            end
         | 
| 316 | 
            +
             | 
| 317 | 
            +
            file XPI.xpi => XPI.files do |t|
         | 
| 318 | 
            +
              STDERR.puts "Building #{t.name}"
         | 
| 319 | 
            +
              Dir["*.xpi"].each{|f| File.unlink(f) }
         | 
| 320 | 
            +
             | 
| 321 | 
            +
              Zip::File.open(t.name, 'w') do |zipfile|
         | 
| 322 | 
            +
                t.sources.sort.each{|src|
         | 
| 323 | 
            +
                  case File.basename(src)
         | 
| 324 | 
            +
                  when 'install.rdf'
         | 
| 325 | 
            +
                    install_rdf = Nokogiri::XML(File.open(src))
         | 
| 326 | 
            +
                    install_rdf.at('//em:version').content = XPI.version
         | 
| 327 | 
            +
                    zipfile.get_output_stream(src){|f| install_rdf.write_xml_to f }
         | 
| 328 | 
            +
                  else
         | 
| 329 | 
            +
                    zipfile.add(src, src)
         | 
| 330 | 
            +
                  end
         | 
| 331 | 
            +
                }
         | 
| 332 | 
            +
              end
         | 
| 333 | 
            +
             | 
| 334 | 
            +
              begin
         | 
| 335 | 
            +
                XPI.sign
         | 
| 336 | 
            +
              rescue => e
         | 
| 337 | 
            +
                FileUtils.rm_f(XPI.xpi)
         | 
| 338 | 
            +
                raise e
         | 
| 339 | 
            +
              end
         | 
| 340 | 
            +
            end
         | 
| 341 | 
            +
             | 
| 342 | 
            +
            rule '.js' => '.pegjs' do |t|
         | 
| 343 | 
            +
              sh "#{NODEBIN}/pegjs -e #{File.basename(t.source, File.extname(t.source))} #{t.source.shellescape} #{t.name.shellescape}"
         | 
| 344 | 
            +
            end
         | 
| 345 | 
            +
             | 
| 346 | 
            +
            task :npm do
         | 
| 347 | 
            +
              sh "npm install --save coffee-script coffeelint pegjs"
         | 
| 348 | 
            +
            end
         | 
| 349 | 
            +
             | 
| 350 | 
            +
            rule '.js' => '.coffee' do |t|
         | 
| 351 | 
            +
              sh "#{NODEBIN}/coffeelint #{t.source.shellescape}"
         | 
| 352 | 
            +
              sh "#{NODEBIN}/coffee -bc #{t.source.shellescape}"
         | 
| 353 | 
            +
            end
         | 
| 354 | 
            +
             | 
| 355 | 
            +
            task :bump, :level do |t, args|
         | 
| 356 | 
            +
              modified = `git ls-files -m`.split(/\n/).reject{|f| f == 'www' || f == 'wiki'}
         | 
| 357 | 
            +
              throw "#{modified.length} modified files not checked in" unless modified.length == 0
         | 
| 358 | 
            +
              XPI.bump(args[:level])
         | 
| 359 | 
            +
             | 
| 360 | 
            +
              sh "git add install.rdf"
         | 
| 361 | 
            +
              sh "git commit -m #{XPI.release_message.shellescape}"
         | 
| 362 | 
            +
              sh "git tag #{XPI.release.shellescape}"
         | 
| 363 | 
            +
            end
         | 
| 364 | 
            +
             | 
| 365 | 
            +
            task :publish => XPI.xpi do
         | 
| 366 | 
            +
              if !XPI.pull_request
         | 
| 367 | 
            +
                STDERR.puts "Publishing #{XPI.release_build? ? 'release' : 'debug'} build #{XPI.versioned_xpi}"
         | 
| 368 | 
            +
                STDERR.puts "Published to " + XPI.publish
         | 
| 369 | 
            +
              end
         | 
| 370 | 
            +
            end
         | 
| @@ -0,0 +1,57 @@ | |
| 1 | 
            +
            #require 'aws-sdk'
         | 
| 2 | 
            +
            #require 'fileutils'
         | 
| 3 | 
            +
            #require 'jwt'
         | 
| 4 | 
            +
            #require 'nokogiri'
         | 
| 5 | 
            +
            #require 'open-uri'
         | 
| 6 | 
            +
            #require 'ostruct'
         | 
| 7 | 
            +
            #require 'rake'
         | 
| 8 | 
            +
            #require 'recursive-open-struct'
         | 
| 9 | 
            +
            #require 'rest-client'
         | 
| 10 | 
            +
            #require 'securerandom'
         | 
| 11 | 
            +
            #require 'socket'
         | 
| 12 | 
            +
            #require 'tempfile'
         | 
| 13 | 
            +
            #require 'uri'
         | 
| 14 | 
            +
            #require 'yaml'
         | 
| 15 | 
            +
            #require 'zip'
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            module Rake
         | 
| 18 | 
            +
              module XPI
         | 
| 19 | 
            +
                class Config
         | 
| 20 | 
            +
                  def publish
         | 
| 21 | 
            +
                    raise "Bintray publishing not configured" unless @config.bintray && @config.bintray.secret
         | 
| 22 | 
            +
                    STDERR.puts "Publishing #{self.versioned_xpi} to Bintray"
         | 
| 23 | 
            +
                    #RestClient.log = 'stdout'
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                    secret = ENV[@config.bintray.secret]
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                    client = RestClient::Resource.new('https://api.bintray.com', @config.bintray.user, secret)
         | 
| 28 | 
            +
                    content = client['content'][@config.bintray.user][@config.bintray.repo]
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                    begin
         | 
| 31 | 
            +
                      client['packages'][@config.bintray.user][@config.bintray.repo][@config.bintray.package]['versions']['latest'].delete
         | 
| 32 | 
            +
                    rescue RestClient::ResourceNotFound
         | 
| 33 | 
            +
                      # that's OK
         | 
| 34 | 
            +
                    end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                    content[@config.bintray.package][self.version][self.versioned_xpi].put(File.new(self.xpi), {
         | 
| 37 | 
            +
                      content_type: 'application/x-xpinstall',
         | 
| 38 | 
            +
                      x_bintray_package: @config.bintray.package,
         | 
| 39 | 
            +
                      x_bintray_version: self.version,
         | 
| 40 | 
            +
                      x_bintray_publish: '1'
         | 
| 41 | 
            +
                    })
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                    if release_build?
         | 
| 44 | 
            +
                      update_rdf("https://bintray.com/artifact/download/#{@config.bintray.user}/#{@config.bintray.repo}/#{@config.bintray.package}/#{self.version}/#{self.versioned_xpi}"){|update|
         | 
| 45 | 
            +
                        content[@config.repo.package]['update.rdf'].put(File.new(update), {
         | 
| 46 | 
            +
                          content_type: 'application/rdf+xml',
         | 
| 47 | 
            +
                          x_bintray_package: @config.repo.package,
         | 
| 48 | 
            +
                          x_bintray_version: 'latest',
         | 
| 49 | 
            +
                          x_bintray_publish: '1',
         | 
| 50 | 
            +
                          x_bintray_override: '1'
         | 
| 51 | 
            +
                        })
         | 
| 52 | 
            +
                      }
         | 
| 53 | 
            +
                    end
         | 
| 54 | 
            +
                  end
         | 
| 55 | 
            +
                end
         | 
| 56 | 
            +
              end
         | 
| 57 | 
            +
            end
         | 
| @@ -0,0 +1,81 @@ | |
| 1 | 
            +
            require 'github_api'
         | 
| 2 | 
            +
            #require 'aws-sdk'
         | 
| 3 | 
            +
            #require 'fileutils'
         | 
| 4 | 
            +
            #require 'jwt'
         | 
| 5 | 
            +
            #require 'nokogiri'
         | 
| 6 | 
            +
            #require 'open-uri'
         | 
| 7 | 
            +
            #require 'ostruct'
         | 
| 8 | 
            +
            #require 'rake'
         | 
| 9 | 
            +
            #require 'recursive-open-struct'
         | 
| 10 | 
            +
            #require 'rest-client'
         | 
| 11 | 
            +
            #require 'securerandom'
         | 
| 12 | 
            +
            #require 'socket'
         | 
| 13 | 
            +
            #require 'tempfile'
         | 
| 14 | 
            +
            #require 'uri'
         | 
| 15 | 
            +
            #require 'yaml'
         | 
| 16 | 
            +
            #require 'zip'
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            module Rake
         | 
| 19 | 
            +
              module XPI
         | 
| 20 | 
            +
                class Config
         | 
| 21 | 
            +
                  def get_stable_release(tag, prerelease)
         | 
| 22 | 
            +
                    release = @releases.list(@config.github.user, @config.github.repo).detect{|rel| rel.tag_name == tag }
         | 
| 23 | 
            +
                    return release if release
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                    sha = `git rev-list --max-parents=0 HEAD`.split(/\n/).collect{|sha| sha.strip}.first
         | 
| 26 | 
            +
                    release = @releases.create(@config.github.user, @config.github.repo, {
         | 
| 27 | 
            +
                      tag_name: tag,
         | 
| 28 | 
            +
                      target_commitish: sha,
         | 
| 29 | 
            +
                      name: tag,
         | 
| 30 | 
            +
                      body: tag,
         | 
| 31 | 
            +
                      prerelease: prerelease
         | 
| 32 | 
            +
                    })
         | 
| 33 | 
            +
                  end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  def publish
         | 
| 36 | 
            +
                    raise "Github publishing not configured" unless @config.github && @config.github.user && @config.github.token
         | 
| 37 | 
            +
                    token = ENV[@config.github.token]
         | 
| 38 | 
            +
                    raise "Github publishing not configured" unless token
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                    @github = Github.new({oauth_token: token})
         | 
| 41 | 
            +
                    @releases = @github.repos.releases
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                    release = nil
         | 
| 44 | 
            +
                    if release_build?
         | 
| 45 | 
            +
                      # create release and upload assets
         | 
| 46 | 
            +
                      release = @releases.create(@config.github.user, @config.github.repo, {
         | 
| 47 | 
            +
                        tag_name: self.release,
         | 
| 48 | 
            +
                        name: self.release,
         | 
| 49 | 
            +
                        body: self.release
         | 
| 50 | 
            +
                      })
         | 
| 51 | 
            +
                    else
         | 
| 52 | 
            +
                      release = get_stable_release('builds', true)
         | 
| 53 | 
            +
                    end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                    @releases.assets.upload(@config.github.user, @config.github.repo, release.id, self.xpi, {
         | 
| 56 | 
            +
                      name: self.versioned_xpi,
         | 
| 57 | 
            +
                      content_type: 'application/x-xpinstall'
         | 
| 58 | 
            +
                    })
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                    download = "https://github.com/#{@config.github.user}/#{@config.github.repo}/releases/download/#{release.name}/#{self.versioned_xpi}"
         | 
| 61 | 
            +
                    if release_build?
         | 
| 62 | 
            +
                      release = get_stable_release('update.rdf', false)
         | 
| 63 | 
            +
                      # Remove any existing assets
         | 
| 64 | 
            +
                      @github.repos.releases.assets.list(@config.github.user, @config.github.repo, release.id){ |asset|
         | 
| 65 | 
            +
                        @github.repos.releases.assets.delete(@config.github.user, @config.github.repo, asset.id)
         | 
| 66 | 
            +
                      }
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                      update_rdf(download){|update|
         | 
| 69 | 
            +
                        @releases.assets.upload(@config.github.user, @config.github.repo, release.id, update, {
         | 
| 70 | 
            +
                          name: 'update.rdf',
         | 
| 71 | 
            +
                          content_type: 'application/rdf+xml'
         | 
| 72 | 
            +
                        })
         | 
| 73 | 
            +
                      }
         | 
| 74 | 
            +
                    end
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                    return download
         | 
| 77 | 
            +
                  end
         | 
| 78 | 
            +
                end
         | 
| 79 | 
            +
              end
         | 
| 80 | 
            +
            end
         | 
| 81 | 
            +
             | 
    
        data/lib/rake/xpi/s3.rb
    ADDED
    
    | @@ -0,0 +1,83 @@ | |
| 1 | 
            +
            #require 'aws-sdk'
         | 
| 2 | 
            +
            #require 'fileutils'
         | 
| 3 | 
            +
            #require 'jwt'
         | 
| 4 | 
            +
            #require 'nokogiri'
         | 
| 5 | 
            +
            #require 'open-uri'
         | 
| 6 | 
            +
            #require 'ostruct'
         | 
| 7 | 
            +
            #require 'rake'
         | 
| 8 | 
            +
            #require 'recursive-open-struct'
         | 
| 9 | 
            +
            #require 'rest-client'
         | 
| 10 | 
            +
            #require 'securerandom'
         | 
| 11 | 
            +
            #require 'socket'
         | 
| 12 | 
            +
            #require 'tempfile'
         | 
| 13 | 
            +
            #require 'uri'
         | 
| 14 | 
            +
            #require 'yaml'
         | 
| 15 | 
            +
            #require 'zip'
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            module Rake
         | 
| 18 | 
            +
              module XPI
         | 
| 19 | 
            +
                class Config
         | 
| 20 | 
            +
                  def publish
         | 
| 21 | 
            +
                    raise "S3 publishing not configured" unless @config.s3 && @config.s3.id && @config.s3.secret
         | 
| 22 | 
            +
                    STDERR.puts "Publishing #{self.versioned_xpi} to S3"
         | 
| 23 | 
            +
                    id = ENV[@config.s3.id]
         | 
| 24 | 
            +
                    secret = ENV[@config.s3.secret]
         | 
| 25 | 
            +
                    return false unless id && secret
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                    s3 = Aws::S3::Resource.new(region: @config.s3.region, credentials: Aws::Credentials.new(id, secret))
         | 
| 28 | 
            +
                    bucket = s3.bucket(@config.s3.bucket)
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                    obj = bucket.object("#{release_build? ? @config.s3.prefix : 'builds'}/#{self.versioned_xpi}")
         | 
| 31 | 
            +
                    obj.upload_file(self.xpi, content_type: 'application/x-xpinstall')
         | 
| 32 | 
            +
                    if release_build?
         | 
| 33 | 
            +
                      update_rdf("https://s3.#{@config.s3.region}.amazonaws.com/#{@config.s3.bucket}/#{@config.s3.prefix}/#{self.versioned_xpi}"){|update|
         | 
| 34 | 
            +
                        obj = bucket.object("#{@config.s3.prefix}/update.rdf")
         | 
| 35 | 
            +
                        obj.upload_file(update, content_type: 'application/rdf+xml')
         | 
| 36 | 
            +
                      }
         | 
| 37 | 
            +
                    end
         | 
| 38 | 
            +
                  end
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
              end
         | 
| 41 | 
            +
            end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
            task :bucket, [:uploader, :id, :secret] do |t, args|
         | 
| 44 | 
            +
              id = args[:id] || ENV[XPI.s3.id]
         | 
| 45 | 
            +
              secret = args[:secret] || ENV[XPI.s3.secret]
         | 
| 46 | 
            +
              uploader = args[:uploader]
         | 
| 47 | 
            +
             | 
| 48 | 
            +
              s3 = Aws::S3::Resource.new(region: XPI.s3.region, credentials: Aws::Credentials.new(id, secret))
         | 
| 49 | 
            +
              bucket = s3.bucket(XPI.s3.bucket)
         | 
| 50 | 
            +
              bucket.create() unless bucket.exists?
         | 
| 51 | 
            +
             | 
| 52 | 
            +
              bucket.policy.put(policy: {
         | 
| 53 | 
            +
                "Version": "2012-10-17",
         | 
| 54 | 
            +
                "Id": "XPI downloads",
         | 
| 55 | 
            +
                "Statement": [
         | 
| 56 | 
            +
                  {
         | 
| 57 | 
            +
                    "Sid": "Stmt1435253907295",
         | 
| 58 | 
            +
                    "Effect": "Allow",
         | 
| 59 | 
            +
                    "Principal": { "AWS": uploader },
         | 
| 60 | 
            +
                    "Action": "s3:*",
         | 
| 61 | 
            +
                    "Resource": "arn:aws:s3:::#{XPI.s3.bucket}/*"
         | 
| 62 | 
            +
                  },
         | 
| 63 | 
            +
                  {
         | 
| 64 | 
            +
                    "Sid": "PublicRead",
         | 
| 65 | 
            +
                    "Effect": "Allow",
         | 
| 66 | 
            +
                    "Principal": "*",
         | 
| 67 | 
            +
                    "Action": "s3:GetObject",
         | 
| 68 | 
            +
                    "Resource": "arn:aws:s3:::#{XPI.s3.bucket}/*"
         | 
| 69 | 
            +
                  }
         | 
| 70 | 
            +
                ]
         | 
| 71 | 
            +
              }.to_json)
         | 
| 72 | 
            +
             | 
| 73 | 
            +
              bucket.lifecycle.put(lifecycle_configuration: {
         | 
| 74 | 
            +
                rules: [
         | 
| 75 | 
            +
                  {
         | 
| 76 | 
            +
                    status: "Enabled",
         | 
| 77 | 
            +
                    prefix: "builds/",
         | 
| 78 | 
            +
                    expiration: { days: 7 },
         | 
| 79 | 
            +
                    id: "cleanup-build"
         | 
| 80 | 
            +
                  }
         | 
| 81 | 
            +
                ]
         | 
| 82 | 
            +
              })
         | 
| 83 | 
            +
            end
         | 
| @@ -0,0 +1,81 @@ | |
| 1 | 
            +
            require 'net/sftp'
         | 
| 2 | 
            +
            require 'nokogiri'
         | 
| 3 | 
            +
            require 'shellwords'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module Rake
         | 
| 6 | 
            +
              module XPI
         | 
| 7 | 
            +
                class Config
         | 
| 8 | 
            +
                  include Rake::DSL
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                  def publish
         | 
| 11 | 
            +
                    raise "Sourceforge publishing not configured" unless @config.sourceforge && @config.sourceforge.project && @config.sourceforge.user && @config.sourceforge.key
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                    STDERR.puts "Publishing #{self.versioned_xpi} to sourceforge"
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                    builds = 'builds'
         | 
| 16 | 
            +
                    download = "http://downloads.sourceforge.net/project/#{@config.sourceforge.project}/#{self.release_build? ? self.release : builds}/#{self.versioned_xpi}"
         | 
| 17 | 
            +
                    latest = nil
         | 
| 18 | 
            +
                    # assumes ssh keys set up properly
         | 
| 19 | 
            +
                    Net::SFTP.start('frs.sourceforge.net', @config.sourceforge.user) do |sftp|
         | 
| 20 | 
            +
                      root = "/home/frs/project/#{@config.sourceforge.project}"
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                      mkdir = lambda do |dir|
         | 
| 23 | 
            +
                        dir = "#{root}/#{dir}" unless dir =~ /^\//
         | 
| 24 | 
            +
                        begin
         | 
| 25 | 
            +
                          sftp.mkdir!(dir)
         | 
| 26 | 
            +
                        rescue => e
         | 
| 27 | 
            +
                          STDERR.puts "#{dir} exists: #{e}"
         | 
| 28 | 
            +
                        end
         | 
| 29 | 
            +
                      end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                      if self.release_build?
         | 
| 32 | 
            +
                        mkdir.call('update')
         | 
| 33 | 
            +
                        update_rdf(download){|update|
         | 
| 34 | 
            +
                          sftp.upload!(update, "#{root}/update/update.rdf")
         | 
| 35 | 
            +
                        }
         | 
| 36 | 
            +
                        latest = self.release
         | 
| 37 | 
            +
                      else
         | 
| 38 | 
            +
                        begin
         | 
| 39 | 
            +
                          latest = Nokogiri::XML(sftp.download!("#{root}/update/update.rdf")).at('//em:version').inner_text
         | 
| 40 | 
            +
                        rescue => e
         | 
| 41 | 
            +
                          STDERR.puts "no existing release (#{e})"
         | 
| 42 | 
            +
                        end
         | 
| 43 | 
            +
                      end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                      # create builds dir
         | 
| 46 | 
            +
                      mkdir.call(builds)
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                      # create release dir
         | 
| 49 | 
            +
                      dir = "#{root}/#{self.release_build? ? self.release : builds}"
         | 
| 50 | 
            +
                      begin
         | 
| 51 | 
            +
                        sftp.mkdir!(dir)
         | 
| 52 | 
            +
                      rescue
         | 
| 53 | 
            +
                      end
         | 
| 54 | 
            +
                      # put the XPI there
         | 
| 55 | 
            +
                      sftp.upload!(File.absolute_path(xpi), "#{dir}/#{self.versioned_xpi}")
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                      # remove builds older than a week
         | 
| 58 | 
            +
                      cutoff = (Time.now - (7*24*60*60)).to_i
         | 
| 59 | 
            +
                      old = []
         | 
| 60 | 
            +
                      sftp.dir.foreach("#{root}/#{builds}") do |file|
         | 
| 61 | 
            +
                        old << file.longname if file.attributes.mtime < cutoff
         | 
| 62 | 
            +
                      end
         | 
| 63 | 
            +
                      old.each{|file|
         | 
| 64 | 
            +
                        sftp.remove(file)
         | 
| 65 | 
            +
                      }
         | 
| 66 | 
            +
                    end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                    if latest
         | 
| 69 | 
            +
                      # https://sourceforge.net/p/forge/documentation/Using%20the%20Release%20API/
         | 
| 70 | 
            +
                      RestClient.put(
         | 
| 71 | 
            +
                        "https://sourceforge.net/projects/#{@config.sourceforge.project}/files/#{latest}/#{self.versioned_xpi(latest)}",
         | 
| 72 | 
            +
                        "default=windows&default=mac&default=linux&default=bsd&default=solaris&default=others&api_key=#{ENV[@config.sourceforge.key]}",
         | 
| 73 | 
            +
                        {accept: :json}
         | 
| 74 | 
            +
                      )
         | 
| 75 | 
            +
                    end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                    return download
         | 
| 78 | 
            +
                  end
         | 
| 79 | 
            +
                end
         | 
| 80 | 
            +
              end
         | 
| 81 | 
            +
            end
         | 
    
        data/rake-xpi.gemspec
    ADDED
    
    | @@ -0,0 +1,33 @@ | |
| 1 | 
            +
            # coding: utf-8
         | 
| 2 | 
            +
            lib = File.expand_path('../lib', __FILE__)
         | 
| 3 | 
            +
            $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            Gem::Specification.new do |spec|
         | 
| 6 | 
            +
              spec.name          = "rake-xpi"
         | 
| 7 | 
            +
              spec.version       = '0.0.4'
         | 
| 8 | 
            +
              spec.authors       = ["Emiliano Heyns"]
         | 
| 9 | 
            +
              spec.email         = ["Emiliano.Heyns@iris-advies.com"]
         | 
| 10 | 
            +
              spec.description   = %q{rake helper to build XPI files}
         | 
| 11 | 
            +
              spec.summary       = %q{rake helper to build XPI files}
         | 
| 12 | 
            +
              spec.homepage      = "http://zotplus.github.io"
         | 
| 13 | 
            +
              spec.license       = "MIT"
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              spec.files         = `git ls-files`.split($/)
         | 
| 16 | 
            +
              spec.executables   = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
         | 
| 17 | 
            +
              spec.test_files    = spec.files.grep(%r{^(test|spec|features)/})
         | 
| 18 | 
            +
              spec.require_paths = ["lib"]
         | 
| 19 | 
            +
              spec.required_ruby_version = '>= 2.2'
         | 
| 20 | 
            +
             | 
| 21 | 
            +
              spec.add_development_dependency "bundler", "~> 1.3"
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              spec.add_runtime_dependency 'aws-sdk'
         | 
| 24 | 
            +
              spec.add_runtime_dependency 'github_api'
         | 
| 25 | 
            +
              spec.add_runtime_dependency 'jwt'
         | 
| 26 | 
            +
              spec.add_runtime_dependency 'multipart-post'
         | 
| 27 | 
            +
              spec.add_runtime_dependency 'nokogiri'
         | 
| 28 | 
            +
              spec.add_runtime_dependency 'rake', '>= 0', '>= 0'
         | 
| 29 | 
            +
              spec.add_runtime_dependency 'recursive-open-struct'
         | 
| 30 | 
            +
              spec.add_runtime_dependency 'rest-client'
         | 
| 31 | 
            +
              spec.add_runtime_dependency 'rubyzip', '>= 1.0.0' # will load new rubyzip version
         | 
| 32 | 
            +
              spec.add_runtime_dependency 'zip-zip' # will load compatibility for old rubyzip API.
         | 
| 33 | 
            +
            end
         | 
    
        metadata
    ADDED
    
    | @@ -0,0 +1,207 @@ | |
| 1 | 
            +
            --- !ruby/object:Gem::Specification
         | 
| 2 | 
            +
            name: rake-xpi
         | 
| 3 | 
            +
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            +
              version: 0.0.4
         | 
| 5 | 
            +
            platform: ruby
         | 
| 6 | 
            +
            authors:
         | 
| 7 | 
            +
            - Emiliano Heyns
         | 
| 8 | 
            +
            autorequire: 
         | 
| 9 | 
            +
            bindir: bin
         | 
| 10 | 
            +
            cert_chain: []
         | 
| 11 | 
            +
            date: 2016-03-29 00:00:00.000000000 Z
         | 
| 12 | 
            +
            dependencies:
         | 
| 13 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 14 | 
            +
              name: bundler
         | 
| 15 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 16 | 
            +
                requirements:
         | 
| 17 | 
            +
                - - "~>"
         | 
| 18 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            +
                    version: '1.3'
         | 
| 20 | 
            +
              type: :development
         | 
| 21 | 
            +
              prerelease: false
         | 
| 22 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 | 
            +
                requirements:
         | 
| 24 | 
            +
                - - "~>"
         | 
| 25 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 26 | 
            +
                    version: '1.3'
         | 
| 27 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 28 | 
            +
              name: aws-sdk
         | 
| 29 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 30 | 
            +
                requirements:
         | 
| 31 | 
            +
                - - ">="
         | 
| 32 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 33 | 
            +
                    version: '0'
         | 
| 34 | 
            +
              type: :runtime
         | 
| 35 | 
            +
              prerelease: false
         | 
| 36 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 37 | 
            +
                requirements:
         | 
| 38 | 
            +
                - - ">="
         | 
| 39 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 40 | 
            +
                    version: '0'
         | 
| 41 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 42 | 
            +
              name: github_api
         | 
| 43 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 44 | 
            +
                requirements:
         | 
| 45 | 
            +
                - - ">="
         | 
| 46 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 47 | 
            +
                    version: '0'
         | 
| 48 | 
            +
              type: :runtime
         | 
| 49 | 
            +
              prerelease: false
         | 
| 50 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 51 | 
            +
                requirements:
         | 
| 52 | 
            +
                - - ">="
         | 
| 53 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 54 | 
            +
                    version: '0'
         | 
| 55 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 56 | 
            +
              name: jwt
         | 
| 57 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 58 | 
            +
                requirements:
         | 
| 59 | 
            +
                - - ">="
         | 
| 60 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 61 | 
            +
                    version: '0'
         | 
| 62 | 
            +
              type: :runtime
         | 
| 63 | 
            +
              prerelease: false
         | 
| 64 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 65 | 
            +
                requirements:
         | 
| 66 | 
            +
                - - ">="
         | 
| 67 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 68 | 
            +
                    version: '0'
         | 
| 69 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 70 | 
            +
              name: multipart-post
         | 
| 71 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 72 | 
            +
                requirements:
         | 
| 73 | 
            +
                - - ">="
         | 
| 74 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 75 | 
            +
                    version: '0'
         | 
| 76 | 
            +
              type: :runtime
         | 
| 77 | 
            +
              prerelease: false
         | 
| 78 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 79 | 
            +
                requirements:
         | 
| 80 | 
            +
                - - ">="
         | 
| 81 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 82 | 
            +
                    version: '0'
         | 
| 83 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 84 | 
            +
              name: nokogiri
         | 
| 85 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 86 | 
            +
                requirements:
         | 
| 87 | 
            +
                - - ">="
         | 
| 88 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 89 | 
            +
                    version: '0'
         | 
| 90 | 
            +
              type: :runtime
         | 
| 91 | 
            +
              prerelease: false
         | 
| 92 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 93 | 
            +
                requirements:
         | 
| 94 | 
            +
                - - ">="
         | 
| 95 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 96 | 
            +
                    version: '0'
         | 
| 97 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 98 | 
            +
              name: rake
         | 
| 99 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 100 | 
            +
                requirements:
         | 
| 101 | 
            +
                - - ">="
         | 
| 102 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 103 | 
            +
                    version: '0'
         | 
| 104 | 
            +
              type: :runtime
         | 
| 105 | 
            +
              prerelease: false
         | 
| 106 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 107 | 
            +
                requirements:
         | 
| 108 | 
            +
                - - ">="
         | 
| 109 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 110 | 
            +
                    version: '0'
         | 
| 111 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 112 | 
            +
              name: recursive-open-struct
         | 
| 113 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 114 | 
            +
                requirements:
         | 
| 115 | 
            +
                - - ">="
         | 
| 116 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 117 | 
            +
                    version: '0'
         | 
| 118 | 
            +
              type: :runtime
         | 
| 119 | 
            +
              prerelease: false
         | 
| 120 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 121 | 
            +
                requirements:
         | 
| 122 | 
            +
                - - ">="
         | 
| 123 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 124 | 
            +
                    version: '0'
         | 
| 125 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 126 | 
            +
              name: rest-client
         | 
| 127 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 128 | 
            +
                requirements:
         | 
| 129 | 
            +
                - - ">="
         | 
| 130 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 131 | 
            +
                    version: '0'
         | 
| 132 | 
            +
              type: :runtime
         | 
| 133 | 
            +
              prerelease: false
         | 
| 134 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 135 | 
            +
                requirements:
         | 
| 136 | 
            +
                - - ">="
         | 
| 137 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 138 | 
            +
                    version: '0'
         | 
| 139 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 140 | 
            +
              name: rubyzip
         | 
| 141 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 142 | 
            +
                requirements:
         | 
| 143 | 
            +
                - - ">="
         | 
| 144 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 145 | 
            +
                    version: 1.0.0
         | 
| 146 | 
            +
              type: :runtime
         | 
| 147 | 
            +
              prerelease: false
         | 
| 148 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 149 | 
            +
                requirements:
         | 
| 150 | 
            +
                - - ">="
         | 
| 151 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 152 | 
            +
                    version: 1.0.0
         | 
| 153 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 154 | 
            +
              name: zip-zip
         | 
| 155 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 156 | 
            +
                requirements:
         | 
| 157 | 
            +
                - - ">="
         | 
| 158 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 159 | 
            +
                    version: '0'
         | 
| 160 | 
            +
              type: :runtime
         | 
| 161 | 
            +
              prerelease: false
         | 
| 162 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 163 | 
            +
                requirements:
         | 
| 164 | 
            +
                - - ">="
         | 
| 165 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 166 | 
            +
                    version: '0'
         | 
| 167 | 
            +
            description: rake helper to build XPI files
         | 
| 168 | 
            +
            email:
         | 
| 169 | 
            +
            - Emiliano.Heyns@iris-advies.com
         | 
| 170 | 
            +
            executables: []
         | 
| 171 | 
            +
            extensions: []
         | 
| 172 | 
            +
            extra_rdoc_files: []
         | 
| 173 | 
            +
            files:
         | 
| 174 | 
            +
            - Gemfile
         | 
| 175 | 
            +
            - Gemfile.lock
         | 
| 176 | 
            +
            - Rakefile
         | 
| 177 | 
            +
            - lib/rake/xpi.rb
         | 
| 178 | 
            +
            - lib/rake/xpi/bintray.rb
         | 
| 179 | 
            +
            - lib/rake/xpi/github.rb
         | 
| 180 | 
            +
            - lib/rake/xpi/s3.rb
         | 
| 181 | 
            +
            - lib/rake/xpi/sourceforge.rb
         | 
| 182 | 
            +
            - rake-xpi.gemspec
         | 
| 183 | 
            +
            homepage: http://zotplus.github.io
         | 
| 184 | 
            +
            licenses:
         | 
| 185 | 
            +
            - MIT
         | 
| 186 | 
            +
            metadata: {}
         | 
| 187 | 
            +
            post_install_message: 
         | 
| 188 | 
            +
            rdoc_options: []
         | 
| 189 | 
            +
            require_paths:
         | 
| 190 | 
            +
            - lib
         | 
| 191 | 
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         | 
| 192 | 
            +
              requirements:
         | 
| 193 | 
            +
              - - ">="
         | 
| 194 | 
            +
                - !ruby/object:Gem::Version
         | 
| 195 | 
            +
                  version: '2.2'
         | 
| 196 | 
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 197 | 
            +
              requirements:
         | 
| 198 | 
            +
              - - ">="
         | 
| 199 | 
            +
                - !ruby/object:Gem::Version
         | 
| 200 | 
            +
                  version: '0'
         | 
| 201 | 
            +
            requirements: []
         | 
| 202 | 
            +
            rubyforge_project: 
         | 
| 203 | 
            +
            rubygems_version: 2.5.0
         | 
| 204 | 
            +
            signing_key: 
         | 
| 205 | 
            +
            specification_version: 4
         | 
| 206 | 
            +
            summary: rake helper to build XPI files
         | 
| 207 | 
            +
            test_files: []
         |