class CreateGithubRelease::Project


@api public
Captures the options for this script

def backtick_debug?

Other tags:
    Api: - private

Returns:
  • (Boolean) -
def backtick_debug?
  verbose?
end

def changelog_path

Other tags:
    Api: - public

Returns:
  • (String) -

Other tags:
    Example: It can also be set explicitly -
    Example: It can also be set in the options -
    Example: By default, this value is 'CHANGELOG.md' -
def changelog_path
  @changelog_path ||= options.changelog_path || 'CHANGELOG.md'
end

def changes

Other tags:
    Api: - public

Returns:
  • (Array) -

Other tags:
    Example: It can also be set explicitly -
    Example: By default, uses `git log` -
def changes
  @changes ||= begin
    tip = "'HEAD'"
    base = first_release? ? '' : "'^#{last_release_tag}' "
    command = "git log #{tip} #{base}--oneline --format='format:%h\t%s'"
    git_log = `#{command}`
    raise "Could not determine changes since #{last_release_tag}" unless $CHILD_STATUS.success?
    git_log.split("\n").map { |l| ::CreateGithubRelease::Change.new(*l.split("\t")) }
  end
end

def current_version

Other tags:
    Api: - private

Returns:
  • (String) - The current version of the project
def current_version
  output = `gem-version-boss current`
  raise 'Could not determine current version using gem-version-boss' unless $CHILD_STATUS.success?
  output.lines.last.chomp
end

def default_branch

Other tags:
    Api: - public

Raises:
  • (RuntimeError) - if the git command fails

Returns:
  • (String) -

Other tags:
    Example: `default_branch` can be set explicitly -
    Example: By default, `default_branch` is based on `git remote show` -
def default_branch
  @default_branch ||= options.default_branch || begin
    output = `git remote show '#{remote}'`
    raise "Could not determine default branch for remote '#{remote}'" unless $CHILD_STATUS.success?
    output.match(/HEAD branch: (.*?)$/)[1]
  end
end

def first_commit

Other tags:
    Api: - public

Returns:
  • (String) -
def first_commit
  @first_commit ||= begin
    command = "git log 'HEAD' --oneline --format='format:%h'"
    git_log = `#{command}`
    raise "Could not list changes from first commit up to #{last_release_tag}" unless $CHILD_STATUS.success?
    git_log.split("\n").last.chomp
  end
end

def first_release

Other tags:
    Api: - public

Returns:
  • (Boolean) -

Other tags:
    Example: Returnss false if release_type is not 'first' -
    Example: Returns true if release_type is 'first' -
def first_release
  @first_release ||= release_type == 'first'
end

def initialize(options)

Other tags:
    Yieldreturn: - the return value is ignored

Other tags:
    Yieldparam: self - the instance being initialized aka `self`

Other tags:
    Yield: - an initialization block

Parameters:
  • options (CreateGithubRelease::CommandLine::Options) -- the options to initialize the instance with

Other tags:
    Example: calling `.new` with a block -
    Example: calling `.new` without a block -
def initialize(options)
  @options = options
  yield self if block_given?
  setup_first_release if release_type == 'first'
end

def last_release_changelog

Other tags:
    Api: - public

Returns:
  • (String) -
def last_release_changelog
  @last_release_changelog ||= begin
    File.read(changelog_path)
  rescue Errno::ENOENT
    ''
  rescue StandardError
    raise 'Could not read the changelog file'
  end
end

def last_release_tag

Other tags:
    Api: - public

Returns:
  • (String) -

Other tags:
    Example: `last_release_tag` can be set explicitly -
    Example: By default, `last_release_tag` is based on `last_release_version` -
def last_release_tag
  @last_release_tag ||= (first_release? ? '' : "v#{last_release_version}")
end

def last_release_version

Other tags:
    Api: - public

Raises:
  • (RuntimeError) - if the gem-version-boss command fails

Returns:
  • (String) -

Other tags:
    Example: It can also be set explicitly -
    Example: By default, `last_release_version` is based on the value returned by `gem-version-boss current` -
def last_release_version
  @last_release_version ||= options.last_release_version || current_version
end

def list_of_changes

Other tags:
    Api: - private

Returns:
  • (String) - The list of changes in the release as a string
def list_of_changes
  return '* No changes' if changes.empty?
  changes.map do |change|
    "* #{change.sha} #{change.subject}"
  end.join("\n")
end

def next_release_changelog

Other tags:
    Api: - public

Returns:
  • (String) -
