From 7928e8816d186d7f221cfbcfde7b9d7f088d1106 Mon Sep 17 00:00:00 2001 From: Javan Makhmali Date: Tue, 1 Dec 2015 08:50:17 -0500 Subject: [PATCH] bin/release [ci skip] --- Gemfile | 1 + Gemfile.lock | 23 ++++++++++ bin/release | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 146 insertions(+) create mode 100755 bin/release diff --git a/Gemfile b/Gemfile index 8310f645e..fe9f28916 100644 --- a/Gemfile +++ b/Gemfile @@ -10,3 +10,4 @@ gem 'uglifier' gem 'blade', github: 'javan/blade' gem 'blade-sauce_labs_plugin', github: 'javan/blade-sauce_labs_plugin' +gem 'github_api' diff --git a/Gemfile.lock b/Gemfile.lock index 15881a895..b1ff50860 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -45,6 +45,8 @@ GEM cookiejar (0.3.2) curses (1.0.1) daemons (1.2.3) + descendants_tracker (0.0.4) + thread_safe (~> 0.3, >= 0.3.1) eco (1.0.0) coffee-script eco-source @@ -74,12 +76,32 @@ GEM eventmachine (>= 0.12.0) websocket-driver (>= 0.5.1) ffi (1.9.10) + github_api (0.13.0) + addressable (~> 2.3) + descendants_tracker (~> 0.0.4) + faraday (~> 0.8, < 0.10) + hashie (>= 3.4) + multi_json (>= 1.7.5, < 2.0) + nokogiri (~> 1.6.6) + oauth2 + hashie (3.4.3) http_parser.rb (0.6.0) i18n (0.7.0) json (1.8.3) + jwt (1.5.2) + mini_portile2 (2.0.0) minitest (5.8.3) multi_json (1.11.2) + multi_xml (0.5.5) multipart-post (2.0.0) + nokogiri (1.6.7) + mini_portile2 (~> 2.0.0.rc2) + oauth2 (1.0.0) + faraday (>= 0.8, < 0.10) + jwt (~> 1.0) + multi_json (~> 1.3) + multi_xml (~> 0.5) + rack (~> 1.2) rack (1.6.4) rake (10.0.4) rubyzip (1.1.7) @@ -117,6 +139,7 @@ DEPENDENCIES coffee-script coffee-script-source (~> 1.9.1) eco + github_api rake sass sprockets diff --git a/bin/release b/bin/release new file mode 100755 index 000000000..73422be10 --- /dev/null +++ b/bin/release @@ -0,0 +1,122 @@ +#!/usr/bin/env ruby + +require "bundler/setup" +require "github_api" +require "pathname" +require "json" + +class Release + NAME = "Trix" + REPO = "trix" + OWNER = "basecamp" + + def perform + confirm_version + check_github_release + check_npm + + build + update_package_json + commit_changes + create_release + npm_publish + end + + def version + @version ||= Pathname.new("src/trix/VERSION").read.chomp + end + + def confirm_version + confirm("Release #{NAME} #{version}?") || abort + end + + def build + puts "Building…" + system("rm -rf tmp/ && bin/blade build") || abort("Build failed") + end + + def update_package_json + puts "Updating package.json…" + + pathname = Pathname.new("package.json") + data = JSON.parse(pathname.read) + data["version"] = version + pathname.write(JSON.pretty_generate(data) + "\n") + end + + def commit_changes + puts `git status #{pathspecs.join(' ')}` + + if confirm "Commit changes?" + abort("Failed to commit") unless \ + system("git add #{pathspecs.join(' ')}") && + system("git commit -m '#{NAME} #{version}'") && + system("git push") && + system("git tag #{version}") && + system("git push --tags") + else + abort + end + end + + def create_release + puts "Creating release…" + release = github.repos.releases.create(OWNER, REPO, tag_name: version) + + puts "Uploading dist files for release…" + dist_pathnames.each do |pathname| + github.repos.releases.assets.upload OWNER, REPO, release.id, pathname.to_s, name: pathname.basename.to_s, content_type: content_type(pathname) + end + end + + def pathspecs + %w( dist/ src/ package.json ) + end + + def dist_pathnames + Pathname.new("dist").children + end + + def content_type(pathname) + case pathname.extname + when ".js" then "application/javascript" + when ".css" then "text/css" + end + end + + def check_github_release + releases = github.repos.releases.list(OWNER, REPO) + if release = releases.detect { |release| release.tag_name == version } + abort "Already released #{version}: #{release.html_url}" + end + end + + def github + @github ||= begin + username = `git config --global --get github.user`.chomp + password = `git config --global --get github.token`.chomp + + if username.nil? || username == "" || password.nil? || password == "" + abort "Must set github.user and github.token in your global gitconfig" + end + + Github.new basic_auth: "#{username}:#{password}" + end + end + + def check_npm + system("npm whoami") || abort("Must be logged in to npm" ) + end + + def npm_publish + puts "Publishing to npm…" + system("npm publish") || abort("npm publish failed") + end + + def confirm(question) + print "#{question} (y/n) " + gets.chomp.downcase == "y" + end +end + +Release.new.perform