discourse/spec/tasks/version_bump_spec.rb
David Taylor 8b51a89919
DEV: Do not squash commits in version_bump:stage_security_fixes (#23547)
Sometimes fixes will deliberately keep commits separate, and we don't want to undo that
2023-09-12 18:00:42 +01:00

231 lines
8.4 KiB
Ruby

# frozen_string_literal: true
def run(*args)
out, err, status = Open3.capture3(*args)
raise "Command failed: #{args.inspect}\n#{out}\n#{err}" unless status.success?
out
end
def fake_version_rb(version)
File.read("#{Rails.root}/lib/version.rb").sub(/STRING = ".*"/, "STRING = \"#{version}\"")
end
RSpec.describe "tasks/version_bump" do
let(:tmpdir) { Dir.mktmpdir }
let(:origin_path) { "#{tmpdir}/origin-repo" }
let(:local_path) { "#{tmpdir}/local-repo" }
before do
ENV["RUNNING_VERSION_BUMP_IN_RSPEC_TESTS"] = "1"
Rake::Task.clear
Discourse::Application.load_tasks
FileUtils.mkdir_p origin_path
Dir.chdir(origin_path) do
FileUtils.mkdir_p "lib"
FileUtils.mkdir_p "tmp"
File.write(".gitignore", "tmp\n")
File.write("lib/version.rb", fake_version_rb("3.2.0.beta1-dev"))
run "git", "init"
run "git", "checkout", "-b", "main"
run "git", "add", "."
run "git", "commit", "-m", "Initial commit"
run "git", "checkout", "-b", "stable"
File.write("#{origin_path}/lib/version.rb", fake_version_rb("3.1.2"))
run "git", "add", "."
run "git", "commit", "-m", "Previous stable version bump"
run "git", "checkout", "main"
run "git", "config", "receive.denyCurrentBranch", "ignore"
end
run "git", "clone", "-b", "main", origin_path, local_path
end
after do
FileUtils.remove_entry(tmpdir)
ENV.delete("RUNNING_VERSION_BUMP_IN_RSPEC_TESTS")
end
it "can bump the beta version with version_bump:beta" do
Dir.chdir(local_path) { capture_stdout { Rake::Task["version_bump:beta"].invoke } }
Dir.chdir(origin_path) do
# Commits are present with correct messages
expect(run("git", "log", "--pretty=%s").lines.map(&:strip)).to eq(
["Bump version to v3.2.0.beta2-dev", "Bump version to v3.2.0.beta1", "Initial commit"],
)
# Expected tags present
expect(run("git", "tag").lines.map(&:strip)).to contain_exactly(
"latest-release",
"beta",
"v3.2.0.beta1",
)
# Tags are all present and attached to the correct commit
%w[latest-release beta v3.2.0.beta1].each do |tag_name|
expect(run("git", "log", "--pretty=%s", "-1", tag_name).strip).to eq(
"Bump version to v3.2.0.beta1",
)
end
# Version numbers in version.rb are correct at all commits
expect(run "git", "show", "HEAD", "lib/version.rb").to include('STRING = "3.2.0.beta2-dev"')
expect(run "git", "show", "HEAD~1", "lib/version.rb").to include('STRING = "3.2.0.beta1"')
expect(run "git", "show", "HEAD~2", "lib/version.rb").to include('STRING = "3.2.0.beta1-dev"')
end
end
it "can perform a minor stable bump with version_bump:minor_stable" do
Dir.chdir(local_path) { capture_stdout { Rake::Task["version_bump:minor_stable"].invoke } }
Dir.chdir(origin_path) do
# No commits on main branch
expect(run("git", "log", "--pretty=%s").lines.map(&:strip)).to eq(["Initial commit"])
# Expected tags present
expect(run("git", "tag").lines.map(&:strip)).to eq(["v3.1.3"])
run "git", "checkout", "stable"
# Correct commits on stable branch
expect(run("git", "log", "--pretty=%s").lines.map(&:strip)).to eq(
["Bump version to v3.1.3", "Previous stable version bump", "Initial commit"],
)
# Tag points to correct commit
expect(run("git", "log", "--pretty=%s", "-1", "v3.1.3").strip).to eq("Bump version to v3.1.3")
# Version numbers in version.rb are correct at all commits
expect(run "git", "show", "HEAD", "lib/version.rb").to include('STRING = "3.1.3"')
expect(run "git", "show", "HEAD~1", "lib/version.rb").to include('STRING = "3.1.2"')
end
end
it "can prepare a major stable bump with version_bump:major_stable_prepare" do
Dir.chdir(local_path) do
capture_stdout { Rake::Task["version_bump:major_stable_prepare"].invoke("3.3.0") }
end
Dir.chdir(origin_path) do
# Commits are present with correct messages
expect(run("git", "log", "--pretty=%s").lines.map(&:strip)).to eq(
["Bump version to v3.3.0.beta1-dev", "Bump version to v3.2.0.beta1", "Initial commit"],
)
# Expected tags present
expect(run("git", "tag").lines.map(&:strip)).to contain_exactly(
"latest-release",
"beta",
"v3.2.0.beta1",
)
# Tags are all present and attached to the correct commit
%w[latest-release beta v3.2.0.beta1].each do |tag_name|
expect(run("git", "log", "--pretty=%s", "-1", tag_name).strip).to eq(
"Bump version to v3.2.0.beta1",
)
end
# Version numbers in version.rb are correct at all commits
expect(run "git", "show", "HEAD:lib/version.rb").to include('STRING = "3.3.0.beta1-dev"')
expect(run "git", "show", "HEAD~1:lib/version.rb").to include('STRING = "3.2.0.beta1"')
expect(run "git", "show", "HEAD~2:lib/version.rb").to include('STRING = "3.2.0.beta1-dev"')
# No changes to stable branch
expect(run("git", "log", "--pretty=%s", "stable").lines.map(&:strip)).to eq(
["Previous stable version bump", "Initial commit"],
)
end
end
it "can merge a stable release commit into the stable branch with version_bump:major_stable_merge" do
Dir.chdir(local_path) do
# Prepare first, and find sha1 in output
output = capture_stdout { Rake::Task["version_bump:major_stable_prepare"].invoke("3.3.0") }
stable_bump_commit = output[/major_stable_merge\[(.*)\]/, 1]
capture_stdout { Rake::Task["version_bump:major_stable_merge"].invoke(stable_bump_commit) }
end
Dir.chdir(origin_path) do
# Commits on stable branch are present with correct messages
expect(run("git", "log", "--pretty=%s", "stable").lines.map(&:strip)).to contain_exactly(
"Merge v3.2.0.beta1 into stable",
"Bump version to v3.2.0",
"Previous stable version bump",
"Bump version to v3.2.0.beta1",
"Initial commit",
)
# Most recent commit is the version bump
expect(run("git", "log", "--pretty=%s", "-1", "stable").strip).to eq("Bump version to v3.2.0")
# Second most recent commit is a merge commit
parents = run("git", "log", "--pretty=%P", "-n", "1", "stable~1").split(/\s+/).map(&:strip)
expect(parents.length).to eq(2)
# With correct parents
parent_commit_messages = parents.map { |p| run("git", "log", "--pretty=%s", "-1", p).strip }
expect(parent_commit_messages).to contain_exactly(
"Bump version to v3.2.0.beta1",
"Previous stable version bump",
)
# Tag is applied to stable version bump commit
expect(run("git", "log", "--pretty=%s", "-1", "v3.2.0").strip).to eq("Bump version to v3.2.0")
end
end
it "can stage a PR of multiple security fixes using version_bump:stage_security_fixes" do
Dir.chdir(origin_path) do
run "git", "checkout", "-b", "security-fix-one"
File.write("firstfile.txt", "contents")
run "git", "add", "firstfile.txt"
run "git", "commit", "-m", "security fix one, commit one"
File.write("secondfile.txt", "contents")
run "git", "add", "secondfile.txt"
run "git", "commit", "-m", "security fix one, commit two"
run "git", "checkout", "main"
run "git", "checkout", "-b", "security-fix-two"
File.write("somefile.txt", "contents")
run "git", "add", "somefile.txt"
run "git", "commit", "-m", "security fix two"
end
Dir.chdir(local_path) do
output =
capture_stdout do
ENV["SECURITY_FIX_REFS"] = "origin/security-fix-one,origin/security-fix-two"
Rake::Task["version_bump:stage_security_fixes"].invoke("main")
ensure
ENV.delete("SECURITY_FIX_REFS")
end
end
Dir.chdir(origin_path) do
# Check each fix has been added as a single commit, with the message matching the first commit on the branch
expect(run("git", "log", "--pretty=%s", "main").lines.map(&:strip)).to eq(
[
"security fix two",
"security fix one, commit two",
"security fix one, commit one",
"Initial commit",
],
)
# Check all the files from both fixes are present
expect(run("git", "show", "main:somefile.txt")).to eq("contents")
expect(run("git", "show", "main:firstfile.txt")).to eq("contents")
expect(run("git", "show", "main:secondfile.txt")).to eq("contents")
end
end
end