Release 0.14.0 (#300)

* Introduce script to automate release

* Rakefile levelup

* Version 0.14.0

* Fix newline at end of podspec.json

* Ensure we start and end on master branch

And that we pull latest master before tagging

* CRLF at EOF

* Remove [:version] param from `release:finish` task

It can be guessed from the current podspec version

* Fix create_release task

* Ensure we run rake via bundle exec

Co-authored-by: David Jennes <djbe@users.noreply.github.com>

Co-authored-by: David Jennes <djbe@users.noreply.github.com>
This commit is contained in:
Olivier Halligon
2020-08-17 20:42:00 +02:00
committed by GitHub
parent 19646bcddf
commit e93b33423b
12 changed files with 335 additions and 8 deletions

View File

@@ -1,6 +1,6 @@
# Stencil Changelog # Stencil Changelog
## Master ## 0.14.0
### Breaking ### Breaking

7
Gemfile Normal file
View File

@@ -0,0 +1,7 @@
# frozen_string_literal: true
source "https://rubygems.org"
gem "octokit"
gem "cocoapods"
gem "rake"

105
Gemfile.lock Normal file
View File

@@ -0,0 +1,105 @@
GEM
remote: https://rubygems.org/
specs:
CFPropertyList (3.0.2)
activesupport (4.2.11.3)
i18n (~> 0.7)
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
addressable (2.7.0)
public_suffix (>= 2.0.2, < 5.0)
algoliasearch (1.27.3)
httpclient (~> 2.8, >= 2.8.3)
json (>= 1.5.1)
atomos (0.1.3)
claide (1.0.3)
cocoapods (1.9.3)
activesupport (>= 4.0.2, < 5)
claide (>= 1.0.2, < 2.0)
cocoapods-core (= 1.9.3)
cocoapods-deintegrate (>= 1.0.3, < 2.0)
cocoapods-downloader (>= 1.2.2, < 2.0)
cocoapods-plugins (>= 1.0.0, < 2.0)
cocoapods-search (>= 1.0.0, < 2.0)
cocoapods-stats (>= 1.0.0, < 2.0)
cocoapods-trunk (>= 1.4.0, < 2.0)
cocoapods-try (>= 1.1.0, < 2.0)
colored2 (~> 3.1)
escape (~> 0.0.4)
fourflusher (>= 2.3.0, < 3.0)
gh_inspector (~> 1.0)
molinillo (~> 0.6.6)
nap (~> 1.0)
ruby-macho (~> 1.4)
xcodeproj (>= 1.14.0, < 2.0)
cocoapods-core (1.9.3)
activesupport (>= 4.0.2, < 6)
algoliasearch (~> 1.0)
concurrent-ruby (~> 1.1)
fuzzy_match (~> 2.0.4)
nap (~> 1.0)
netrc (~> 0.11)
typhoeus (~> 1.0)
cocoapods-deintegrate (1.0.4)
cocoapods-downloader (1.4.0)
cocoapods-plugins (1.0.0)
nap
cocoapods-search (1.0.0)
cocoapods-stats (1.1.0)
cocoapods-trunk (1.5.0)
nap (>= 0.8, < 2.0)
netrc (~> 0.11)
cocoapods-try (1.2.0)
colored2 (3.1.2)
concurrent-ruby (1.1.6)
escape (0.0.4)
ethon (0.12.0)
ffi (>= 1.3.0)
faraday (1.0.1)
multipart-post (>= 1.2, < 3)
ffi (1.13.1)
fourflusher (2.3.1)
fuzzy_match (2.0.4)
gh_inspector (1.1.3)
httpclient (2.8.3)
i18n (0.9.5)
concurrent-ruby (~> 1.0)
json (2.3.1)
minitest (5.14.1)
molinillo (0.6.6)
multipart-post (2.1.1)
nanaimo (0.3.0)
nap (1.1.0)
netrc (0.11.0)
octokit (4.18.0)
faraday (>= 0.9)
sawyer (~> 0.8.0, >= 0.5.3)
public_suffix (4.0.5)
rake (13.0.1)
ruby-macho (1.4.0)
sawyer (0.8.2)
addressable (>= 2.3.5)
faraday (> 0.8, < 2.0)
thread_safe (0.3.6)
typhoeus (1.4.0)
ethon (>= 0.9.0)
tzinfo (1.2.7)
thread_safe (~> 0.1)
xcodeproj (1.17.1)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
colored2 (~> 3.1)
nanaimo (~> 0.3.0)
PLATFORMS
ruby
DEPENDENCIES
cocoapods
octokit
rake
BUNDLED WITH
2.1.4

10
Rakefile Executable file
View File

@@ -0,0 +1,10 @@
PODSPEC_FILE = 'Stencil.podspec.json'
CHANGELOG_FILE = 'CHANGELOG.md'
if ENV['BUNDLE_GEMFILE'].nil?
puts "\u{274C} Please use bundle exec"
exit 1
end
task :default => 'release:new'

View File

@@ -1,6 +1,6 @@
{ {
"name": "Stencil", "name": "Stencil",
"version": "0.13.1", "version": "0.14.0",
"summary": "Stencil is a simple and powerful template language for Swift.", "summary": "Stencil is a simple and powerful template language for Swift.",
"homepage": "https://stencil.fuller.li", "homepage": "https://stencil.fuller.li",
"license": { "license": {
@@ -13,7 +13,7 @@
"social_media_url": "https://twitter.com/kylefuller", "social_media_url": "https://twitter.com/kylefuller",
"source": { "source": {
"git": "https://github.com/stencilproject/Stencil.git", "git": "https://github.com/stencilproject/Stencil.git",
"tag": "0.13.1" "tag": "0.14.0"
}, },
"source_files": [ "source_files": [
"Sources/*.swift" "Sources/*.swift"
@@ -24,7 +24,10 @@
"tvos": "9.0" "tvos": "9.0"
}, },
"cocoapods_version": ">= 1.7.0", "cocoapods_version": ">= 1.7.0",
"swift_versions": ["4.2", "5.0"], "swift_versions": [
"4.2",
"5.0"
],
"requires_arc": true, "requires_arc": true,
"dependencies": { "dependencies": {
"PathKit": [ "PathKit": [

View File

@@ -58,9 +58,9 @@ author = 'Kyle Fuller'
# built documents. # built documents.
# #
# The short X.Y version. # The short X.Y version.
version = '0.13.1' version = '0.14.0'
# The full version, including alpha/beta/rc tags. # The full version, including alpha/beta/rc tags.
release = '0.13.1' release = '0.14.0'
# The language for content autogenerated by Sphinx. Refer to documentation # The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages. # for a list of supported languages.

View File

@@ -26,7 +26,7 @@ If you're using CocoaPods, you can add Stencil to your ``Podfile`` and then run
.. code-block:: ruby .. code-block:: ruby
pod 'Stencil', '~> 0.13.1' pod 'Stencil', '~> 0.14.0'
Carthage Carthage
-------- --------
@@ -37,7 +37,7 @@ Carthage
.. code-block:: text .. code-block:: text
github "stencilproject/Stencil" ~> 0.13.1 github "stencilproject/Stencil" ~> 0.14.0
2) Checkout your dependencies, generate the Stencil Xcode project, and then use Carthage to build Stencil: 2) Checkout your dependencies, generate the Stencil Xcode project, and then use Carthage to build Stencil:

34
rakelib/changelog.rake Normal file
View File

@@ -0,0 +1,34 @@
NEW_CHANGELOG_SECTION = "## Master\n" + ['Breaking', 'Enhancements', 'Deprecations', 'Bug Fixes', 'Internal Changes'].map do |s|
<<~MARKDOWN
### #{s}
_None_
MARKDOWN
end.join
def changelog_first_section
content = []
section_count = 0
File.foreach(CHANGELOG_FILE) do |line|
section_count += 1 if line.start_with?('## ')
break if section_count > 1
content.append(line) if section_count == 1
end
content[1..].join
end
namespace :changelog do
# rake changelog:reset
desc "Add a new empty section at the top of the changelog and git push it"
task :reset do
header "Reset CHANGELOG"
content = File.read(CHANGELOG_FILE)
new_content = NEW_CHANGELOG_SECTION + "\n" + content
File.write(CHANGELOG_FILE, new_content)
sh("git", "add", CHANGELOG_FILE)
sh("git", "commit", "-m", "Reset CHANGELOG")
sh("git", "push")
end
end

52
rakelib/github.rake Normal file
View File

@@ -0,0 +1,52 @@
require 'octokit'
def repo_slug
url_parts = `git remote get-url origin`.chomp.split(%r{/|:})
last_two_parts = url_parts[-2..-1].join('/')
last_two_parts.gsub(/\.git$/, '')
end
def github_client
Octokit::Client.new(:netrc => true)
end
namespace :github do
# rake github:create_release_pr[version]
task :create_release_pr, [:version] do |_, args|
version = args[:version]
branch = release_branch(version)
title = "Release #{version}"
body = <<~BODY
This PR prepares the release for version #{version}.
Once the PR is merged into master, run `bundle exec rake release:finish` to tag and push to trunk.
BODY
header "Opening PR"
res = github_client.create_pull_request(repo_slug, "master", branch, title, body)
info "Pull request created: #{res['html_url']}"
end
# rake github:tag
task :tag do
tag = current_pod_version
sh("git", "tag", tag)
sh("git", "push", origin, tag)
end
# rake github:create_release
task :create_release do
tag_name = current_pod_version
title = tag_name
body = changelog_first_section()
res = github_client.create_release(repo_slug, tag_name, name: title, body: body)
info "GitHub Release created: #{res['html_url']}"
end
# rake github:pull_master
task :pull_master do
sh("git", "switch", "master")
sh("git", "pull")
end
end

21
rakelib/pod.rake Normal file
View File

@@ -0,0 +1,21 @@
require 'json'
def current_pod_version
JSON.parse(File.read(PODSPEC_FILE))['version']
end
namespace :pod do
# rake pod:lint
desc "Lint the podspec"
task :lint do
header "Linting podspec"
sh("pod", "lib", "lint", PODSPEC_FILE)
end
# rake pod:push
desc "Push the podspec to trunk"
task :push do
header "Pushing podspec to trunk"
sh("pod", "trunk", "push", PODSPEC_FILE)
end
end

67
rakelib/release.rake Normal file
View File

@@ -0,0 +1,67 @@
require 'json'
namespace :release do
# rake release:new
desc "Ask for a version number and prepare a release PR for that version"
task :new do
info "Current version is: #{current_pod_version}"
print "What version do you want to release? "
new_version = STDIN.gets.chomp
Rake::Task['release:start'].invoke(new_version)
end
# rake release:start[version]
desc "Start a release by creating a PR with the required changes to bump the version"
task :start, [:version] => ['release:create_branch', 'release:update_files', 'pod:lint', 'release:push_branch', 'github:create_release_pr', 'github:pull_master']
# rake release:finish[version]
desc "Finish a release after the PR has been merged, by tagging master and pushing to trunk"
task :finish => ['github:pull_master', 'github:tag', 'pod:push', 'github:create_release', 'changelog:reset']
### Helper tasks ###
# rake release:create_branch[version]
task :create_branch, [:version] do |_, args|
branch = release_branch(args[:version])
header "Creating release branch"
sh("git", "checkout", "-b", branch)
end
# rake release:update_files[version]
task :update_files, [:version] do |_, args|
version = args[:version]
header "Updating files for version #{version}"
podspec = JSON.parse(File.read(PODSPEC_FILE))
podspec['version'] = version
podspec['source']['tag'] = version
File.write(PODSPEC_FILE, JSON.pretty_generate(podspec) + "\n")
replace(CHANGELOG_FILE, '## Master' => "\#\# #{version}")
replace("docs/conf.py",
/^version = .*/ => %Q(version = '#{version}'),
/^release = .*/ => %Q(release = '#{version}')
)
replace("docs/installation.rst",
/pod 'Stencil', '.*'/ => %Q(pod 'Stencil', '~> #{version}'),
/github "stencilproject\/Stencil" ~> .*/ => %Q(github "stencilproject/Stencil" ~> #{version})
)
## Commit Changes
sh("git", "add", PODSPEC_FILE, CHANGELOG_FILE, "docs/*")
sh("git", "commit", "-m", "Version #{version}")
end
# rake release:push_branch[version]
task :push_branch, [:version] do |_, args|
branch = release_branch(args[:version])
header "Pushing #{branch} to origin"
sh("git", "push", "-u", "origin", branch)
end
end

28
rakelib/utils.rake Normal file
View File

@@ -0,0 +1,28 @@
def colorize(string, *codes)
if `tput colors`.chomp.to_i >= 8
code = codes.join(';')
puts "\e[#{code}m" + string + "\e[0m"
else
puts string
end
end
def header(title)
puts colorize("==> #{title}...", 1, 32) # bold, green
end
def info(string)
puts colorize(string, 34) # blue
end
def release_branch(version)
"release/#{version}"
end
def replace(file, replacements)
content = File.read(file)
replacements.each do |match, replacement|
content.gsub!(match, replacement)
end
File.write(file, content)
end