semaph 0.4.0 → 0.9.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/.rubocop.yml +39 -0
- data/.semaph +9 -0
- data/.semaphore/semaphore.yml +5 -1
- data/Gemfile.lock +21 -1
- data/README.md +12 -8
- data/Rakefile +4 -1
- data/lib/semaph.rb +43 -8
- data/lib/semaph/{api.rb → client.rb} +24 -3
- data/lib/semaph/commands.rb +63 -0
- data/lib/semaph/commands/rerun_workflow_command.rb +0 -2
- data/lib/semaph/commands/stop_workflow_command.rb +0 -2
- data/lib/semaph/formatting.rb +19 -1
- data/lib/semaph/model/job.rb +21 -2
- data/lib/semaph/model/job_collection.rb +19 -3
- data/lib/semaph/model/pipeline.rb +29 -3
- data/lib/semaph/model/promotion.rb +31 -0
- data/lib/semaph/model/promotion_collection.rb +21 -0
- data/lib/semaph/model/workflow.rb +17 -3
- data/lib/semaph/shells/organisation/organisation_shell.rb +4 -4
- data/lib/semaph/shells/organisation/projects_select_command.rb +6 -0
- data/lib/semaph/shells/organisations/organisations_list_command.rb +2 -2
- data/lib/semaph/shells/organisations/organisations_select_command.rb +11 -2
- data/lib/semaph/shells/organisations/organisations_shell.rb +2 -2
- data/lib/semaph/shells/pipeline/job_debug_command.rb +29 -0
- data/lib/semaph/shells/pipeline/job_log_command.rb +17 -15
- data/lib/semaph/shells/pipeline/job_log_grep_command.rb +5 -11
- 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 +4 -2
- data/lib/semaph/shells/pipeline/jobs_poll_command.rb +58 -22
- data/lib/semaph/shells/pipeline/pipeline_shell.rb +28 -68
- 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 +4 -2
- data/lib/semaph/shells/project/save_command.rb +26 -0
- data/lib/semaph/shells/project/workflows_list_command.rb +11 -17
- data/lib/semaph/shells/workflow/pipelines_list_command.rb +3 -1
- data/lib/semaph/shells/workflow/workflow_shell.rb +6 -66
- data/lib/semaph/version.rb +1 -1
- data/semaph.gemspec +1 -0
- metadata +30 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0653a67cbd9a978c6650491d39594eaf22d59b0be26d43bacc7a2f0933d5432c
|
4
|
+
data.tar.gz: 1ffb51d996af36938a6fc8b61e26da3db154161b7c420f31a8570a77545d6e1e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e7f196dfd55567cbd4621c0b2223b0367020d0c1d104560b108fc03a73846ccb56bbbca248321b0fb0c02c2ad4122c3093fe8280336440a2fc80c555bc191a5a
|
7
|
+
data.tar.gz: 59b468eccf7a64f79d4ea8317df870f24c4d3271d08a3616b992c9994fb4838276865ffc3fc47805795dec5f921323d53864a75c529e4852c9ac3cbe0f4b4ebd
|
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/.semaph
ADDED
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.9.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
@@ -60,8 +60,6 @@ If you have only one set of credentials in `~/.sem.yml` then this will be the in
|
|
60
60
|
|
61
61
|
From here you can `list-projects` and then `select-project` to enter a shell for that project.
|
62
62
|
|
63
|
-
If new projects have been added/removed while you are using this shell, you can `reload-projects`.
|
64
|
-
|
65
63
|
### project shell
|
66
64
|
|
67
65
|
🏗 foo.semaphoreci.com my-app >
|
@@ -71,8 +69,8 @@ substring of the git branch you want to see workflows for) and then `select-work
|
|
71
69
|
(where 'index' is the number displayed for each workflow `list-workflows` - tab completion on uuids
|
72
70
|
seemed a bad idea) to enter a shell for that specific workflow.
|
73
71
|
|
74
|
-
You can also `open-github` (opens a web browser for the github project associated with the project)
|
75
|
-
(opens the semaphoreci project in a browser)
|
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).
|
76
74
|
|
77
75
|
### workflow shell
|
78
76
|
|
@@ -83,16 +81,22 @@ from `semaphore.yml` plus any promotion pipelines that might be executed. You c
|
|
83
81
|
what's happening with the pipeline.
|
84
82
|
|
85
83
|
You can also `open-github-branch`, `open-github-commit` to see the branch/commit in a browser and
|
86
|
-
`open-workflow`, `open-branch` to see the semaphore branch/workflow in a browser
|
87
|
-
any changes that have happened in semaphore.
|
84
|
+
`open-workflow`, `open-branch` to see the semaphore branch/workflow in a browser.
|
88
85
|
|
89
86
|
### pipeline shell
|
90
87
|
|
91
88
|
🏗 foo.semaphoreci.com my-app workflowuuid semaphore.yml >
|
92
89
|
|
93
|
-
From this shell, you can `list-jobs` and `
|
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.
|
94
98
|
|
95
|
-
|
99
|
+
You can also open the same browser views in semaphoreci and github from this shell.
|
96
100
|
|
97
101
|
## Development
|
98
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]
|
data/lib/semaph.rb
CHANGED
@@ -1,22 +1,57 @@
|
|
1
|
+
require "semaph/client"
|
2
|
+
require "semaph/model/project"
|
1
3
|
require "semaph/version"
|
2
4
|
require "semaph/shells/organisations/organisations_shell"
|
3
5
|
require "semaph/shells/organisation/organisation_shell"
|
6
|
+
require "semaph/shells/project/project_shell"
|
4
7
|
require "yaml"
|
5
8
|
|
6
9
|
module Semaph
|
7
10
|
class Error < StandardError; end
|
8
11
|
|
9
12
|
def self.console
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
sem_config = YAML.load_file(yaml_path)
|
14
|
-
contexts = sem_config["contexts"]
|
13
|
+
organisations = load_organisations
|
14
|
+
config = load_config
|
15
15
|
|
16
|
-
if
|
17
|
-
|
16
|
+
if config
|
17
|
+
console_with_config(organisations, config)
|
18
|
+
elsif organisations.count == 1
|
19
|
+
Shells::Organisation::OrganisationShell.new(organisations.first).push
|
18
20
|
else
|
19
|
-
Shells::Organisations::OrganisationsShell.new(
|
21
|
+
Shells::Organisations::OrganisationsShell.new(organisations).push
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.console_with_config(organisations, config)
|
26
|
+
organisation = organisations.find { |o| o["host"] == config[:host] }
|
27
|
+
|
28
|
+
Shells::Project::ProjectShell.new(
|
29
|
+
Model::Project.new(
|
30
|
+
::Semaph::Client.new(
|
31
|
+
organisation["auth"]["token"],
|
32
|
+
organisation["host"],
|
33
|
+
),
|
34
|
+
config[:project],
|
35
|
+
),
|
36
|
+
).push
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.load_organisations
|
40
|
+
yaml_path = File.join(File.expand_path("~"), ".sem.yaml")
|
41
|
+
|
42
|
+
unless File.exist?(yaml_path)
|
43
|
+
unless organisations
|
44
|
+
puts "Please install the sem tool and authenticate to semaphoreci.com"
|
45
|
+
exit 1
|
46
|
+
end
|
20
47
|
end
|
48
|
+
|
49
|
+
YAML.load_file(yaml_path)["contexts"].values
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.load_config
|
53
|
+
return nil unless File.exist?(".semaph")
|
54
|
+
|
55
|
+
YAML.load_file(".semaph")
|
21
56
|
end
|
22
57
|
end
|
@@ -3,7 +3,17 @@ require "json"
|
|
3
3
|
|
4
4
|
module Semaph
|
5
5
|
# Refer to https://docs.semaphoreci.com/reference/api-v1alpha/
|
6
|
-
class
|
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
|
+
|
7
17
|
attr_reader :host, :name
|
8
18
|
|
9
19
|
def initialize(token, host)
|
@@ -42,10 +52,22 @@ module Semaph
|
|
42
52
|
get "pipelines/#{id}", { detailed: true }
|
43
53
|
end
|
44
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
|
+
|
45
63
|
def job(id)
|
46
64
|
get "jobs/#{id}"
|
47
65
|
end
|
48
66
|
|
67
|
+
def stop_job(id)
|
68
|
+
post "jobs/#{id}/stop"
|
69
|
+
end
|
70
|
+
|
49
71
|
def job_log(id)
|
50
72
|
get_raw "jobs/#{id}/plain_logs.json"
|
51
73
|
end
|
@@ -87,8 +109,7 @@ module Semaph
|
|
87
109
|
def check_response(response, url)
|
88
110
|
return response.body if response.status == 200
|
89
111
|
|
90
|
-
|
91
|
-
exit 1
|
112
|
+
raise RequestException.new(url, response)
|
92
113
|
end
|
93
114
|
end
|
94
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
|
data/lib/semaph/formatting.rb
CHANGED
@@ -1,9 +1,27 @@
|
|
1
|
+
require "rainbow"
|
2
|
+
|
1
3
|
module Semaph
|
2
4
|
module Formatting
|
3
|
-
TIME_FORMAT = "%
|
5
|
+
TIME_FORMAT = "%m-%d %H:%M".freeze
|
4
6
|
|
5
7
|
def self.time(time)
|
6
8
|
time.strftime(TIME_FORMAT)
|
7
9
|
end
|
10
|
+
|
11
|
+
def self.hours_minutes_seconds(total_seconds)
|
12
|
+
seconds = total_seconds % 60
|
13
|
+
minutes = (total_seconds / 60) % 60
|
14
|
+
hours = total_seconds / (60 * 60)
|
15
|
+
|
16
|
+
format("%02<hours>d:%02<minutes>d:%02<seconds>d", hours: hours, minutes: minutes, seconds: seconds)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.index(number)
|
20
|
+
Rainbow(number.to_s.rjust(2)).yellow
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.length(collection)
|
24
|
+
Rainbow(collection.length.to_s).cyan
|
25
|
+
end
|
8
26
|
end
|
9
27
|
end
|
data/lib/semaph/model/job.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
|
1
3
|
module Semaph
|
2
4
|
module Model
|
3
5
|
class Job
|
@@ -20,8 +22,25 @@ module Semaph
|
|
20
22
|
assign_from_block(raw_block)
|
21
23
|
end
|
22
24
|
|
23
|
-
def
|
24
|
-
pipeline.workflow.project.client.
|
25
|
+
def stop
|
26
|
+
pipeline.workflow.project.client.stop_job(id)
|
27
|
+
end
|
28
|
+
|
29
|
+
def show
|
30
|
+
pp pipeline.workflow.project.client.job(id)
|
31
|
+
end
|
32
|
+
|
33
|
+
def write_log(base)
|
34
|
+
FileUtils.mkdir_p(base)
|
35
|
+
filename = "#{base}/#{id}.log"
|
36
|
+
return filename if File.exist?(filename)
|
37
|
+
|
38
|
+
puts "retrieving log for job #{id}"
|
39
|
+
File.open(filename, "w") do |file|
|
40
|
+
file.puts pipeline.workflow.project.client.job_log(id)
|
41
|
+
end
|
42
|
+
|
43
|
+
filename
|
25
44
|
end
|
26
45
|
|
27
46
|
def description
|