codebuild 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitmodules +3 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +6 -0
- data/README.md +25 -19
- data/codebuild.gemspec +2 -0
- data/exe/cb +14 -0
- data/img/github-admin-settings-tab.png +0 -0
- data/lib/codebuild/autoloader.rb +21 -0
- data/lib/codebuild/aws_services/helpers.rb +19 -2
- data/lib/codebuild/aws_services.rb +0 -1
- data/lib/codebuild/cli.rb +13 -29
- data/lib/codebuild/completer.rb +0 -2
- data/lib/codebuild/core.rb +61 -0
- data/lib/codebuild/default/settings.yml +3 -0
- data/lib/codebuild/delete.rb +2 -1
- data/lib/codebuild/dsl/project.rb +0 -1
- data/lib/codebuild/evaluate.rb +1 -6
- data/lib/codebuild/init.rb +4 -2
- data/lib/codebuild/project.rb +10 -1
- data/lib/codebuild/sequence.rb +7 -1
- data/lib/codebuild/setting.rb +80 -0
- data/lib/codebuild/stack.rb +46 -7
- data/lib/codebuild/start.rb +17 -6
- data/lib/codebuild/version.rb +1 -1
- data/lib/codebuild.rb +12 -19
- data/lib/template/.codebuild/buildspec.yml +2 -2
- data/lib/template/.codebuild/project.rb.tt +5 -1
- data/lib/template/.codebuild/role.rb +2 -1
- data/readme/github_oauth.md +14 -12
- data/readme/type.md +33 -0
- metadata +41 -5
- data/lib/codebuild/dsl.rb +0 -8
- data/readme/lookup.md +0 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6bcfea57ca3fcb04bc2f1f79e5bbd6ccb8a69cb736b4be4c4c10cd8bebc422db
|
4
|
+
data.tar.gz: 141de3012147451070013d00cfe3ec4d67d8ed3289f143fe37d4d1f7ff57d3cc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dec4e8ba192c051d5b23ab9ca9069e0ea6cfd134fcdb5db210f6cf2d056f5e8a65d0b58d4a92f5ec24b61ed270f0e7d3396ef43b10d18bd12e24979ce32e6921
|
7
|
+
data.tar.gz: 416cb5263cfd06c4691e5f67f016854dca5b3e88fa7342c59358eee8d06ec65d7ee9971382bec3064db6b35aa5e9d2b31d950b57984abd24a4674a7c235b840a
|
data/.gitmodules
ADDED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.5.3
|
data/CHANGELOG.md
CHANGED
@@ -3,6 +3,12 @@
|
|
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.3.0]
|
7
|
+
* rework cb cli interface
|
8
|
+
* project_name as cli main parameter
|
9
|
+
* type option for subprojects in .codebuild folder
|
10
|
+
* update to zeitwerk for autoloading
|
11
|
+
|
6
12
|
## [0.2.0]
|
7
13
|
- First good release.
|
8
14
|
- Project and Role DSL
|
data/README.md
CHANGED
@@ -2,13 +2,19 @@
|
|
2
2
|
|
3
3
|
![Build Status](https://codebuild.us-west-2.amazonaws.com/badges?uuid=eyJlbmNyeXB0ZWREYXRhIjoidHFFaithL1pLZWFEUzBXbk5LY05Mc0FrZW56NDVJWTArbUlOdzBUalVPWWZ5a1ZYUEFtTkhlbFBjeURRZEd1Q292WTI1RUJwWkcvdEgxUXhSYnBqVU9VPSIsIml2UGFyYW1ldGVyU3BlYyI6IjJ0dnpqMC9XMzQ4VExCMGgiLCJtYXRlcmlhbFNldFNlcmlhbCI6MX0%3D&branch=master)
|
4
4
|
|
5
|
-
|
5
|
+
The codebuild tool provides a DSL to create a CodeBuild project with some reasonable defaults.
|
6
|
+
|
7
|
+
The codebuild tool installs `cb` and `codebuild` executables. Both of them do the same thing, `cb` is just shorter to type.
|
6
8
|
|
7
9
|
## Quick Start
|
8
10
|
|
9
|
-
|
10
|
-
|
11
|
-
|
11
|
+
cb init
|
12
|
+
cb deploy
|
13
|
+
cb start
|
14
|
+
|
15
|
+
## Private Repo
|
16
|
+
|
17
|
+
IMPORTANT: Before deploying, if you are using a private repo, use [aws codebuild import-source-credentials](https://docs.aws.amazon.com/cli/latest/reference/codebuild/import-source-credentials.html) to add credentials so that codebuild can clone down the repo. Refer to [github_oauth.md](readme/github_oauth.md) for more info.
|
12
18
|
|
13
19
|
## Usage
|
14
20
|
|
@@ -29,37 +35,37 @@ First, run `codebuild init` to generate a starter .codebuild structure.
|
|
29
35
|
File | Description
|
30
36
|
--- | ---
|
31
37
|
buildspec.yml | The build commands to run.
|
32
|
-
project.rb | The codebuild project
|
33
|
-
role.rb | The IAM role
|
38
|
+
project.rb | The codebuild project written as a DSL.
|
39
|
+
role.rb | The IAM role associated with the codebuild project written as a DSL.
|
34
40
|
|
35
41
|
### Deploy
|
36
42
|
|
37
43
|
Adjust the files in `.codebuild` to fit your needs. When you're ready, deploy the CodeBuild project with:
|
38
44
|
|
39
|
-
|
45
|
+
cb deploy STACK_NAME
|
40
46
|
|
41
47
|
More examples:
|
42
48
|
|
43
|
-
|
44
|
-
|
49
|
+
cb deploy # infers the CloudFormation name from the parent folder
|
50
|
+
cb deploy stack-name # explicitly specify stack name
|
45
51
|
|
46
52
|
It is useful to just see the generated CloudFormation template with `--noop` mode:
|
47
53
|
|
48
|
-
|
54
|
+
cb deploy --noop # see generated CloudFormation template
|
49
55
|
|
50
56
|
For more help:
|
51
57
|
|
52
|
-
|
58
|
+
cb deploy -h
|
53
59
|
|
54
60
|
### Start
|
55
61
|
|
56
62
|
When you are ready to start a codebuild project run, you can use `codebuild start`. Examples:
|
57
63
|
|
58
|
-
|
59
|
-
|
60
|
-
|
64
|
+
cb start # infers the name from the parent folder
|
65
|
+
cb start stack-name # looks up project via CloudFormation stack
|
66
|
+
cb start demo-project # looks up project via CodeBuild project name
|
61
67
|
|
62
|
-
The `
|
68
|
+
The `cb start` command understands multiple identifiers. It will look up the codebuild project either via CloudFormation or the CodeBuild project name.
|
63
69
|
|
64
70
|
## Project DSL
|
65
71
|
|
@@ -68,12 +74,12 @@ The tool provides a DSL to create a codebuild project. Here's an example.
|
|
68
74
|
.codebuild/project.rb:
|
69
75
|
|
70
76
|
```ruby
|
71
|
-
name("demo")
|
77
|
+
# name("demo") # recommended to leave unset and use the conventional name that cb tool sets
|
72
78
|
github_url("https://github.com/tongueroo/demo-ufo")
|
73
79
|
linux_image("aws/codebuild/ruby:2.5.3-1.7.0")
|
74
80
|
environment_variables(
|
75
81
|
UFO_ENV: "development",
|
76
|
-
API_KEY: "ssm:/codebuild/demo/api_key"
|
82
|
+
API_KEY: "ssm:/codebuild/demo/api_key" # ssm param example
|
77
83
|
)
|
78
84
|
```
|
79
85
|
|
@@ -119,9 +125,9 @@ iam_policy(
|
|
119
125
|
|
120
126
|
The convenience DSL methods shown above are short and clean. They merely wrap a DSL that map to the properties of CloudFormation resources like [AWS::CodeBuild::Project](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-codebuild-project.html) and [AWS::IAM::Role](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html). Refer the [Full DSL docs](readme/full_dsl.md) for more info.
|
121
127
|
|
122
|
-
##
|
128
|
+
## Type Option
|
123
129
|
|
124
|
-
By default, the codebuild tool looks up files in the `.codebuild` folder. You can affect the behavior of the
|
130
|
+
By default, the codebuild tool looks up files in the `.codebuild` folder. You can affect the behavior of the Type logic with the `--Type` option. More info [Type docs](readme/type.md).
|
125
131
|
|
126
132
|
## Installation
|
127
133
|
|
data/codebuild.gemspec
CHANGED
@@ -23,7 +23,9 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.add_dependency "aws-sdk-codebuild"
|
24
24
|
spec.add_dependency "aws-sdk-ssm"
|
25
25
|
spec.add_dependency "cfn_camelizer"
|
26
|
+
spec.add_dependency "memoist"
|
26
27
|
spec.add_dependency "rainbow"
|
28
|
+
spec.add_dependency "render_me_pretty"
|
27
29
|
spec.add_dependency "thor"
|
28
30
|
|
29
31
|
spec.add_development_dependency "bundler"
|
data/exe/cb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Trap ^C
|
4
|
+
Signal.trap("INT") {
|
5
|
+
puts "\nCtrl-C detected. Exiting..."
|
6
|
+
sleep 1
|
7
|
+
exit
|
8
|
+
}
|
9
|
+
|
10
|
+
$:.unshift(File.expand_path("../../lib", __FILE__))
|
11
|
+
require "codebuild"
|
12
|
+
require "codebuild/cli"
|
13
|
+
|
14
|
+
Codebuild::CLI.start(ARGV)
|
Binary file
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "zeitwerk"
|
2
|
+
|
3
|
+
module Codebuild
|
4
|
+
class Autoloader
|
5
|
+
class Inflector < Zeitwerk::Inflector
|
6
|
+
def camelize(basename, _abspath)
|
7
|
+
map = { cli: "CLI", version: "VERSION" }
|
8
|
+
map[basename.to_sym] || super
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class << self
|
13
|
+
def setup
|
14
|
+
loader = Zeitwerk::Loader.new
|
15
|
+
loader.inflector = Inflector.new
|
16
|
+
loader.push_dir(File.dirname(__dir__)) # lib
|
17
|
+
loader.setup
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -25,8 +25,25 @@ module Codebuild::AwsServices
|
|
25
25
|
exist
|
26
26
|
end
|
27
27
|
|
28
|
-
def
|
29
|
-
|
28
|
+
def project_name_convention(name_base)
|
29
|
+
[@project_name, @options[:type], Codebuild.env, Codebuild.env_extra].reject(&:blank?).compact.join("-")
|
30
|
+
end
|
31
|
+
|
32
|
+
def inferred_project_name
|
33
|
+
# Essentially the project's parent folder
|
34
|
+
File.basename(Dir.pwd).gsub('_','-').gsub(/\.+/,'-').gsub(/[^0-9a-zA-Z,-]/, '')
|
35
|
+
end
|
36
|
+
|
37
|
+
# Examples:
|
38
|
+
#
|
39
|
+
# myapp-ci-deploy # with Settings stack_naming append_env set to false.
|
40
|
+
# myapp-ci-deploy-development
|
41
|
+
# myapp-ci-deploy-development-2
|
42
|
+
#
|
43
|
+
def inferred_stack_name(project_name)
|
44
|
+
items = [project_name, "cb", @options[:type], Codebuild.env_extra]
|
45
|
+
items.insert(3, Codebuild.env) if Codebuild.settings.dig(:stack_naming, :append_env)
|
46
|
+
items.reject(&:blank?).compact.join("-")
|
30
47
|
end
|
31
48
|
|
32
49
|
def are_you_sure?(stack_name, action)
|
data/lib/codebuild/cli.rb
CHANGED
@@ -10,49 +10,33 @@ module Codebuild
|
|
10
10
|
end
|
11
11
|
register(Init, "init", "init", "Set up initial ufo files.")
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
Dsl.new(options).evaluate
|
17
|
-
end
|
18
|
-
|
19
|
-
deploy_options = Proc.new do
|
20
|
-
option :lookup, desc: "folder to use within .codebuild folder for extra lookups of files"
|
21
|
-
end
|
22
|
-
|
23
|
-
desc "create", "Create codebuild project."
|
24
|
-
long_desc Help.text(:create)
|
25
|
-
deploy_options.call
|
26
|
-
def create(stack_name=nil)
|
27
|
-
Create.new(options.merge(stack_name: stack_name)).run
|
28
|
-
end
|
29
|
-
|
30
|
-
desc "update", "Update codebuild project."
|
31
|
-
long_desc Help.text(:update)
|
32
|
-
deploy_options.call
|
33
|
-
def update(stack_name=nil)
|
34
|
-
Update.new(options.merge(stack_name: stack_name)).run
|
13
|
+
common_options = Proc.new do
|
14
|
+
option :type, desc: "folder to use within .codebuild folder for different build types"
|
15
|
+
option :stack_name, desc: "Override the generated stack name. If you use this you must always specify it"
|
35
16
|
end
|
36
17
|
|
37
18
|
desc "deploy", "Deploy codebuild project."
|
38
19
|
long_desc Help.text(:deploy)
|
39
|
-
|
40
|
-
def deploy(
|
41
|
-
Deploy.new(options.merge(
|
20
|
+
common_options.call
|
21
|
+
def deploy(project_name=nil)
|
22
|
+
Deploy.new(options.merge(project_name: project_name)).run
|
42
23
|
end
|
43
24
|
|
44
25
|
desc "delete", "Delete codebuild project."
|
45
26
|
long_desc Help.text(:delete)
|
46
27
|
option :sure, desc: "Bypass are you sure prompt"
|
47
|
-
|
48
|
-
|
28
|
+
common_options.call
|
29
|
+
def delete(project_name=nil)
|
30
|
+
Delete.new(options.merge(project_name: project_name)).run
|
49
31
|
end
|
50
32
|
|
51
33
|
desc "start", "start codebuild project."
|
52
34
|
long_desc Help.text(:start)
|
53
35
|
option :source_version, default: "master", desc: "git branch"
|
54
|
-
|
55
|
-
|
36
|
+
option :branch, aliases: "b", default: "master", desc: "git branch"
|
37
|
+
common_options.call
|
38
|
+
def start(project_name=nil)
|
39
|
+
Start.new(options.merge(project_name: project_name)).run
|
56
40
|
end
|
57
41
|
|
58
42
|
desc "completion *PARAMS", "Prints words for auto-completion."
|
data/lib/codebuild/completer.rb
CHANGED
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
module Codebuild
|
5
|
+
module Core
|
6
|
+
extend Memoist
|
7
|
+
|
8
|
+
def root
|
9
|
+
path = ENV['CB_ROOT'] || '.'
|
10
|
+
Pathname.new(path)
|
11
|
+
end
|
12
|
+
|
13
|
+
def env
|
14
|
+
# 2-way binding
|
15
|
+
cb_env = env_from_profile || 'development'
|
16
|
+
cb_env = ENV['CB_ENV'] if ENV['CB_ENV'] # highest precedence
|
17
|
+
cb_env
|
18
|
+
end
|
19
|
+
memoize :env
|
20
|
+
|
21
|
+
def env_extra
|
22
|
+
env_extra = ENV['CB_ENV_EXTRA'] if ENV['CB_ENV_EXTRA'] # highest precedence
|
23
|
+
return if env_extra&.empty?
|
24
|
+
env_extra
|
25
|
+
end
|
26
|
+
memoize :env_extra
|
27
|
+
|
28
|
+
# Overrides AWS_PROFILE based on the Codebuild.env if set in configs/settings.yml
|
29
|
+
# 2-way binding.
|
30
|
+
def set_aws_profile!
|
31
|
+
return if ENV['TEST']
|
32
|
+
return unless File.exist?("#{Codebuild.root}/.codebuild/settings.yml") # for rake docs
|
33
|
+
return unless settings # Only load if within Codebuild project and there's a settings.yml
|
34
|
+
data = settings[Codebuild.env] || {}
|
35
|
+
if data["aws_profile"]
|
36
|
+
puts "Using AWS_PROFILE=#{data["aws_profile"]} from CB_ENV=#{Codebuild.env} in config/settings.yml"
|
37
|
+
ENV['AWS_PROFILE'] = data["aws_profile"]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def settings
|
42
|
+
Setting.new.data
|
43
|
+
end
|
44
|
+
memoize :settings
|
45
|
+
|
46
|
+
def check_codebuild_project!
|
47
|
+
check_path = "#{Codebuild.root}/.codebuild/settings.yml"
|
48
|
+
unless File.exist?(check_path)
|
49
|
+
puts "ERROR: No settings file at #{check_path}. Are you sure you are in a project with codebuild setup?".color(:red)
|
50
|
+
puts "Current directory: #{Dir.pwd}"
|
51
|
+
puts "If you want to set up codebuild for this prjoect, please create a settings file via: codebuild init"
|
52
|
+
exit 1 unless ENV['TEST']
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
def env_from_profile
|
58
|
+
Codebuild::Setting.new.cb_env
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/lib/codebuild/delete.rb
CHANGED
@@ -4,7 +4,8 @@ module Codebuild
|
|
4
4
|
|
5
5
|
def initialize(options)
|
6
6
|
@options = options
|
7
|
-
@
|
7
|
+
@project_name = options[:project_name] || inferred_project_name
|
8
|
+
@stack_name = options[:stack_name] || inferred_stack_name(@project_name)
|
8
9
|
end
|
9
10
|
|
10
11
|
def run
|
data/lib/codebuild/evaluate.rb
CHANGED
@@ -41,12 +41,7 @@ module Codebuild
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def lookup_codebuild_file(name)
|
44
|
-
|
45
|
-
if File.exist?(folder_path)
|
46
|
-
folder_path
|
47
|
-
else
|
48
|
-
".codebuild/#{name}" # default
|
49
|
-
end
|
44
|
+
[".codebuild", @options[:type], name].compact.join("/")
|
50
45
|
end
|
51
46
|
end
|
52
47
|
end
|
data/lib/codebuild/init.rb
CHANGED
@@ -20,7 +20,7 @@ module Codebuild
|
|
20
20
|
def set_source_path
|
21
21
|
return unless @options[:template]
|
22
22
|
|
23
|
-
custom_template = "#{ENV['HOME']}/.codebuild/templates/#{
|
23
|
+
custom_template = "#{ENV['HOME']}/.codebuild/templates/#{full_repo_name}"
|
24
24
|
|
25
25
|
if @options[:template_mode] == "replace" # replace the template entirely
|
26
26
|
override_source_paths(custom_template)
|
@@ -69,7 +69,9 @@ module Codebuild
|
|
69
69
|
end
|
70
70
|
end
|
71
71
|
versions = versions.select { |v| v =~ pattern }
|
72
|
-
|
72
|
+
# IE: aws/codebuild/ruby:2.5.3-1.7.0
|
73
|
+
# Falls back to hard-coded image name since the API changed and looks like it's returning no ruby images
|
74
|
+
versions.sort.last || "aws/codebuild/ruby:2.5.3-1.7.0"
|
73
75
|
end
|
74
76
|
end
|
75
77
|
end
|
data/lib/codebuild/project.rb
CHANGED
@@ -5,13 +5,20 @@ module Codebuild
|
|
5
5
|
include Dsl::Project
|
6
6
|
include Evaluate
|
7
7
|
|
8
|
+
attr_reader :project_name, :full_project_name, :project_path
|
8
9
|
def initialize(options={})
|
9
10
|
@options = options
|
11
|
+
@project_name = options[:project_name]
|
12
|
+
@full_project_name = options[:full_project_name] # includes -development at the end
|
10
13
|
@project_path = options[:project_path] || get_project_path
|
11
14
|
# These defaults make it the project.rb simpler
|
12
15
|
@properties = default_properties
|
13
16
|
end
|
14
17
|
|
18
|
+
def exist?
|
19
|
+
File.exist?(@project_path)
|
20
|
+
end
|
21
|
+
|
15
22
|
def run
|
16
23
|
evaluate(@project_path)
|
17
24
|
resource = {
|
@@ -25,6 +32,8 @@ module Codebuild
|
|
25
32
|
|
26
33
|
def default_properties
|
27
34
|
{
|
35
|
+
name: @full_project_name,
|
36
|
+
description: @full_project_name,
|
28
37
|
artifacts: { type: "NO_ARTIFACTS" },
|
29
38
|
service_role: { ref: "IamRole" },
|
30
39
|
badge_enabled: true,
|
@@ -38,7 +47,7 @@ module Codebuild
|
|
38
47
|
source: {
|
39
48
|
type: "GITHUB",
|
40
49
|
# location: "", # required
|
41
|
-
git_clone_depth: 1,
|
50
|
+
# git_clone_depth: 1,
|
42
51
|
git_submodules_config: { fetch_submodules: true },
|
43
52
|
build_spec: build_spec,
|
44
53
|
# auth doesnt seem to work, refer to https://github.com/tongueroo/codebuild/blob/master/readme/github_oauth.md
|
data/lib/codebuild/sequence.rb
CHANGED
@@ -29,7 +29,7 @@ module Codebuild
|
|
29
29
|
abort "Unable to detect git installation on your system. Git needs to be installed in order to use the --template option."
|
30
30
|
end
|
31
31
|
|
32
|
-
template_path = "#{ENV['HOME']}/.codebuild/templates/#{
|
32
|
+
template_path = "#{ENV['HOME']}/.codebuild/templates/#{full_repo_name}"
|
33
33
|
if File.exist?(template_path)
|
34
34
|
sh("cd #{template_path} && git pull")
|
35
35
|
else
|
@@ -38,6 +38,12 @@ module Codebuild
|
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
+
def full_repo_name
|
42
|
+
full_repo = options[:template].split("/")[-2..-1].join("/")
|
43
|
+
full_repo = full_repo.split(":").last
|
44
|
+
full_repo.sub(".git", "")
|
45
|
+
end
|
46
|
+
|
41
47
|
# normalize repo_url
|
42
48
|
def repo_url
|
43
49
|
template = options[:template]
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'render_me_pretty'
|
3
|
+
|
4
|
+
module Codebuild
|
5
|
+
class Setting
|
6
|
+
extend Memoist
|
7
|
+
def initialize(check_codebuild_project=true)
|
8
|
+
@check_codebuild_project = check_codebuild_project
|
9
|
+
end
|
10
|
+
|
11
|
+
# data contains the settings.yml config. The order or precedence for settings
|
12
|
+
# is the project ufo/settings.yml and then the ~/.codebuild/settings.yml.
|
13
|
+
def data
|
14
|
+
if @check_codebuild_project && !File.exist?(project_settings_path)
|
15
|
+
Codebuild.check_codebuild_project!
|
16
|
+
end
|
17
|
+
|
18
|
+
# project based settings files
|
19
|
+
project = load_file(project_settings_path)
|
20
|
+
|
21
|
+
user_file = "#{ENV['HOME']}/.codebuild/settings.yml"
|
22
|
+
user = File.exist?(user_file) ? YAML.load_file(user_file) : {}
|
23
|
+
|
24
|
+
default_file = File.expand_path("default/settings.yml", __dir__)
|
25
|
+
default = load_file(default_file)
|
26
|
+
|
27
|
+
all_envs = default.deep_merge(user.deep_merge(project))
|
28
|
+
all_envs = merge_base(all_envs)
|
29
|
+
data = all_envs[cb_env] || all_envs["base"] || {}
|
30
|
+
data.deep_symbolize_keys
|
31
|
+
end
|
32
|
+
memoize :data
|
33
|
+
|
34
|
+
# Resolves infinite problem since Codebuild.env can be determined from CB_ENV or settings.yml files.
|
35
|
+
# When ufo is determined from settings it should not called Codebuild.env since that in turn calls
|
36
|
+
# Settings.new.data which can then cause an infinite loop.
|
37
|
+
def cb_env
|
38
|
+
settings = YAML.load_file("#{cb_root}/.codebuild/settings.yml")
|
39
|
+
env = settings.find do |_env, section|
|
40
|
+
section ||= {}
|
41
|
+
ENV['AWS_PROFILE'] && ENV['AWS_PROFILE'] == section['aws_profile']
|
42
|
+
end
|
43
|
+
|
44
|
+
cb_env = env.first if env
|
45
|
+
cb_env = ENV['CB_ENV'] if ENV['CB_ENV'] # highest precedence
|
46
|
+
cb_env || 'development'
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
def load_file(path)
|
51
|
+
return Hash.new({}) unless File.exist?(path)
|
52
|
+
|
53
|
+
content = RenderMePretty.result(path)
|
54
|
+
data = YAML.load(content)
|
55
|
+
# If key is is accidentally set to nil it screws up the merge_base later.
|
56
|
+
# So ensure that all keys with nil value are set to {}
|
57
|
+
data.each do |env, _setting|
|
58
|
+
data[env] ||= {}
|
59
|
+
end
|
60
|
+
data
|
61
|
+
end
|
62
|
+
|
63
|
+
# automatically add base settings to the rest of the environments
|
64
|
+
def merge_base(all_envs)
|
65
|
+
base = all_envs["base"] || {}
|
66
|
+
all_envs.each do |env, settings|
|
67
|
+
all_envs[env] = base.merge(settings) unless env == "base"
|
68
|
+
end
|
69
|
+
all_envs
|
70
|
+
end
|
71
|
+
|
72
|
+
def project_settings_path
|
73
|
+
"#{cb_root}/.codebuild/settings.yml"
|
74
|
+
end
|
75
|
+
|
76
|
+
def cb_root
|
77
|
+
ENV["CODEBUILD_ROOT"] || Dir.pwd
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
data/lib/codebuild/stack.rb
CHANGED
@@ -6,12 +6,28 @@ module Codebuild
|
|
6
6
|
|
7
7
|
def initialize(options)
|
8
8
|
@options = options
|
9
|
-
@
|
10
|
-
@
|
9
|
+
@project_name = @options[:project_name] || inferred_project_name
|
10
|
+
@stack_name = options[:stack_name] || inferred_stack_name(@project_name)
|
11
|
+
|
12
|
+
@full_project_name = project_name_convention(@project_name)
|
13
|
+
@template = {
|
14
|
+
"Description" => "CodeBuild Project: #{@full_project_name}",
|
15
|
+
"Resources" => {}
|
16
|
+
}
|
11
17
|
end
|
12
18
|
|
13
19
|
def run
|
14
|
-
|
20
|
+
options = @options.merge(
|
21
|
+
project_name: @project_name,
|
22
|
+
full_project_name: @full_project_name,
|
23
|
+
)
|
24
|
+
project_builder = Project.new(options)
|
25
|
+
unless project_builder.exist?
|
26
|
+
puts "ERROR: Codebuild project does not exist: #{project_builder.project_path}".color(:red)
|
27
|
+
exit 1
|
28
|
+
return
|
29
|
+
end
|
30
|
+
project = project_builder.run
|
15
31
|
@template["Resources"].merge!(project)
|
16
32
|
|
17
33
|
if project["CodeBuild"]["Properties"]["ServiceRole"] == {"Ref"=>"IamRole"}
|
@@ -19,16 +35,39 @@ module Codebuild
|
|
19
35
|
@template["Resources"].merge!(role)
|
20
36
|
end
|
21
37
|
|
22
|
-
|
23
|
-
|
38
|
+
template_path = "/tmp/codebuild.yml"
|
39
|
+
FileUtils.mkdir_p(File.dirname(template_path))
|
40
|
+
IO.write(template_path, YAML.dump(@template))
|
41
|
+
puts "Generated CloudFormation template at #{template_path.color(:green)}"
|
24
42
|
return if @options[:noop]
|
43
|
+
puts "Deploying stack #{@stack_name.color(:green)} with CodeBuild project #{@full_project_name.color(:green)}"
|
25
44
|
|
26
45
|
begin
|
27
46
|
perform
|
47
|
+
url_info
|
48
|
+
status.wait
|
49
|
+
exit 2 unless status.success?
|
28
50
|
rescue Aws::CloudFormation::Errors::ValidationError => e
|
29
|
-
|
30
|
-
|
51
|
+
if e.message.include?("No updates") # No updates are to be performed.
|
52
|
+
puts "WARN: #{e.message}".color(:yellow)
|
53
|
+
else
|
54
|
+
puts "ERROR: #{e.message}".color(:red)
|
55
|
+
exit 1
|
56
|
+
end
|
31
57
|
end
|
32
58
|
end
|
59
|
+
|
60
|
+
private
|
61
|
+
def url_info
|
62
|
+
stack = cfn.describe_stacks(stack_name: @stack_name).stacks.first
|
63
|
+
region = `aws configure get region`.strip rescue "us-east-1"
|
64
|
+
url = "https://console.aws.amazon.com/cloudformation/home?region=#{region}#/stacks"
|
65
|
+
puts "Stack name #{@stack_name.color(:yellow)} status #{stack["stack_status"].color(:yellow)}"
|
66
|
+
puts "Here's the CloudFormation url to check for more details #{url}"
|
67
|
+
end
|
68
|
+
|
69
|
+
def status
|
70
|
+
@status ||= Cfn::Status.new(@stack_name)
|
71
|
+
end
|
33
72
|
end
|
34
73
|
end
|
data/lib/codebuild/start.rb
CHANGED
@@ -4,26 +4,31 @@ module Codebuild
|
|
4
4
|
|
5
5
|
def initialize(options)
|
6
6
|
@options = options
|
7
|
-
@
|
7
|
+
@project_name = options[:project_name] || inferred_project_name
|
8
|
+
@full_project_name = project_name_convention(@project_name)
|
8
9
|
end
|
9
10
|
|
10
11
|
def run
|
12
|
+
source_version = @options[:branch] || @options[:source_version] || 'master'
|
11
13
|
resp = codebuild.start_build(
|
12
14
|
project_name: project_name,
|
13
|
-
source_version:
|
15
|
+
source_version: source_version
|
14
16
|
)
|
15
17
|
puts "Build started for project: #{project_name}"
|
18
|
+
puts "Please check the CodeBuild console for the status."
|
19
|
+
puts "Codebuild Log Url:"
|
20
|
+
puts codebuild_log_url(resp.build.id)
|
16
21
|
end
|
17
22
|
|
18
23
|
def project_name
|
19
|
-
if
|
20
|
-
|
24
|
+
if project_exists?(@full_project_name)
|
25
|
+
@full_project_name
|
26
|
+
elsif stack_exists?(@project_name) # allow `cb start STACK_NAME` to work too
|
27
|
+
resp = cfn.describe_stack_resources(stack_name: @project_name)
|
21
28
|
resource = resp.stack_resources.find do |r|
|
22
29
|
r.logical_resource_id == "CodeBuild"
|
23
30
|
end
|
24
31
|
resource.physical_resource_id # codebuild project name
|
25
|
-
elsif project_exists?(@identifier)
|
26
|
-
@identifier
|
27
32
|
else
|
28
33
|
puts "ERROR: Unable to find the codebuild project with identifier #@identifier".color(:red)
|
29
34
|
exit 1
|
@@ -31,6 +36,12 @@ module Codebuild
|
|
31
36
|
end
|
32
37
|
|
33
38
|
private
|
39
|
+
def codebuild_log_url(build_id)
|
40
|
+
build_id = build_id.split(':').last
|
41
|
+
region = `aws configure get region`.strip rescue "us-east-1"
|
42
|
+
"https://#{region}.console.aws.amazon.com/codesuite/codebuild/projects/#{project_name}/build/#{project_name}%3A#{build_id}/log"
|
43
|
+
end
|
44
|
+
|
34
45
|
def project_exists?(name)
|
35
46
|
resp = codebuild.batch_get_projects(names: [name])
|
36
47
|
resp.projects.size > 0
|
data/lib/codebuild/version.rb
CHANGED
data/lib/codebuild.rb
CHANGED
@@ -2,26 +2,19 @@ $:.unshift(File.expand_path("../", __FILE__))
|
|
2
2
|
require "cfn_camelizer"
|
3
3
|
require "codebuild/version"
|
4
4
|
require "rainbow/ext/string"
|
5
|
+
require "yaml"
|
6
|
+
|
7
|
+
require "codebuild/autoloader"
|
8
|
+
Codebuild::Autoloader.setup
|
9
|
+
|
10
|
+
gem_root = File.dirname(__dir__)
|
11
|
+
$:.unshift("#{gem_root}/vendor/cfn-status/lib")
|
12
|
+
require "cfn/status"
|
5
13
|
|
6
14
|
module Codebuild
|
7
15
|
class Error < StandardError; end
|
8
|
-
|
9
|
-
autoload :AwsServices, "codebuild/aws_services"
|
10
|
-
autoload :CLI, "codebuild/cli"
|
11
|
-
autoload :Command, "codebuild/command"
|
12
|
-
autoload :Completer, "codebuild/completer"
|
13
|
-
autoload :Completion, "codebuild/completion"
|
14
|
-
autoload :Create, "codebuild/create"
|
15
|
-
autoload :Delete, "codebuild/delete"
|
16
|
-
autoload :Deploy, "codebuild/deploy"
|
17
|
-
autoload :Dsl, "codebuild/dsl"
|
18
|
-
autoload :Evaluate, "codebuild/evaluate"
|
19
|
-
autoload :Help, "codebuild/help"
|
20
|
-
autoload :Init, "codebuild/init"
|
21
|
-
autoload :Project, "codebuild/project"
|
22
|
-
autoload :Role, "codebuild/role"
|
23
|
-
autoload :Sequence, "codebuild/sequence"
|
24
|
-
autoload :Stack, "codebuild/stack"
|
25
|
-
autoload :Start, "codebuild/start"
|
26
|
-
autoload :Update, "codebuild/update"
|
16
|
+
extend Core
|
27
17
|
end
|
18
|
+
|
19
|
+
|
20
|
+
Codebuild.set_aws_profile!
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# For methods, refer to the properties of the CloudFormation CodeBuild::Project https://amzn.to/2UTeNlr
|
2
2
|
# For convenience methods, refer to the source https://github.com/tongueroo/codebuild/blob/master/lib/codebuild/dsl/project.rb
|
3
3
|
|
4
|
-
name("
|
4
|
+
# name("example-project-name") # recommend leaving unset and codebuild will use a conventional name
|
5
5
|
github_url("<%= project_github_url %>")
|
6
6
|
linux_image("<%= lookup_managed_image(/ruby:/) %>")
|
7
7
|
environment_variables(
|
@@ -9,6 +9,10 @@ environment_variables(
|
|
9
9
|
# API_KEY: "ssm:/codebuild/demo/api_key" # Example of ssm parameter
|
10
10
|
)
|
11
11
|
|
12
|
+
# Some useful helpers:
|
13
|
+
# puts "project_name #{project_name}" # IE: demo-web
|
14
|
+
# puts "full_project_name #{full_project_name}" # demo-web-development
|
15
|
+
|
12
16
|
# Uncomment to enable github webhook, the GitHub oauth token needs admin:repo_hook permissions
|
13
17
|
# Refer to https://github.com/tongueroo/codebuild/blob/master/readme/github_oauth.md
|
14
18
|
# triggers(webhook: true)
|
@@ -1 +1,2 @@
|
|
1
|
-
|
1
|
+
# Example:
|
2
|
+
# iam_policy("logs", "ssm")
|
data/readme/github_oauth.md
CHANGED
@@ -4,9 +4,22 @@ Thought that we need to set the oauth token as part of the CloudFormation templa
|
|
4
4
|
|
5
5
|
Instead this guide [Using Access Tokens with Your Source Provider in CodeBuild](https://docs.aws.amazon.com/codebuild/latest/userguide/sample-access-tokens.html) with [aws codebuild import-source-credentials](https://docs.aws.amazon.com/cli/latest/reference/codebuild/import-source-credentials.html) worked.
|
6
6
|
|
7
|
+
## Create the GitHub Oauth Token
|
8
|
+
|
9
|
+
One way to create an GitHub oauth token:
|
10
|
+
|
11
|
+
1. Go to GitHub
|
12
|
+
2. Settings
|
13
|
+
3. Developer Settings
|
14
|
+
4. Personal access tokens
|
15
|
+
|
16
|
+
IMPORTANT: If using webhook, the oauth token needs `admin:repo_hook` also. To check this, you can log into the github, go to the repo, and see if you have access to the "Settings" tab.
|
17
|
+
|
18
|
+
![](https://raw.githubusercontent.com/tongueroo/codebuild/master/img/github-admin-settings-tab.png)
|
19
|
+
|
7
20
|
## Commands
|
8
21
|
|
9
|
-
Here are the commands for posterity.
|
22
|
+
Here are the import-source-credentials commands for posterity.
|
10
23
|
|
11
24
|
Save the GitHub oauth token to parameter store, in case we need it in the future.
|
12
25
|
|
@@ -24,14 +37,3 @@ Import the source credential into codebuild.
|
|
24
37
|
EOL
|
25
38
|
aws codebuild import-source-credentials --cli-input-json file:///tmp/codebuild-source-credentials.json
|
26
39
|
aws codebuild list-source-credentials
|
27
|
-
|
28
|
-
## Creating the GitHub Oauth Token
|
29
|
-
|
30
|
-
One way to create an GitHub oauth token:
|
31
|
-
|
32
|
-
1. Go to GitHub
|
33
|
-
2. Settings
|
34
|
-
3. Developer Settings
|
35
|
-
4. Personal access tokens
|
36
|
-
|
37
|
-
If using webhook, the oauth token needs `admin:repo_hook` also.
|
data/readme/type.md
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# Type Option
|
2
|
+
|
3
|
+
By default, the codebuild tool looks up files in the `.codebuild` folder. You can affect the behavior of the lookup logic with the `--type` option.
|
4
|
+
|
5
|
+
## Examples
|
6
|
+
|
7
|
+
cb deploy --type deploy
|
8
|
+
|
9
|
+
This will look up buildspec.yml, project.rb, and role.rb files in the `.codebuild/deploy` folder. So:
|
10
|
+
|
11
|
+
.codebuild/deploy/buildspec.yml
|
12
|
+
.codebuild/deploy/project.rb
|
13
|
+
.codebuild/deploy/role.rb
|
14
|
+
|
15
|
+
Likewise `cb deploy --type unit` would result in:
|
16
|
+
|
17
|
+
.codebuild/unit/buildspec.yml
|
18
|
+
.codebuild/unit/project.rb
|
19
|
+
.codebuild/unit/role.rb
|
20
|
+
|
21
|
+
## Type Stack Name
|
22
|
+
|
23
|
+
The CloudFormation stack name is appended with the name of the type option. So if you project folder is `demo` and the type option is `unit`.
|
24
|
+
|
25
|
+
cd demo # project folder
|
26
|
+
cb deploy --type deploy
|
27
|
+
|
28
|
+
It produces an inferred stack name of `demo-cb-deploy-development`. You can override the CloudFormation stack name by specifying the project name explicitly. The project name is an optional first argument. Here's an example:
|
29
|
+
|
30
|
+
cd demo # project folder
|
31
|
+
cb deploy demo-web --type deploy # stack name: demo-web-cb-deploy-development
|
32
|
+
|
33
|
+
You can also override the stack name with the `--stack-name` option.
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: codebuild
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.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
|
+
date: 2019-06-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: memoist
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: rainbow
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,6 +108,20 @@ dependencies:
|
|
94
108
|
- - ">="
|
95
109
|
- !ruby/object:Gem::Version
|
96
110
|
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: render_me_pretty
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
97
125
|
- !ruby/object:Gem::Dependency
|
98
126
|
name: thor
|
99
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -182,6 +210,7 @@ description:
|
|
182
210
|
email:
|
183
211
|
- tongueroo@gmail.com
|
184
212
|
executables:
|
213
|
+
- cb
|
185
214
|
- codebuild
|
186
215
|
extensions: []
|
187
216
|
extra_rdoc_files: []
|
@@ -189,7 +218,9 @@ files:
|
|
189
218
|
- ".codebuild/buildspec.yml"
|
190
219
|
- ".codebuild/project.rb"
|
191
220
|
- ".gitignore"
|
221
|
+
- ".gitmodules"
|
192
222
|
- ".rspec"
|
223
|
+
- ".ruby-version"
|
193
224
|
- CHANGELOG.md
|
194
225
|
- Gemfile
|
195
226
|
- Guardfile
|
@@ -197,8 +228,11 @@ files:
|
|
197
228
|
- README.md
|
198
229
|
- Rakefile
|
199
230
|
- codebuild.gemspec
|
231
|
+
- exe/cb
|
200
232
|
- exe/codebuild
|
233
|
+
- img/github-admin-settings-tab.png
|
201
234
|
- lib/codebuild.rb
|
235
|
+
- lib/codebuild/autoloader.rb
|
202
236
|
- lib/codebuild/aws_services.rb
|
203
237
|
- lib/codebuild/aws_services/helpers.rb
|
204
238
|
- lib/codebuild/cli.rb
|
@@ -206,10 +240,11 @@ files:
|
|
206
240
|
- lib/codebuild/completer.rb
|
207
241
|
- lib/codebuild/completer/script.rb
|
208
242
|
- lib/codebuild/completer/script.sh
|
243
|
+
- lib/codebuild/core.rb
|
209
244
|
- lib/codebuild/create.rb
|
245
|
+
- lib/codebuild/default/settings.yml
|
210
246
|
- lib/codebuild/delete.rb
|
211
247
|
- lib/codebuild/deploy.rb
|
212
|
-
- lib/codebuild/dsl.rb
|
213
248
|
- lib/codebuild/dsl/project.rb
|
214
249
|
- lib/codebuild/dsl/project/ssm.rb
|
215
250
|
- lib/codebuild/dsl/role.rb
|
@@ -224,6 +259,7 @@ files:
|
|
224
259
|
- lib/codebuild/project.rb
|
225
260
|
- lib/codebuild/role.rb
|
226
261
|
- lib/codebuild/sequence.rb
|
262
|
+
- lib/codebuild/setting.rb
|
227
263
|
- lib/codebuild/stack.rb
|
228
264
|
- lib/codebuild/start.rb
|
229
265
|
- lib/codebuild/update.rb
|
@@ -233,7 +269,7 @@ files:
|
|
233
269
|
- lib/template/.codebuild/role.rb
|
234
270
|
- readme/full_dsl.md
|
235
271
|
- readme/github_oauth.md
|
236
|
-
- readme/
|
272
|
+
- readme/type.md
|
237
273
|
- spec/fixtures/app/.codebuild/project.rb
|
238
274
|
- spec/fixtures/app/.codebuild/role.rb
|
239
275
|
- spec/lib/cli_spec.rb
|
@@ -259,7 +295,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
259
295
|
- !ruby/object:Gem::Version
|
260
296
|
version: '0'
|
261
297
|
requirements: []
|
262
|
-
rubygems_version: 3.0.
|
298
|
+
rubygems_version: 3.0.3
|
263
299
|
signing_key:
|
264
300
|
specification_version: 4
|
265
301
|
summary: CodeBuild DSL Tool to Quickly Create CodeBuild Project
|
data/lib/codebuild/dsl.rb
DELETED
data/readme/lookup.md
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
# Lookup Paths
|
2
|
-
|
3
|
-
By default, the codebuild tool looks up files in the `.codebuild` folder. You can affect the behavior of the lookup logic with the `--lookup` option.
|
4
|
-
|
5
|
-
## Example 1
|
6
|
-
|
7
|
-
codebuild deploy --lookup unit
|
8
|
-
|
9
|
-
This will look up buildspec.yml, project.rb, and role.rb files in the `.codebuild/unit` folder first. If files are found, then it will use those files in that folder. If not found, it'll fall back to the `.codebuild` parent folder.
|
10
|
-
|
11
|
-
Lookup order with `--lookup unit` for `buildspec.yml`:
|
12
|
-
|
13
|
-
1. .codebuild/unit/buildspec.yml
|
14
|
-
2. .codebuild/buildspec.yml
|
15
|
-
|
16
|
-
Lookup order with `--lookup unit` for `project.rb`:
|
17
|
-
|
18
|
-
1. .codebuild/unit/project.rb
|
19
|
-
2. .codebuild/project.rb
|
20
|
-
|
21
|
-
The same goes other files in the `.codebuild` like `role.rb`.
|
22
|
-
|
23
|
-
## Example 2
|
24
|
-
|
25
|
-
Here's another example:
|
26
|
-
|
27
|
-
codebuild deploy --lookup deploy
|
28
|
-
|
29
|
-
Lookup order with `--lookup deploy` for `buildspec.yml`:
|
30
|
-
|
31
|
-
1. .codebuild/deploy/buildspec.yml
|
32
|
-
2. .codebuild/buildspec.yml
|
33
|
-
|
34
|
-
The same goes other files in the `.codebuild` like `project.rb` and `role.rb`.
|