construi 0.35.2 → 0.36.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.
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