construi 0.35.2 → 0.36.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -14,3 +14,5 @@
14
14
  mkmf.log
15
15
  vendor
16
16
  .git-credentials
17
+ target
18
+ .sass-cache
data/Gemfile CHANGED
@@ -2,4 +2,3 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in construi.gemspec
4
4
  gemspec
5
-
data/README.md CHANGED
@@ -2,9 +2,6 @@
2
2
 
3
3
  [![Gem](https://img.shields.io/gem/v/construi.svg?style=plastic)](https://rubygems.org/gems/construi)
4
4
  [![Build Status](http://jenkins.mylonelybear.org/buildStatus/icon?job=construi-develop&style=plastic)](http://jenkins.mylonelybear.org/job/construi-develop/)
5
- [![Gemnasium](https://img.shields.io/gemnasium/mathiasbynens/he.svg?style=plastic)](https://gemnasium.com/lstephen/construi)
6
- [![Code Climate](https://img.shields.io/codeclimate/github/lstephen/construi.svg?style=plastic)](https://codeclimate.com/github/lstephen/construi)
7
- [![Coveralls](https://img.shields.io/coveralls/lstephen/construi/origin/develop.svg?style=plastic)](https://coveralls.io/r/lstephen/construi)
8
5
 
9
6
  Construi allows you to use [Docker](http://www.docker.com) containers as your build environment.
10
7
  This allows a consistent and recreatable build environment on any machine running Construi
@@ -23,126 +20,7 @@ It can be installed as a Gem.
23
20
  > gem install construi
24
21
  ```
25
22
 
26
- ## Running
27
-
28
- Construi requires that a `construi.yml` file be present in the root directory of your project.
29
- Targets can then be run by specifying them on the command line. For example:
30
-
31
- ```
32
- > construi build
33
- > construi build install
34
- ```
35
-
36
- Construi will create a Docker container with the project directory as a volume.
37
- It will then run the commands configured for the given targets.
38
-
39
- ## The Construi File
40
-
41
- As a minimal `construi.yml` requires an image and a target to be configured.
42
- For example a simple configuration for a Java 8 project built with Maven could be:
43
-
44
- ```
45
- image: maven:3-jdk-8
46
-
47
- targets:
48
- install: mvn install
49
- ```
50
-
51
- Construi is built using itself, so it's
52
- [`construi.yml`](https://github.com/lstephen/construi/blob/develop/construi.yml)
53
- can be used as an example also.
54
-
55
- ### Image
56
-
57
- Specifies an image to be pulled that will be used as the build environment.
58
- It can also be given on a per target basis.
59
-
60
- ```
61
- image: maven:3-jdk-7
62
-
63
- targets:
64
- install: mvn install
65
-
66
- test-java-8:
67
- image: maven:3-jdk-8
68
- run: mvn verify
69
- ```
70
-
71
- ### Build
72
-
73
- Specifies a directory containing a `Dockerfile`.
74
- Construi will build a Docker container based on that `Dockerfile` and use it as the build
75
- environment.
76
- Can be used as an alternative to providing an image.
77
- Can also be given on a per target basis.
78
-
79
- ```
80
- build: etc/build_environment
81
-
82
- targets:
83
- build:
84
- - mvn install
85
- - /usr/local/bin/custom_installed_command.sh
86
- ```
87
-
88
- ### Environment
89
-
90
- Declares environment variables that will be passed through or set in the build environment.
91
- If no value is provided then the value from the host environment will be used.
92
- In this example `NEXUS_SERVER_URL` will be set as provided, while `NEXUS_USERNAME` and
93
- `NEXUS_PASSWORD` will be retrieved from the host.
94
-
95
- ```
96
- image: maven:3-jdk-7
97
-
98
- environment:
99
- - NEXUS_SERVER_URL=http://nexus.example.com
100
- - NEXUS_USERNAME
101
- - NEXUS_PASSWORD
102
- targets:
103
- build: mvn install
104
- ```
105
-
106
- ### Files
107
-
108
- Declares files to be copied into the build environment before the build is run.
109
- Also allows setting of permissions.
110
- Can be used on a per target basis.
111
-
112
- ```
113
- image: maven:3-jdk-7
114
-
115
- files:
116
- - etc/maven-settings.xml:/home/root/.m2/settings.xml
117
-
118
- targets:
119
- deploy:
120
- files:
121
- - $GIT_SSH_KEY:/home/root/.ssh/id_rsa:0600
122
- run: scripts/construi/deploy.sh
123
- ```
124
-
125
- ### Targets
126
-
127
- Any number of targets can be specified.
128
- Each must specify at least one command.
129
- If additional configuration is required for a target then the commands should be provided
130
- under the `run` key.
131
- If more than one command is required then a YAML list should be used.
132
-
133
- ```
134
- image: maven:3-jdk-7
135
-
136
- targets:
137
- build: mvn install
138
-
139
- test-java-8:
140
- image: maven:3-jdk-8
141
- run: mvn verify
142
-
143
- deploy:
144
- - mvn deploy
145
- - curl http://ci.example.com/deploy/trigger
146
- ```
23
+ ## Usage
147
24
 
25
+ See the main site at http://lstephen.github.io/construi
148
26
 
data/Rakefile CHANGED
@@ -3,5 +3,4 @@ require 'rspec/core/rake_task'
3
3
 
4
4
  RSpec::Core::RakeTask.new(:spec)
5
5
 
6
- task :default => :spec
7
-
6
+ task default: :spec
data/bin/construi CHANGED
@@ -3,4 +3,3 @@
3
3
  require 'construi'
4
4
 
5
5
  Construi.run ARGV
6
-
data/construi.gemspec CHANGED
@@ -4,29 +4,34 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  require 'construi/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
- spec.name = "construi"
7
+ spec.name = 'construi'
8
8
  spec.version = Construi::VERSION
9
- spec.authors = ["lstephen"]
10
- spec.email = ["levi.stephen@gmail.com"]
11
- spec.summary = %q{Build tool using Docker to specify build environment}
12
- spec.description = %q{Build tool using Docker to specify build environment}
13
- spec.homepage = "https://github.com/lstephen/construi"
14
- spec.license = "MIT"
9
+ spec.authors = ['Levi Stephen']
10
+ spec.email = ['levi.stephen@gmail.com']
11
+ spec.summary = 'Build tool using Docker to specify build environment'
12
+ spec.description = 'Build tool using Docker to specify build environment'
13
+ spec.homepage = 'https://github.com/lstephen/construi'
14
+ spec.license = 'MIT'
15
15
 
16
16
  spec.files = `git ls-files -z`.split("\x0")
17
17
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
- spec.require_paths = ["lib"]
19
+ spec.require_paths = ['lib']
20
20
 
21
21
  spec.required_ruby_version = '>= 1.9'
22
22
 
23
23
  spec.add_dependency 'docker-api', '=1.21.4'
24
24
  spec.add_dependency 'colorize', '=0.7.7'
25
25
 
26
- spec.add_development_dependency 'bundler', '~> 1.7'
27
- spec.add_development_dependency 'codeclimate-test-reporter', '~> 0.4'
28
- spec.add_development_dependency 'coveralls', '~> 0.7'
26
+ spec.add_development_dependency 'bundler', '~> 1.9'
27
+ spec.add_development_dependency 'execjs', '~> 2.5'
29
28
  spec.add_development_dependency 'gem-release', '~> 0.7'
30
- spec.add_development_dependency 'rake', '~> 10.0'
29
+ spec.add_development_dependency 'jekyll', '~> 2.5'
30
+ spec.add_development_dependency 'rake', '~> 10.4'
31
+ spec.add_development_dependency 'redcarpet', '~> 3.2'
31
32
  spec.add_development_dependency 'rspec', '~> 3.2'
33
+ spec.add_development_dependency 'rubocop', '~> 0.31'
34
+ spec.add_development_dependency 'simplecov', '~> 0.10'
35
+ spec.add_development_dependency 'therubyracer', '~> 0.12'
36
+ spec.add_development_dependency 'yard', '~> 0.8'
32
37
  end
data/construi.yml CHANGED
@@ -1,16 +1,14 @@
1
1
  image: ruby:1.9
2
2
 
3
3
  environment:
4
- - JENKINS_URL
5
- - BUILD_NUMBER
6
- - CODECLIMATE_REPO_TOKEN
7
- - COVERALLS_REPO_TOKEN
4
+ - COVERAGE
8
5
  - GIT_COMMIT
9
6
  - GIT_BRANCH
10
7
  - GIT_SSH_KEY
11
8
  - GIT_AUTHOR_NAME
12
9
  - GIT_AUTHOR_EMAIL
13
10
  - RUBYGEMS_API_KEY
11
+ - SITE_DEPLOY
14
12
 
15
13
  targets:
16
14
  build:
@@ -21,6 +19,14 @@ targets:
21
19
  - bundle install --path=vendor/bundle
22
20
  - bundle exec rake install
23
21
 
22
+ site:
23
+ build: construi/site
24
+ files:
25
+ - $GIT_SSH_KEY:/root/.ssh/id_rsa:0600
26
+ run:
27
+ - bundle install --path=vendor/bundle
28
+ - bash construi/site/run.sh
29
+
24
30
  release:
25
31
  files:
26
32
  - $GIT_SSH_KEY:/root/.ssh/id_rsa:0600
@@ -7,14 +7,22 @@ set -e
7
7
 
8
8
  printf "Host github.com\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
9
9
 
10
- git config push.default simple
11
- git checkout master
12
- git pull --rebase
13
- git merge --commit ${GIT_COMMIT}
14
- git push origin
15
- git checkout develop
16
- git pull --rebase
10
+ release_commit=`git rev-parse HEAD`
11
+
12
+ echo "Release commit ${release_commit}..."
13
+
14
+ echo "Pushing to master..."
15
+ git push -f origin `git rev-parse HEAD`:master
16
+
17
+ echo "Push to master done."
18
+
19
+ echo "Updating development version..."
17
20
  bundle install --path vendor/bundle
18
21
  bundle exec gem bump --version minor
19
- git push origin
22
+
23
+ echo "Pushing to develop..."
24
+ git push origin `get rev-parse HEAD`:develop
25
+ echo "Push to develop done."
26
+
27
+ echo "Release done."
20
28
 
@@ -0,0 +1,6 @@
1
+ FROM ruby:1.9
2
+
3
+ RUN apt-get update && apt-get -y install python python-pip
4
+
5
+ RUN pip install ghp-import
6
+
@@ -0,0 +1,35 @@
1
+ #!/bin/bash
2
+
3
+ set -e
4
+
5
+ echo "Generating Site..."
6
+
7
+ bundle exec jekyll build --source site --destination target/site
8
+
9
+ echo "Generating Reports..."
10
+
11
+ echo "Yard..."
12
+ bundle exec yard --output-dir target/site/yard
13
+
14
+ echo "Coverage..."
15
+ COVERAGE=true bundle exec rake spec
16
+
17
+ echo "Rubocop..."
18
+ bundle exec rubocop --format html -o target/site/rubocop.html || true
19
+
20
+ echo "Reports done."
21
+
22
+ if [[ -n "$SITE_DEPLOY" ]]
23
+ then
24
+ [[ -n "$GIT_AUTHOR_NAME" ]] && git config user.name $GIT_AUTHOR_NAME
25
+ [[ -n "$GIT_AUTHOR_EMAIL" ]] && git config user.email $GIT_AUTHOR_EMAIL
26
+
27
+ printf "Host github.com\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
28
+
29
+ echo "Deploying site to gh-pages..."
30
+ ghp-import -p target/site
31
+ echo "Deployment done."
32
+ fi
33
+
34
+ echo "Site done."
35
+
data/lib/construi.rb CHANGED
@@ -1,6 +1,7 @@
1
1
 
2
2
  require 'yaml'
3
3
 
4
+ # Entrypoint for the Construi application
4
5
  module Construi
5
6
  require 'construi/config'
6
7
  require 'construi/runner'
@@ -11,4 +12,3 @@ module Construi
11
12
  Runner.new(Config.load_file('construi.yml')).run(targets)
12
13
  end
13
14
  end
14
-
@@ -1,126 +1,134 @@
1
1
 
2
- module Construi::Config
2
+ module Construi
3
+ module Config
4
+ module Image
5
+ def image
6
+ image_configured :image
7
+ end
3
8
 
4
- module Image
5
- def image
6
- image_configured :image
7
- end
9
+ def build
10
+ image_configured :build
11
+ end
8
12
 
9
- def build
10
- image_configured :build
11
- end
13
+ def privileged?
14
+ key?(:privileged) ? yaml['privileged'] : with_parent(false, &:privileged?)
15
+ end
12
16
 
13
- def image_configured?
14
- yaml.is_a?(Hash) && (yaml.has_key?('build') || yaml.has_key?('image'))
15
- end
17
+ def image_configured?
18
+ key?(:build) || key?(:image)
19
+ end
16
20
 
17
- def image_configured(what)
18
- image_configured? ? yaml[what.to_s] : with_parent(&what)
21
+ def image_configured(what)
22
+ image_configured? ? yaml[what.to_s] : with_parent(&what)
23
+ end
19
24
  end
20
- end
21
25
 
22
- module Files
26
+ module Files
27
+ class File
28
+ attr_reader :container, :permissions
23
29
 
24
- class File
25
- attr_reader :container, :permissions
30
+ def initialize(host, container, permissions)
31
+ @host = host
32
+ @container = container
33
+ @permissions = permissions
34
+ end
26
35
 
27
- def initialize(host, container, permissions)
28
- @host = host
29
- @container = container
30
- @permissions = permissions
36
+ def host
37
+ @host.gsub(/\$(\w+)/) { ENV[$1] }
38
+ end
39
+
40
+ def self.parse(str)
41
+ split = str.split(':')
42
+ File.new split[0], split[1], split[2]
43
+ end
31
44
  end
32
45
 
33
- def host
34
- @host.gsub(/\$(\w+)/) { ENV[$1] }
46
+ def files_configured?
47
+ key? :files
35
48
  end
36
49
 
37
- def self.parse(str)
38
- split = str.split(':')
39
- File.new split[0], split[1], split[2]
50
+ def files
51
+ fs = files_configured? ? yaml['files'].map { |str| File.parse(str) } : []
52
+
53
+ with_parent([], &:files).concat fs
40
54
  end
41
55
  end
42
56
 
43
- def files_configured?
44
- yaml.is_a? Hash and yaml.has_key? 'files'
45
- end
57
+ module Environment
58
+ include Image
59
+ include Files
60
+
61
+ def parent
62
+ nil
63
+ end
46
64
 
47
- def files
48
- fs = files_configured? ? yaml['files'].map { |str| File.parse(str) } : []
65
+ def key?(key)
66
+ yaml.is_a?(Hash) && yaml.key?(key.to_s)
67
+ end
49
68
 
50
- with_parent([], &:files).concat fs
69
+ def with_parent(or_else = nil)
70
+ parent ? yield(parent) : or_else
71
+ end
51
72
  end
52
- end
53
73
 
54
- module Environment
55
- include Image
56
- include Files
74
+ class Global
75
+ include Environment
57
76
 
58
- def parent
59
- nil
60
- end
77
+ attr_reader :yaml
61
78
 
62
- def with_parent(or_else = nil)
63
- parent ? yield(parent) : or_else
64
- end
65
- end
79
+ def initialize(yaml)
80
+ @yaml = yaml
81
+ end
66
82
 
67
- class Global
68
- include Environment
83
+ def env
84
+ return [] if yaml['environment'].nil?
69
85
 
70
- attr_reader :yaml
86
+ yaml['environment'].reduce([]) do |acc, e|
87
+ key = e.partition('=').first
88
+ value = e.partition('=').last
71
89
 
72
- def initialize(yaml)
73
- @yaml = yaml
74
- end
90
+ value = ENV[key] if value.empty?
75
91
 
76
- def env
77
- return [] if yaml['environment'].nil?
92
+ acc << "#{key}=#{value}" unless value.nil? or value.empty?
93
+ acc
94
+ end
95
+ end
78
96
 
79
- yaml['environment'].reduce([]) do |acc, e|
80
- key = e.partition('=').first
81
- value = e.partition('=').last
97
+ def target(target)
98
+ targets = yaml['targets']
82
99
 
83
- value = ENV[key] if value.empty?
100
+ return nil if targets.nil?
84
101
 
85
- acc << "#{key}=#{value}" unless value.nil? or value.empty?
86
- acc
102
+ return Target.new yaml['targets'][target], self
87
103
  end
88
104
  end
89
105
 
90
- def target(target)
91
- targets = yaml['targets']
106
+ class Target
107
+ include Environment
92
108
 
93
- return nil if targets.nil?
94
-
95
- return Target.new yaml['targets'][target], self
96
- end
97
- end
109
+ attr_reader :yaml, :parent
98
110
 
99
- class Target
100
- include Environment
111
+ def initialize(yaml, parent)
112
+ @yaml = yaml
113
+ @parent = parent
114
+ end
101
115
 
102
- attr_reader :yaml, :parent
116
+ def commands
117
+ Array(@yaml.is_a?(Hash) ? @yaml['run'] : @yaml)
118
+ end
103
119
 
104
- def initialize(yaml, parent)
105
- @yaml = yaml
106
- @parent = parent
120
+ def options
121
+ { env: parent.env, privileged: parent.privileged? }
122
+ end
107
123
  end
108
124
 
109
- def commands
110
- Array(@yaml.is_a?(Hash) ? @yaml['run'] : @yaml)
125
+ def self.load(content)
126
+ Global.new YAML.load(content)
111
127
  end
112
128
 
113
- def env
114
- parent.env
129
+ def self.load_file(path)
130
+ Global.new YAML.load_file(path)
115
131
  end
116
132
  end
117
-
118
- def self.load(content)
119
- Global.new YAML.load(content)
120
- end
121
-
122
- def self.load_file(path)
123
- Global.new YAML.load_file(path)
124
- end
125
133
  end
126
134