tug 0.0.4 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +30 -1
- data/lib/tug/command/command.rb +4 -1
- data/lib/tug/command/ipa_command.rb +3 -3
- data/lib/tug/command/provision_command.rb +15 -0
- data/lib/tug/config/.tug.yml +6 -1
- data/lib/tug/config/config_file.rb +2 -0
- data/lib/tug/interface/interface.rb +19 -9
- data/lib/tug/keychain/keychain.rb +69 -0
- data/lib/tug/version.rb +1 -1
- data/lib/tug.rb +4 -1
- data/spec/build_command_spec.rb +4 -1
- data/spec/command_spec.rb +5 -0
- data/spec/config_file_spec.rb +7 -2
- data/spec/ipa_command_spec.rb +6 -3
- data/spec/keychain_spec.rb +113 -0
- data/spec/output.txt +2 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a3a19cbd80c7658c71fc5354c84c7703b52b33d6
|
4
|
+
data.tar.gz: 5669abeb191d05076e9a98b6429f7f3462ce887a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 49cc50b509c9a4c45de9c77eb501af64c889a026aae9c4ab292f0c1be18249885e82f9dc6f8e52d7ec41d7d656ad2430881dec0888f498daafd9623b058bec10
|
7
|
+
data.tar.gz: 102358c25830e6457f3bd5cd91492429da44bee78445690579173829ffe56cd3ee4173cdbe45dbe96fc601b70eea017d82e0ba6ce7a4fdaf608787c5a1f11fe1
|
data/README.md
CHANGED
@@ -33,7 +33,7 @@ Run `tug ipa` from your Xcode projects root directory, see the example config be
|
|
33
33
|
|
34
34
|
### Config
|
35
35
|
|
36
|
-
tug will look in the
|
36
|
+
tug will look in the current directory for a `.tug.yml` config file by default, use the `--config` option to pass a path to your config file if it's in a different folder.
|
37
37
|
|
38
38
|
A sample config file:
|
39
39
|
|
@@ -45,6 +45,35 @@ project:
|
|
45
45
|
ipa_config: Release # The configuration to use to build ipas
|
46
46
|
```
|
47
47
|
|
48
|
+
### Provisioning
|
49
|
+
|
50
|
+
Provisioning requires you to export the following files from your keychain and place them within your project directory:
|
51
|
+
|
52
|
+
* Apple Worldwide Developer Relations Certificate
|
53
|
+
* iPhone Distribution Certificate
|
54
|
+
* iPhone Distribution Private Key
|
55
|
+
* Distribution Provisioning Profile
|
56
|
+
|
57
|
+
Run `tug provision` to provision a new machine ready for signing ipas, provisioning requires a `keychain` object in the config yaml file to specify the path to the provisioning certificates and profile:
|
58
|
+
|
59
|
+
```
|
60
|
+
keychain:
|
61
|
+
apple_certificate: certs/apple.cer
|
62
|
+
distribution_certificate: certs/dist.cer
|
63
|
+
distribution_profile: certs/profile.mobileprovision
|
64
|
+
private_key: certs/dist.p12
|
65
|
+
```
|
66
|
+
|
67
|
+
#### Private Key Password
|
68
|
+
|
69
|
+
If your `.p12` private key requires a password, you can either set the environment variable:
|
70
|
+
|
71
|
+
`$ export TUG_P12_PASSWORD=yourpassword`
|
72
|
+
|
73
|
+
or use the `--password` option when running the provision command:
|
74
|
+
|
75
|
+
`$ tug provision --password yourpassword`
|
76
|
+
|
48
77
|
## Contributing
|
49
78
|
|
50
79
|
1. Fork it
|
data/lib/tug/command/command.rb
CHANGED
@@ -8,13 +8,16 @@ module Tug
|
|
8
8
|
Tug::BuildCommand.new
|
9
9
|
when "ipa"
|
10
10
|
Tug::IpaCommand.new
|
11
|
+
when "provision"
|
12
|
+
Tug::ProvisionCommand.new
|
11
13
|
else
|
12
14
|
Tug::Command.new
|
13
15
|
end
|
14
16
|
end
|
15
17
|
end
|
16
18
|
|
17
|
-
def execute(
|
19
|
+
def execute(config_file)
|
20
|
+
project = config_file.project
|
18
21
|
@xctool = xctool(project.ipa_config)
|
19
22
|
project.schemes.each do |scheme|
|
20
23
|
@xctool.build(project.workspace, scheme)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Tug
|
2
|
+
class ProvisionCommand < Command
|
3
|
+
|
4
|
+
def execute(config_file)
|
5
|
+
keychain = config_file.keychain
|
6
|
+
|
7
|
+
keychain.create_keychain
|
8
|
+
keychain.select_keychain(keychain.name)
|
9
|
+
keychain.import_apple_certificate
|
10
|
+
keychain.import_distribution_certificate
|
11
|
+
keychain.import_private_key
|
12
|
+
keychain.import_profile
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/tug/config/.tug.yml
CHANGED
@@ -2,6 +2,7 @@ module Tug
|
|
2
2
|
class ConfigFile
|
3
3
|
|
4
4
|
attr_reader :project
|
5
|
+
attr_reader :keychain
|
5
6
|
|
6
7
|
class << self
|
7
8
|
def config_file(path=default_path)
|
@@ -16,6 +17,7 @@ module Tug
|
|
16
17
|
def initialize(path)
|
17
18
|
config = YAML::load_file(path)
|
18
19
|
@project = Tug::Project.new(config['project'])
|
20
|
+
@keychain = Tug::Keychain.keychain(config['keychain'])
|
19
21
|
end
|
20
22
|
|
21
23
|
private
|
@@ -2,26 +2,36 @@ module Tug
|
|
2
2
|
class Interface < Thor
|
3
3
|
|
4
4
|
desc "build", "build a project"
|
5
|
-
option :config, :default => "#{Dir.pwd}/.tug.yml"
|
5
|
+
option :config, :default => "#{Dir.pwd}/.tug.yml", :aliases => "-c"
|
6
6
|
def build
|
7
7
|
config_file = Tug::ConfigFile.config_file(options[:config])
|
8
|
-
execute(__method__.to_s, config_file
|
8
|
+
execute(__method__.to_s, config_file)
|
9
9
|
end
|
10
10
|
|
11
11
|
desc "ipa", "generate an ipa"
|
12
|
-
option :config, :default => "#{Dir.pwd}/.tug.yml"
|
13
|
-
option :export, :default => "#{Dir.pwd}"
|
12
|
+
option :config, :default => "#{Dir.pwd}/.tug.yml", :aliases => "-c"
|
13
|
+
option :export, :default => "#{Dir.pwd}", :aliases => "-e"
|
14
14
|
def ipa
|
15
15
|
config_file = Tug::ConfigFile.config_file(options[:config])
|
16
|
-
project =
|
17
|
-
|
18
|
-
|
16
|
+
config_file.project.ipa_export_path = options[:export]
|
17
|
+
execute(__method__.to_s, config_file)
|
18
|
+
end
|
19
|
+
|
20
|
+
desc "provision", "provision system distrubution certificates and provisioning profile"
|
21
|
+
option :config, :default => "#{Dir.pwd}/.tug.yml", :aliases => "-c"
|
22
|
+
option :keychain, :default => "tug", :aliases => "-k"
|
23
|
+
option :password, :aliases => "-p"
|
24
|
+
def provision
|
25
|
+
config_file = Tug::ConfigFile.config_file(options[:config])
|
26
|
+
config_file.keychain.name = options[:keychain]
|
27
|
+
config_file.keychain.private_key_password = options[:password]
|
28
|
+
execute(__method__.to_s, config_file)
|
19
29
|
end
|
20
30
|
|
21
31
|
no_commands do
|
22
|
-
def execute(command,
|
32
|
+
def execute(command, config_file)
|
23
33
|
command = Tug::Command.command_for_string(command)
|
24
|
-
command.execute(
|
34
|
+
command.execute(config_file)
|
25
35
|
end
|
26
36
|
end
|
27
37
|
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module Tug
|
2
|
+
class Keychain
|
3
|
+
|
4
|
+
attr_reader :apple_certificate
|
5
|
+
attr_reader :distribution_certificate
|
6
|
+
attr_reader :distribution_profile
|
7
|
+
attr_reader :private_key
|
8
|
+
attr_accessor :private_key_password
|
9
|
+
attr_accessor :name
|
10
|
+
|
11
|
+
class << self
|
12
|
+
def keychain(keychain_yaml)
|
13
|
+
Tug::Keychain.new(keychain_yaml)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(keychain_yaml)
|
18
|
+
@apple_certificate = keychain_yaml["apple_certificate"]
|
19
|
+
@distribution_certificate = keychain_yaml["distribution_certificate"]
|
20
|
+
@distribution_profile = keychain_yaml["distribution_profile"]
|
21
|
+
@private_key = keychain_yaml["private_key"]
|
22
|
+
@private_key_password = ENV['TUG_P12_PASSWORD']
|
23
|
+
@name = "tug"
|
24
|
+
end
|
25
|
+
|
26
|
+
def create_keychain
|
27
|
+
system("security create-keychain -p tug #{name}.keychain")
|
28
|
+
end
|
29
|
+
|
30
|
+
def select_keychain(keychain_name=name)
|
31
|
+
system("security default-keychain -s #{keychain_name}.keychain")
|
32
|
+
end
|
33
|
+
|
34
|
+
def delete_keychain
|
35
|
+
system("security delete-keychain #{name}.keychain")
|
36
|
+
end
|
37
|
+
|
38
|
+
def import_apple_certificate
|
39
|
+
system(import_command(apple_certificate))
|
40
|
+
end
|
41
|
+
|
42
|
+
def import_distribution_certificate
|
43
|
+
system(import_command(distribution_certificate))
|
44
|
+
end
|
45
|
+
|
46
|
+
def import_private_key
|
47
|
+
system(import_command(private_key) + " -P '#{private_key_password}'")
|
48
|
+
end
|
49
|
+
|
50
|
+
def import_profile
|
51
|
+
FileUtils.mkdir_p "#{File.expand_path('~')}/Library/MobileDevice/Provisioning\ Profiles/"
|
52
|
+
system("cp #{distribution_profile} #{profile_export_path}")
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def profile_export_path
|
58
|
+
"#{File.expand_path('~')}/Library/MobileDevice/Provisioning\\ Profiles/"
|
59
|
+
end
|
60
|
+
|
61
|
+
def import_command(file)
|
62
|
+
"security import #{file} -k #{keychain_path} -T /usr/bin/codesign"
|
63
|
+
end
|
64
|
+
|
65
|
+
def keychain_path
|
66
|
+
"#{File.expand_path('~')}/Library/Keychains/#{name}.keychain"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/lib/tug/version.rb
CHANGED
data/lib/tug.rb
CHANGED
@@ -7,6 +7,7 @@ require "tug/version"
|
|
7
7
|
require "tug/command/command"
|
8
8
|
require "tug/command/build_command"
|
9
9
|
require "tug/command/ipa_command"
|
10
|
+
require "tug/command/provision_command"
|
10
11
|
|
11
12
|
require "tug/interface/interface"
|
12
13
|
|
@@ -18,4 +19,6 @@ require "tug/project/project"
|
|
18
19
|
require "tug/tool/xcode_build"
|
19
20
|
require "tug/tool/xctool"
|
20
21
|
require "tug/tool/xctool_build"
|
21
|
-
require "tug/tool/xctool_archive"
|
22
|
+
require "tug/tool/xctool_archive"
|
23
|
+
|
24
|
+
require "tug/keychain/keychain"
|
data/spec/build_command_spec.rb
CHANGED
@@ -8,11 +8,14 @@ describe Tug::BuildCommand do
|
|
8
8
|
@command = Tug::BuildCommand.new
|
9
9
|
allow(@command).to receive(:system)
|
10
10
|
@project = Tug::Project.new(project_yaml)
|
11
|
+
|
12
|
+
@config = double(Tug::ConfigFile)
|
13
|
+
allow(@config).to receive(:project).and_return(@project)
|
11
14
|
end
|
12
15
|
|
13
16
|
it "should build using xctool" do
|
14
17
|
expect_any_instance_of(Tug::XCTool).to receive(:system).with("xctool -workspace workspace -scheme scheme -configuration Debug -sdk iphonesimulator")
|
15
|
-
@command.execute(@
|
18
|
+
@command.execute(@config)
|
16
19
|
end
|
17
20
|
end
|
18
21
|
end
|
data/spec/command_spec.rb
CHANGED
@@ -21,5 +21,10 @@ describe Tug::Command do
|
|
21
21
|
command = Tug::Command.command_for_string("hello")
|
22
22
|
expect(command).to be_kind_of(Tug::Command)
|
23
23
|
end
|
24
|
+
|
25
|
+
it "should return a provision command" do
|
26
|
+
command = Tug::Command.command_for_string("provision")
|
27
|
+
expect(command).to be_kind_of(Tug::ProvisionCommand)
|
28
|
+
end
|
24
29
|
end
|
25
30
|
end
|
data/spec/config_file_spec.rb
CHANGED
@@ -2,8 +2,9 @@ require "spec_helper"
|
|
2
2
|
|
3
3
|
describe Tug::ConfigFile do
|
4
4
|
|
5
|
-
before(:each) do
|
6
|
-
|
5
|
+
before(:each) do
|
6
|
+
file = File.expand_path(File.join(File.dirname(__FILE__), "../lib/tug/config/.tug.yml"))
|
7
|
+
config = YAML.load_file(file)
|
7
8
|
allow(YAML).to receive(:load_file).and_return(config)
|
8
9
|
@config_file = Tug::ConfigFile.new("path")
|
9
10
|
end
|
@@ -27,5 +28,9 @@ describe Tug::ConfigFile do
|
|
27
28
|
it "should load a project" do
|
28
29
|
expect(@config_file.project).to be
|
29
30
|
end
|
31
|
+
|
32
|
+
it "should load a keychain" do
|
33
|
+
expect(@config_file.keychain).to be
|
34
|
+
end
|
30
35
|
end
|
31
36
|
end
|
data/spec/ipa_command_spec.rb
CHANGED
@@ -12,22 +12,25 @@ describe Tug::IpaCommand do
|
|
12
12
|
yaml = project_yaml
|
13
13
|
yaml["ipa_config"] = "InHouse"
|
14
14
|
@project = Tug::Project.new(yaml)
|
15
|
+
|
16
|
+
@config = double(Tug::ConfigFile)
|
17
|
+
allow(@config).to receive(:project).and_return(@project)
|
15
18
|
end
|
16
19
|
|
17
20
|
it "should generate an archive using xctool" do
|
18
21
|
expect_any_instance_of(Tug::XCTool).to receive(:system).with("xctool -workspace workspace -scheme scheme -configuration InHouse archive -archivePath /tmp/scheme.xcarchive")
|
19
|
-
@command.execute(@
|
22
|
+
@command.execute(@config)
|
20
23
|
end
|
21
24
|
|
22
25
|
it "should export an ipa using xcode build" do
|
23
26
|
expect_any_instance_of(Tug::XcodeBuild).to receive(:system).with("xcodebuild -archivePath /tmp/scheme.xcarchive -exportPath /tmp/scheme.ipa -exportFormat ipa -exportArchive -exportWithOriginalSigningIdentity")
|
24
|
-
@command.execute(@
|
27
|
+
@command.execute(@config)
|
25
28
|
end
|
26
29
|
|
27
30
|
it "should move the ipa file into the export path location" do
|
28
31
|
@project.ipa_export_path = "/hello/world"
|
29
32
|
expect(FileUtils).to receive(:mv).with(anything, /hello\/world/)
|
30
|
-
@command.execute(@
|
33
|
+
@command.execute(@config)
|
31
34
|
end
|
32
35
|
end
|
33
36
|
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Tug::Keychain do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@yaml = {"apple_certificate" => "apple",
|
7
|
+
"distribution_certificate" => "dist",
|
8
|
+
"distribution_profile" => "path/to/profile",
|
9
|
+
"private_key" => "private"}
|
10
|
+
|
11
|
+
@keychain = Tug::Keychain.keychain(@yaml)
|
12
|
+
allow(@keychain).to receive(:system)
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "when returning keychains" do
|
16
|
+
it "should return a keychian" do
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should return a protected keychain if password is missing" do
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "when created" do
|
24
|
+
it "should have a apple certificate" do
|
25
|
+
expect(@keychain.apple_certificate).to be
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should have a distribution certificate" do
|
29
|
+
expect(@keychain.distribution_certificate).to be
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should have a distribution profile" do
|
33
|
+
expect(@keychain.distribution_profile).to be
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should have a private key" do
|
37
|
+
expect(@keychain.private_key).to be
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should have a default keychain name" do
|
41
|
+
expect(@keychain.name).to match("tug")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "when importing certificates" do
|
46
|
+
|
47
|
+
it "should select a keychain" do
|
48
|
+
expect(@keychain).to receive(:system).with("security default-keychain -s test.keychain")
|
49
|
+
@keychain.select_keychain("test")
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should create a keychain" do
|
53
|
+
expect(@keychain).to receive(:system).with("security create-keychain -p tug tug.keychain")
|
54
|
+
@keychain.create_keychain
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should delete a keychain" do
|
58
|
+
expect(@keychain).to receive(:system).with("security delete-keychain tug.keychain")
|
59
|
+
@keychain.delete_keychain
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should import the apple certificate" do
|
63
|
+
expect(@keychain).to receive(:system).with("security import apple -k #{File.expand_path('~')}/Library/Keychains/tug.keychain -T /usr/bin/codesign")
|
64
|
+
@keychain.import_apple_certificate
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should import the dist certificate" do
|
68
|
+
expect(@keychain).to receive(:system).with("security import dist -k #{File.expand_path('~')}/Library/Keychains/tug.keychain -T /usr/bin/codesign")
|
69
|
+
@keychain.import_distribution_certificate
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should import the private key" do
|
73
|
+
ENV['TUG_P12_PASSWORD'] = nil
|
74
|
+
@keychain = Tug::Keychain.keychain(@yaml)
|
75
|
+
|
76
|
+
expect(@keychain).to receive(:system).with("security import private -k #{File.expand_path('~')}/Library/Keychains/tug.keychain -T /usr/bin/codesign -P ''")
|
77
|
+
@keychain.import_private_key
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should import the private key with a password via env var" do
|
81
|
+
ENV['TUG_P12_PASSWORD'] = "password"
|
82
|
+
@keychain = Tug::Keychain.keychain(@yaml)
|
83
|
+
|
84
|
+
expect(@keychain).to receive(:system).with("security import private -k #{File.expand_path('~')}/Library/Keychains/tug.keychain -T /usr/bin/codesign -P 'password'")
|
85
|
+
@keychain.import_private_key
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should import the private key with a password via setter" do
|
89
|
+
@keychain = Tug::Keychain.keychain(@yaml)
|
90
|
+
@keychain.private_key_password = "hello"
|
91
|
+
|
92
|
+
expect(@keychain).to receive(:system).with("security import private -k #{File.expand_path('~')}/Library/Keychains/tug.keychain -T /usr/bin/codesign -P 'hello'")
|
93
|
+
@keychain.import_private_key
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe "when importing profiles" do
|
98
|
+
|
99
|
+
before(:each) do
|
100
|
+
allow(FileUtils).to receive(:mkdir_p)
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should create a profile folder" do
|
104
|
+
expect(FileUtils).to receive(:mkdir_p).with("#{File.expand_path('~')}/Library/MobileDevice/Provisioning\ Profiles/")
|
105
|
+
@keychain.import_profile
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should import the dist profile" do
|
109
|
+
expect(@keychain).to receive(:system).with("cp path/to/profile #{File.expand_path('~')}/Library/MobileDevice/Provisioning\\ Profiles/")
|
110
|
+
@keychain.import_profile
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
data/spec/output.txt
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tug
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex Fish
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-07-
|
11
|
+
date: 2014-07-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -102,10 +102,12 @@ files:
|
|
102
102
|
- lib/tug/command/build_command.rb
|
103
103
|
- lib/tug/command/command.rb
|
104
104
|
- lib/tug/command/ipa_command.rb
|
105
|
+
- lib/tug/command/provision_command.rb
|
105
106
|
- lib/tug/config/.tug.yml
|
106
107
|
- lib/tug/config/config_file.rb
|
107
108
|
- lib/tug/config/missing_config_file.rb
|
108
109
|
- lib/tug/interface/interface.rb
|
110
|
+
- lib/tug/keychain/keychain.rb
|
109
111
|
- lib/tug/project/project.rb
|
110
112
|
- lib/tug/tool/xcode_build.rb
|
111
113
|
- lib/tug/tool/xctool.rb
|
@@ -116,6 +118,7 @@ files:
|
|
116
118
|
- spec/command_spec.rb
|
117
119
|
- spec/config_file_spec.rb
|
118
120
|
- spec/ipa_command_spec.rb
|
121
|
+
- spec/keychain_spec.rb
|
119
122
|
- spec/output.txt
|
120
123
|
- spec/project_spec.rb
|
121
124
|
- spec/spec_helper.rb
|
@@ -150,6 +153,7 @@ test_files:
|
|
150
153
|
- spec/command_spec.rb
|
151
154
|
- spec/config_file_spec.rb
|
152
155
|
- spec/ipa_command_spec.rb
|
156
|
+
- spec/keychain_spec.rb
|
153
157
|
- spec/output.txt
|
154
158
|
- spec/project_spec.rb
|
155
159
|
- spec/spec_helper.rb
|