From aa033acfb695217e989a3d0de364da3e0f22dec5 Mon Sep 17 00:00:00 2001 From: Oguz Kocer Date: Tue, 28 Jul 2026 16:57:37 -0400 Subject: [PATCH 1/3] Fix `create_github_release` crashing when no release notes are given `release_notes_file_path` is optional, but its `''` fallback is a frozen literal (the file sets `frozen_string_literal: true`), so the `gsub!` that rewrites bracketed GitHub URLs raised `FrozenError`. Use the non-mutating `gsub` instead. Adds specs for the action, which had none. --- .../common/create_github_release_action.rb | 2 +- spec/create_github_release_spec.rb | 78 +++++++++++++++++++ 2 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 spec/create_github_release_spec.rb diff --git a/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/create_github_release_action.rb b/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/create_github_release_action.rb index f56856f00..897b4634b 100644 --- a/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/create_github_release_action.rb +++ b/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/create_github_release_action.rb @@ -14,7 +14,7 @@ def self.run(params) # Replace full URLs to PRs/Issues that are in `[https://some-url]` brackets with shorthand, because GitHub does not render them properly otherwise. # That syntax is sometimes used by devs in `RELEASE-NOTES.txt` when pointing to a PR to another repo (e.g. Gutenberg PR from WP repo). # We should NOT transform URLs to PRs/Issues that are in `[text](url)` form (those are valid), only the ones directly in `[]` brackets. - release_notes.gsub!(%r{\[https://github.com/([^/]*/[^/]*)/(pulls?|issues?)/([0-9]*)\]}, '[\1#\3]') + release_notes = release_notes.gsub(%r{\[https://github.com/([^/]*/[^/]*)/(pulls?|issues?)/([0-9]*)\]}, '[\1#\3]') prerelease = params[:prerelease] is_draft = params[:is_draft] diff --git a/spec/create_github_release_spec.rb b/spec/create_github_release_spec.rb new file mode 100644 index 000000000..bc777e411 --- /dev/null +++ b/spec/create_github_release_spec.rb @@ -0,0 +1,78 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Fastlane::Actions::CreateGithubReleaseAction do + let(:test_token) { 'ghp_fake_token' } + let(:test_repo) { 'repo-test/project-test' } + let(:test_version) { '1.0.0' } + let(:release_url) { 'https://github.com/repo-test/project-test/releases/tag/1.0.0' } + let(:github_helper) { instance_double(Fastlane::Helper::GithubHelper) } + + before do + allow(Fastlane::Helper::GithubHelper).to receive(:new).and_return(github_helper) + end + + context 'when no release notes file is provided' do + it 'creates the release with an empty description' do + expect(github_helper).to receive(:create_release).with( + repository: test_repo, + version: test_version, + name: nil, + target: nil, + description: '', + assets: [], + prerelease: false, + is_draft: true + ).and_return(release_url) + + result = run_described_fastlane_action( + github_token: test_token, + repository: test_repo, + version: test_version, + release_assets: [] + ) + + expect(result).to eq(release_url) + end + end + + context 'when a release notes file is provided' do + it 'rewrites bracketed GitHub PR and issue URLs to shorthand' do + notes = <<~NOTES + - Fix a thing [https://github.com/org-test/other-repo/pull/123] + - Fix another thing [https://github.com/org-test/other-repo/issues/456] + - Leave markdown links alone [as a link](https://github.com/org-test/other-repo/pull/789) + NOTES + + expected_description = <<~NOTES + - Fix a thing [org-test/other-repo#123] + - Fix another thing [org-test/other-repo#456] + - Leave markdown links alone [as a link](https://github.com/org-test/other-repo/pull/789) + NOTES + + with_tmp_file(named: 'release-notes.txt', content: notes) do |notes_path| + expect(github_helper).to receive(:create_release).with( + repository: test_repo, + version: test_version, + name: nil, + target: nil, + description: expected_description, + assets: [], + prerelease: false, + is_draft: true + ).and_return(release_url) + + result = run_described_fastlane_action( + github_token: test_token, + repository: test_repo, + version: test_version, + release_assets: [], + release_notes_file_path: notes_path + ) + + expect(result).to eq(release_url) + end + end + end +end From 042879b304311cdbc302e064e5ab43c998f59c26 Mon Sep 17 00:00:00 2001 From: Oguz Kocer Date: Tue, 28 Jul 2026 17:02:20 -0400 Subject: [PATCH 2/3] Add CHANGELOG entry --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 94863e518..74a8ec505 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,7 @@ _None_ ### Bug Fixes -_None_ +- `create_github_release` no longer crashes with `FrozenError` when the optional `release_notes_file_path` is omitted. [#759] ### Internal Changes From 8fdd88218bf5b45f75cee13ba2bba709630e6ef3 Mon Sep 17 00:00:00 2001 From: Oguz Kocer Date: Tue, 28 Jul 2026 17:16:05 -0400 Subject: [PATCH 3/3] Use `allow` instead of `expect` when stubbing `create_release` --- spec/create_github_release_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/create_github_release_spec.rb b/spec/create_github_release_spec.rb index bc777e411..ee06dc70c 100644 --- a/spec/create_github_release_spec.rb +++ b/spec/create_github_release_spec.rb @@ -15,7 +15,7 @@ context 'when no release notes file is provided' do it 'creates the release with an empty description' do - expect(github_helper).to receive(:create_release).with( + allow(github_helper).to receive(:create_release).with( repository: test_repo, version: test_version, name: nil, @@ -52,7 +52,7 @@ NOTES with_tmp_file(named: 'release-notes.txt', content: notes) do |notes_path| - expect(github_helper).to receive(:create_release).with( + allow(github_helper).to receive(:create_release).with( repository: test_repo, version: test_version, name: nil,