Class: Fastlane::Actions::StampChangelogAction

Inherits:
Action
  • Object
show all
Defined in:
lib/fastlane/plugin/changelog/actions/stamp_changelog.rb

Constant Summary collapse

UNRELEASED_IDENTIFIER =
'[Unreleased]'

Documentation collapse

Class Method Summary collapse

Class Method Details

.authorsObject



159
160
161
# File 'lib/fastlane/plugin/changelog/actions/stamp_changelog.rb', line 159

def self.authors
  ["pajapro"]
end

.available_optionsObject



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# 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

.descriptionObject



113
114
115
# 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

.detailsObject



117
118
119
120
# 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) ⇒ Boolean

Returns:

  • (Boolean)


163
164
165
# File 'lib/fastlane/plugin/changelog/actions/stamp_changelog.rb', line 163

def self.is_supported?(platform)
  true
end

.run(params) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 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) ⇒ Object



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# 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