def next_release_changelog
  @next_release_changelog ||=
    CreateGithubRelease::Changelog.new(last_release_changelog, next_release_description).to_s
end

def next_release_date

Other tags:
    Api: - public

Raises:
  • (RuntimeError) - if the git command fails

Returns:
  • (Date) -

Other tags:
    Example: It can also be set explicitly -
    Example: By default, `next_release_date` is based on `next_release_tag` -
def next_release_date
  @next_release_date ||=
    if tag_exist?(next_release_tag)
      date = `git show --format=format:%aI --quiet "#{next_release_tag}"`
      raise "Could not determine date for tag '#{next_release_tag}'" unless $CHILD_STATUS.success?
      Date.parse(date.chomp)
    else
      Date.today
    end
end

def next_release_description

Other tags:
    Api: - public

Returns:
  • (String) -
def next_release_description
  @next_release_description ||= begin
    header = first_release? ? 'Changes:' : "Changes since #{last_release_tag}:"
    <<~DESCRIPTION
      ## #{next_release_tag} (#{next_release_date.strftime('%Y-%m-%d')})
      [Full Changelog](#{release_log_url})
      #{header}
      #{list_of_changes}
    DESCRIPTION
  end
end

def next_release_tag

Other tags:
    Api: - public

Returns:
  • (String) -

Other tags:
    Example: `next_tag` can be set explicitly -
    Example: By default, `next_release_tag` is based on `next_release_version` -
def next_release_tag
  @next_release_tag ||= "v#{next_release_version}"
end

def next_release_version

Other tags:
    Api: - public

Raises:
  • (RuntimeError) - if the gem-version-boss command fails

Returns:
  • (String) -

Other tags:
    Example: It can also be set explicitly -
    Example: By default, `next_release_version` is based on `gem-version-boss --dry-run` -
def next_release_version
  @next_release_version ||= options.next_release_version || next_version
end

def next_version

Other tags:
    Api: - private

Returns:
  • (String) - The next version of the project
def next_version
  output = `#{next_version_cmd}`
  raise 'Could not determine next version using gem-version-boss' unless $CHILD_STATUS.success?
  output.lines.last.chomp
end

def next_version_cmd

Other tags:
    Api: - private

Returns:
  • (String) -
def next_version_cmd
  cmd = "gem-version-boss next-#{release_type}"
  cmd << ' --pre' if pre
  cmd << " --pre-type=#{pre_type}" if pre_type
  cmd << ' --dry-run'
end

def pre

Other tags:
    Api: - public

Returns:
  • (Boolean) -

Other tags:
    Example: It can also be set explicitly -
    Example: By default, this value comes from the options object -
def pre
  @pre ||= options.pre
end

def pre_type

Other tags:
    Api: - public

Returns:
  • (String) -

Other tags:
    Example: It can also be set explicitly -
    Example: By default, this value comes from the options object -
def pre_type
  @pre_type ||= options.pre_type
end

def quiet

Other tags:
    Api: - public

Returns:
  • (Boolean) -

Other tags:
    Example: It can also be set explicitly -
    Example: By default, this value is based on the `quiet` option -
def quiet
  @quiet ||= options.quiet || false
end

def release_branch

Other tags:
    Api: - public

Raises:
  • (RuntimeError) - if the gem-version-boss command fails

Returns:
  • (String) -

Other tags:
    Example: It can also be set explicitly -
    Example: By default, `release_branch` is based on the value returned by `next_release_tag` -
def release_branch
  @release_branch ||= options.release_branch || "release-#{next_release_tag}"
end

def release_log_url

Other tags:
    Api: - public

Raises:
  • (RuntimeError) - if the gem-version-boss command fails

Returns:
  • (URI) -

Other tags:
    Example: It can also be set explicitly -
    Example: By default, `release_log_url` is based on `remote_url`, `last_release_tag`, and `next_release_tag` -
def release_log_url
  @release_log_url ||= begin
    from = first_release? ? first_commit : last_release_tag
    to = next_release_tag
    URI.parse("#{remote_url}/compare/#{from}..#{to}")
  end
end

def release_pr_label

Other tags:
    Api: - public

Returns:
  • (String, nil) -

Other tags:
    Example: It can also be set explicitly -
    Example: Set to 'release' -
    Example: By default, `release_pr_label` is nil indicating no label should be applied -
def release_pr_label
  @release_pr_label ||= options.release_pr_label || nil
end

def release_pr_number

Other tags:
    Api: - public

Returns:
  • (String, nil) -
def release_pr_number
  @release_pr_number ||= begin
    pr_number = `gh pr list --search "head:#{release_branch}" --json number --jq ".[].number"`.chomp
    pr_number.empty? ? nil : pr_number
  end
end

def release_pr_url

Other tags:
    Api: - public

Returns:
  • (String) -
def release_pr_url
  @release_pr_url ||= release_pr_number.nil? ? nil : URI.parse("#{remote_url}/pull/#{release_pr_number}")
end

def release_type

Other tags:
    Api: - public

Raises:
  • (ArgumentError) - if a release type was not provided

Returns:
  • (String) -

Other tags:
    Example: It can also be set explicitly -
    Example: By default, this value comes from the options object -

Other tags:
    Note: - this must be one of the values accepted by the `gem-version-boss` command
def release_type
  @release_type ||= options.release_type || raise(ArgumentError, 'release_type is required')
end

def release_url

Other tags:
    Api: - public

Returns:
  • (URI::Generic) -

Other tags:
    Example: It can also be set explicitly -
    Example: By default, `release_url` is based on `remote_url` and `next_release_tag` -
def release_url
  @release_url ||= URI.parse("#{remote_url}/releases/tag/#{next_release_tag}")
end

def remote

Other tags:
    Api: - public

Returns:
  • (String) -

Other tags:
    Example: It can also be set explicitly -
    Example: It can also be set in the options -
    Example: By default, 'origin' is used -
def remote
  @remote ||= options.remote || 'origin'
end

def remote_base_url

Other tags:
    Api: - public

Returns:
  • (URI::Generic) -

Other tags:
    Example: It can also be set explicitly -
    Example: By default, this value is based on `remote_url` -
def remote_base_url
  @remote_base_url ||= URI.parse(remote_url.to_s[0..-remote_url.path.length])
end

def remote_repository

Other tags:
    Api: - public

Returns:
  • (String) -

Other tags:
    Example: It can also be set explicitly -
    Example: By default, this value is based on `remote_url` -
def remote_repository
  @remote_repository ||= remote_url.path.sub(%r{^/}, '').sub(/\.git$/, '')
end

def remote_url

Other tags:
    Api: - public

Returns:
  • (URI) -

Other tags:
    Example: It can also be set explicitly -
    Example: By default, this value is based on `remote` and the `git remote get-url` command -
def remote_url
  @remote_url ||= begin
    remote_url_string = `git remote get-url '#{remote}'`
    raise "Could not determine remote url for remote '#{remote}'" unless $CHILD_STATUS.success?
    remote_url_string = remote_url_string.chomp
    remote_url_string = remote_url_string[0..-5] if remote_url_string.end_with?('.git')
    URI.parse(remote_url_string)
  end
end

def setup_first_release

Other tags:
    Api: - private

Returns:
  • (void) -
def setup_first_release
  self.next_release_version = @next_release_version || current_version
  self.last_release_version = ''
  self.last_release_tag = ''
end

def tag_exist?(tag)

Other tags:
    Api: - public

Returns:
  • (Boolean) -

Parameters:
  • tag (String) -- the tag to check
def tag_exist?(tag)
  tags = `git tag --list "#{tag}"`.chomp
  raise 'Could not list tags' unless $CHILD_STATUS.success?
  !tags.empty?
end

def to_s

Other tags:
    Api: - public

Returns:
  • (String) -
def to_s
  <<~OUTPUT
    first_release: #{first_release}
    default_branch: #{default_branch}
    next_release_tag: #{next_release_tag}
    next_release_date: #{next_release_date}
    next_release_version: #{next_release_version}
    last_release_tag: #{last_release_tag}
    last_release_version: #{last_release_version}
    release_branch: #{release_branch}
    release_log_url: #{release_log_url}
    release_type: #{release_type}
    release_url: #{release_url}
    remote: #{remote}
    remote_base_url: #{remote_base_url}
    remote_repository: #{remote_repository}
    remote_url: #{remote_url}
    release_pr_number: #{release_pr_number}
    release_pr_url: #{release_pr_url}
    changelog_path: #{changelog_path}
    verbose?: #{verbose?}
    quiet?: #{quiet?}
  OUTPUT
end

def verbose

Other tags:
    Api: - public

Returns:
  • (Boolean) -

Other tags:
    Example: It can also be set explicitly -
    Example: By default, this value is based on the `verbose` option -
def verbose
  @verbose ||= options.verbose || false
end