class GitPivotalTrackerIntegration::Command::Release

The class that encapsulates releasing a Pivotal Tracker Story

Constants

CANDIDATE_STATES
CANDIDATE_TYPES

Public Instance Methods

run(filter) click to toggle source

Releases a Pivotal Tracker story by doing the following steps:

  • Update the version to the release version

  • Create a tag for the release version

  • Update the version to the new development version

  • Push tag and changes to remote

@param [String, nil] filter a filter for selecting the release to start. This

filter can be either:
* a story id
* +nil+

@return [void]

# File lib/git-pivotal-tracker-integration/command/release.rb, line 36
def run(filter)

  $LOG.debug("#{self.class} in project:#{@project.name} pwd:#{pwd} branch:#{Util::Git.branch_name}")
  story = Util::Story.select_release(@project, filter.nil? ? 'v' : filter)

  # commenting the 2 lines below before we find an acceptable solution for story sorting
  #place_version_release story
  #pull_out_rejected_stories story
  Util::Story.pretty_print story
  $LOG.debug("story:#{story.name}")

  current_branch = Util::Git.branch_name

  # checkout QA branch
  # Update QA from origin
  puts Util::Shell.exec "git checkout QA"
  Util::Shell.exec "git reset --hard origin/QA"
  puts Util::Shell.exec "git fetch"
  Util::Shell.exec "git merge -s recursive --strategy-option theirs origin/QA"


  # checkout master branch
  # Merge QA into master
  puts Util::Shell.exec "git checkout master"
  puts Util::Shell.exec "git pull"
  if (Util::Shell.exec "git merge -s recursive --strategy-option theirs QA")
    puts "Merged 'QA' in to 'master'"
  else
    abort "FAILED to merge 'QA' in to 'master'"
  end

  # Update version and build numbers
  version_number    = story.name.dup
  version_number[0] = ""
  working_directory = pwd

  puts "Story Name:         #{story.name}"
  puts "Version Number:     #{version_number}"
  puts "Working Directory:  #{working_directory}*"
  puts ""

  if (OS.mac? && @platform.downcase == "ios")
    project_directory = @configuration.xcode_project_path
    project_directory ||= ((Util::Shell.exec 'find . -name "*.xcodeproj" 2>/dev/null').split /\/(?=[^\/]*$)/)[0]

    # cd to the project_directory
    Dir.chdir(project_directory)

    # set project number in project file
    pwd
    puts Util::Shell.exec "xcrun agvtool new-marketing-version #{version_number}"

    # cd back to the working_directory
    Dir.chdir(working_directory)
    # Change spec version
    change_spec_version(version_number) if has_spec_path?
  elsif @platform.downcase == 'android'
    updater = VersionUpdate::Gradle.new(@repository_root)
    updater.update_uat_version(version_number)
    updater.update_prod_version(version_number)
  elsif @platform.downcase == 'ruby-gem'
    file = Dir["#{Util::Git.repository_root}/*.gemspec"].first
    if file
      file_text = File.read(file)
      File.open(file, "w") {|gemspec| gemspec.puts file_text.gsub(/(?<!_)version(.*)=(.*)['|"]/, "version     = '#{version_number}'")}
    end
  end

  # Create a new build commit, push to QA
  puts Util::Git.create_commit( "Update version number to #{version_number} for release to UAT", story)
  puts Util::Shell.exec "git push"

  # Create release tag
  #create_release_tag(version_number)

  #Created tag should be pushed to private Podspec repo
  if has_spec_path? && @platform == "ios"
    puts Util::Shell.exec "git checkout #{version_number}"
    puts Util::Shell.exec "pod repo push V2PodSpecs #{@configuration.pconfig["spec"]["spec-path"]}"
    puts Util::Shell.exec "git checkout develop"
  end

  #checkout develop branch
  puts Util::Shell.exec "git checkout #{current_branch}"

  #add story name as one of the labels for the story
  story.add_label(story.name)

  i_stories = included_stories @project, story
  add_version_tag_to_stories i_stories, story

end

Private Instance Methods

add_version_tag_to_stories(stories, release_story) click to toggle source
# File lib/git-pivotal-tracker-integration/command/release.rb, line 131
def add_version_tag_to_stories(stories, release_story)
  all_stories = stories.dup
  all_stories << release_story
  puts "Included stories:\n"
  all_stories.each do |story|
    story.add_label(release_story.name)
    puts "#{story.id} - #{story.name}"
  end
end
change_spec_version(version_number) click to toggle source
# File lib/git-pivotal-tracker-integration/command/release.rb, line 183
def change_spec_version(version_number)
  spec_file_path = "#{Util::Git.repository_root}/#{@configuration.pconfig["spec"]["spec-path"]}"
  spec_file_text = File.read(spec_file_path)
  File.open(spec_file_path, "w") {|file| file.puts spec_file_text.gsub(/(?<!_)version(.*)=(.*)['|"]/, "version     = '#{version_number}'")}
end
create_release_tag(version_number) click to toggle source
# File lib/git-pivotal-tracker-integration/command/release.rb, line 189
def create_release_tag(version_number)
  Util::Shell.exec "git tag -a #{version_number} -m \"release #{version_number}\""
  puts Util::Shell.exec "git push origin #{version_number}"
end
has_spec_path?() click to toggle source
# File lib/git-pivotal-tracker-integration/command/release.rb, line 171
def has_spec_path?
  config_file_path = "#{Util::Git.repository_root}/.v2gpti/config"
  config_file_text = File.read(config_file_path)
  spec_pattern_check = /spec-path(.*)=/.match("#{config_file_text}")
  if spec_pattern_check.nil?
    return false
  else
    spec_file_path = @configuration.pconfig["spec"]["spec-path"]
    return !spec_file_path.nil?
  end
end
included_stories(project, release_story) click to toggle source
# File lib/git-pivotal-tracker-integration/command/release.rb, line 141
def included_stories(project, release_story)
  project.stories filter: "current_state:delivered type:bug,chore,feature -id:#{release_story.id}"
end
place_version_release(release_story) click to toggle source
# File lib/git-pivotal-tracker-integration/command/release.rb, line 145
def place_version_release(release_story)
  not_accepted_releases     = @project.stories(filter: "current_state:unstarted type:release")
  not_accepted_releases_ids = not_accepted_releases.map(&:id)
  unless (not_accepted_releases_ids.include?(release_story.id))
    not_accepted_releases     << release_story
    not_accepted_releases_ids << release_story.id
  end
  specified_pt_story = @project.stories(filter: "current_state:unstarted,started,finished,delivered,rejected").first
  last_accepted_release_story = @project.stories(filter: "current_state:accepted type:release").last
  if not_accepted_releases.size > 1
    release_story.after_id  = not_accepted_releases[-2].id
    release_story.save
  elsif !specified_pt_story.nil?
    release_story.before_id = specified_pt_story.id
    release_story.save
  end
end
pull_out_rejected_stories(release_story) click to toggle source
# File lib/git-pivotal-tracker-integration/command/release.rb, line 163
def pull_out_rejected_stories(release_story)
  rejected_stories = @project.stories(filter: "current_state:rejected type:bug,chore,feature")
  rejected_stories.each do |rejected_story|
    rejected_story.after_id = release_story.id
    rejected_story.save
  end
end