Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Initial import.

  • Loading branch information...
commit 77849011d84f7f57e401e05dadb6c893a9814060 0 parents
Luke Redpath authored
Showing with 240 additions and 0 deletions.
  1. +19 −0 LICENSE
  2. +83 −0 README.md
  3. +137 −0 lib/beta_builder.rb
  4. +1 −0  lib/betabuilder.rb
19 LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2010 Luke Redpath
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
83 README.md
@@ -0,0 +1,83 @@
+# BetaBuilder, a gem for managing iOS ad-hoc builds
+
+BetaBuilder is a simple collection of Rake tasks and utilities for managing and publishing Adhoc builds of your iOS apps.
+
+It is inspired by and owes a lot of credit to [Hunter Hillegas](http://www.hanchorllc.com/2010/08/24/introducing-ios-beta-builder/) who created the original OSX Beta Builder utility.
+
+## Motiviation
+
+The problem with using a GUI app to create the beta packages is that it is yet another manual step in the process of producing an ad-hoc build for your beta testers. It simplifies some steps but it still requires running Build and Archive in Xcode, saving the resulting build as an IPA package, running the Beta Builder app, locating the IPA, filling in the rest of the fields and generating the deployment files. Then you need to upload those files somewhere.
+
+As a Ruby developer, I use Rake in most of my projects to run repetitive, often build or test-related tasks and it's equally as useful for non-Ruby projects as it is for Ruby ones.
+
+This simple task library allows you to configure once and then build, package and distribute your ad-hoc releases with a single command.
+
+## Usage
+
+To get started, if you don't already have a Rakefile in the root of your project, create one. If you aren't familiar with Rake, it might be worth [going over some of the basics](http://rake.rubyforge.org/) but it's fairly straightforward.
+
+You can install the BetaBuilder gem from your terminal (OSX 10.6 works with a perfectly useful Ruby installation):
+
+ $ gem install betabuilder
+
+At the top of your Rakefile, you'll need to require `rubygems` and the `betabuilder` gem (obviously).
+
+ require 'rubygems'
+ require 'betabuilder'
+
+Because BetaBuilder is a Rake task library, you do not need to define any tasks yourself. You simply need to configure BetaBuilder with some basic information about your project and it will generate the tasks for you. A sample configuration might look something like this:
+
+ BetaBuilder::Tasks.new do |config|
+ # your Xcode target name
+ config.target = "MyGreatApp"
+
+ # the Xcode configuration profile
+ config.configuration = "Adhoc"
+
+ # where the distribution files will be uploaded to
+ config.deploy_to = "http://yourwebsite.com/betas/"
+ end
+
+Now, if you run `rake -T` in Terminal.app in the root of your project, the available tasks will be printed with a brief description of each one:
+
+ rake beta:build # Build the beta release of the app
+ rake beta:deploy # Deploy the beta to your server
+ rake beta:package # Package the beta release as an IPA file
+
+To deploy a beta to your server, some additional configuration is needed (see the next section).
+
+Most of the time, you'll not need to run the `beta:build` task directly; it will be run automatically as a dependency of `beta:package`. Upon running this task, your ad-hoc build will be packaged into an IPA file and will be saved in ${PROJECT_ROOT}/pkg/dist, along with a HTML index file and the manifest file needed for over-the-air installation.
+
+If you are not using the automatic deployment task, you will need to upload the contents of the pkg/dist directory to your server.
+
+## Automatic deployment
+
+BetaBuilder also comes with a (rather rudimentary) automatic deployment task that uses SCP so you will need SSH access to your server and appropriate permissions to use it. You will also need one extra line of configuration in your Rakefile, specifying the path on the remote server where the files will be copied to:
+
+ config.remote_directory = "/var/www/yourwebsite.com/betas"
+
+Now, instead of using the `beta:package` task, you can run the `beta:deploy` task instead. This task will run the package task as a dependency and upload the pkg/dist directory to the remote directory you have configured (again, you will need to ensure that you have the correct permissions for this to work).
+
+## License
+
+This code is licensed under the MIT license.
+
+Copyright (c) 2010 Luke Redpath
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
137 lib/beta_builder.rb
@@ -0,0 +1,137 @@
+module BetaBuilder
+ class Tasks < ::Rake::TaskLib
+ def initialize(&block)
+ @configuration = Configuration.new(
+ :configuration => "Adhoc",
+ :build_dir => "build"
+ )
+ yield @configuration if block_given?
+ define
+ end
+
+ class Configuration < OpenStruct
+ def build_arguments
+ "-target #{target} -configuration #{configuration} -sdk iphoneos"
+ end
+
+ def app_name
+ "#{target}.app"
+ end
+
+ def ipa_name
+ "#{target}.ipa"
+ end
+
+ def built_app_path
+ "#{build_dir}/#{configuration}-iphoneos/#{app_name}"
+ end
+
+ def deployment_url
+ File.join(deploy_to, target.downcase, ipa_name)
+ end
+
+ def manifest_url
+ File.join(deploy_to, target.downcase, "manifest.plist")
+ end
+
+ def remote_installation_path
+ File.join(remote_directory, target.downcase)
+ end
+ end
+
+ private
+
+ def define
+ namespace :beta do
+ desc "Build the beta release of the app"
+ task :build => :clean do
+ system("xcodebuild #{@configuration.build_arguments} build")
+ end
+
+ task :clean do
+ system("xcodebuild #{@configuration.build_arguments} clean")
+ end
+
+ desc "Package the beta release as an IPA file"
+ task :package => :build do
+ FileUtils.rm_rf('pkg') && FileUtils.mkdir_p('pkg')
+ FileUtils.mkdir_p("pkg/Payload")
+ FileUtils.mv(@configuration.built_app_path, "pkg/Payload/#{@configuration.app_name}")
+ Dir.chdir("pkg") do
+ system("zip -r #{@configuration.ipa_name} Payload")
+ end
+ FileUtils.mkdir('pkg/dist')
+ FileUtils.mv("pkg/#{@configuration.ipa_name}", "pkg/dist")
+ plist = CFPropertyList::List.new(:file => "pkg/Payload/#{@configuration.app_name}/Info.plist")
+ plist_data = CFPropertyList.native_types(plist.value)
+ File.open("pkg/dist/manifest.plist", "w") do |io|
+ io << %{
+ <?xml version="1.0" encoding="UTF-8"?>
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+ <plist version="1.0">
+ <dict>
+ <key>items</key>
+ <array>
+ <dict>
+ <key>assets</key>
+ <array>
+ <dict>
+ <key>kind</key>
+ <string>software-package</string>
+ <key>url</key>
+ <string>#{@configuration.deployment_url}</string>
+ </dict>
+ </array>
+ <key>metadata</key>
+ <dict>
+ <key>bundle-identifier</key>
+ <string>#{plist_data['CFBundleIdentifier']}</string>
+ <key>bundle-version</key>
+ <string>#{plist_data['CFBundleVersion']}</string>
+ <key>kind</key>
+ <string>software</string>
+ <key>title</key>
+ <string>#{plist_data['CFBundleDisplayName']}</string>
+ </dict>
+ </dict>
+ </array>
+ </dict>
+ </plist>
+ }
+ end
+ File.open("pkg/dist/index.html", "w") do |io|
+ io << %{
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ <html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
+ <title>Beta Download</title>
+ <style type="text/css">
+ body {background:#fff;margin:0;padding:0;font-family:arial,helvetica,sans-serif;text-align:center;padding:10px;color:#333;font-size:16px;}
+ #container {width:300px;margin:0 auto;}
+ h1 {margin:0;padding:0;font-size:14px;}
+ p {font-size:13px;}
+ .link {background:#ecf5ff;border-top:1px solid #fff;border:1px solid #dfebf8;margin-top:.5em;padding:.3em;}
+ .link a {text-decoration:none;font-size:15px;display:block;color:#069;}
+ </style>
+ </head>
+ <body>
+ <div id="container">
+ <div class="link"><a href="itms-services://?action=download-manifest&url=#{@configuration.manifest_url}">Tap Here to Install<br />#{@configuration.target}<br />On Your Device</a></div>
+ <p><strong>Link didn't work?</strong><br />
+ Make sure you're visiting this page on your device, not your computer.</p>
+ </body>
+ </html>
+ }
+ end
+ end
+
+ desc "Deploy the beta to your server"
+ task :deploy => :package do
+ system("scp pkg/dist/* lukeredpath.co.uk:#{@configuration.remote_installation_path}")
+ end
+ end
+ end
+ end
+end
1  lib/betabuilder.rb
@@ -0,0 +1 @@
+require 'beta_builder'
Please sign in to comment.
Something went wrong with that request. Please try again.