Class: Match::Storage::GitLabSecureFiles

Inherits:
Interface
  • Object
show all
Defined in:
match/lib/match/storage/gitlab_secure_files.rb

Overview

Store the code signing identities in GitLab Secure Files

Constant Summary

Constants inherited from Interface

Interface::MATCH_VERSION_FILE_NAME

Instance Attribute Summary collapse

Attributes inherited from Interface

#working_directory

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Interface

#clear_changes, #configure, #save_changes!

Constructor Details

#initialize(api_v4_url: nil, project_id: nil, job_token: nil, private_token: nil, readonly: nil, username: nil, team_id: nil, team_name: nil, api_key_path: nil, api_key: nil) ⇒ GitLabSecureFiles

Returns a new instance of GitLabSecureFiles.



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
# File 'match/lib/match/storage/gitlab_secure_files.rb', line 53

def initialize(api_v4_url: nil,
               project_id: nil,
               job_token: nil,
               private_token: nil,
               readonly: nil,
               username: nil,
               team_id: nil,
               team_name: nil,
               api_key_path: nil,
               api_key: nil)

  @readonly = readonly
  @username = username
  @team_id = team_id
  @team_name = team_name
  @api_key_path = api_key_path
  @api_key = api_key

  @job_token = job_token
  @private_token = private_token
  @api_v4_url = api_v4_url
  @project_id = project_id
  @gitlab_client = GitLab::Client.new(job_token: job_token, private_token: private_token, project_id: project_id, api_v4_url: api_v4_url)

  UI.message("Initializing match for GitLab project #{@project_id}")
end

Instance Attribute Details

#api_keyObject (readonly)

Returns the value of attribute api_key.



24
25
26
# File 'match/lib/match/storage/gitlab_secure_files.rb', line 24

def api_key
  @api_key
end

#api_key_pathObject (readonly)

Returns the value of attribute api_key_path.



23
24
25
# File 'match/lib/match/storage/gitlab_secure_files.rb', line 23

def api_key_path
  @api_key_path
end

#gitlab_clientObject (readonly)

Returns the value of attribute gitlab_client.



17
18
19
# File 'match/lib/match/storage/gitlab_secure_files.rb', line 17

def gitlab_client
  @gitlab_client
end

#project_idObject (readonly)

Returns the value of attribute project_id.



18
19
20
# File 'match/lib/match/storage/gitlab_secure_files.rb', line 18

def project_id
  @project_id
end

#readonlyObject (readonly)

Returns the value of attribute readonly.



19
20
21
# File 'match/lib/match/storage/gitlab_secure_files.rb', line 19

def readonly
  @readonly
end

#team_idObject (readonly)

Returns the value of attribute team_id.



21
22
23
# File 'match/lib/match/storage/gitlab_secure_files.rb', line 21

def team_id
  @team_id
end

#team_nameObject (readonly)

Returns the value of attribute team_name.



22
23
24
# File 'match/lib/match/storage/gitlab_secure_files.rb', line 22

def team_name
  @team_name
end

#usernameObject (readonly)

Returns the value of attribute username.



20
21
22
# File 'match/lib/match/storage/gitlab_secure_files.rb', line 20

def username
  @username
end

Class Method Details

.configure(params) ⇒ Object



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'match/lib/match/storage/gitlab_secure_files.rb', line 26

def self.configure(params)
  api_v4_url     = params[:api_v4_url] || ENV['CI_API_V4_URL'] || 'https://gitlab.com/api/v4'
  project_id     = params[:gitlab_project] || ENV['GITLAB_PROJECT'] || ENV['CI_PROJECT_ID']
  job_token      = params[:job_token] || ENV['CI_JOB_TOKEN']
  private_token  = params[:private_token] || ENV['PRIVATE_TOKEN']

  if params[:git_url].to_s.length > 0
    UI.important("Looks like you still define a `git_url` somewhere, even though")
    UI.important("you use GitLab Secure Files. You can remove the `git_url`")
    UI.important("from your Matchfile and Fastfile")
    UI.message("The above is just a warning, fastlane will continue as usual now...")
  end

  return self.new(
    api_v4_url: api_v4_url,
    project_id: project_id,
    job_token: job_token,
    private_token: private_token,
    readonly: params[:readonly],
    username: params[:username],
    team_id: params[:team_id],
    team_name: params[:team_name],
    api_key_path: params[:api_key_path],
    api_key: params[:api_key]
  )
end

Instance Method Details

#api_tokenObject



123
124
125
126
127
# File 'match/lib/match/storage/gitlab_secure_files.rb', line 123

def api_token
  api_token = Spaceship::ConnectAPI::Token.from(hash: self.api_key, filepath: self.api_key_path)
  api_token ||= Spaceship::ConnectAPI.token
  return api_token
