diff --git a/CHANGELOG.md b/CHANGELOG.md index f7e88e62b..1f6dff4b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ _None_ ### New Features -_None_ +- Added optional `exclude` parameter to `find_previous_tag` action, mapping to git's `--exclude` flag. This allows skipping beta/pre-release tags when searching for the previous stable release tag [#696] ### Bug Fixes diff --git a/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/find_previous_tag.rb b/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/find_previous_tag.rb index bd627d494..dad0a771f 100644 --- a/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/find_previous_tag.rb +++ b/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/find_previous_tag.rb @@ -8,6 +8,7 @@ module Actions class FindPreviousTagAction < Action def self.run(params) tag_pattern = params[:pattern] + exclude_patterns = params[:exclude] || [] # Make sure we have all the latest tags fetched locally Actions.sh('git', 'fetch', '--tags', '--force') { nil } @@ -17,6 +18,7 @@ def self.run(params) # Finally find the previous tag matching the provided pattern, and that is not the current commit git_cmd = %w[git describe --tags --abbrev=0] git_cmd += ['--match', tag_pattern] unless tag_pattern.nil? + exclude_patterns.each { |p| git_cmd += ['--exclude', p] } git_cmd += ['--exclude', current_commit_tag] unless current_commit_tag.empty? Actions.sh(*git_cmd) { |exit_status, stdout, _| exit_status.success? ? stdout.chomp : nil } end @@ -38,7 +40,9 @@ def self.details Uses `git describe --tags --abbrev=0 --match … --exclude …` to find the previous git tag reachable from the current commit and that matches a specific naming pattern - e.g. `find_previous_tag(pattern: '12.3.*.*')`, `find_previous_tag(pattern: '12.3-rc-*')` + e.g. `find_previous_tag(pattern: '12.3.*.*')`, `find_previous_tag(pattern: '12.3-rc-*')`, + `find_previous_tag(pattern: 'v*', exclude: ['*beta*'])`, + `find_previous_tag(pattern: 'v*', exclude: ['*alpha*', '*beta*'])` DETAILS end @@ -49,6 +53,11 @@ def self.available_options optional: true, default_value: nil, type: String), + FastlaneCore::ConfigItem.new(key: :exclude, + description: 'An array of _fnmatch_-style patterns of tags to exclude from the search (maps to `git describe --exclude`)', + optional: true, + default_value: nil, + type: Array), ] end diff --git a/spec/find_previous_tag_spec.rb b/spec/find_previous_tag_spec.rb index 909b1cafb..3ccd0d4c6 100644 --- a/spec/find_previous_tag_spec.rb +++ b/spec/find_previous_tag_spec.rb @@ -65,6 +65,70 @@ def stub_main_command(expected_command, stdout:, success: true) expect(tag).to eq('12.2') end + it 'excludes tags matching the exclude pattern' do + # Arrange + stub_current_commit_tag(nil) + stub_main_command( + %w[git describe --tags --abbrev=0 --match v* --exclude *beta*], + stdout: 'v1.7.3' + ) + # Act + tag = run_described_fastlane_action( + pattern: 'v*', + exclude: ['*beta*'] + ) + # Assert + expect(tag).to eq('v1.7.3') + end + + it 'excludes both the exclude pattern and the current commit tag' do + # Arrange + stub_current_commit_tag('v1.8.0') + stub_main_command( + %w[git describe --tags --abbrev=0 --match v* --exclude *beta* --exclude v1.8.0], + stdout: 'v1.7.3' + ) + # Act + tag = run_described_fastlane_action( + pattern: 'v*', + exclude: ['*beta*'] + ) + # Assert + expect(tag).to eq('v1.7.3') + end + + it 'auto-converts a single exclude string into an array' do + # Arrange + stub_current_commit_tag(nil) + stub_main_command( + %w[git describe --tags --abbrev=0 --match v* --exclude *beta*], + stdout: 'v1.7.3' + ) + # Act — Fastlane's ConfigItem auto-converts a String to Array when type is Array + tag = run_described_fastlane_action( + pattern: 'v*', + exclude: '*beta*' + ) + # Assert + expect(tag).to eq('v1.7.3') + end + + it 'excludes tags matching multiple exclude patterns' do + # Arrange + stub_current_commit_tag(nil) + stub_main_command( + %w[git describe --tags --abbrev=0 --match v* --exclude *alpha* --exclude *beta*], + stdout: 'v1.7.3' + ) + # Act + tag = run_described_fastlane_action( + pattern: 'v*', + exclude: %w[*alpha* *beta*] + ) + # Assert + expect(tag).to eq('v1.7.3') + end + it 'returns nil if no previous commit could be found' do # Arrange stub_current_commit_tag(nil)