224 lines
8.0 KiB
Ruby
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'
|