#!/usr/bin/env ruby -wKU require "rubygems" require "net/netrc" require "json" require 'base64' require 'openssl' require 'digest/sha1' KEYFILE = File.join(File.dirname(__FILE__), "../../TextMate/etc/sign_key.pem") PW_INFO = Net::Netrc.locate("sign.textmate.org") or abort "*** missing passphrase in ~/.netrc." REPOSITORY = 'textmate/textmate' def sign(path) # %x{openssl dgst -dss1 -sign '#{KEYFILE}' -passin 'pass:#{PW_INFO.password}' '#{path}'|openssl enc -base64}.chomp key = OpenSSL::PKey::DSA.new(File.read(KEYFILE), PW_INFO.password) or abort "*** error reading keyfile: ‘#{KEYFILE}’." digest = Digest::SHA1.digest(File.read(path)) signature = key.syssign(digest) Base64.encode64(signature).gsub("\n", '') end def aws_upload(path, url, key, acl, filename, content_type, access_key, policy, signature) rc = %x{curl -sw'%{http_code}' --show-error -o/dev/null \ -F "key=#{key}" \ -F "acl=#{acl}" \ -F "success_action_status=201" \ -F "Filename=#{filename}" \ -F "Content-Type=#{content_type}" \ -F "AWSAccessKeyId=#{access_key}" \ -F "Policy=#{policy}" \ -F "Signature=#{signature}" \ -F "file=@#{path}" \ #{url} } abort "aws error: #{rc}" unless rc == '201' end def create_download(path, repository, name, description, content_type) payload = { 'name' => name || File::basename(path), 'size' => File::size(path), 'content_type' => content_type || 'application/octet-stream' } payload['description'] = description unless description.nil? open("|curl -snd '#{payload.to_json}' https://api.github.com/repos/#{repository}/downloads") do |io| github = JSON.parse(io.read) abort "github error: #{github['errors'].inspect}" if github.include? 'errors' aws_upload(path, github['s3_url'], github['path'], github['acl'], payload['name'], payload['content_type'], github['accesskeyid'], github['policy'], github['signature']) end end if path = ARGV.shift if File.basename(path) =~ /(.+)_r(\d+)\.tbz$/ base, name, version = $&, $1, $2 description = '' create_download(path, REPOSITORY, base, description, 'application/x-bzip2') url = "https://github.com/downloads/#{REPOSITORY}/#{base}" info = { 'url' => url, 'version' => version, 'signature' => sign(path), 'signee' => PW_INFO.login } STDOUT << info.to_json end end