Class: Highway::Steps::Library::CodeSignStep

Inherits:
Step
  • Object
show all
Defined in:
lib/highway/steps/library/code_sign.rb

Class Method Summary collapse

Methods inherited from Step

root_parameter

Class Method Details

.nameObject

[View source]

15
16
17
# File 'lib/highway/steps/library/code_sign.rb', line 15

def self.name
  "code_sign"
end

.parametersObject

[View source]

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/highway/steps/library/code_sign.rb', line 19

def self.parameters
  [
    Parameters::Single.new(
      name: "path",
      required: true,
      type: Types::String.new()
    ),
    Parameters::Single.new(
      name: "passphrase",
      required: true,
      type: Types::String.new()
    ),
    Parameters::Single.new(
      name: "keychain_name",
      required: false,
      type: Types::String.new()
    ),
    Parameters::Single.new(
      name: "keychain_password",
      required: false,
      type: Types::String.new()
    )
  ]
end

.run(parameters:, context:, report:) ⇒ Object

[View source]

44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/highway/steps/library/code_sign.rb', line 44

def self.run(parameters:, context:, report:)
    path = parameters["path"]
    passphrase = parameters["passphrase"]
    keychain_name = parameters["keychain_name"]
    keychain_password = parameters["keychain_password"]

    # First of all, check if file exist.

    unless File.exist?(path)
        context.interface.fatal!("File '#{path}' does not exist.")
    end

    # Now prepare output directory and file.

    output_temp_dir = Dir.mktmpdir()
    output_archive_name = "decrypted.zip"
    output_file_path = File.join(output_temp_dir, output_archive_name)
    output_file = File.open(output_file_path, "w+")

    # Decrypt given archive.

    crypto = GPGME::Crypto.new
    begin
        crypto.decrypt(File.open(path), { :password => passphrase, :output => output_file, :pinentry_mode => GPGME::PINENTRY_MODE_LOOPBACK })
    rescue
        context.interface.fatal!("Cannot decrypt with given passphrase.")
    end

    # Unzip decrypted archive.

    zipped_files = Array[]
    Zip::File.open(output_file_path) do |zip_file|
      zip_file.each do |file|
          file_path = File.join(output_temp_dir, file.name)
          unless file_path.match?(/\.DS_Store|__MACOSX|(^|\/)\._/)
            zip_file.extract(file, file_path) unless File.exist?(file_path)
            zipped_files.push(file_path) unless File.directory?(file_path)
          end
      end
    end

    # Filter paths to certificates and profiles.
    
    provisioning_profile_paths = zipped_files.grep(/.*\.mobileprovision/)
    certificates_paths = zipped_files.grep(/.*\.p12/)

    # Prepare new keychain.

    keychain_name = "highway.keychain-db" if keychain_name.nil?
    keychain_password = passphrase if keychain_password.nil?
    context.run_action("create_keychain", options: {
      name: keychain_name,
      password: keychain_password,
      default_keychain: true,
      unlock: true,
      timeout: 72000,
      lock_when_sleeps: true,
      lock_after_timeout: true,
      add_to_search_list: true
    })

    # Install provisioning profiles.

    provisioning_profile_paths.each do |path|
        context.run_action("install_provisioning_profile", options: {
            path: path
        })
    end

    # Install certificates.

    certificates_paths.each do |path|
        context.run_action("import_certificate", options: {
            certificate_path: path,
            certificate_password: passphrase,
            keychain_name: keychain_name,
            keychain_password: keychain_password
        })
    end
end