semaph 0.2.0 → 0.7.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 +4 -4
- data/.gitignore +2 -1
- data/.rubocop.yml +39 -0
- data/.semaphore/semaphore.yml +5 -1
- data/Gemfile.lock +21 -1
- data/README.md +85 -11
- data/Rakefile +4 -1
- data/lib/semaph/client.rb +115 -0
- data/lib/semaph/commands.rb +63 -0
- data/lib/semaph/commands/reload_command.rb +5 -4
- data/lib/semaph/commands/rerun_workflow_command.rb +16 -0
- data/lib/semaph/commands/stop_workflow_command.rb +16 -0
- data/lib/semaph/formatting.rb +15 -1
- data/lib/semaph/model/job.rb +70 -1
- data/lib/semaph/model/job_collection.rb +18 -5
- data/lib/semaph/model/pipeline.rb +54 -2
- data/lib/semaph/model/pipeline_collection.rb +0 -1
- data/lib/semaph/model/project.rb +1 -1
- data/lib/semaph/model/project_collection.rb +0 -1
- data/lib/semaph/model/promotion.rb +31 -0
- data/lib/semaph/model/promotion_collection.rb +21 -0
- data/lib/semaph/model/workflow.rb +28 -4
- data/lib/semaph/model/workflow_collection.rb +0 -1
- data/lib/semaph/shells/organisation/organisation_shell.rb +15 -11
- data/lib/semaph/shells/organisation/projects_list_command.rb +1 -0
- data/lib/semaph/shells/organisation/projects_select_command.rb +6 -0
- data/lib/semaph/shells/organisations/organisations_select_command.rb +8 -1
- data/lib/semaph/shells/organisations/organisations_shell.rb +6 -2
- data/lib/semaph/shells/pipeline/job_debug_command.rb +29 -0
- data/lib/semaph/shells/pipeline/job_log_command.rb +44 -0
- data/lib/semaph/shells/pipeline/job_log_grep_command.rb +28 -0
- data/lib/semaph/shells/pipeline/job_show_command.rb +28 -0
- data/lib/semaph/shells/pipeline/job_stop_command.rb +28 -0
- data/lib/semaph/shells/pipeline/jobs_list_command.rb +6 -16
- data/lib/semaph/shells/pipeline/jobs_poll_command.rb +55 -0
- data/lib/semaph/shells/pipeline/pipeline_shell.rb +42 -7
- data/lib/semaph/shells/pipeline/promote_command.rb +21 -0
- data/lib/semaph/shells/pipeline/promotions_list_command.rb +21 -0
- data/lib/semaph/shells/project/project_shell.rb +31 -18
- data/lib/semaph/shells/project/workflows_list_command.rb +4 -16
- data/lib/semaph/shells/project/workflows_select_command.rb +10 -3
- data/lib/semaph/shells/workflow/pipelines_list_command.rb +4 -1
- data/lib/semaph/shells/workflow/pipelines_select_command.rb +9 -3
- data/lib/semaph/shells/workflow/workflow_shell.rb +13 -42
- data/lib/semaph/version.rb +1 -1
- data/semaph.gemspec +1 -0
- metadata +33 -6
- data/lib/semaph/api.rb +0 -61
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7db37cbca829e1b13372c7a8687b86080b1e4a579bbb7707e6cc207ebdcb4ba1
|
4
|
+
data.tar.gz: 4b5015379f62ad0382991f26b525583d2a6e077889071e5bde58dc1399d69ada
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 243de9cc3425299a5d7a5a11d3a6e06a89e56ad22e0bab59fe4568544fc8e05f0a6e902363497d493811a00c30f84a95456a0679417fb7d4d39b10ad35ece692
|
7
|
+
data.tar.gz: f1fd8d22e22885357f0b5c1ba962ac1edb91b61b6ab3b9e03cfec9aeda88197a40bfcfe2b047417d3d2629e5eb8f9fa3e32b9dde40e8feefeb09bae8e7e5527d
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -1,3 +1,42 @@
|
|
1
|
+
Layout/EmptyLinesAroundAttributeAccessor:
|
2
|
+
Enabled: true
|
3
|
+
|
4
|
+
Layout/SpaceAroundMethodCallOperator:
|
5
|
+
Enabled: true
|
6
|
+
|
7
|
+
Lint/DeprecatedOpenSSLConstant:
|
8
|
+
Enabled: true
|
9
|
+
|
10
|
+
Lint/MixedRegexpCaptureTypes:
|
11
|
+
Enabled: true
|
12
|
+
|
13
|
+
Lint/RaiseException:
|
14
|
+
Enabled: true
|
15
|
+
|
16
|
+
Lint/StructNewOverride:
|
17
|
+
Enabled: true
|
18
|
+
|
19
|
+
Style/ExponentialNotation:
|
20
|
+
Enabled: true
|
21
|
+
|
22
|
+
Style/HashEachMethods:
|
23
|
+
Enabled: true
|
24
|
+
|
25
|
+
Style/HashTransformKeys:
|
26
|
+
Enabled: true
|
27
|
+
|
28
|
+
Style/HashTransformValues:
|
29
|
+
Enabled: true
|
30
|
+
|
31
|
+
Style/RedundantRegexpCharacterClass:
|
32
|
+
Enabled: true
|
33
|
+
|
34
|
+
Style/RedundantRegexpEscape:
|
35
|
+
Enabled: true
|
36
|
+
|
37
|
+
Style/SlicingWithRange:
|
38
|
+
Enabled: true
|
39
|
+
|
1
40
|
Style/Documentation:
|
2
41
|
Enabled: false
|
3
42
|
|
data/.semaphore/semaphore.yml
CHANGED
@@ -16,4 +16,8 @@ blocks:
|
|
16
16
|
- name: Build
|
17
17
|
commands:
|
18
18
|
- checkout
|
19
|
-
-
|
19
|
+
- sem-version ruby $(grep ruby .tool-versions | cut -d ' ' -f 2)
|
20
|
+
- cache restore $(git ls-tree HEAD Gemfile.lock | cut -f3 -d$' ' | cut -f1 -d$'\t')
|
21
|
+
- bundle install --deployment --path vendor/bundle
|
22
|
+
- cache store $(git ls-tree HEAD Gemfile.lock | cut -f3 -d$' ' | cut -f1 -d$'\t') vendor/bundle
|
23
|
+
- bundle exec rake
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
semaph (0.
|
4
|
+
semaph (0.7.0)
|
5
5
|
faraday
|
6
6
|
rainbow
|
7
7
|
shell_shock
|
@@ -9,18 +9,37 @@ PATH
|
|
9
9
|
GEM
|
10
10
|
remote: https://rubygems.org/
|
11
11
|
specs:
|
12
|
+
ast (2.4.0)
|
12
13
|
coderay (1.1.2)
|
13
14
|
faraday (1.0.1)
|
14
15
|
multipart-post (>= 1.2, < 3)
|
15
16
|
method_source (1.0.0)
|
16
17
|
minitest (5.14.1)
|
17
18
|
multipart-post (2.1.1)
|
19
|
+
parallel (1.19.1)
|
20
|
+
parser (2.7.1.3)
|
21
|
+
ast (~> 2.4.0)
|
18
22
|
pry (0.13.1)
|
19
23
|
coderay (~> 1.1)
|
20
24
|
method_source (~> 1.0)
|
21
25
|
rainbow (3.0.0)
|
22
26
|
rake (12.3.3)
|
27
|
+
regexp_parser (1.7.0)
|
28
|
+
rexml (3.2.4)
|
29
|
+
rubocop (0.85.0)
|
30
|
+
parallel (~> 1.10)
|
31
|
+
parser (>= 2.7.0.1)
|
32
|
+
rainbow (>= 2.2.2, < 4.0)
|
33
|
+
regexp_parser (>= 1.7)
|
34
|
+
rexml
|
35
|
+
rubocop-ast (>= 0.0.3)
|
36
|
+
ruby-progressbar (~> 1.7)
|
37
|
+
unicode-display_width (>= 1.4.0, < 2.0)
|
38
|
+
rubocop-ast (0.0.3)
|
39
|
+
parser (>= 2.7.0.1)
|
40
|
+
ruby-progressbar (1.10.1)
|
23
41
|
shell_shock (0.0.5)
|
42
|
+
unicode-display_width (1.7.0)
|
24
43
|
|
25
44
|
PLATFORMS
|
26
45
|
ruby
|
@@ -29,6 +48,7 @@ DEPENDENCIES
|
|
29
48
|
minitest (~> 5.0)
|
30
49
|
pry
|
31
50
|
rake (~> 12.0)
|
51
|
+
rubocop
|
32
52
|
semaph!
|
33
53
|
|
34
54
|
BUNDLED WITH
|
data/README.md
CHANGED
@@ -1,28 +1,102 @@
|
|
1
1
|
# Semaph
|
2
2
|
|
3
|
-
|
3
|
+
This is command line shell for interacting with [semaphoreci 2.0](http://docs.semaphoreci.com/).
|
4
|
+
|
5
|
+
It complements the [sem](https://docs.semaphoreci.com/reference/sem-command-line-tool/) tool with some
|
6
|
+
overlap in responsibilities.
|
4
7
|
|
5
|
-
TODO: Delete this and the text above, and describe your gem
|
6
8
|
|
7
9
|
## Installation
|
8
10
|
|
9
|
-
|
11
|
+
gem install semaph
|
12
|
+
|
13
|
+
## Usage
|
14
|
+
|
15
|
+
To set up authentication to semaphoreci, you can just follow the instructions to install and setup
|
16
|
+
[sem](https://docs.semaphoreci.com/reference/sem-command-line-tool/). This will result
|
17
|
+
in your authentication details being written to `~/.sem.yaml`.
|
10
18
|
|
11
|
-
|
12
|
-
|
19
|
+
You should see something like the following in this file:
|
20
|
+
|
21
|
+
```yaml
|
22
|
+
active-context: foo_semaphoreci_com
|
23
|
+
contexts:
|
24
|
+
foo_semaphoreci_com:
|
25
|
+
auth:
|
26
|
+
token: qwerty
|
27
|
+
host: foo.semaphoreci.com
|
13
28
|
```
|
14
29
|
|
15
|
-
|
30
|
+
Now you can run `semaph` and will be presented with a prompt like one of the following:
|
16
31
|
|
17
|
-
|
32
|
+
🏗 >
|
18
33
|
|
19
|
-
|
34
|
+
or
|
20
35
|
|
21
|
-
|
36
|
+
🏗 foo.semaphoreci.com >
|
22
37
|
|
23
|
-
|
38
|
+
This is the first of a series of nested shells. Each shell represents a different context
|
39
|
+
and has different commands available. To see the commands available, execute `help` and
|
40
|
+
to see the details of a particular command, execute `help <command name>`. Once you are
|
41
|
+
familar with the commands for each context, you can type the first couple of characters
|
42
|
+
and then hit tab to complete the rest. For some commands you can also tab complete the
|
43
|
+
parameters. Once you enter a shell, return to the previous shell or exit `semaph`, you can
|
44
|
+
press ctrl-d.
|
45
|
+
|
46
|
+
### organisations shell
|
47
|
+
|
48
|
+
🏗 >
|
49
|
+
|
50
|
+
You will only see this shell if you have multiple sets of credentials in your `~/.sem.yml` file.
|
51
|
+
|
52
|
+
From this shell, you can `list-organisations` you are authenticated to and `select-organisation`
|
53
|
+
to enter a shell for that organisation.
|
54
|
+
|
55
|
+
### organisation shell
|
56
|
+
|
57
|
+
🏗 foo.semaphoreci.com >
|
58
|
+
|
59
|
+
If you have only one set of credentials in `~/.sem.yml` then this will be the initial shell.
|
60
|
+
|
61
|
+
From here you can `list-projects` and then `select-project` to enter a shell for that project.
|
62
|
+
|
63
|
+
### project shell
|
64
|
+
|
65
|
+
🏗 foo.semaphoreci.com my-app >
|
66
|
+
|
67
|
+
From this shell, you will mostly be interested in `list-workflows <branch>` (where 'branch' is any
|
68
|
+
substring of the git branch you want to see workflows for) and then `select-workflow <index>`
|
69
|
+
(where 'index' is the number displayed for each workflow `list-workflows` - tab completion on uuids
|
70
|
+
seemed a bad idea) to enter a shell for that specific workflow.
|
71
|
+
|
72
|
+
You can also `open-github` (opens a web browser for the github project associated with the project) and `open-project`
|
73
|
+
(opens the semaphoreci project in a browser).
|
74
|
+
|
75
|
+
### workflow shell
|
76
|
+
|
77
|
+
🏗 foo.semaphoreci.com my-app workflowuuid >
|
78
|
+
|
79
|
+
From this shell, you can `list-pipelines` for the selected workflow. These are the builds usually starting
|
80
|
+
from `semaphore.yml` plus any promotion pipelines that might be executed. You can `select-pipeline` to monitor
|
81
|
+
what's happening with the pipeline.
|
82
|
+
|
83
|
+
You can also `open-github-branch`, `open-github-commit` to see the branch/commit in a browser and
|
84
|
+
`open-workflow`, `open-branch` to see the semaphore branch/workflow in a browser.
|
85
|
+
|
86
|
+
### pipeline shell
|
87
|
+
|
88
|
+
🏗 foo.semaphoreci.com my-app workflowuuid semaphore.yml >
|
89
|
+
|
90
|
+
From this shell, you can `list-jobs`, `poll-jobs`, `job-log` and `grep-logs`.
|
91
|
+
|
92
|
+
Job polling will stop as soon as any one job has failed and send a system notification
|
93
|
+
(as long as `terminal-notifier` is installed).
|
94
|
+
|
95
|
+
You can look at the log for a specific job (by the index presented in `list-jobs`) using `less`.
|
96
|
+
|
97
|
+
You can grep across all jobs (using `ag`) with `grep-logs` which will download the logs for all completed jobs.
|
24
98
|
|
25
|
-
|
99
|
+
You can also open the same browser views in semaphoreci and github from this shell.
|
26
100
|
|
27
101
|
## Development
|
28
102
|
|
data/Rakefile
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
2
|
require "rake/testtask"
|
3
|
+
require "rubocop/rake_task"
|
3
4
|
|
4
5
|
Rake::TestTask.new(:test) do |t|
|
5
6
|
t.libs << "test"
|
@@ -7,4 +8,6 @@ Rake::TestTask.new(:test) do |t|
|
|
7
8
|
t.test_files = FileList["test/**/*_test.rb"]
|
8
9
|
end
|
9
10
|
|
10
|
-
|
11
|
+
RuboCop::RakeTask.new(:cop)
|
12
|
+
|
13
|
+
task default: %i[cop test]
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require "faraday"
|
2
|
+
require "json"
|
3
|
+
|
4
|
+
module Semaph
|
5
|
+
# Refer to https://docs.semaphoreci.com/reference/api-v1alpha/
|
6
|
+
class Client
|
7
|
+
class RequestException < RuntimeError
|
8
|
+
attr_reader :url, :response
|
9
|
+
|
10
|
+
def initialize(url, response)
|
11
|
+
@url = url
|
12
|
+
@response = response
|
13
|
+
super("http response #{response.status} received for #{url}:\n#{response.body}")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_reader :host, :name
|
18
|
+
|
19
|
+
def initialize(token, host)
|
20
|
+
@token = token
|
21
|
+
@host = host
|
22
|
+
@name = host.split(".").first
|
23
|
+
@host_url = "https://#{host}"
|
24
|
+
@base = "#{@host_url}/api/v1alpha"
|
25
|
+
end
|
26
|
+
|
27
|
+
def projects
|
28
|
+
get "projects"
|
29
|
+
end
|
30
|
+
|
31
|
+
def workflows(project_id)
|
32
|
+
get "plumber-workflows", { project_id: project_id }
|
33
|
+
end
|
34
|
+
|
35
|
+
def workflow(workflow_id)
|
36
|
+
get "plumber-workflows/#{workflow_id}"
|
37
|
+
end
|
38
|
+
|
39
|
+
def stop_workflow(workflow_id)
|
40
|
+
post "plumber-workflows/#{workflow_id}/terminate"
|
41
|
+
end
|
42
|
+
|
43
|
+
def rerun_workflow(workflow_id)
|
44
|
+
post "plumber-workflows/#{workflow_id}/reschedule?request_token=#{workflow_id}"
|
45
|
+
end
|
46
|
+
|
47
|
+
def pipelines(options)
|
48
|
+
get "pipelines", options
|
49
|
+
end
|
50
|
+
|
51
|
+
def pipeline(id)
|
52
|
+
get "pipelines/#{id}", { detailed: true }
|
53
|
+
end
|
54
|
+
|
55
|
+
def promotions(pipeline_id)
|
56
|
+
get "promotions", { pipeline_id: pipeline_id }
|
57
|
+
end
|
58
|
+
|
59
|
+
def promote(pipeline_id, name)
|
60
|
+
post "promotions", { pipeline_id: pipeline_id, name: name }
|
61
|
+
end
|
62
|
+
|
63
|
+
def job(id)
|
64
|
+
get "jobs/#{id}"
|
65
|
+
end
|
66
|
+
|
67
|
+
def stop_job(id)
|
68
|
+
post "jobs/#{id}/stop"
|
69
|
+
end
|
70
|
+
|
71
|
+
def job_log(id)
|
72
|
+
get_raw "jobs/#{id}/plain_logs.json"
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def get_raw(path, params = {})
|
78
|
+
url = "#{@host_url}/#{path}"
|
79
|
+
puts url if ENV["SEMAPH_DEBUG"]
|
80
|
+
response = Faraday.get(url, params, { "Authorization" => "Token #{@token}" })
|
81
|
+
check_response(response, url)
|
82
|
+
end
|
83
|
+
|
84
|
+
def get(path, params = {})
|
85
|
+
url = "#{@base}/#{path}"
|
86
|
+
puts url if ENV["SEMAPH_DEBUG"]
|
87
|
+
response = Faraday.get(url, params, headers)
|
88
|
+
JSON.parse(check_response(response, url)).tap do |hash|
|
89
|
+
pp hash if ENV["SEMAPH_DEBUG"]
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def post(path, params = {})
|
94
|
+
url = "#{@base}/#{path}"
|
95
|
+
response = Faraday.post(url, params.to_json, headers)
|
96
|
+
JSON.parse(check_response(response, url)).tap do |hash|
|
97
|
+
pp hash if ENV["SEMAPH_DEBUG"]
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def headers
|
102
|
+
{
|
103
|
+
"Authorization" => "Token #{@token}",
|
104
|
+
"Content-Type" => "application/json",
|
105
|
+
"Accept" => "application/json",
|
106
|
+
}
|
107
|
+
end
|
108
|
+
|
109
|
+
def check_response(response, url)
|
110
|
+
return response.body if response.status == 200
|
111
|
+
|
112
|
+
raise RequestException.new(url, response)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require "semaph/commands/reload_command"
|
2
|
+
require "semaph/commands/rerun_workflow_command"
|
3
|
+
require "semaph/commands/stop_workflow_command"
|
4
|
+
require "semaph/commands/visit_url_command"
|
5
|
+
|
6
|
+
module Semaph
|
7
|
+
module Commands
|
8
|
+
def self.workflow_commands(shell, workflow)
|
9
|
+
shell.add_command ::Semaph::Commands::RerunWorkflowCommand.new(workflow), "rerun"
|
10
|
+
shell.add_command ::Semaph::Commands::StopWorkflowCommand.new(workflow), "stop"
|
11
|
+
add_open_workflow_command(shell, workflow)
|
12
|
+
add_open_branch_command(shell, workflow)
|
13
|
+
add_github_commands(shell, workflow)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.add_open_workflow_command(shell, workflow)
|
17
|
+
shell.add_command(
|
18
|
+
::Semaph::Commands::VisitUrlCommand.new(
|
19
|
+
"https://#{workflow.project.client.host}/workflows/#{workflow.id}",
|
20
|
+
"browse to workflow",
|
21
|
+
),
|
22
|
+
"open-workflow",
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.add_open_branch_command(shell, workflow)
|
27
|
+
shell.add_command(
|
28
|
+
::Semaph::Commands::VisitUrlCommand.new(
|
29
|
+
"https://#{workflow.project.client.host}/branches/#{workflow.branch_id}",
|
30
|
+
"browse to branch in semaphore",
|
31
|
+
),
|
32
|
+
"open-branch",
|
33
|
+
)
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.add_github_commands(shell, workflow)
|
37
|
+
return unless workflow.project.github_url
|
38
|
+
|
39
|
+
add_github_branch(shell, workflow)
|
40
|
+
add_github_commit(shell, workflow)
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.add_github_branch(shell, workflow)
|
44
|
+
shell.add_command(
|
45
|
+
::Semaph::Commands::VisitUrlCommand.new(
|
46
|
+
"#{workflow.project.github_url}/tree/#{workflow.branch}",
|
47
|
+
"browse to the branch in github",
|
48
|
+
),
|
49
|
+
"open-github-branch",
|
50
|
+
)
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.add_github_commit(shell, workflow)
|
54
|
+
shell.add_command(
|
55
|
+
::Semaph::Commands::VisitUrlCommand.new(
|
56
|
+
"#{workflow.project.github_url}/commit/#{workflow.sha}",
|
57
|
+
"browse to the commit in github",
|
58
|
+
),
|
59
|
+
"open-github-commit",
|
60
|
+
)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -3,13 +3,14 @@ module Semaph
|
|
3
3
|
class ReloadCommand
|
4
4
|
attr_reader :help
|
5
5
|
|
6
|
-
def initialize
|
7
|
-
@
|
8
|
-
@help = help
|
6
|
+
def initialize
|
7
|
+
@help = "reload all code"
|
9
8
|
end
|
10
9
|
|
11
10
|
def execute(_whatever)
|
12
|
-
|
11
|
+
Dir["lib/**/*.rb"].each do |path|
|
12
|
+
load path
|
13
|
+
end
|
13
14
|
end
|
14
15
|
end
|
15
16
|
end
|