build_spec_runner 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 35382674855121efe797abd6329e163abe23c3bb
4
+ data.tar.gz: 6c65f76c371144c0a5f4360f4c237e4cf368685a
5
+ SHA512:
6
+ metadata.gz: 6b4bc59acb06804758e3d646705ce66839a6ae4940e9e18eeaeb086c50037adcd6bea238c6100573915f626c317e1a331e80cf2af4c0be70c1da4e83a55bf878
7
+ data.tar.gz: 3a0bba4b3f1253b6da766d6ea5d6699999bb8faaaf671dcf3c36d31fe2edb1fe3bbf5d12cd1cd595ccb8a15982618802fa2f4181899d4807356e21bd08af296a
@@ -0,0 +1,15 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+
11
+ # rspec failure tracking
12
+ .rspec_status
13
+
14
+ # built gems
15
+ *.gem
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.1
5
+ before_install: gem install bundler -v 1.15.1
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at jzuber4@gmail.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in build_spec_runner.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Jimmy Zuber
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,98 @@
1
+ # BuildSpecRunner
2
+
3
+ [![Gem Version](https://img.shields.io/gem/v/build_spec_runner.svg)](https://rubygems.org/gems/build_spec_runner)
4
+ [![Code Climate](https://img.shields.io/codeclimate/github/jzuber4/build_spec_runner.svg)](https://codeclimate.com/github/jzuber4/build_spec_runner)
5
+ [![Gemnasium](https://img.shields.io/gemnasium/jzuber4/build_spec_runner.svg)](https://gemnasium.com/github.com/jzuber4/build_spec_runner/)
6
+
7
+ BuildSpecRunner is a utility for running [AWS CodeBuild](https://aws.amazon.com/codebuild/) ```build_spec.yml``` files. It does so by running the project locally in a Docker container, trying to mirror the execution semantics of CodeBuild as much as possible. It is primarily useful as a CLI utility but can also be used as a library.
8
+
9
+ Currently *unsupported* features:
10
+
11
+ * Build artifact export -- BuildSpecRunner will not export your build artifacts. It essentially ignores the "artifacts" section of the Build Spec file.
12
+ * [Build Environment Variables](http://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-env-vars.html) -- BuildSpecRunner does not specify all the same environment variables as AWS CodeBuild. It does support environment variables declared in the Build Spec file.
13
+
14
+ ## Installation
15
+
16
+ ### Dependencies
17
+
18
+ BuildSpecRunner requires Docker. See the [Docker installation instructions](https://docs.docker.com/engine/installation/).
19
+ If you wish to be able to execute docker without root, you may want to follow the [Linux Post-Installation Instructions](https://docs.docker.com/engine/installation/linux/linux-postinstall/). Please be aware of the security risks of doing so.
20
+
21
+ BuildSpecRunner tries to attach [AWS STS](http://docs.aws.amazon.com/STS/latest/APIReference/Welcome.html) credentials to the Docker container by default. It is recommended that you [configure the AWS CLI](http://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html) to enable this functionality. This lets you run any actions in your project that require AWS authentication. You may choose the AWS profile to use, otherwise it falls back to the configured default.
22
+
23
+ ### CLI utility installation
24
+
25
+ $ gem install build_spec_runner
26
+
27
+ ### Library installation
28
+
29
+ Add this line to your application's Gemfile:
30
+
31
+ ```ruby
32
+ gem 'build_spec_runner'
33
+ ```
34
+
35
+ And then execute:
36
+
37
+ $ bundle
38
+
39
+ Or install it yourself as:
40
+
41
+ $ gem install build_spec_runner
42
+
43
+ ## Usage
44
+
45
+ Execute a project located at a directory, given the default ```buildspec.yml``` Build Spec filename:
46
+
47
+ $ build_spec_runner -p /path/to/project/
48
+
49
+ Specify a different Build Spec filepath with ```--build_spec_path```:
50
+
51
+ $ build_spec_runner -p /path/to/project/ --build_spec_path ./my_build_spec_so_unique.yml
52
+
53
+ Relative and absolute paths are OK:
54
+
55
+ $ build_spec_runner -p ../project/ --build_spec_path /path/to/build/spec/bs.yml
56
+
57
+ You can silence BuildSpecRunner's debug output with ```-q``` or ```--quiet```:
58
+
59
+ $ build_spec_runner -p /path/to/project/ --quiet
60
+
61
+ Specify your own Docker image by its ID with ```--image_id```:
62
+
63
+ $ build_spec_runner -p /path/to/project/ --image_id fee13e06bbce
64
+
65
+ Specify a different AWS CodeBuild vended image with ```--aws_dockerfile_path```. See the official [AWS CodeBuild Docker images repo](https://github.com/aws/aws-codebuild-docker-images) for more information:
66
+
67
+ $ build_spec_runner -p /path/to/project/ --aws_dockerfile_path ubuntu/java/openjdk-8
68
+
69
+ By default BuildSpecRunner will use the configured default AWS profile. Specify a different profile with ```--profile```:
70
+
71
+ $ build_spec_runner -p /path/to/project/ --profile MyBuilderBot
72
+
73
+ By default BuildSpecRunner will attach AWS STS credentials for the current default AWS profile to the project's Docker container.
74
+ You can opt out of this by passing ```--no_credentials```:
75
+
76
+ $ build_spec_runner -p /path/to/project/ --no_credentials
77
+
78
+ You may specify the AWS region provided to the project. This will set the [appropriate env variables](http://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-env-vars.html) to make it look like the project is running in the specified region. Otherwise it uses the default region configured by the current or provided AWS profile.
79
+
80
+ $ build_spec_runner -p /path/to/project/ --region us-east-2
81
+
82
+ ## Development
83
+
84
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
85
+
86
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
87
+
88
+ ## Contributing
89
+
90
+ Bug reports and pull requests are welcome on GitHub at https://github.com/jzuber4/build_spec_runner. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
91
+
92
+ ## License
93
+
94
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
95
+
96
+ ## Code of Conduct
97
+
98
+ Everyone interacting in the BuildSpecRunner project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/jzuber4/build_spec_runner/blob/master/CODE_OF_CONDUCT.md).
@@ -0,0 +1,15 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
7
+
8
+ desc "Open a terminal with this gem required"
9
+ task :irb do
10
+ require 'irb'
11
+ require 'irb/completion'
12
+ require 'build_spec_runner'
13
+ ARGV.clear
14
+ IRB.start
15
+ end
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "build_spec_runner"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,36 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "build_spec_runner/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "build_spec_runner"
8
+ spec.version = BuildSpecRunner::VERSION
9
+ spec.authors = ["Jimmy Zuber"]
10
+ spec.email = ["jzuber4@gmail.com"]
11
+
12
+ spec.summary = %q{A gem to execute AWS CodeBuild build_spec.yml files locally.}
13
+ spec.description = %q{A gem to execute AWS CodeBuild build_spec.yml files locally.
14
+ AWS CodeBuild (https://aws.amazon.com/codebuild/) is an AWS product. This gem is a third-party creation not affiliated with AWS.
15
+ }
16
+ spec.homepage = "https://github.com/jzuber4/build_spec_runner"
17
+ spec.license = "MIT"
18
+
19
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
20
+ f.match(%r{^(test|spec|features)/})
21
+ end
22
+ spec.bindir = "exe"
23
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
+ spec.require_paths = ["lib"]
25
+
26
+ spec.add_dependency 'aws-sdk-core', '~> 3'
27
+ spec.add_dependency 'aws-sdk-ssm', '~> 1.1'
28
+ spec.add_dependency 'docker-api', '~> 1.33'
29
+ spec.add_dependency 'git', '~> 1.3'
30
+ spec.add_dependency 'kwalify', '~> 0.7'
31
+ spec.add_development_dependency "bundler", "~> 1.15"
32
+ spec.add_development_dependency 'pry', '~> 0.11'
33
+ spec.add_development_dependency "rake", "~> 12.1"
34
+ spec.add_development_dependency "rspec", "~> 3.6"
35
+ spec.add_development_dependency "yard", "~> 0.9"
36
+ end
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
4
+
5
+ require 'build_spec_runner'
6
+
7
+ BuildSpecRunner::CLI.main
@@ -0,0 +1,6 @@
1
+ require 'build_spec_runner/build_spec/build_spec'
2
+ require 'build_spec_runner/cli'
3
+ require 'build_spec_runner/default_images'
4
+ require 'build_spec_runner/runner'
5
+ require 'build_spec_runner/source_provider'
6
+ require 'build_spec_runner/version'
@@ -0,0 +1,148 @@
1
+ require 'kwalify'
2
+ require 'yaml'
3
+
4
+ module BuildSpecRunner
5
+ module BuildSpec
6
+
7
+ # Phases of a buildspec file.
8
+
9
+ PHASES = ['install', 'pre_build', 'build', 'post_build']
10
+
11
+ # Error for communicating issues with buildspec
12
+
13
+ class BuildSpecError < StandardError
14
+
15
+ # @!attribute [r] filename
16
+ # @return [String] the filename of the buildspec that caused the error
17
+
18
+ attr_reader :filename
19
+
20
+ def initialize(message, filename)
21
+ @filename = filename
22
+ super(message)
23
+ end
24
+ end
25
+
26
+ # Class for representing a buildspec defined by a buildspec file.
27
+ # @see http://docs.aws.amazon.com/codebuild/latest/userguide/build-spec-ref.html
28
+
29
+ class BuildSpec
30
+
31
+ # @!attribute [r] env
32
+ # @return [Map<String, String>] A mapping of environment variable names to values.
33
+ # @!attribute [r] paremeter_store
34
+ # @return [Map<String, String>] A mapping of parameter store environment variable names to the parameter store key.
35
+ # @!attribute [r] phases
36
+ # @return [Map<String, Array<String>>] A mapping of phase name to a list of commands
37
+ # for that phase
38
+
39
+ attr_reader :env, :parameter_store, :phases
40
+
41
+ # Parse a buildspec file to create a BuildSpec object. Parses the file according to a
42
+ # buildspec schema.
43
+
44
+ def initialize filename
45
+ @filename = filename
46
+ parse_file
47
+ end
48
+
49
+ private
50
+
51
+ # The filename of the build spec file, used for raising {BuildSpecError}s
52
+
53
+ attr_reader :filename
54
+
55
+ # Parse a buildspec yaml file to create a BuildSpec object. Uses a Kwalify schema for validation
56
+
57
+ def parse_file
58
+ document = YAML.load_file @filename
59
+ validate_with_schema document
60
+
61
+ validate_version document
62
+ @env, @parameter_store = validate_env document
63
+ @phases = validate_phases document
64
+ validate_artifacts document
65
+ end
66
+
67
+ # Validate the buildspec file using a Kwalify schema
68
+ #
69
+ # @param document [Hash] a document object representing the build spec
70
+ # @raise [BuildSpecError] if the build spec doesn't comply with the schema
71
+
72
+ def validate_with_schema document
73
+ schema_filename = File.join(File.dirname(__FILE__), './buildspec_schema.yml')
74
+ schema = Kwalify::Yaml.load_file(schema_filename)
75
+
76
+ errors = Kwalify::Validator.new(schema).validate document
77
+ if errors && !errors.empty?
78
+ raise BuildSpecError.new "Encountered errors while validating buildspec according to schema: #{errors}", @filename
79
+ end
80
+ end
81
+
82
+ # Validate the build spec document's version
83
+ #
84
+ # @raise [BuildSpecError] if the version is not supported
85
+
86
+ def validate_version document
87
+ version = document['version']
88
+ if version != 0.2
89
+ raise BuildSpecError.new "Unsupported version: #{version}. This only supports 0.2", @filename
90
+ end
91
+ end
92
+
93
+ # Validate and parse the build spec document's environment variables and parameter-store variables
94
+ #
95
+ # @raise [BuildSpecError] if the env variables or paremeter-store variables are invalid
96
+ # @return [Array<String>, Array<String>] the environment variables and parameter store variables, in that order
97
+
98
+ def validate_env document
99
+ assert_not_nil_key document, 'env', 'Mapping "env" requires at least one of ["variables", "parameter-store"]'
100
+
101
+ assert_not_nil_key document['env'], 'variables', 'Mapping "env => variables" requires at least one entry, if it exists'
102
+ env = document['env']['variables'] if document['env'] and document['env']['variables']
103
+ env ||= {}
104
+ env.freeze
105
+
106
+ assert_not_nil_key document['env'], 'parameter-store', 'Mapping "env => parameter-store" requires at least one entry, if it exists'
107
+ parameter_store = document['env']['parameter-store'] if document['env'] and document['env']['parameter-store']
108
+ parameter_store ||= {}
109
+ parameter_store.freeze
110
+
111
+ return env, parameter_store
112
+ end
113
+
114
+ # Validate and parse the build spec document's phases
115
+ #
116
+ # @raise [BuildSpecError] if the phase mappings are invalid
117
+ # @return [Hash<String, Array[String]>] a mapping of phase name to a list of commands in that phase
118
+
119
+ def validate_phases document
120
+ phases = {}
121
+ for phase in PHASES
122
+ assert_not_nil_key document['phases'], phase, "Mapping \"phases => #{phase}\" requires mapping \"commands\""
123
+ phases[phase] = document['phases'][phase]['commands'] unless document['phases'][phase].nil?
124
+ phases[phase] ||= []
125
+ end
126
+ phases
127
+ end
128
+
129
+ # Validate the build spec document's artifacts
130
+ #
131
+ # @raise [BuildSpecError] if the artifact mapping is invalid
132
+
133
+ def validate_artifacts document
134
+ assert_not_nil_key document, 'artifacts', 'Mapping "artifacts" requires mapping "files"'
135
+ end
136
+
137
+ # Assert that the document does not have the key with a nil value
138
+ #
139
+ # @raise [BuildSpecError] If the document has the key but the key's value is nil
140
+
141
+ def assert_not_nil_key document, key, message
142
+ if !document.nil? and document.key? key and document[key].nil?
143
+ raise BuildSpecError.new message, @filename
144
+ end
145
+ end
146
+ end
147
+ end
148
+ end