cody 0.7.3 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1523d8ce4c22cf41cecba80623b9c473e49ff97d4b981972d5e277dde195da05
4
- data.tar.gz: 6deb1ea47229b7471c0f7de73f5d7f21d40aabb64560297b6e320e4a3e85fe9b
3
+ metadata.gz: d8ae54a008252e6ce83388bea8b82a78b6f3fff32724fc822b63d02baa39fdee
4
+ data.tar.gz: 717b8030c9046966f909eef2b64487482e1a8e1819d6e12d43747520499de642
5
5
  SHA512:
6
- metadata.gz: 6051044570a30f31b94ce57bd6a2a514ffd669cf0371ef30c8e14e4b50f57a6f6cc02d126a74d34a0aa2048b43f11f4370419fbaed93ee955cc61a973200227c
7
- data.tar.gz: a45a69611e76dd64d4dd9aac1c11598c1629c666a403f630f095f49cf6d84d407d556d32bf57912d4d487e2b2d58894cc1452b2b1b9976bc22f4bb90fd76d7ce
6
+ metadata.gz: 6a340b073735c12b2166ef78a43d79851c047780074a46f638021c7a0d7c60d8f380e4674ae2be09587f6b00400ced580391af72970cc96236869c108539fafe
7
+ data.tar.gz: 503328e1e3feb629877eb1dc901da9e2e3a52ed1a450b2da299ed662bb3cf38d9506d09ede8a8fccbb470186ebddaceeb4110ce37554d69a3146dc0b7dc17433
data/.cody/project.rb CHANGED
@@ -1,4 +1,7 @@
1
1
  github_url("https://github.com/tongueroo/cody")
2
2
  linux_image("aws/codebuild/ruby:2.5.3-1.7.0")
3
- triggers(webhook: true)
3
+ triggers(
4
+ webhook: true,
5
+ filter_groups: [[{type: "EVENT", pattern: "PUSH"}]]
6
+ )
4
7
  local_cache(false)
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
  [![BoltOps Badge](https://img.boltops.com/boltops/badges/boltops-badge.png)](https://www.boltops.com)
11
11
 
12
- Cody lets you create a AWS CodeBuild projects with a beautiful DSL.
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 `codebuild start`. Examples:
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 "Please check the CodeBuild console for the status."
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
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Cody
2
- VERSION = "0.7.3"
2
+ VERSION = "0.8.0"
3
3
  end
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.7.3
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-20 00:00:00.000000000 Z
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