#!/usr/bin/env ruby begin require 'cocaine' rescue LoadError puts "Cocaine gem not found, install it: 'gem install cocaine'" exit end require 'yaml' module Release class Version attr_accessor :major, :minor, :patch VERSION_REGEX = /.*([0-9]+)\.([0-9]+)\.([0-9]+).*/ def self.load [Ruby, Yaml].detect(&:check?).new end def initialize read end def file self.class::FILE end def increment if ENV.key?('VERSION') self.version = ENV['VERSION'] elsif ENV.key?('MAJOR') increment_major elsif ENV.key?('MINOR') increment_minor else increment_patch end self end def increment_major self.patch = 0 self.minor = 0 self.major += 1 end def increment_minor self.patch = 0 self.minor += 1 end def increment_patch self.patch += 1 end def next dup.increment end def version "#{major}.#{minor}.#{patch}" end def version=(version) match = VERSION_REGEX.match version self.major = match[1].to_i self.minor = match[2].to_i self.patch = match[3].to_i end def save write version end class Ruby < Version FILE = Dir.glob(File.join('lib', '*', 'version.rb')).first REGEX = /VERSION\s*=\s*['"]([0-9]+)\.([0-9]+)\.([0-9]+)['"]/ def self.check? !FILE.nil? end private def read file_version = File.open(FILE, 'r') { |f| f.grep(REGEX).first } self.version = file_version end def write content = File.read(FILE).gsub(REGEX, "VERSION = '#{version}'") File.open(FILE, 'w') { |f| f.write content } end end class Yaml < Version FILE = File.join('config', 'version.yml') def self.check? File.exist?(FILE) end private def read yaml = YAML.load_file(FILE) self.major = yaml['major'].to_i self.minor = yaml['minor'].to_i self.patch = yaml['patch'].to_i end def write File.open(FILE, 'w') do |f| f.write YAML.dump('major' => major, 'minor' => minor, 'patch' => patch) end end end end class Git REMOTE = 'origin' RELEASE_BRANCH = 'master' def self.create develop_branch = current_branch Cocaine::CommandLine.new('git', 'fetch :remote').run(remote: REMOTE) stash = Cocaine::CommandLine.new('git', 'stash create').run.chomp Cocaine::CommandLine.new('git', 'reset --hard').run Cocaine::CommandLine.new('git', 'checkout :branch').run(branch: RELEASE_BRANCH) Cocaine::CommandLine.new('git', 'merge --ff-only :branch').run( branch: "#{REMOTE}/#{RELEASE_BRANCH}") Cocaine::CommandLine.new('git', 'checkout :branch').run(branch: develop_branch) version = Version.load version.increment version.save Cocaine::CommandLine.new('git', 'add :file').run(file: version.file) Cocaine::CommandLine.new('git', 'commit -m :message').run( message: "Bump version to #{version.version}") Cocaine::CommandLine.new('git', 'checkout :branch').run(branch: RELEASE_BRANCH) Cocaine::CommandLine.new('git', 'merge --no-ff -m :message :branch').run( message: "Merge release #{version.version}", branch: develop_branch) Cocaine::CommandLine.new('git', 'tag -a -m :message :tag').run( message: "Release #{version.version}", tag: version.version) ensure Cocaine::CommandLine.new('git', 'checkout :branch').run(branch: develop_branch) Cocaine::CommandLine.new('git', 'stash apply :stash').run(stash: stash) unless stash.to_s.empty? end def self.current_branch branch = Cocaine::CommandLine.new('git', 'rev-parse --abbrev-ref HEAD').run.chomp branch == 'HEAD' ? current_commit : branch end def self.current_commit Cocaine::CommandLine.new('git', 'rev-parse HEAD').run.chomp end end end Release::Git.create