docbrown/scripts/stage_release
Jamie Gaskins f0edbcef90
Add support for versioned releases (#13750)
* Add release scripts

* Use `delete` over `gsub` with an empty string

Co-authored-by: Michael Kohl <citizen428@dev.to>

* wip

* wip

* Include stable release-channel branches in builds

* Add changelog stub

* Include the union of changes to the changelog

* Add things

* Add stuff

* Remove test changelog content

* Fix String#delete call

Extraneous `.` made Ruby parse it as a range

* Fix suggested release command

* Use backticks to denote a command to run

* Add debugging output to script

* Build more appropriate containers for stable

This includes tags

* Check if branch *starts with* release channel name

* Cache tag builds from production tag

* Skip trying to build containers for untagged pushes

* Clear out stubbed changelog

* Update PR template to incorporate CHANGELOG.md

* Run Rubocop on release scripts

This excludes some linter rules that only make sense in code that is
running as part of the Rails app. For example, we can't rely on
`ActiveSupport::TimeWithZone` because these scripts don't load Rails,
and we define top-level methods because they're scripts rather than
complex applications.

Co-authored-by: Michael Kohl <citizen428@dev.to>
2021-07-28 10:10:33 -04:00

64 lines
1.9 KiB
Ruby
Executable file

#!/usr/bin/env ruby
require "date"
require "optparse"
def run(command, abort_on_fail: true)
puts "> #{command}" if $VERBOSE
system(command, exception: abort_on_fail)
rescue StandardError => e
raise "#{command.inspect} failed: #{e}"
end
remote = ENV.fetch("FOREM_RELEASE_REMOTE", "origin")
source = ENV.fetch("FOREM_RELEASE_FROM", "main")
target = "#{ENV.fetch('FOREM_RELEASE_CHANNEL', 'stable')}-next"
OptionParser.new ARGV.dup do |options|
options.banner = <<~USAGE
Usage: #{$PROGRAM_NAME} [options]
Staging banches are named CHANNEL-next. Example: #{target}
USAGE
options.on "-c", "--channel CHANNEL",
"Specify the release channel (defaults to #{target.sub(/-next$/, '').inspect})" do |release_channel|
target = "#{release_channel}-next"
end
options.on "-f", "--from BRANCH/COMMIT/TAG",
"Specify the source branch for this release (defaults to #{source.inspect})" do |from_branch|
source = from_branch
end
options.on "-r", "--remote REMOTE", "Git remote to push to (defaults to #{remote.inspect})" do |git_remote|
remote = git_remote
end
options.on "-v", "--verbose", "Enable verbose mode" do
$VERBOSE = true
end
end.parse!
original_branch = `git branch --show-current`.strip
begin
puts "Fetching from #{remote}..."
[source, target].each do |branch|
run "git checkout --quiet #{branch}"
run "git pull --ff-only --quiet #{remote} #{branch}"
puts "Pulled latest #{branch.inspect}"
end
run "git merge --quiet #{source}"
puts "Merged latest #{source} into #{target}"
run "git push --quiet #{remote} #{target}"
puts "Pushed #{target}, run the following to release:"
puts " scripts/release --channel #{target.sub(/-next$/, '')} --remote #{remote} --from #{target}"
ensure
# Go back to the branch we were on before running this script
run "git checkout --quiet #{original_branch}"
end