class Fastlane::Actions::StampChangelogAction

Constants

UNRELEASED_IDENTIFIER

Public Class Methods

authors() click to toggle source
# File lib/fastlane/plugin/changelog/actions/stamp_changelog.rb, line 159
def self.authors
  ["pajapro"]
end
available_options() click to toggle source
# File lib/fastlane/plugin/changelog/actions/stamp_changelog.rb, line 122
def self.available_options
  [
    FastlaneCore::ConfigItem.new(key: :changelog_path,
                                 env_name: "FL_CHANGELOG_PATH",
                                 description: "The path to your project CHANGELOG.md",
                                 is_string: true,
                                 default_value: "./CHANGELOG.md",
                                 optional: true),
    FastlaneCore::ConfigItem.new(key: :section_identifier,
                                 env_name: "FL_STAMP_CHANGELOG_SECTION_IDENTIFIER",
                                 description: "The unique section identifier to stamp the [Unreleased] section with",
                                 is_string: true),
    FastlaneCore::ConfigItem.new(key: :should_stamp_date,
                                 env_name: "FL_STAMP_CHANGELOG_SHOULD_STAMP_DATE",
                                 description: "Specifies whether the current date as per the stamp_datetime_format should be stamped to the section identifier",
                                 default_value: true,
                                 is_string: false,
                                 optional: true),
    FastlaneCore::ConfigItem.new(key: :stamp_datetime_format,
                                 env_name: "FL_STAMP_CHANGELOG_DATETIME_FORMAT",
                                 description: "The strftime format string to use for the date in the stamped section",
                                 default_value: '%FZ',
                                 is_string: true,
                                 optional: true),
    FastlaneCore::ConfigItem.new(key: :git_tag,
                                 env_name: "FL_STAMP_CHANGELOG_GIT_TAG",
                                 description: "The git tag associated with this section",
                                 is_string: true,
                                 optional: true),
    FastlaneCore::ConfigItem.new(key: :placeholder_line,
                                 env_name: "FL_STAMP_CHANGELOG_PLACEHOLDER_LINE",
                                 description: "The placeholder line to be excluded in stamped section and added to [Unreleased] section",
                                 is_string: true,
                                 optional: true)
  ]
end
description() click to toggle source

@!group Documentation

# File lib/fastlane/plugin/changelog/actions/stamp_changelog.rb, line 113
def self.description
  "Stamps the [Unreleased] section with provided identifier in your project CHANGELOG.md file"
end
details() click to toggle source
# File lib/fastlane/plugin/changelog/actions/stamp_changelog.rb, line 117
def self.details
  "Use this action to stamp the [Unreleased] section with provided identifier in your project CHANGELOG.md. Additionally, you can provide git tag
  associated with this section. `stamp_changelog` will then create a new link to diff between this and previous section's tag on Github"
end
is_supported?(platform) click to toggle source
# File lib/fastlane/plugin/changelog/actions/stamp_changelog.rb, line 163
def self.is_supported?(platform)
  true
end
run(params) click to toggle source
# File lib/fastlane/plugin/changelog/actions/stamp_changelog.rb, line 6
def self.run(params)
  # 1. Ensure CHANGELOG.md exists
  changelog_path = params[:changelog_path] unless params[:changelog_path].to_s.empty?
  changelog_path = Helper::ChangelogHelper.ensure_changelog_exists(changelog_path)

  # 2. Ensure there are changes in [Unreleased] section
  unreleased_section_content = Actions::ReadChangelogAction.run(changelog_path: changelog_path, section_identifier: UNRELEASED_IDENTIFIER, excluded_markdown_elements: ["###"])
  if unreleased_section_content.eql?("")
    UI.important("WARNING: No changes in [Unreleased] section to stamp!")
  else
    section_identifier = params[:section_identifier] unless params[:section_identifier].to_s.empty?
    should_stamp_date = params[:should_stamp_date]
    stamp_datetime_format = params[:stamp_datetime_format]
    git_tag = params[:git_tag]
    placeholder_line = params[:placeholder_line]

    stamp(changelog_path, section_identifier, should_stamp_date, stamp_datetime_format, git_tag, placeholder_line)
  end
end
stamp(changelog_path, section_identifier, should_stamp_date, stamp_datetime_format, git_tag, placeholder_line) click to toggle source
# File lib/fastlane/plugin/changelog/actions/stamp_changelog.rb, line 26
def self.stamp(changelog_path, section_identifier, should_stamp_date, stamp_datetime_format, git_tag, placeholder_line)
  # 1. Update [Unreleased] section with given identifier
  Actions::UpdateChangelogAction.run(changelog_path: changelog_path,
                                    section_identifier: UNRELEASED_IDENTIFIER,
                                    updated_section_identifier: section_identifier,
                                    should_append_date: should_stamp_date,
                                    append_datetime_format: stamp_datetime_format,
                                    excluded_placeholder_line: placeholder_line)

  file_content = ""

  # 2. Create new [Unreleased] section (placeholder)
  inserted_unreleased = false
  File.open(changelog_path, "r") do |file|
    file.each_line do |line|
      # Find the first section identifier
      if !inserted_unreleased && line =~ /\#{2}\s?\[(.*?)\]/
        unreleased_section = "## [Unreleased]"

        # Insert placeholder line (if provided)
        if !placeholder_line.nil? && !placeholder_line.empty?
          line = "#{unreleased_section}\n#{placeholder_line}\n\n#{line}"
        else
          line = "#{unreleased_section}\n\n#{line}"
        end

        inserted_unreleased = true

        UI.message("Created [Unreleased] placeholder section")

        # Output updated line
        file_content.concat(line)
        next
      end

      # Output read line
      file_content.concat(line)
    end
  end

  # 3. Create link to git tags diff
  if !git_tag.nil? && !git_tag.empty?
    last_line = file_content.lines.last
    previous_tag = ''
    previous_previous_tag = ''
    reversed_tags = false

    if last_line.include? 'https://github.com' # GitHub uses compare/olderTag...newerTag structure
      previous_previous_tag = %r{(?<=compare\/)(.*)?(?=\.{3})}.match(last_line)
      previous_tag = /(?<=\.{3})(.*)?/.match(last_line)
    elsif last_line.include? 'https://bitbucket.org' # Bitbucket uses compare/newerTag..olderTag structure
      reversed_tags = true
      previous_tag = %r{(?<=compare\/)(.*)?(?=\.{2})}.match(last_line)
      previous_previous_tag = /(?<=\.{2})(.*)?/.match(last_line)
    end

    # Replace section identifier
    previous_section_identifier = /(?<=\[)[^\]]+(?=\]:)/.match(last_line)
    last_line.sub!("[#{previous_section_identifier}]:", "[#{section_identifier}]:")

    # Replace first tag
    last_line.sub!(
      reversed_tags ? previous_tag.to_s : previous_previous_tag.to_s,
      reversed_tags ? git_tag.to_s : previous_tag.to_s
    )
    # Replace second tag
    last_line.sub!(
      "..#{reversed_tags ? previous_previous_tag : previous_tag}",
      "..#{reversed_tags ? previous_tag : git_tag}"
    )

    UI.message("Created a link for comparison between #{previous_tag} and #{git_tag} tag")

    file_content.concat(last_line)
  end

  # 4. Write updated content to file
  changelog = File.open(changelog_path, "w")
  changelog.puts(file_content)
  changelog.close
  UI.success("Successfully stamped #{section_identifier} in #{changelog_path}")
end