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:
@@ -1,6 +1,6 @@
|
|||||||
# Stencil Changelog
|
# Stencil Changelog
|
||||||
|
|
||||||
## Master
|
## 0.14.0
|
||||||
|
|
||||||
### Breaking
|
### Breaking
|
||||||
|
|
||||||
|
|||||||
7
Gemfile
Normal file
7
Gemfile
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
source "https://rubygems.org"
|
||||||
|
|
||||||
|
gem "octokit"
|
||||||
|
gem "cocoapods"
|
||||||
|
gem "rake"
|
||||||
105
Gemfile.lock
Normal file
105
Gemfile.lock
Normal 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
10
Rakefile
Executable 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'
|
||||||
@@ -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": [
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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
34
rakelib/changelog.rake
Normal 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
52
rakelib/github.rake
Normal 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
21
rakelib/pod.rake
Normal 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
67
rakelib/release.rake
Normal 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
28
rakelib/utils.rake
Normal 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
|
||||||
Reference in New Issue
Block a user