Skip to content

Commit

Permalink
Updated build process to automatically push tagged successful builds …
Browse files Browse the repository at this point in the history
…to CocoaPods, then add release notes for them to GitHub (Issue #23)
  • Loading branch information
abbeycode committed Mar 25, 2016
1 parent ab9c1cc commit 16e8959
Show file tree
Hide file tree
Showing 10 changed files with 265 additions and 10 deletions.
21 changes: 15 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,31 +1,40 @@
language: objective-c
osx_image: xcode7.1
osx_image: xcode7.3

before_install:
# Fixing an issue with xctool 0.2.8 in conjunction with Xcode 7.3
- brew update
- brew install carthage
- brew upgrade xctool
- brew uninstall --force xctool && brew install --HEAD xctool
# Used to allow pushing to CocoaPods only after all matrixed builds have succeeded
- npm install --save-dev travis-after-all

xcode_workspace: UnrarKit.xcworkspace

matrix:
include:
- xcode_scheme: UnrarKit
xcode_sdk: macosx
env: NAME=Mac
env:
- NAME=Mac
- secure: YTWr9wh/Ud39iWSN7uYojg2DkIDOGUhlNwguX3p6e7hrW3qMTzTceWHVFAGTmUnEiiVQf6f0QZlZEXUPHPE6ymgiY6TFZYe3/ptGpK8TRDwX1lQCujMuEpaCxtT5p+f+NjVnJlWywZnUU2R//EYNj154mWADFMDsK+rWJBaBa/U=
- secure: MEDKuebBqo7LnL1VXtxDvU8pY1Ml531J4mrRILTdi+5ik50eH+EWr1fTJ8uIVc39CBGbkzoWq8Hng0bDfv8GioTn97tTeZQlurhmao8J8VR1GoUAS2t/9LQfDFXiHbGA3ouCOzXhoNEKrFCbmtBp4u8pDYQDHAxq0ZkFPzc/pXU=

- xcode_scheme: UnrarKit iOS
xcode_sdk: iphonesimulator
env: NAME=iOSTests
env: NAME=iOS

- xcode_scheme: UnrarExample
xcode_sdk: iphonesimulator
env: NAME=ExampleAppBuild

script:
- xctool --version
- xctool -workspace $TRAVIS_XCODE_WORKSPACE -scheme "$TRAVIS_XCODE_SCHEME" -sdk $TRAVIS_XCODE_SDK -configuration Release analyze test
- ./Scripts/carthage-validate.sh
- ./Scripts/cocoapod-validate.sh

after_script:
- ./Scripts/push-output.sh

# Turn on Docker, container-based infrastructure
sudo: false
sudo: false
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# UnrarKit CHANGELOG

## 2.7.1

* Pushing tagged builds to CocoaPods from Travis
* Adding release notes to GitHub

## 2.7

Updated to the latest version of the UnRAR library (v5.3.11)
Expand Down
34 changes: 34 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,42 @@ To open in Xcode, use the [UnrarKit.xcworkspace](UnrarKit.xcworkspace) file, whi
Full documentation for the project is available on [CocoaDocs](http://cocoadocs.org/docsets/UnrarKit).
# Pushing a new CocoaPods version
New tagged builds (in any branch) get pushed to CocoaPods automatically, provided they meet the following criteria:
1. All builds and tests succeed
2. The library builds successfully for CocoaPods and for Carthage
3. The build is tagged with something resembling a version number (`#.#.#(-beta#)`, e.g. **2.9** or **2.9-beta5**)
4. `pod spec lint` passes, making sure the CocoaPod is 100% valid
Before pushing a build, you must:
1. Add the release notes to the [CHANGELOG.md](CHANGELOG.md), and commit
2. Run [set-version](Scripts/set-version.sh), like so:
`./Scripts/set-version.sh <version number>`
This does the following:
1. Updates the [UnrarKit-Info.plist](Resources/UnrarKit-Info.plist) file to indicate the new version number, and commits it
2. Makes an annotated tag whose message contains the release notes entered in Step 1
Once that's done, you can call `git push --follow-tags` [<sup id=a1>1</sup>](#f1), and let [Travis CI](https://travis-ci.org/abbeycode/UnrarKit/builds) take care of the rest.
# Credits
* Dov Frankel ([email protected])
* Rogerio Pereira Araujo ([email protected])
* Vicent Scott ([email protected])
<hr>
<span id="f1">1</span>: Or set `followTags = true` in your git config to always get this behavior:
git config --global push.followTags true
[↩](#a1)
4 changes: 2 additions & 2 deletions Resources/UnrarKit-Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>2.7</string>
<string>2.7.1-beta4</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>2.7</string>
<string>2.7.1-beta4</string>
</dict>
</plist>
87 changes: 87 additions & 0 deletions Scripts/add-github-release.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#!/usr/bin/env python
# -*- coding: UTF-8 -*-

# Usage: add-github-release.py <API token> <repo> <tag being released> <release notes>
#
# Creates a release in GitHub for the given tag
#

import json
import urllib2
import sys

def add_release(token, repo, tag, notes):
'''
'''
print('token: "{}", repo: "{}", tag: "{}", notes: "{}"'.format('SECURE' if token else '', repo, tag, notes))

assert token, 'No API token given'
assert repo, 'No repo given'
assert '/' in repo, "Repo doesn't look like a valid GitHub repo (e.g. abbeycode/UnrarKit)"
assert tag, 'No tag given'
assert notes, 'No notes given'

is_beta = tag_is_beta(tag)

url = 'https://api.github.com/repos/{}/releases?access_token={}'.format(repo, token)
values = {
'tag_name': tag,
'name': 'v{}'.format(tag),
'body': notes,
'prerelease': True if is_beta else False
}

data = json.dumps(values)
req = urllib2.Request(url, data)
response = urllib2.urlopen(req)
the_page = response.read()

response_dict = json.loads(the_page)
release_url = response_dict['url']

print('Release added: {}'.format(release_url))
return True

def tag_is_beta(tag):
'''
Returns True if the tag contains a label indicating it's a beta build
>>> tag_is_beta('1.2.3')
False
>>> tag_is_beta('1.2.3-beta')
True
>>> tag_is_beta('1.2.3-beta2')
True
>>> tag_is_beta('1.2.3-RC')
True
>>> tag_is_beta('1.2.3-RC1')
True
>>> tag_is_beta('1.2.3-prerelease')
True
>>> tag_is_beta('1.2.3-prerelease2')
True
>>> tag_is_beta('1.2.3-alpha')
True
>>> tag_is_beta('1.2.3-alpha2')
True
'''

return 'beta' in tag or 'RC' in tag or 'prerelease' in tag or 'alpha' in tag



if __name__ == '__main__':
# Allow script to be called with 'test' argument
if len(sys.argv) == 2 and sys.argv[1].lower() == 'test':
import doctest
result = doctest.testmod()
sys.exit(0 if result.failed == 0 else 1)

expected_arg_count = 5

if len(sys.argv) != expected_arg_count:
print('\nadd-github-release given {} arguments ({}). Expecting {}\n'.format(len(sys.argv) - 1, sys.argv[1:], expected_arg_count - 1))
sys.exit(1)

exit_code = 0 if add_release(*sys.argv[1:]) else 1
sys.exit(exit_code)
13 changes: 12 additions & 1 deletion Scripts/cocoapod-validate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,16 @@

set -ev

if [ -z "$TRAVIS_TAG" ]; then
TRAVIS_TAG_SUBSTITUTED=1
export TRAVIS_TAG="$(git tag -l | tail -1)"
echo "Not a tagged build. Using last tag ($TRAVIS_TAG) for pod lib lint..."
fi

# Lint the podspec to check for errors. Don't call `pod spec lint`, because we want it to evaluate locally
pod lib lint
pod lib lint

if [ -n "$TRAVIS_TAG_SUBSTITUTED" ]; then
echo "Unsetting TRAVIS_TAG..."
unset TRAVIS_TAG
fi
12 changes: 12 additions & 0 deletions Scripts/get-release-notes.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash

# Usage: get-release-notes.sh <version-number>
#
# Prints the release notes for a given version out of CHANGELOG.md

# Remove the "-beta#" from the end of the version number
[[ $1 =~ ^([0-9\.]+)(\-beta[0-9]*)?$ ]]
RELEASE_VERSION=${BASH_REMATCH[1]}

# Require release notes to be written
sed "/^## $RELEASE_VERSION$/,/^##/!d;//d;/^$/d" CHANGELOG.md
45 changes: 45 additions & 0 deletions Scripts/push-output.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/bin/bash

echo

# Only potentially push to CocoaPods when it's a tagged build
if [ -z "$TRAVIS_TAG" ]; then
echo -e "\nBuild is not tagged"
exit 1
fi

# Make sure tag name looks like a version number
if ! [[ $TRAVIS_TAG =~ ^[0-9\.]+(\-beta[0-9]*)?$ ]]; then
echo -e "\nBranch build not a valid version number: $TRAVIS_TAG"
exit 1
else
echo -e "\nTag looks like a version number: $TRAVIS_TAG"
fi

$(npm bin)/travis-after-all
exitCode=$?

if [ $exitCode -ne 0 ]; then
echo -e "\nThis or another matrixed job has failed"
exit 0
fi

echo -e "\nLinting podspec..."
pod spec lint --fail-fast

if [ $? -ne 0 ]; then
echo -e "\nPodspec failed lint. Run again with --verbose to troubleshoot"
exit 1
fi

echo -e "\nPushing to CocoaPods...\n"
pod trunk push

# If push is successful, add release to GitHub
if [ $? -ne 0 ]; then
echo -e "\nPush to CocoaPods failed"
exit 1
fi

RELEASE_NOTES=$(./Scripts/get-release-notes.sh $TRAVIS_TAG)
./Scripts/add-github-release.py $GITHUB_RELEASE_API_TOKEN $TRAVIS_REPO_SLUG $TRAVIS_TAG "$RELEASE_NOTES"
52 changes: 52 additions & 0 deletions Scripts/set-version.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/bin/bash

# Usage: set-version.sh <version-number>
#
# Updates the main plist file, then tags the build in Git, using the release notes from CHANGELOG.md

# Colors
COLOR_OFF='\033[0m'
RED='\033[0;31m'
GREEN='\033[0;32m'
BOLD_YELLOW='\033[1;33m'

# Did this script change since the last commit?
THIS_FILE_REGEX='.*Scripts/set-version\.sh.*'
THIS_FILE_CHANGED=$(git status --porcelain --untracked-files=no | grep $THIS_FILE_REGEX | wc -l)

# Only continue if the repo has no changes (excluding this script)
CHANGED_FILE_COUNT=$(git status --porcelain --untracked-files=no | grep -v $THIS_FILE_REGEX | wc -l)
if [ $CHANGED_FILE_COUNT -gt 0 ]; then
echo -e "${RED}Please commit or discard any changes before continuing$COLOR_OFF"
exit 1
fi

# Require a single argument to be passed in
if [ "$#" -ne 1 ]; then
echo -e "${RED}Please pass the desired version number as an argument$COLOR_OFF"
exit 1
fi

RELEASE_NOTES=$(./Scripts/get-release-notes.sh $1)
if [ -z "$RELEASE_NOTES" ]; then
echo -e "${RED}Please add release notes for v$1 into CHANGELOG.md$COLOR_OFF"
exit 1
fi

echo -e "${GREEN}Updating version numbers in plist to '$1'..$COLOR_OFF"
agvtool new-version -all "$1" # CFBundleVersion
agvtool new-marketing-version "$1" # CFBundleShortVersionString

if [ "$THIS_FILE_CHANGED" -gt 0 ]; then
echo -e "${BOLD_YELLOW}Not committing to Git, as this script isn't final. Commit it to continue$COLOR_OFF"
exit 2
fi

echo -e "${GREEN}Committing updated plist...$COLOR_OFF"
git commit -m "Updated plist to v$1" Resources

# Revert changes to other plist files
git checkout .

echo -e "${GREEN}Tagging build...$COLOR_OFF"
git tag $1 -m "$RELEASE_NOTES"
2 changes: 1 addition & 1 deletion UnrarKit.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "UnrarKit"
s.version = "2.7"
s.version = ENV["TRAVIS_TAG"]
s.summary = "UnrarKit is here to enable Mac and iOS Cocoa apps to easily work with RAR files for read-only operations"
s.license = "BSD"
s.homepage = "https://github.com/abbeycode/UnrarKit"
Expand Down

0 comments on commit 16e8959

Please sign in to comment.