cody 0.7.3 → 0.8.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/.cody/project.rb +4 -1
- data/.cody/role.rb +14 -0
- data/CHANGELOG.md +3 -0
- data/README.md +9 -4
- data/cody.gemspec +2 -1
- data/lib/cody/cli.rb +9 -0
- data/lib/cody/help/logs.md +62 -0
- data/lib/cody/logs.rb +27 -0
- data/lib/cody/start.rb +7 -2
- data/lib/cody/tailer.rb +119 -0
- data/lib/cody/version.rb +1 -1
- metadata +20 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d8ae54a008252e6ce83388bea8b82a78b6f3fff32724fc822b63d02baa39fdee
|
4
|
+
data.tar.gz: 717b8030c9046966f909eef2b64487482e1a8e1819d6e12d43747520499de642
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6a340b073735c12b2166ef78a43d79851c047780074a46f638021c7a0d7c60d8f380e4674ae2be09587f6b00400ced580391af72970cc96236869c108539fafe
|
7
|
+
data.tar.gz: 503328e1e3feb629877eb1dc901da9e2e3a52ed1a450b2da299ed662bb3cf38d9506d09ede8a8fccbb470186ebddaceeb4110ce37554d69a3146dc0b7dc17433
|
data/.cody/project.rb
CHANGED
data/.cody/role.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
iam_policy(
|
2
|
+
action: [
|
3
|
+
"logs:CreateLogGroup",
|
4
|
+
"logs:CreateLogStream",
|
5
|
+
"logs:PutLogEvents",
|
6
|
+
"ssm:DescribeDocumentParameters",
|
7
|
+
"ssm:DescribeParameters",
|
8
|
+
"ssm:GetParameter*",
|
9
|
+
],
|
10
|
+
effect: "Allow",
|
11
|
+
resource: "*"
|
12
|
+
)
|
13
|
+
|
14
|
+
managed_iam_policy("AWSCloudFormationReadOnlyAccess")
|
data/CHANGELOG.md
CHANGED
@@ -3,6 +3,9 @@
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
4
4
|
This project *tries* to adhere to [Semantic Versioning](http://semver.org/), even before v1.0.
|
5
5
|
|
6
|
+
## [0.8.0]
|
7
|
+
- #7 add cody logs command and automatically tail logs after a cody start
|
8
|
+
|
6
9
|
## [0.7.3]
|
7
10
|
- cleanup starter buildspec.yml
|
8
11
|
|
data/README.md
CHANGED
@@ -9,15 +9,14 @@
|
|
9
9
|
|
10
10
|
[](https://www.boltops.com)
|
11
11
|
|
12
|
-
Cody lets you create
|
13
|
-
|
14
|
-
The documentation site is at: [cody.run](https://cody.run/)
|
12
|
+
Cody is an AWS CodeBuild Management Tool. Cody lets you create AWS CodeBuild projects with a beautiful DSL. The documentation site is at: [cody.run](https://cody.run/)
|
15
13
|
|
16
14
|
## Quick Start
|
17
15
|
|
18
16
|
cody init
|
19
17
|
cody deploy
|
20
18
|
cody start
|
19
|
+
cody logs
|
21
20
|
|
22
21
|
## Private Repo
|
23
22
|
|
@@ -66,13 +65,19 @@ For more help:
|
|
66
65
|
|
67
66
|
### Start
|
68
67
|
|
69
|
-
When you are ready to start a codebuild project run, you can use
|
68
|
+
When you are ready to start a codebuild project run, you can use [codebuild start](https://cody.run/reference/cody-start/). Examples:
|
70
69
|
|
71
70
|
cody start # infers the name from the parent folder
|
72
71
|
cody start PROJECT_NAME # looks up project via CodeBuild project name
|
73
72
|
|
74
73
|
The `cody start` command understands multiple identifiers. It will look up the codebuild project either via CloudFormation or the CodeBuild project name.
|
75
74
|
|
75
|
+
The start command continuously polls the CodeBuild project and prints out the logs until the build completes. To disable this, use the `--no-wait` option.
|
76
|
+
|
77
|
+
cody start PROJECT_NAME --no-wait
|
78
|
+
|
79
|
+
The logs from the Phase Details and CloudWatch Logs are both displayed. Because they come from 2 different sources, the logs can interlace.
|
80
|
+
|
76
81
|
## Project DSL
|
77
82
|
|
78
83
|
The tool provides a DSL to create a codebuild project. Here's an example.
|
data/cody.gemspec
CHANGED
@@ -22,7 +22,8 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
23
23
|
spec.require_paths = ["lib"]
|
24
24
|
|
25
|
-
spec.add_dependency "activesupport"
|
25
|
+
spec.add_dependency "activesupport", "~> 6.0.0"
|
26
|
+
spec.add_dependency "aws-logs"
|
26
27
|
spec.add_dependency "aws-mfa-secure"
|
27
28
|
spec.add_dependency "aws-sdk-cloudformation"
|
28
29
|
spec.add_dependency "aws-sdk-codebuild"
|
data/lib/cody/cli.rb
CHANGED
@@ -41,6 +41,15 @@ module Cody
|
|
41
41
|
Start.new(options.merge(project_name: project_name)).run
|
42
42
|
end
|
43
43
|
|
44
|
+
desc "logs", "Prints out logs for codebuild project."
|
45
|
+
long_desc Help.text(:logs)
|
46
|
+
option :build_id, desc: "Project build id. Defaults to most recent."
|
47
|
+
option :since, desc: "From what time to begin displaying logs. By default, logs will be displayed starting from 7 days in the past. The value provided can be an ISO 8601 timestamp or a relative time."
|
48
|
+
common_options.call
|
49
|
+
def logs(project_name=nil)
|
50
|
+
Logs.new(options.merge(project_name: project_name)).run
|
51
|
+
end
|
52
|
+
|
44
53
|
desc "completion *PARAMS", "Prints words for auto-completion."
|
45
54
|
long_desc Help.text(:completion)
|
46
55
|
def completion(*params)
|
@@ -0,0 +1,62 @@
|
|
1
|
+
## Examples
|
2
|
+
|
3
|
+
cody logs # project name inferred
|
4
|
+
cody logs PROJECT # project name explicit
|
5
|
+
|
6
|
+
## Examples with Output
|
7
|
+
|
8
|
+
$ cody logs
|
9
|
+
Showing logs for build demo:ada202f1-6b30-4eb9-8625-7371a9911b7d
|
10
|
+
Phase: SUBMITTED Status: SUCCEEDED Duration: 0
|
11
|
+
Phase: QUEUED Status: SUCCEEDED Duration: 1
|
12
|
+
Phase: PROVISIONING Status: SUCCEEDED Duration: 40
|
13
|
+
Phase: DOWNLOAD_SOURCE Status: SUCCEEDED Duration: 0
|
14
|
+
Phase: INSTALL Status: SUCCEEDED Duration: 20
|
15
|
+
Phase: PRE_BUILD Status: SUCCEEDED Duration: 20
|
16
|
+
Phase: BUILD Status: SUCCEEDED Duration: 20
|
17
|
+
Phase: POST_BUILD Status: SUCCEEDED Duration: 20
|
18
|
+
Phase: UPLOAD_ARTIFACTS Status: SUCCEEDED Duration: 0
|
19
|
+
Phase: FINALIZING Status: SUCCEEDED Duration: 2
|
20
|
+
Phase: COMPLETED Status: Duration:
|
21
|
+
2019-11-28 05:15:12 UTC [Container] 2019/11/28 05:15:06 Waiting for agent ping
|
22
|
+
2019-11-28 05:15:12 UTC [Container] 2019/11/28 05:15:08 Waiting for DOWNLOAD_SOURCE
|
23
|
+
2019-11-28 05:15:12 UTC [Container] 2019/11/28 05:15:08 Phase is DOWNLOAD_SOURCE
|
24
|
+
2019-11-28 05:15:12 UTC [Container] 2019/11/28 05:15:08 CODEBUILD_SRC_DIR=/codebuild/output/src088335237/src/github.com/tongueroo/cody-demo
|
25
|
+
2019-11-28 05:15:12 UTC [Container] 2019/11/28 05:15:08 YAML location is /codebuild/output/src088335237/src/github.com/tongueroo/cody-demo/.cody/buildspec.yml
|
26
|
+
2019-11-28 05:15:12 UTC [Container] 2019/11/28 05:15:08 Processing environment variables
|
27
|
+
2019-11-28 05:15:12 UTC [Container] 2019/11/28 05:15:08 Moving to directory /codebuild/output/src088335237/src/github.com/tongueroo/cody-demo
|
28
|
+
2019-11-28 05:15:12 UTC [Container] 2019/11/28 05:15:08 Registering with agent
|
29
|
+
2019-11-28 05:15:12 UTC [Container] 2019/11/28 05:15:08 Phases found in YAML: 4
|
30
|
+
2019-11-28 05:15:12 UTC [Container] 2019/11/28 05:15:08 PRE_BUILD: 2 commands
|
31
|
+
2019-11-28 05:15:12 UTC [Container] 2019/11/28 05:15:08 BUILD: 2 commands
|
32
|
+
2019-11-28 05:15:12 UTC [Container] 2019/11/28 05:15:08 POST_BUILD: 2 commands
|
33
|
+
2019-11-28 05:15:12 UTC [Container] 2019/11/28 05:15:08 INSTALL: 2 commands
|
34
|
+
2019-11-28 05:15:12 UTC [Container] 2019/11/28 05:15:08 Phase complete: DOWNLOAD_SOURCE State: SUCCEEDED
|
35
|
+
2019-11-28 05:15:12 UTC [Container] 2019/11/28 05:15:08 Phase context status code: Message:
|
36
|
+
2019-11-28 05:15:12 UTC [Container] 2019/11/28 05:15:08 Entering phase INSTALL
|
37
|
+
2019-11-28 05:15:12 UTC [Container] 2019/11/28 05:15:08 Running command pwd
|
38
|
+
2019-11-28 05:15:12 UTC /codebuild/output/src088335237/src/github.com/tongueroo/cody-demo
|
39
|
+
2019-11-28 05:15:12 UTC
|
40
|
+
2019-11-28 05:15:12 UTC [Container] 2019/11/28 05:15:08 Running command .cody/sleep.sh install
|
41
|
+
2019-11-28 05:15:12 UTC 0: install
|
42
|
+
2019-11-28 05:15:12 UTC Thu Nov 28 05:15:08 UTC 2019
|
43
|
+
...
|
44
|
+
19-11-28 05:16:29 UTC [Container] 2019/11/28 05:16:29 Phase complete: POST_BUILD State: SUCCEEDED
|
45
|
+
2019-11-28 05:16:29 UTC [Container] 2019/11/28 05:16:29 Phase context status code: Message:
|
46
|
+
$
|
47
|
+
|
48
|
+
## Since Option
|
49
|
+
|
50
|
+
By default, Cody logs searches only 7 days in the past. This is done for speed. If you have an older build and would like to search further in the past. You can use the `--since option`. Example:
|
51
|
+
|
52
|
+
cody logs --since 1m # 1 month ago
|
53
|
+
|
54
|
+
The since format is from the [aws-logs gem](https://github.com/tongueroo/aws-logs). Since formats:
|
55
|
+
|
56
|
+
* s - seconds
|
57
|
+
* m - minutes
|
58
|
+
* h - hours
|
59
|
+
* d - days
|
60
|
+
* w - weeks
|
61
|
+
|
62
|
+
Since does not support combining the formats. IE: 5m30s.
|
data/lib/cody/logs.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
module Cody
|
2
|
+
class Logs
|
3
|
+
include AwsServices
|
4
|
+
|
5
|
+
def initialize(options)
|
6
|
+
@options = options
|
7
|
+
@project_name = options[:project_name] || inferred_project_name
|
8
|
+
@full_project_name = project_name_convention(@project_name)
|
9
|
+
end
|
10
|
+
|
11
|
+
def run
|
12
|
+
Tailer.new(@options, build_id).run
|
13
|
+
rescue Aws::CodeBuild::Errors::ResourceNotFoundException => e
|
14
|
+
puts "ERROR: #{e.class}: #{e.message}".color(:red)
|
15
|
+
puts "CodeBuild project #{@full_project_name} not found."
|
16
|
+
rescue Aws::CodeBuild::Errors::InvalidInputException => e
|
17
|
+
puts "ERROR: #{e.class}: #{e.message}".color(:red)
|
18
|
+
end
|
19
|
+
|
20
|
+
def build_id
|
21
|
+
return @options[:build_id] if @options[:build_id]
|
22
|
+
|
23
|
+
resp = codebuild.list_builds_for_project(project_name: @full_project_name)
|
24
|
+
resp.ids.first # most recent build_id
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/cody/start.rb
CHANGED
@@ -16,10 +16,15 @@ module Cody
|
|
16
16
|
}
|
17
17
|
params[:environment_variables_override] = environment_variables_override if @options[:env_vars]
|
18
18
|
resp = codebuild.start_build(params)
|
19
|
+
|
19
20
|
puts "Build started for project: #{project_name}"
|
20
|
-
puts "
|
21
|
-
puts "CodeBuild Log Url:"
|
21
|
+
puts "Here's the CodeBuild Console Log url:"
|
22
22
|
puts codebuild_log_url(resp.build.id)
|
23
|
+
tail_logs(resp.build.id) if @options[:wait]
|
24
|
+
end
|
25
|
+
|
26
|
+
def tail_logs(build_id)
|
27
|
+
Tailer.new(@options, build_id).run
|
23
28
|
end
|
24
29
|
|
25
30
|
def environment_variables_override
|
data/lib/cody/tailer.rb
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
require "aws-logs"
|
2
|
+
|
3
|
+
module Cody
|
4
|
+
class Tailer
|
5
|
+
include AwsServices
|
6
|
+
|
7
|
+
def initialize(options, build_id)
|
8
|
+
@options, @build_id = options, build_id
|
9
|
+
|
10
|
+
@output = [] # for specs
|
11
|
+
@shown_phases = []
|
12
|
+
@thread = nil
|
13
|
+
set_trap
|
14
|
+
end
|
15
|
+
|
16
|
+
def find_build
|
17
|
+
resp = codebuild.batch_get_builds(ids: [@build_id])
|
18
|
+
resp.builds.first
|
19
|
+
end
|
20
|
+
|
21
|
+
def run
|
22
|
+
puts "Showing logs for build #{@build_id}"
|
23
|
+
complete = false
|
24
|
+
until complete do
|
25
|
+
build = find_build
|
26
|
+
unless build
|
27
|
+
puts "ERROR: Build id not found: #{@build_id}".color(:red)
|
28
|
+
return
|
29
|
+
end
|
30
|
+
print_phases(build)
|
31
|
+
set_log_group_name(build)
|
32
|
+
|
33
|
+
complete = build.build_complete
|
34
|
+
start_cloudwatch_tail unless ENV["CODY_TEST"]
|
35
|
+
sleep 5 if !@@end_loop_signal && !complete && !ENV["CODY_TEST"]
|
36
|
+
end
|
37
|
+
AwsLogs::Tail.stop_follow!
|
38
|
+
@thread.join if @thread
|
39
|
+
end
|
40
|
+
|
41
|
+
def start_cloudwatch_tail
|
42
|
+
return if @cloudwatch_tail_started
|
43
|
+
return unless @log_group_name && @log_stream_name
|
44
|
+
|
45
|
+
@thread = Thread.new do
|
46
|
+
cloudwatch_tail
|
47
|
+
end
|
48
|
+
@cloudwatch_tail_started = true
|
49
|
+
end
|
50
|
+
|
51
|
+
def cloudwatch_tail
|
52
|
+
since = @options[:since] || "7d" # by default, search only 7 days in the past
|
53
|
+
cw_tail = AwsLogs::Tail.new(
|
54
|
+
log_group_name: @log_group_name,
|
55
|
+
log_stream_names: [@log_stream_name],
|
56
|
+
since: since,
|
57
|
+
follow: true,
|
58
|
+
format: "simple",
|
59
|
+
)
|
60
|
+
cw_tail.run
|
61
|
+
end
|
62
|
+
|
63
|
+
# Setting enables start_cloudwatch_tail
|
64
|
+
def set_log_group_name(build)
|
65
|
+
logs = build.logs
|
66
|
+
@log_group_name = logs.group_name if logs.group_name
|
67
|
+
@log_stream_name = logs.stream_name if logs.stream_name
|
68
|
+
end
|
69
|
+
|
70
|
+
def print_phases(build)
|
71
|
+
build.phases.each do |phase|
|
72
|
+
details = {
|
73
|
+
phase_type: phase.phase_type,
|
74
|
+
phase_status: phase.phase_status,
|
75
|
+
start_time: phase.start_time,
|
76
|
+
duration_in_seconds: phase.duration_in_seconds,
|
77
|
+
}
|
78
|
+
display_phase(details)
|
79
|
+
@shown_phases << details
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def display_phase(details)
|
84
|
+
already_shown = @shown_phases.detect do |p|
|
85
|
+
p[:phase_type] == details[:phase_type] &&
|
86
|
+
p[:phase_status] == details[:phase_status] &&
|
87
|
+
p[:start_time] == details[:start_time] &&
|
88
|
+
p[:duration_in_seconds] == details[:duration_in_seconds]
|
89
|
+
end
|
90
|
+
return if already_shown
|
91
|
+
|
92
|
+
status = details[:phase_status]
|
93
|
+
status = status&.include?("FAILED") ? status.color(:red) : status
|
94
|
+
say [
|
95
|
+
"Phase:".color(:green), details[:phase_type],
|
96
|
+
"Status:".color(:purple), status,
|
97
|
+
# "Time: ".color(:purple), details[:start_time],
|
98
|
+
"Duration:".color(:purple), details[:duration_in_seconds],
|
99
|
+
].join(" ")
|
100
|
+
end
|
101
|
+
|
102
|
+
def say(text)
|
103
|
+
ENV["CODY_TEST"] ? @output << text : puts(text)
|
104
|
+
end
|
105
|
+
|
106
|
+
def output
|
107
|
+
@output.join("\n") + "\n"
|
108
|
+
end
|
109
|
+
|
110
|
+
@@end_loop_signal = false
|
111
|
+
def set_trap
|
112
|
+
Signal.trap("INT") {
|
113
|
+
puts "\nCtrl-C detected. Exiting..."
|
114
|
+
@@end_loop_signal = true # useful to control loop
|
115
|
+
exit # immediate exit
|
116
|
+
}
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
data/lib/cody/version.rb
CHANGED
metadata
CHANGED
@@ -1,17 +1,31 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cody
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tung Nguyen
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-11-
|
11
|
+
date: 2019-11-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 6.0.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 6.0.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: aws-logs
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
16
30
|
requirements:
|
17
31
|
- - ">="
|
@@ -230,6 +244,7 @@ extra_rdoc_files: []
|
|
230
244
|
files:
|
231
245
|
- ".cody/buildspec.yml"
|
232
246
|
- ".cody/project.rb"
|
247
|
+
- ".cody/role.rb"
|
233
248
|
- ".cody/settings.yml"
|
234
249
|
- ".gitignore"
|
235
250
|
- ".gitmodules"
|
@@ -268,8 +283,10 @@ files:
|
|
268
283
|
- lib/cody/help/completion_script.md
|
269
284
|
- lib/cody/help/deploy.md
|
270
285
|
- lib/cody/help/init.md
|
286
|
+
- lib/cody/help/logs.md
|
271
287
|
- lib/cody/help/start.md
|
272
288
|
- lib/cody/init.rb
|
289
|
+
- lib/cody/logs.rb
|
273
290
|
- lib/cody/project.rb
|
274
291
|
- lib/cody/role.rb
|
275
292
|
- lib/cody/schedule.rb
|
@@ -277,6 +294,7 @@ files:
|
|
277
294
|
- lib/cody/setting.rb
|
278
295
|
- lib/cody/stack.rb
|
279
296
|
- lib/cody/start.rb
|
297
|
+
- lib/cody/tailer.rb
|
280
298
|
- lib/cody/update.rb
|
281
299
|
- lib/cody/variables.rb
|
282
300
|
- lib/cody/version.rb
|