Files

224 lines
8.0 KiB
Ruby

# frozen_string_literal: true
# Used constants:
# - BUILD_DIR
require 'digest'
require 'net/http'
require 'open3'
require 'open-uri'
require 'uri'
def first_match_in_file(file, regexp)
File.foreach(file) do |line|
m = regexp.match(line)
return m if m
end
end
## [ Release a new version ] ##################################################
namespace :release do
desc 'Create a new release on GitHub, CocoaPods and Homebrew'
task :new => [:check_versions, :confirm, 'spm:test', :github, :cocoapods, :homebrew]
desc 'Check if all versions from the podspecs and CHANGELOG match'
task :check_versions do
results = []
Utils.table_header('Check', 'Status')
# Check if bundler is installed first, as we'll need it for the cocoapods task (and we prefer to fail early)
results << Utils.table_result(
Open3.capture3('which', 'bundler')[2].success?,
'Bundler installed',
'Please install bundler using `gem install bundler` and run `bundle install` first.'
)
# Extract version from SwiftGen.podspec
sg_version = Utils.podspec_version(POD_NAME)
Utils.table_info('SwiftGen.podspec', sg_version)
# Extract version from SwiftGenKit.podspec
sgk_version = Utils.podspec_version('SwiftGenKit')
Utils.table_info('SwiftGenKit.podspec', sgk_version)
results << Utils.table_result(
sg_version == sgk_version,
'SwiftGen & SwiftGenKit versions equal',
'Please ensure SwiftGen & SwiftGenKit use the same version numbers'
)
# Check if version matches the Versions.swift
sg_code = File.open('Sources/SwiftGen/Version.swift').grep(/swiftgen = "(.+)"/) { Regexp.last_match(1) }.first
results << Utils.table_result(
sg_version == sg_code,
'SwiftGen Version.swift version matches',
'Please update the version numbers in Versions.swift file'
)
# Check if version matches the Versions.swift
sgk_code = File.open('Sources/SwiftGen/Version.swift').grep(/swiftGenKit = "(.+)"/) { Regexp.last_match(1) }.first
results << Utils.table_result(
sgk_version == sgk_code,
'SwiftGenKit Version.swift version matches',
'Please update the version numbers in Versions.swift file'
)
# Check StencilSwiftKit version too
lock_version = Utils.spm_resolved_version('StencilSwiftKit')
pod_version = Utils.pod_trunk_last_version('StencilSwiftKit')
results << Utils.table_result(
lock_version == pod_version,
"StencilSwiftKit up-to-date (latest: #{pod_version})",
'Please update StencilSwiftKit to latest version in your Package.swift'
)
# Check if entry present in CHANGELOG
changelog_entry = first_match_in_file('CHANGELOG.md', /^## #{Regexp.quote(sg_version)}$/)
results << Utils.table_result(
!changelog_entry.nil?,
'CHANGELOG: Release entry added',
"Please add an entry for #{sg_version} in CHANGELOG.md"
)
changelog_develop = first_match_in_file('CHANGELOG.md', /^## Develop/)
results << Utils.table_result(
changelog_develop.nil?,
'CHANGELOG: No develop entry',
'Please remove entry for develop in CHANGELOG'
)
# Check README instructions
readme_pod_version = first_match_in_file('README.md', /pod 'SwiftGen', '(.*)'/) || ['0.0', '0.0']
readme_requirement = Gem::Requirement.new(readme_pod_version[1])
readme_requirement_ok = readme_requirement.satisfied_by?(Gem::Version.new(sg_version))
results << Utils.table_result(
readme_requirement_ok,
"README: pod version #{readme_pod_version[1]}",
'Please update the README instructions with the right pod version'
)
exit 1 unless results.all?
end
task :confirm do
version = Utils.podspec_version(POD_NAME)
print "Release version #{version} [Y/n]? "
exit 2 unless STDIN.gets.chomp == 'Y'
end
desc 'Create a zip containing all the prebuilt binaries'
task :zip => ['cli:clean'] do
# Force a universal build
task('cli:install').invoke(nil, true)
`cp LICENCE README.md CHANGELOG.md #{BUILD_DIR}/swiftgen`
`cd #{BUILD_DIR}/swiftgen; zip -r ../swiftgen-#{Utils.podspec_version(POD_NAME)}.zip .`
end
desc 'Create a zip containing all the prebuilt binaries in the artifact bundle format (for SwiftPM Package Plugins)'
task :artifactbundle => :zip do
bundle_dir = "#{BUILD_DIR}/swiftgen.artifactbundle"
version = Utils.podspec_version(POD_NAME)
# Copy the built product to an artifact bundle
`mkdir -p #{bundle_dir}`
`cp -Rf #{BUILD_DIR}/swiftgen #{bundle_dir}`
# Write the `info.json` artifact bundle manifest
info_template = File.read("rakelib/artifactbundle.info.json.template")
info_file_content = info_template.gsub(/(VERSION)/, version)
File.open("#{bundle_dir}/info.json", "w") do |f|
f.write(info_file_content)
end
# Zip the bundle
`cd #{BUILD_DIR}; zip -r swiftgen-#{version}.artifactbundle.zip swiftgen.artifactbundle/`
end
desc "Create a new GitHub release"
task :github => :artifactbundle do
require 'octokit'
client = Utils.octokit_client
version = Utils.podspec_version(POD_NAME)
body = Utils.top_changelog_entry
artifacts = [
"swiftgen-#{version}.zip",
"swiftgen-#{version}.artifactbundle.zip"
]
repo_name = File.basename(`git remote get-url origin`.chomp, '.git').freeze
# Create (or update) release
puts "Pushing release notes for tag #{version}"
begin
release = client.release_for_tag("SwiftGen/#{repo_name}", version)
client.update_release(release.url, tag_name: version, name: version, body: body)
rescue Octokit::NotFound
release = client.create_release("SwiftGen/#{repo_name}", version, name: version, body: body)
end
# Upload our artifacts
artifacts.each do |artifact|
artifact_path = File.join(BUILD_DIR, artifact)
client.upload_asset(release.url, artifact_path, name: artifact, content_type: 'application/zip')
end
end
desc 'pod trunk push SwiftGen to CocoaPods'
task :cocoapods do
Utils.print_header 'Pushing pod to CocoaPods Trunk'
sh "bundle exec pod trunk push #{POD_NAME}.podspec"
end
desc 'Release a new version on Homebrew and prepare a PR'
task :homebrew do
Utils.print_header 'Updating Homebrew Formula'
tag = Utils.podspec_version(POD_NAME)
archive_url = "https://github.com/SwiftGen/SwiftGen/archive/#{tag}.tar.gz"
digest = Digest::SHA256.hexdigest URI.open(archive_url).read
formulas_dir = Bundler.with_original_env { `brew --repository homebrew/core`.chomp }
Dir.chdir(formulas_dir) do
sh 'git checkout master'
sh 'git pull'
sh "git checkout -b swiftgen-#{tag} origin/master"
formula_file = "#{formulas_dir}/Formula/swiftgen.rb"
formula = File.read(formula_file)
new_formula = formula
.gsub(/(url\s+)".*"/, %(\\1"#{archive_url}"))
.gsub(/(sha256\s+)".*"/, %(\\1"#{digest}"))
File.write(formula_file, new_formula)
Utils.print_info 'Formula has been auto-updated. Do you need to also do manual updates to it before continuing [y/n]?'
if STDIN.gets.chomp.downcase == 'y'
sh 'open', formula_file
puts "Once you've finished editing the formula file, press enter to continue."
STDIN.gets.chomp
end
Utils.print_header 'Checking Homebrew formula...'
Bundler.with_original_env do
sh 'brew audit --strict --online swiftgen'
sh 'brew reinstall swiftgen --build-from-source'
sh 'brew test swiftgen'
end
Utils.print_header 'Pushing to Homebrew'
sh "git add #{formula_file}"
sh "git commit -m 'swiftgen #{tag}'"
# Add remote pointing to our fork, if it doesn't exist yet, then push the new branch to it before opening the PR
sh 'git remote add SwiftGen https://github.com/SwiftGen/homebrew-core 2>/dev/null || true'
sh "git push -u SwiftGen swiftgen-#{tag}"
sh "open 'https://github.com/Homebrew/homebrew-core/compare/master...SwiftGen:swiftgen-#{tag}?expand=1'"
sh 'git checkout master'
end
end
end
task :default => 'release:new'