fastlane-plugin-github_action 1.0.0
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 +7 -0
- data/LICENSE +21 -0
- data/README.md +144 -0
- data/lib/assets/workflow_template.erb +33 -0
- data/lib/fastlane/plugin/github_action.rb +16 -0
- data/lib/fastlane/plugin/github_action/actions/github_action_action.rb +345 -0
- data/lib/fastlane/plugin/github_action/helper/github_actions_helper.rb +42 -0
- data/lib/fastlane/plugin/github_action/version.rb +5 -0
- metadata +217 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 44c5cdfcae088a572473300d61913b344f1686ad5aa55d7aba835a1c7aa518e4
|
4
|
+
data.tar.gz: 04e3b9a4b7b7319c8be27844638d4558015a55df9a9e929ac67da3eba2fe2fd5
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2df6f588a5aaf0c3d68146827696c40f3be2741a8454d5a670da520cb22c48b938503287680ee464dfe590004e2489999cd22c7496875d95e3b25b2df508b06f
|
7
|
+
data.tar.gz: b349172726654a17741d338df9eab2e05eb70337de00e69cfa8aa826273c3f6b515e8e3bfa88c449bf4c43f8504f0aeebf79f3467979557838e9ea2c2f9a6594
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2020 Josh Holtz <josh@rokkincat.com>
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
# GitHub Action plugin for _fastlane_
|
2
|
+
|
3
|
+
[](https://rubygems.org/gems/fastlane-plugin-github_action)
|
4
|
+
[](https://badge.fury.io/rb/fastlane-plugin-github_action)
|
5
|
+
|
6
|
+
## About github_action
|
7
|
+
|
8
|
+
[GitHub Actions](https://github.com/features/actions) makes it easy to build, test, and deploy your code right from GitHub. However, etting up [_fastlane_](https://github.com/fastlane/fastlane) to work with [match](https://docs.fastlane.tools/actions/match/#match) on GitHub Actions can take bit of juggling and manual work :pensive:
|
9
|
+
|
10
|
+
But `fastlane-plugin-github_action` to the rescue :muscle:
|
11
|
+
|
12
|
+
This plugin will:
|
13
|
+
|
14
|
+
### 1. Prompt you if `setup_ci` is not found in your `Fastfile`
|
15
|
+
Running _fastlane_ on a CI requires the environment to be setup properly. Calling the [setup_ci](http://docs.fastlane.tools/actions/setup_ci/#setup_ci) action does that by configuring a new keychain that will be used for code signing with _match_
|
16
|
+
|
17
|
+
### 2. Create a Deploy Key on your _match_ repository to be used from your GitHub Action
|
18
|
+
A [Deploy Key](https://developer.github.com/v3/guides/managing-deploy-keys/) is needed for GitHub Actions to access your _match_ repository. This action creates a new SSH key and uses the public key for the Deploy Key on your _match_ repository.
|
19
|
+
|
20
|
+
This will only get executed if the `match_org` and `match_repo` options are specified.
|
21
|
+
|
22
|
+
### 3. Set the Deploy Key private key in secrets (along with secrets in your [dotenv](https://github.com/bkeepers/dotenv) file(s)
|
23
|
+
The private key created for the Deploy Key is store encrypted in your [repository secrets](https://help.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets). The private key is stored under the name `MATCH_DEPLOY_KEY`.
|
24
|
+
|
25
|
+
Encrypted secrets will also get set for environment variables from [dotenv](https://github.com/bkeepers/dotenv) files specified by the `dotenv_paths` option.
|
26
|
+
|
27
|
+
### 4. Generate a Workflow YAML file to use
|
28
|
+
A Workflow YAML file is created at `.github/workflows/fastlane.yml`. This will enable your repository to start running GitHub Actions right away - once committed and pushed :wink:. The Workflow YAML template will add the Deploy Key private key into the GitHub Action by loading it from the `MATCH_DEPLOY_KEY` secret and executing `ssh-add`. All of your other encrypted secrets will also be loaded into environment variables for you as well.
|
29
|
+
|
30
|
+
An example can be [seen here](https://github.com/joshdholtz/test-repo-for-fastlane-plugin-github_action/blob/add-github-action/.github/workflows/fastlane.yml).
|
31
|
+
|
32
|
+
## Getting Started
|
33
|
+
|
34
|
+
This project is a [_fastlane_](https://github.com/fastlane/fastlane) plugin. To get started with `fastlane-plugin-github_action`, add it to your project by running:
|
35
|
+
|
36
|
+
```bash
|
37
|
+
fastlane add_plugin github_action
|
38
|
+
```
|
39
|
+
|
40
|
+
### Requirements
|
41
|
+
|
42
|
+
`fastlane-plugin-github_action` depends on [rbnacl](https://github.com/RubyCrypto/rbnacl) which uses [libsodium](https://github.com/jedisct1/libsodium)
|
43
|
+
|
44
|
+
For macOS, libsodium can be installed with:
|
45
|
+
|
46
|
+
```sh
|
47
|
+
brew install libsodium
|
48
|
+
```
|
49
|
+
|
50
|
+
See https://github.com/RubyCrypto/rbnacl/wiki/Installing-libsodium for more installation instructions.
|
51
|
+
|
52
|
+
## Usage
|
53
|
+
|
54
|
+
`fastlane-plugin-github_action` can be execute either direction on the command line with `bundle exec fastlane run github_action` or by adding `github_action` to your `Fastfile`.
|
55
|
+
|
56
|
+
### CLI
|
57
|
+
|
58
|
+
```sh
|
59
|
+
bundle exec fastlane run github_action \
|
60
|
+
api_token:"your-github-personal-access-token-with-all-repo-permissions" \
|
61
|
+
org:"your-org" \
|
62
|
+
repo:"your-repo"
|
63
|
+
```
|
64
|
+
|
65
|
+
or
|
66
|
+
|
67
|
+
```sh
|
68
|
+
bundle exec fastlane run github_action \
|
69
|
+
api_token:"your-github-personal-access-token-with-all-repo-permissions" \
|
70
|
+
org:"your-org" \
|
71
|
+
repo:"your-repo" \
|
72
|
+
match_org:"your-match-repo-org" \
|
73
|
+
match_repo:"your-match-repo" \
|
74
|
+
dotenv_paths:"fastlane/.env.secret,fastlane/.env.secret2"
|
75
|
+
```
|
76
|
+
|
77
|
+
### In `Fastfile`
|
78
|
+
|
79
|
+
```ruby
|
80
|
+
lane :init_ci do
|
81
|
+
github_action(
|
82
|
+
api_token: "your-github-personal-access-token-with-all-repo-permissions",
|
83
|
+
org: "your-org",
|
84
|
+
repo: "your-repo",
|
85
|
+
match_org: "your-match-repo-org", # optional
|
86
|
+
match_repo: "your-match-repo", # optional
|
87
|
+
dotenv_paths: ["fastlane/.env.secret", "fastlane/.env.secret2"] # optional
|
88
|
+
)
|
89
|
+
end
|
90
|
+
```
|
91
|
+
|
92
|
+
### Help
|
93
|
+
|
94
|
+
Once installed, information and help for an action can be printed out with this command:
|
95
|
+
|
96
|
+
```bash
|
97
|
+
fastlane action github_action # or any action included with this plugin
|
98
|
+
```
|
99
|
+
|
100
|
+
### Options
|
101
|
+
|
102
|
+
| Key | Environment Variable | Description |
|
103
|
+
|---|---|---|
|
104
|
+
| `server_url` | `FL_GITHUB_API_SERVER_URL` | The server url. e.g. 'https://your.internal.github.host/api/v3' (Default: 'https://api.github.com') |
|
105
|
+
| `api_token` | `FL_GITHUB_API_TOKEN` | Personal API Token for GitHub - generate one at https://github.com/settings/tokens |
|
106
|
+
| `org` | `FL_GITHUB_ACTIONS_ORG` | Name of organization of the repository for GitHub Actions |
|
107
|
+
| `repo` | `FL_GITHUB_ACTIONS_REPO` | Name of repository for GitHub Actions |
|
108
|
+
| `match_org` | `FL_GITHUB_ACTIONS_MATCH_ORG` | Name of organization of the match repository |
|
109
|
+
| `match_repo` | `FL_GITHUB_ACTIONS_MATCH_REPO` | Name of match repository |
|
110
|
+
| `dotenv_paths` | `FL_GITHUB_ACTINOS_DOTENV_PATHS` | Paths of .env files to parse |
|
111
|
+
|
112
|
+
|
113
|
+
## Example
|
114
|
+
|
115
|
+
Check out the [example `Fastfile`](fastlane/Fastfile) to see how to use this plugin. Try it by cloning the repo, running `fastlane install_plugins` and `bundle exec fastlane test`.
|
116
|
+
|
117
|
+
## Run tests for this plugin
|
118
|
+
|
119
|
+
To run both the tests, and code style validation, run
|
120
|
+
|
121
|
+
```
|
122
|
+
rake
|
123
|
+
```
|
124
|
+
|
125
|
+
To automatically fix many of the styling issues, use
|
126
|
+
```
|
127
|
+
rubocop -a
|
128
|
+
```
|
129
|
+
|
130
|
+
## Issues and Feedback
|
131
|
+
|
132
|
+
For any other issues and feedback about this plugin, please submit it to this repository.
|
133
|
+
|
134
|
+
## Troubleshooting
|
135
|
+
|
136
|
+
If you have trouble using plugins, check out the [Plugins Troubleshooting](https://docs.fastlane.tools/plugins/plugins-troubleshooting/) guide.
|
137
|
+
|
138
|
+
## Using _fastlane_ Plugins
|
139
|
+
|
140
|
+
For more information about how the `fastlane` plugin system works, check out the [Plugins documentation](https://docs.fastlane.tools/plugins/create-plugin/).
|
141
|
+
|
142
|
+
## About _fastlane_
|
143
|
+
|
144
|
+
_fastlane_ is the easiest way to automate beta deployments and releases for your iOS and Android apps. To learn more, check out [fastlane.tools](https://fastlane.tools).
|
@@ -0,0 +1,33 @@
|
|
1
|
+
name: Execute fastlane
|
2
|
+
|
3
|
+
on:
|
4
|
+
pull_request:
|
5
|
+
branches:
|
6
|
+
- master
|
7
|
+
|
8
|
+
jobs:
|
9
|
+
build_dev:
|
10
|
+
name: Execute fastlane
|
11
|
+
runs-on: macos-latest
|
12
|
+
steps:
|
13
|
+
- uses: actions/checkout@master
|
14
|
+
- name: Install Ruby Dependencies
|
15
|
+
run: bundle install
|
16
|
+
<% if use_match %>
|
17
|
+
- name: Match Repo Clone Test (please delete this)
|
18
|
+
env:
|
19
|
+
<%= clone_test_secrets %>
|
20
|
+
run: |
|
21
|
+
<%= clone_test_commands %>
|
22
|
+
<% end %>
|
23
|
+
<% if secrets.size == 0 %>
|
24
|
+
- name: fastlane
|
25
|
+
run: |
|
26
|
+
<%= commands %>
|
27
|
+
<% else %>
|
28
|
+
- name: fastlane
|
29
|
+
env:
|
30
|
+
<%= secrets %>
|
31
|
+
run: |
|
32
|
+
<%= commands %>
|
33
|
+
<% end %>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'fastlane/plugin/github_action/version'
|
2
|
+
|
3
|
+
module Fastlane
|
4
|
+
module GithubAction
|
5
|
+
# Return all .rb files inside the "actions" and "helper" directory
|
6
|
+
def self.all_classes
|
7
|
+
Dir[File.expand_path('**/{actions,helper}/*.rb', File.dirname(__FILE__))]
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# By default we want to import all available actions and helpers
|
13
|
+
# A plugin can contain any number of actions and plugins
|
14
|
+
Fastlane::GithubAction.all_classes.each do |current|
|
15
|
+
require current
|
16
|
+
end
|
@@ -0,0 +1,345 @@
|
|
1
|
+
require 'fastlane/action'
|
2
|
+
require_relative '../helper/github_actions_helper'
|
3
|
+
|
4
|
+
module Fastlane
|
5
|
+
module Actions
|
6
|
+
class GithubActionAction < Action
|
7
|
+
def self.run(params)
|
8
|
+
UI.message("The github_actions plugin is working!")
|
9
|
+
|
10
|
+
self.check_for_setup_ci_in_fastfile
|
11
|
+
|
12
|
+
additional_secrets = self.generate_deploy_key(params)
|
13
|
+
secret_names = self.post_secrets(params, additional_secrets)
|
14
|
+
self.generate_workflow_template(params, secret_names)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.match_deploy_key
|
18
|
+
"MATCH_DEPLOY_KEY"
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.deploy_key_title
|
22
|
+
"Match Deploy Key (created by fastalne-plugin-github_actions)"
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.check_for_setup_ci_in_fastfile
|
26
|
+
fastfiles = Dir.glob("./*/Fastfile").map do |path|
|
27
|
+
File.absolute_path(path)
|
28
|
+
end
|
29
|
+
|
30
|
+
fastfiles.each do |path|
|
31
|
+
content = File.read(path)
|
32
|
+
|
33
|
+
if !content.include?("setup_ci")
|
34
|
+
UI.confirm("`setup_ci` is not detected for '#{path}'. Do you still want to continue on?")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.generate_workflow_template(params, secret_names)
|
41
|
+
workflows_dir = File.absolute_path(".github/workflows")
|
42
|
+
workflow_path = File.join(workflows_dir, 'fastlane.yml')
|
43
|
+
|
44
|
+
if File.exist?(workflow_path)
|
45
|
+
if UI.confirm("File already exists at #{workflow_path}. Do you want to overwrite?")
|
46
|
+
UI.message("Overwriting #{workflow_path}")
|
47
|
+
else
|
48
|
+
UI.message("Cancelled workflow template generation...")
|
49
|
+
return
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
require 'fastlane/erb_template_helper'
|
54
|
+
include ERB::Util
|
55
|
+
|
56
|
+
spaces = " " * 10
|
57
|
+
|
58
|
+
use_match = secret_names.include?(match_deploy_key)
|
59
|
+
|
60
|
+
#
|
61
|
+
# Clone test secrets and commands
|
62
|
+
#
|
63
|
+
if use_match
|
64
|
+
clone_test_secrets = [
|
65
|
+
'GIT_SSH_COMMAND: "ssh -o StrictHostKeyChecking=no"',
|
66
|
+
"#{match_deploy_key}: ${{ secrets.#{match_deploy_key} }}"
|
67
|
+
].map do |secret|
|
68
|
+
"#{spaces}#{secret}"
|
69
|
+
end.join("\n")
|
70
|
+
|
71
|
+
clone_test_commands = [
|
72
|
+
'eval "$(ssh-agent -s)"',
|
73
|
+
"ssh-add - <<< \"${#{match_deploy_key}}\"",
|
74
|
+
"git clone git@github.com:#{params[:match_org]}/#{params[:match_repo]}.git",
|
75
|
+
"ls #{params[:match_repo]}"
|
76
|
+
].map do |command|
|
77
|
+
"#{spaces}#{command}"
|
78
|
+
end.join("\n")
|
79
|
+
end
|
80
|
+
|
81
|
+
#
|
82
|
+
# Secrets and commands
|
83
|
+
#
|
84
|
+
secrets = secret_names.map do |secret_name|
|
85
|
+
"#{secret_name}: ${{ secrets.#{secret_name} }}"
|
86
|
+
end
|
87
|
+
|
88
|
+
if use_match
|
89
|
+
secrets << 'GIT_SSH_COMMAND: "ssh -o StrictHostKeyChecking=no"'
|
90
|
+
secrets << 'MATCH_READONLY: true'
|
91
|
+
end
|
92
|
+
|
93
|
+
secrets = secrets.map do |secret|
|
94
|
+
"#{spaces}#{secret}"
|
95
|
+
end.join("\n")
|
96
|
+
|
97
|
+
commands = []
|
98
|
+
if use_match
|
99
|
+
commands = [
|
100
|
+
'eval "$(ssh-agent -s)"',
|
101
|
+
"ssh-add - <<< \"${#{match_deploy_key}}\"",
|
102
|
+
]
|
103
|
+
end
|
104
|
+
|
105
|
+
commands << 'bundle exec fastlane test'
|
106
|
+
commands = commands.map do |command|
|
107
|
+
"#{spaces}#{command}"
|
108
|
+
end.join("\n")
|
109
|
+
|
110
|
+
puts "secret size: #{secrets.size}"
|
111
|
+
|
112
|
+
workflow_template = Helper::GithubActionHelper.load("workflow_template")
|
113
|
+
workflow_render = Helper::GithubActionHelper.render(workflow_template, {
|
114
|
+
use_match: use_match,
|
115
|
+
clone_test_secrets: clone_test_secrets,
|
116
|
+
clone_test_commands: clone_test_commands,
|
117
|
+
secrets: secrets,
|
118
|
+
commands: commands
|
119
|
+
})
|
120
|
+
|
121
|
+
FileUtils.mkdir_p(workflows_dir)
|
122
|
+
File.write(workflow_path, workflow_render)
|
123
|
+
end
|
124
|
+
|
125
|
+
def self.generate_deploy_key(params)
|
126
|
+
if params[:match_org].to_s == "" && params[:match_repo].to_s == ""
|
127
|
+
UI.message("Skipping Deploy Key generation...")
|
128
|
+
return {}
|
129
|
+
elsif params[:match_org].to_s == ""
|
130
|
+
UI.user_error!("`match_org` also needs to be specified")
|
131
|
+
elsif params[:match_repo].to_s == ""
|
132
|
+
UI.user_error!("`match_repo` also needs to be specified")
|
133
|
+
end
|
134
|
+
|
135
|
+
get_deploy_keys_resp = self.match_repo_get(params, "/keys")
|
136
|
+
|
137
|
+
sleep(1)
|
138
|
+
|
139
|
+
deploy_keys = get_deploy_keys_resp[:json] || []
|
140
|
+
deploy_keys.each do |deploy_key|
|
141
|
+
if deploy_key["title"] == deploy_key_title
|
142
|
+
if UI.confirm("Deploy Key for the match repo already exists... Delete it?")
|
143
|
+
self.match_repo_delete(params, "/keys/#{deploy_key["id"]}")
|
144
|
+
UI.message("Deleted existing Deploy Key")
|
145
|
+
sleep(1)
|
146
|
+
else
|
147
|
+
return {}
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
require 'sshkey'
|
153
|
+
k = SSHKey.generate()
|
154
|
+
|
155
|
+
body = {
|
156
|
+
title: deploy_key_title,
|
157
|
+
key: k.ssh_public_key,
|
158
|
+
read_only: true
|
159
|
+
}
|
160
|
+
post_deploy_key_resp = self.match_repo_post(params, "/keys", body)
|
161
|
+
UI.message("Created Deploy Key")
|
162
|
+
|
163
|
+
sleep(3)
|
164
|
+
|
165
|
+
secrets = {}
|
166
|
+
secrets[match_deploy_key] = k.private_key
|
167
|
+
return secrets
|
168
|
+
end
|
169
|
+
|
170
|
+
def self.post_secrets(params, additional_secrets)
|
171
|
+
public_key_resp = self.repo_get(params, "/actions/secrets/public-key")
|
172
|
+
key_id = public_key_resp[:json]["key_id"]
|
173
|
+
key64 = public_key_resp[:json]["key"]
|
174
|
+
|
175
|
+
secrets = self.parse_dotenvs(params)
|
176
|
+
secrets = secrets.merge(additional_secrets || {})
|
177
|
+
|
178
|
+
encrypted_secrets = {}
|
179
|
+
secrets.each do |k,v|
|
180
|
+
encrypted_value = self.encrypt_secret(key64, v)
|
181
|
+
encrypted_secrets[k] = encrypted_value
|
182
|
+
end
|
183
|
+
|
184
|
+
existing_secrets_resp = self.repo_get(params, "/actions/secrets")
|
185
|
+
existing_secret_names = existing_secrets_resp[:json]["secrets"].map do |secret|
|
186
|
+
secret["name"].to_s
|
187
|
+
end
|
188
|
+
|
189
|
+
encrypted_secrets.reject! do |k,v|
|
190
|
+
if existing_secret_names.include?(k.to_s)
|
191
|
+
!UI.confirm("Overwrite #{k}?")
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
encrypted_secrets.each do |k,v|
|
196
|
+
body = {
|
197
|
+
key_id: key_id,
|
198
|
+
encrypted_value: v
|
199
|
+
}
|
200
|
+
self.repo_put(params, "/actions/secrets/#{k}", body)
|
201
|
+
UI.message("Saving secret #{k}")
|
202
|
+
end
|
203
|
+
|
204
|
+
return secrets.keys
|
205
|
+
end
|
206
|
+
|
207
|
+
def self.parse_dotenvs(params)
|
208
|
+
dotenv_paths = (params[:dotenv_paths] || [])
|
209
|
+
|
210
|
+
if dotenv_paths.empty?
|
211
|
+
UI.message "No dotenv paths to parse..."
|
212
|
+
return {}
|
213
|
+
end
|
214
|
+
|
215
|
+
require "dotenv"
|
216
|
+
return Dotenv.parse(*dotenv_paths)
|
217
|
+
end
|
218
|
+
|
219
|
+
def self.repo_get(params, path)
|
220
|
+
return other_action.github_api(
|
221
|
+
server_url: params[:server_url],
|
222
|
+
api_token: params[:api_token],
|
223
|
+
http_method: "GET",
|
224
|
+
path: "/repos/#{params[:org]}/#{params[:repo]}#{path}",
|
225
|
+
body: {},
|
226
|
+
)
|
227
|
+
end
|
228
|
+
|
229
|
+
def self.repo_put(params, path, body)
|
230
|
+
return other_action.github_api(
|
231
|
+
server_url: params[:server_url],
|
232
|
+
api_token: params[:api_token],
|
233
|
+
http_method: "PUT",
|
234
|
+
path: "/repos/#{params[:org]}/#{params[:repo]}#{path}",
|
235
|
+
body: body,
|
236
|
+
)
|
237
|
+
end
|
238
|
+
|
239
|
+
def self.match_repo_get(params, path)
|
240
|
+
return other_action.github_api(
|
241
|
+
server_url: params[:server_url],
|
242
|
+
api_token: params[:api_token],
|
243
|
+
http_method: "GET",
|
244
|
+
path: "/repos/#{params[:match_org]}/#{params[:match_repo]}#{path}",
|
245
|
+
body: {},
|
246
|
+
)
|
247
|
+
end
|
248
|
+
|
249
|
+
def self.match_repo_post(params, path, body)
|
250
|
+
return other_action.github_api(
|
251
|
+
server_url: params[:server_url],
|
252
|
+
api_token: params[:api_token],
|
253
|
+
http_method: "POST",
|
254
|
+
path: "/repos/#{params[:match_org]}/#{params[:match_repo]}#{path}",
|
255
|
+
body: body,
|
256
|
+
)
|
257
|
+
end
|
258
|
+
|
259
|
+
def self.match_repo_delete(params, path)
|
260
|
+
return other_action.github_api(
|
261
|
+
server_url: params[:server_url],
|
262
|
+
api_token: params[:api_token],
|
263
|
+
http_method: "DELETE",
|
264
|
+
path: "/repos/#{params[:match_org]}/#{params[:match_repo]}#{path}",
|
265
|
+
body: {},
|
266
|
+
)
|
267
|
+
end
|
268
|
+
|
269
|
+
def self.encrypt_secret(key64, secret)
|
270
|
+
require "rbnacl"
|
271
|
+
require "base64"
|
272
|
+
|
273
|
+
key = Base64.decode64(key64)
|
274
|
+
public_key = RbNaCl::PublicKey.new(key)
|
275
|
+
|
276
|
+
box = RbNaCl::Boxes::Sealed.from_public_key(public_key)
|
277
|
+
encrypted_secret = box.encrypt(secret)
|
278
|
+
|
279
|
+
return Base64.strict_encode64(encrypted_secret)
|
280
|
+
end
|
281
|
+
|
282
|
+
def self.description
|
283
|
+
"Helper to setup GitHub actions for fastlane and match"
|
284
|
+
end
|
285
|
+
|
286
|
+
def self.authors
|
287
|
+
["josdholtz"]
|
288
|
+
end
|
289
|
+
|
290
|
+
def self.details
|
291
|
+
"Helper to setup GitHub actions for fastlane and match"
|
292
|
+
end
|
293
|
+
|
294
|
+
def self.available_options
|
295
|
+
[
|
296
|
+
FastlaneCore::ConfigItem.new(key: :server_url,
|
297
|
+
env_name: "FL_GITHUB_API_SERVER_URL",
|
298
|
+
description: "The server url. e.g. 'https://your.internal.github.host/api/v3' (Default: 'https://api.github.com')",
|
299
|
+
default_value: "https://api.github.com",
|
300
|
+
optional: true,
|
301
|
+
verify_block: proc do |value|
|
302
|
+
UI.user_error!("Please include the protocol in the server url, e.g. https://your.github.server/api/v3") unless value.include?("//")
|
303
|
+
end),
|
304
|
+
FastlaneCore::ConfigItem.new(key: :api_token,
|
305
|
+
env_name: "FL_GITHUB_API_TOKEN",
|
306
|
+
description: "Personal API Token for GitHub - generate one at https://github.com/settings/tokens",
|
307
|
+
sensitive: true,
|
308
|
+
code_gen_sensitive: true,
|
309
|
+
is_string: true,
|
310
|
+
default_value: ENV["GITHUB_API_TOKEN"],
|
311
|
+
default_value_dynamic: true,
|
312
|
+
optional: false),
|
313
|
+
FastlaneCore::ConfigItem.new(key: :org,
|
314
|
+
env_name: "FL_GITHUB_ACTIONS_ORG",
|
315
|
+
description: "Name of organization of the repository for GitHub Actions"),
|
316
|
+
FastlaneCore::ConfigItem.new(key: :repo,
|
317
|
+
env_name: "FL_GITHUB_ACTIONS_REPO",
|
318
|
+
description: "Name of repository for GitHub Actions"),
|
319
|
+
FastlaneCore::ConfigItem.new(key: :match_org,
|
320
|
+
env_name: "FL_GITHUB_ACTIONS_MATCH_ORG",
|
321
|
+
description: "Name of organization of the match repository",
|
322
|
+
optional: true),
|
323
|
+
FastlaneCore::ConfigItem.new(key: :match_repo,
|
324
|
+
env_name: "FL_GITHUB_ACTIONS_MATCH_REPO",
|
325
|
+
description: "Name of match repository",
|
326
|
+
optional: true),
|
327
|
+
FastlaneCore::ConfigItem.new(key: :dotenv_paths,
|
328
|
+
env_name: "FL_GITHUB_ACTINOS_DOTENV_PATHS",
|
329
|
+
description: "Paths of .env files to parse",
|
330
|
+
optional: true,
|
331
|
+
type: Array,
|
332
|
+
verify_block: proc do |values|
|
333
|
+
values.each do |value|
|
334
|
+
UI.user_error!("Path #{value} doesn't exist") unless File.exist?(value)
|
335
|
+
end
|
336
|
+
end),
|
337
|
+
]
|
338
|
+
end
|
339
|
+
|
340
|
+
def self.is_supported?(platform)
|
341
|
+
true
|
342
|
+
end
|
343
|
+
end
|
344
|
+
end
|
345
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'fastlane_core/ui/ui'
|
2
|
+
|
3
|
+
module Fastlane
|
4
|
+
UI = FastlaneCore::UI unless Fastlane.const_defined?("UI")
|
5
|
+
|
6
|
+
module Helper
|
7
|
+
class GithubActionHelper
|
8
|
+
#
|
9
|
+
# Taken from https://github.com/fastlane/fastlane/blob/9c0494ef5e7d71afc51c73fe0b141b02e8991d9c/fastlane/lib/fastlane/erb_template_helper.rb
|
10
|
+
# Because I need to load from my plugin gem (not main fastlane gem)
|
11
|
+
#
|
12
|
+
require "erb"
|
13
|
+
def self.load(template_name)
|
14
|
+
path = "#{gem_path('fastlane-plugin-github_action')}/lib/assets/#{template_name}.erb"
|
15
|
+
load_from_path(path)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.load_from_path(template_filepath)
|
19
|
+
unless File.exist?(template_filepath)
|
20
|
+
UI.user_error!("Could not find Template at path '#{template_filepath}'")
|
21
|
+
end
|
22
|
+
File.read(template_filepath)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.render(template, template_vars_hash)
|
26
|
+
Fastlane::ErbalT.new(template_vars_hash).render(template)
|
27
|
+
end
|
28
|
+
|
29
|
+
#
|
30
|
+
# Taken from https://github.com/fastlane/fastlane/blob/f0dd4d0f4ecc74d9f7f62e0efc33091d975f2043/fastlane_core/lib/fastlane_core/helper.rb#L248-L259
|
31
|
+
# Unsure best other way to do this so using this logic for now since its deprecated in fastlane proper
|
32
|
+
#
|
33
|
+
def self.gem_path(gem_name)
|
34
|
+
if !Helper.is_test? and Gem::Specification.find_all_by_name(gem_name).any?
|
35
|
+
return Gem::Specification.find_by_name(gem_name).gem_dir
|
36
|
+
else
|
37
|
+
return './'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
metadata
ADDED
@@ -0,0 +1,217 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fastlane-plugin-github_action
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Josh Holtz
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-05-19 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: fastlane
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 2.148.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 2.148.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: dotenv
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rbnacl
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: sshkey
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: bundler
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rspec
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rspec_junit_formatter
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rake
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: rubocop
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - '='
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: 0.49.1
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - '='
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: 0.49.1
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: rubocop-require_tools
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: simplecov
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - ">="
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0'
|
181
|
+
description:
|
182
|
+
email: me@joshholtz.com
|
183
|
+
executables: []
|
184
|
+
extensions: []
|
185
|
+
extra_rdoc_files: []
|
186
|
+
files:
|
187
|
+
- LICENSE
|
188
|
+
- README.md
|
189
|
+
- lib/assets/workflow_template.erb
|
190
|
+
- lib/fastlane/plugin/github_action.rb
|
191
|
+
- lib/fastlane/plugin/github_action/actions/github_action_action.rb
|
192
|
+
- lib/fastlane/plugin/github_action/helper/github_actions_helper.rb
|
193
|
+
- lib/fastlane/plugin/github_action/version.rb
|
194
|
+
homepage: https://github.com/joshdholtz/fastlane-plugin-github_action
|
195
|
+
licenses:
|
196
|
+
- MIT
|
197
|
+
metadata: {}
|
198
|
+
post_install_message:
|
199
|
+
rdoc_options: []
|
200
|
+
require_paths:
|
201
|
+
- lib
|
202
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
203
|
+
requirements:
|
204
|
+
- - ">="
|
205
|
+
- !ruby/object:Gem::Version
|
206
|
+
version: '0'
|
207
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
208
|
+
requirements:
|
209
|
+
- - ">="
|
210
|
+
- !ruby/object:Gem::Version
|
211
|
+
version: '0'
|
212
|
+
requirements: []
|
213
|
+
rubygems_version: 3.0.6
|
214
|
+
signing_key:
|
215
|
+
specification_version: 4
|
216
|
+
summary: Helper to setup GitHub actions for fastlane and match
|
217
|
+
test_files: []
|