end

#currently_used_team_idObject



110
111
112
113
114
115
116
117
118
119
120
121
# File 'match/lib/match/storage/gitlab_secure_files.rb', line 110

def currently_used_team_id
  if self.readonly
    # In readonly mode, we still want to see if the user provided a team_id
    # see `prefixed_working_directory` comments for more details
    return self.team_id
  else
    UI.user_error!("The `team_id` option is required. fastlane cannot automatically determine portal team id via the App Store Connect API (yet)") if self.team_id.to_s.empty?

    spaceship = SpaceshipEnsure.new(self.username, self.team_id, self.team_name, api_token)
    return spaceship.team_id
  end
end

#delete_files(files_to_delete: [], custom_message: nil) ⇒ Object



154
155
156
157
158
159
160
161
162
# File 'match/lib/match/storage/gitlab_secure_files.rb', line 154

def delete_files(files_to_delete: [], custom_message: nil)
  files_to_delete.each do |current_file|
    target_path = current_file.gsub(self.working_directory + "/", "")

    secure_file = @gitlab_client.find_file_by_name(target_path)
    UI.message("Deleting '#{target_path}' from GitLab Secure Files...")
    secure_file.delete
  end
end

#downloadObject



96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'match/lib/match/storage/gitlab_secure_files.rb', line 96

def download
  # Check if we already have a functional working_directory
  return if @working_directory

  # No existing working directory, creating a new one now
  self.working_directory = Dir.mktmpdir

  @gitlab_client.files.each do |secure_file|
    secure_file.download(self.working_directory)
  end

  UI.verbose("Successfully downloaded all Secure Files from GitLab to #{self.working_directory}")
end

#generate_matchfile_content(template: nil) ⇒ Object

Implement this for the ‘fastlane match init` command This method must return the content of the Matchfile that should be generated



175
176
177
178
179
# File 'match/lib/match/storage/gitlab_secure_files.rb', line 175

def generate_matchfile_content(template: nil)
  project = UI.input("What is your GitLab Project (i.e. gitlab-org/gitlab): ")

  return "gitlab_project(\"#{project}\")"
end

#human_readable_descriptionObject

Returns a short string describing + identifing the current storage backend. This will be printed when nuking a storage



131
132
133
# File 'match/lib/match/storage/gitlab_secure_files.rb', line 131

def human_readable_description
  "GitLab Secure Files Storage [#{self.project_id}]"
end

#list_files(file_name: "", file_ext: "") ⇒ Object



168
169
170
# File 'match/lib/match/storage/gitlab_secure_files.rb', line 168

def list_files(file_name: "", file_ext: "")
  Dir[File.join(working_directory, self.team_id, "**", file_name, "*.#{file_ext}")]
end

#prefixed_working_directoryObject

To make debugging easier, we have a custom exception here



81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'match/lib/match/storage/gitlab_secure_files.rb', line 81

def prefixed_working_directory
  # We fall back to "*", which means certificates and profiles
  # from all teams that use this bucket would be installed. This is not ideal, but
  # unless the user provides a `team_id`, we can't know which one to use
  # This only happens if `readonly` is activated, and no `team_id` was provided
  @_folder_prefix ||= currently_used_team_id
  if @_folder_prefix.nil?
    # We use a `@_folder_prefix` variable, to keep state between multiple calls of this
    # method, as the value won't change. This way the warning is only printed once
    UI.important("Looks like you run `match` in `readonly` mode, and didn't provide a `team_id`. This will still work, however it is recommended to provide a `team_id` in your Appfile or Matchfile")
    @_folder_prefix = "*"
  end
  return File.join(working_directory, @_folder_prefix)
end

#skip_docsObject



164
165
166
# File 'match/lib/match/storage/gitlab_secure_files.rb', line 164

def skip_docs
  true
end

#upload_files(files_to_upload: [], custom_message: nil) ⇒ Object



135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'match/lib/match/storage/gitlab_secure_files.rb', line 135

def upload_files(files_to_upload: [], custom_message: nil)
  # `files_to_upload` is an array of files that need to be uploaded to GitLab Secure Files
  # Those doesn't mean they're new, it might just be they're changed
  # Either way, we'll upload them using the same technique

  files_to_upload.each do |current_file|
    # Go from
    #   "/var/folders/px/bz2kts9n69g8crgv4jpjh6b40000gn/T/d20181026-96528-1av4gge/profiles/development/Development_me.mobileprovision"
    # to
    #   "profiles/development/Development_me.mobileprovision"
    #

    # We also remove the trailing `/`
    target_file = current_file.gsub(self.working_directory + "/", "")
    UI.verbose("Uploading '#{target_file}' to GitLab Secure Files...")
    @gitlab_client.upload_file(current_file, target_file)
  end
end