concourse 0.22.0 → 0.23.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: b0107e8ffc49ba8bd8ad43183da66ecb29d89478440fd0cb70b9eb2e1305c427
4
- data.tar.gz: 40fa32805af4c9d08d2b2b4f0ebcde942bd6e1135a98b491bba6f148cea1c1ee
3
+ metadata.gz: 50517da26e0d7eb88bb231814b9a664ee17bc5e08c278eb2724e472797832867
4
+ data.tar.gz: 7c0ce4a2fc2844bf187ba242d47c62c5b1ab684ef85d6194520c90807b10b8c3
5
5
  SHA512:
6
- metadata.gz: 5e9e9633794c23f7306688fd979167def21e3f2efd5ab4ad3de73ba18f64ee87c3fe45accf0d19c4d3afb7cac8a54e198304e2b023b39bc3db40f1d65ffe26b9
7
- data.tar.gz: af0504712cfbef8764296617f523eea2d1f97171857c58ea4b85d8e3da70a2e855f3baed3cffebff6af9f7e379711cba2d69d6c9fe2c63d7b68a2b31acddba81
6
+ metadata.gz: c19043e491bd57cfc3f57babcc494ac0eee2e35e501f3a45e076af6655c8b94940f89ece2d7b067f762039a0723031e3329c2b635525927bf0a40202158727be
7
+ data.tar.gz: fb3024061b013b796d65e68757cb9aade22126868d7c3c29be367c0ac39142da96c3024575c7753f5c3909f67d53104cb25c5eb1fd85a8a283c99b8ddc41c7f2
data/.gitignore CHANGED
@@ -10,3 +10,7 @@
10
10
 
11
11
  # rspec failure tracking
12
12
  .rspec_status
13
+
14
+ # npm
15
+ node_modules
16
+ package-lock.json
@@ -1,5 +1,12 @@
1
1
  # concourse-gem changelog
2
2
 
3
+ ## 0.23.0 / 2019-01-19
4
+
5
+ ### Features
6
+
7
+ * Support for multiple pipelines.
8
+
9
+
3
10
  ## 0.22.0 / 2019-01-18
4
11
 
5
12
  ### Breaking changes
data/README.md CHANGED
@@ -1,72 +1,120 @@
1
- # Concourse
1
+ # concourse (the rubygem)
2
2
 
3
- The `Concourse` gem provides rake tasks to help you manage your Concourse pipelines, and to assist in running individual tasks with `fly execute`.
3
+ The `concourse` gem provides rake tasks to help you manage Concourse pipelines, jobs, and workers, and to assist in running tasks with `fly execute`.
4
4
 
5
5
  If you're not familiar with Concourse CI, you can read up on it at https://concourse.ci
6
6
 
7
7
 
8
- ## Usage
8
+ ## Contents
9
9
 
10
- In your Rakefile,
10
+ <!-- to update this TOC run `rake readme_toc` -->
11
11
 
12
- ``` ruby
13
- require 'concourse'
12
+ <!-- toc -->
14
13
 
15
- Concourse.new("myproject", fly_target: "myci").create_tasks!
16
- ```
14
+ - [Basic Usage](#basic-usage)
15
+ * [Install](#install)
16
+ * [Add to your `Rakefile`](#add-to-your-rakefile)
17
+ * [Set up your Concourse pipeline](#set-up-your-concourse-pipeline)
18
+ - [Concourse pipeline configuration](#concourse-pipeline-configuration)
19
+ * [ERB Templating and `RUBIES`](#erb-templating-and-rubies)
20
+ * [Secrets](#secrets)
21
+ * [Multiple pipelines](#multiple-pipelines)
22
+ - [Configuration](#configuration)
23
+ * [`directory`: Concourse subdirectory name](#directory-concourse-subdirectory-name)
24
+ * [`fly_target`: Concourse `fly` target name](#fly_target-concourse-fly-target-name)
25
+ * [`pipeline_erb_filename`: Pipeline filename](#pipeline_erb_filename-pipeline-filename)
26
+ * [`secrets_filename`: Secrets filename](#secrets_filename-secrets-filename)
27
+ - [Rake Tasks](#rake-tasks)
28
+ * [Manage your Concourse pipeline](#manage-your-concourse-pipeline)
29
+ * [List pipeline tasks](#list-pipeline-tasks)
30
+ * [Run a Concourse task with `fly execute`](#run-a-concourse-task-with-fly-execute)
31
+ * [Abort running builds](#abort-running-builds)
32
+ * [Prune stalled concourse workers](#prune-stalled-concourse-workers)
33
+ - [Contributing](#contributing)
34
+ - [License](#license)
17
35
 
18
- This will create a set of rake tasks for you.
36
+ <!-- tocstop -->
19
37
 
20
- ``` sh
21
- rake concourse:init
22
- ```
38
+ ## Basic Usage
23
39
 
24
- The `concourse:init` task will create a subdirectory named `concourse`, and create a Concourse pipeline file named `<myproject>.yml`, which will be interpreted as an ERB template. It will also ensure that files with sensitive data (`concourse/private.yml` and `concourse/myproject.yml.generated`) are in `.gitignore`.
40
+ ### Install
25
41
 
42
+ Add this line to your application's Gemfile:
26
43
 
27
- ### Concourse subdirectory name
44
+ ```ruby
45
+ gem 'concourse'
46
+ ```
28
47
 
29
- You can choose a directory name other than the default `concourse`:
48
+ and then run `bundle`.
30
49
 
31
- ``` ruby
32
- Concourse.new("myproject", directory: "ci").create_tasks!
33
- ```
50
+ You can also install it via `gem install concourse`.
34
51
 
35
52
 
36
- ### Concourse `fly` target name
53
+ ### Add to your `Rakefile`
37
54
 
38
- If the initializer is given no additional parameters, your fly target is assumed to be named "default":
55
+ The primary functionality of the Concourse gem is to provide rake tasks. So, in your Rakefile:
39
56
 
40
57
  ``` ruby
41
- Concourse.new("myproject").create_tasks! # `fly -t default <command>`
58
+ require 'concourse'
59
+
60
+ Concourse.new("myproject").create_tasks!
42
61
  ```
43
62
 
44
- But this is likely an inappropriate default, and so you can specify your target name:
63
+ ### Set up your Concourse pipeline
45
64
 
46
- ``` ruby
47
- Concourse.new("myproject", fly_target: "myci").create_tasks! # `fly -t myci <command>`
65
+ ``` sh
66
+ rake concourse:init
48
67
  ```
49
68
 
69
+ The `concourse:init` task will do a few different things for you:
50
70
 
51
- ### Pipeline file
71
+ 1. create a subdirectory named `concourse` (or whatever you've configured with the `:directory` parameter)
72
+ 2. create an empty Concourse pipeline file in that subdirectory named `<myproject>.yml` (or whatever you've configured with the `:pipeline_erb_filename` parameter)
73
+ 3. ensure git will ignore your secrets file named `private.yml` (or whatever you've configured with the `:secrets_filename` parameter)
74
+ 4. ensure git will ignore the generated pipeline file (named after your ERB pipeline file as `<pipeline_erb_filename>.generated`)
52
75
 
53
- By default the pipeline file will be named `<myproject>.yml`, but can be set to something else:
76
+
77
+ ## Concourse pipeline configuration
78
+
79
+ ### ERB Templating and `RUBIES`
80
+
81
+ Your Concourse pipeline configuration file, `<myproject>.yml` (or whatever you've configured with the `:pipeline_erb_filename` parameter), will be treated like an ERB template.
82
+
83
+ (If you're unfamiliar with ERB and how you can mix Ruby into the document, you can [read about it here](https://www.stuartellis.name/articles/erb/).)
84
+
85
+ The ruby variable `RUBIES` is defined in the ERB binding during pipeline file generation. This variable looks like:
54
86
 
55
87
  ``` ruby
56
- Concourse.new("myproject", pipeline_erb_filename: "pipeline.yml").create_tasks!
88
+ # these numbers/names align with public docker image names
89
+ RUBIES = {
90
+ mri: %w[2.1 2.2 2.3 2.4], # docker repository: "ruby"
91
+ jruby: %w[1.7 9.1], # docker repository: "jruby"
92
+ rbx: %w[latest], # docker repository: "rubinius/docker"
93
+ windows: %w[2.3 2.4] # windows-ruby-dev-tools-release
94
+ }
57
95
  ```
58
96
 
59
- Note that the generated, final pipeline file is always named `<pipeline_erb_filename>.generated`.
97
+ and allows you to write a pipeline like this to get coverage on all the supported rubies:
60
98
 
99
+ ``` yaml
100
+ # myproject.yml
101
+ jobs:
102
+ <% for ruby_version in RUBIES[:mri] %>
103
+ - name: "ruby-<%= ruby_version %>"
104
+ plan:
105
+ - get: git-master
106
+ trigger: true
107
+ - task: rake-test
108
+ ...
109
+ <% end %>
110
+ ```
61
111
 
112
+ Note that the `windows` rubies are not Docker images, since Concourse's Houdini backend doesn't use Docker. Instead, these are implicitly referring to the supported ruby versions installed by the BOSH release at https://github.com/flavorjones/windows-ruby-dev-tools-release
62
113
 
63
- ### Keeping credentials private
64
114
 
65
- You can use a separate file to keep your pipeline variables secure. By default, `concourse/private.yml` will be used. You can specify a different filename:
115
+ ### Secrets
66
116
 
67
- ``` ruby
68
- Concourse.new("myproject", secrets_filename: "secrets.yml").create_tasks!
69
- ```
117
+ You can use a separate file to keep your pipeline variables secret. By default, `concourse/private.yml` will be used. This filename can also be configured (see below)
70
118
 
71
119
  If the secrets file exists, it will be passed to the `fly` commandline with the `-l` option to fill in template values.
72
120
 
@@ -91,128 +139,171 @@ github-repo-status-access-token: "your-token-here"
91
139
  and the final generate template will substitute your credentials into the appropriate place.
92
140
 
93
141
 
94
- ### Templating and `RUBIES`
142
+ ### Multiple pipelines
95
143
 
96
- The ruby variable `RUBIES` is defined in the ERB binding during pipeline file generation. This variable looks like:
144
+ Setting up multiple pipelines might be useful for you, for example one pipeline for running tests against `master` and another for pull requests; or a pipeline for tests and a pipeline for deployments.
145
+
146
+ If you'd like to set up multiple pipelines, invoke Concourse in your Rakefile like this:
97
147
 
98
148
  ``` ruby
99
- # these numbers/names align with public docker image names
100
- RUBIES = {
101
- mri: %w[2.1 2.2 2.3 2.4], # docker repository: "ruby"
102
- jruby: %w[1.7 9.1], # docker repository: "jruby"
103
- rbx: %w[latest], # docker repository: "rubinius/docker"
104
- windows: %w[2.3 2.4] # windows-ruby-dev-tools-release
105
- }
149
+ require 'concourse'
150
+
151
+ Concourse.new("myproject") do |c|
152
+ c.add_pipeline "master", "myproject.yml"
153
+ c.add_pipeline "pull-requests", "pr.yml"
154
+ c.add_pipeline "deploy", "big-red-button.yml"
155
+ end
106
156
  ```
107
157
 
108
- and allows you to write a pipeline like this to get coverage on all the supported rubies:
158
+ Note that when you use the block form:
109
159
 
110
- ``` yaml
111
- # myproject.yml
112
- jobs:
113
- <% for ruby_version in RUBIES[:mri] %>
114
- - name: "ruby-<%= ruby_version %>"
115
- plan:
116
- - get: git-master
117
- trigger: true
118
- - task: rake-test
119
- ...
120
- <% end %>
160
+ * it's not necessary to explicitly call `#create_tasks!`
161
+ * only the pipelines declared via `#add_pipeline` will be managed
162
+
163
+
164
+ ## Configuration
165
+
166
+ ### `directory`: Concourse subdirectory name
167
+
168
+ You can choose a directory name other than the default `concourse`:
169
+
170
+ ``` ruby
171
+ Concourse.new("myproject", directory: "ci").create_tasks!
121
172
  ```
122
173
 
123
- Note that the `windows` rubies are not Docker images, since Concourse's Houdini backend doesn't use Docker. Instead, these are implicitly referring to the supported ruby versions installed by the BOSH release at https://github.com/flavorjones/windows-ruby-dev-tools-release
174
+
175
+ ### `fly_target`: Concourse `fly` target name
176
+
177
+ If the initializer is given no additional parameters, your fly target is assumed to be named "default". But this is likely an inappropriate default, and so you can specify your target name:
178
+
179
+ ``` ruby
180
+ Concourse.new("myproject", fly_target: "myci").create_tasks! # `fly -t myci <command>`
181
+ ```
182
+
183
+
184
+ ### `pipeline_erb_filename`: Pipeline filename
185
+
186
+ By default the pipeline file will be named `<myproject>.yml`, but can be set to something else:
187
+
188
+ ``` ruby
189
+ Concourse.new("myproject", pipeline_erb_filename: "pipeline.yml").create_tasks!
190
+ ```
191
+
192
+ Note that the generated, final pipeline file is always named `<pipeline_erb_filename>.generated`.
193
+
124
194
 
125
195
 
126
- ### Managing your Concourse pipeline
196
+ ### `secrets_filename`: Secrets filename
197
+
198
+ You can use a separate file to keep your pipeline variables secret. By default, `concourse/private.yml` will be used. You can specify a different filename:
199
+
200
+ ``` ruby
201
+ Concourse.new("myproject", secrets_filename: "secrets.yml").create_tasks!
202
+ ```
203
+
204
+
205
+ ## Rake Tasks
206
+
207
+
208
+ ### Manage your Concourse pipeline
127
209
 
128
210
  Tasks to manage a local pipeline file, generated from an ERB template:
129
211
 
130
212
  ```
131
- rake concourse:clean # remove generate pipeline file
132
- rake concourse:generate # generate and validate the pipeline file for myproject
213
+ rake concourse:clean # remove generated pipeline files
214
+ rake concourse:generate # generate and validate the pipeline files for myproject
133
215
  ```
134
216
 
135
217
  A task to update your pipeline configuration:
136
218
 
137
219
  ```
138
- rake concourse:set # upload the pipeline file for myproject
220
+ rake concourse:set # upload the pipeline files for myproject
139
221
  ```
140
222
 
141
223
  Tasks to publicly expose or hide your pipeline:
142
224
 
143
225
  ```
144
- rake concourse:expose # expose the myproject pipeline
145
- rake concourse:hide # hide the myproject pipeline
226
+ rake concourse:expose # expose the myproject pipelines
227
+ rake concourse:hide # hide the myproject pipelines
146
228
  ```
147
229
 
148
230
  Tasks to pause and unpause your pipeline:
149
231
 
150
232
  ```
151
- rake concourse:pause # pause the myproject pipeline
152
- rake concourse:unpause # unpause the myproject pipeline
233
+ rake concourse:pause # pause the myproject pipelines
234
+ rake concourse:unpause # unpause the myproject pipelines
153
235
  ```
154
236
 
155
237
  And, should you ever need to [nuke the site from orbit][ripley], a task to destroy your pipeline:
156
238
 
157
239
  ```
158
- rake concourse:destroy # destroy the myproject pipeline
240
+ rake concourse:destroy # destroy the myproject pipelines
159
241
  ```
160
242
 
161
-
162
243
  [ripley]: https://www.youtube.com/watch?v=aCbfMkh940Q
163
244
 
164
245
 
165
- ### Running tasks with `fly execute`
246
+ ### List pipeline tasks
247
+
248
+ You can see a list of all the tasks defined in your pipelines:
166
249
 
167
250
  ```
168
- rake concourse:tasks # list all the available tasks from the nokogiri pipeline
169
- rake concourse:task[job_task,fly_execute_args] # fly execute the specified task
251
+ rake concourse:tasks # list all the available tasks from the myproject pipelines
170
252
  ```
171
253
 
172
- where:
173
-
174
- * _required_: `job_task` is formatted as `job-name/task-name`, for example, `ruby-2.4/rake-test`. Run the `concourse:tasks` rake task to see all available names.
175
- * _optional_: `fly_execute_args` will default to map the project directory to a resource with the project name, e.g. `--input=myproject=.`, so your pipeline must name the input resource appropriately in order to use the default.
176
-
177
-
178
- ### Aborting running builds
254
+ You'll see output suitable for the `concourse:task` rake task, formatted as `job-name/task-name`, looking something like:
179
255
 
180
256
  ```
181
- rake concourse:abort-builds # abort all running builds for this pipeline
257
+ RUNNING: (in /home/flavorjones/code/oss/nokogiri) fly validate-pipeline -c concourse/nokogiri.yml.generated
258
+ looks good
259
+ NOTE: Available Concourse tasks for nokogiri are:
260
+ * jruby-9.1/rake-test
261
+ * jruby-9.2-pr/rake-test
262
+ * jruby-9.2/rake-test
263
+ * ruby-2.5-system/rake-test
264
+ * ruby-2.5-vendored/rake-test
265
+ * ruby-2.6-system-pr/rake-test
266
+ * ruby-2.6-system/rake-test
267
+ * ruby-2.6-vendored-pr/rake-test
268
+ * ruby-2.6-vendored/rake-test
182
269
  ```
183
270
 
184
271
 
185
- ### Pruning stalled concourse workers
272
+ ### Run a Concourse task with `fly execute`
186
273
 
187
- Especially useful if you're deploying via BOSH, which often results in stalled workers;
274
+ You can `fly execute` a task defined in your pipelines:
188
275
 
189
276
  ```
190
- rake concourse:prune-stalled-workers # prune any stalled workers
277
+ rake concourse:task[job_task,fly_execute_args] # fly execute the specified task
191
278
  ```
192
279
 
280
+ where:
193
281
 
194
- ## Installation
282
+ * _required_: `job_task` is formatted as `job-name/task-name`, for example, `ruby-2.4/rake-test`. (See `concourse:tasks` for a list of all available task names.)
283
+ * _optional_: `fly_execute_args` will default to map the project directory to a resource with the project name, e.g. `--input=myproject=.`, so your pipeline must name the input resource appropriately in order to use the default.
195
284
 
196
- Add this line to your application's Gemfile:
197
285
 
198
- ```ruby
199
- gem 'concourse'
286
+ ### Abort running builds
287
+
288
+ ```
289
+ rake concourse:abort-builds # abort all running builds for this pipeline
200
290
  ```
201
291
 
202
- And then execute:
203
292
 
204
- $ bundle
293
+ ### Prune stalled concourse workers
205
294
 
206
- Or install it yourself as:
295
+ Especially useful if you're deploying via BOSH, which often results in stalled workers;
207
296
 
208
- $ gem install concourse
297
+ ```
298
+ rake concourse:prune-stalled-workers # prune any stalled workers
299
+ ```
209
300
 
210
301
 
211
302
  ## Contributing
212
303
 
213
- Bug reports and pull requests are welcome on GitHub at https://github.com/flavorjones/concourse-gem. 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.
304
+ Bug reports and pull requests are welcome on GitHub at https://github.com/flavorjones/concourse-gem. 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. See [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md).
214
305
 
215
306
 
216
307
  ## License
217
308
 
218
- The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
309
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT). See [`LICENSE.txt`](LICENSE.txt).
data/Rakefile CHANGED
@@ -4,3 +4,14 @@ require "rspec/core/rake_task"
4
4
  RSpec::Core::RakeTask.new(:spec)
5
5
 
6
6
  task :default => :spec
7
+
8
+ desc "update README table of contents"
9
+ task :readme_toc => :install_markdown_utils do
10
+ system "node_modules/.bin/markdown-toc -i --maxdepth 3 README.md"
11
+ end
12
+
13
+ task :install_markdown_utils do
14
+ if ! File.exist?("node_modules/.bin/markdown-toc")
15
+ system "npm install markdown-toc"
16
+ end
17
+ end
@@ -1,14 +1,12 @@
1
1
  require "concourse/version"
2
+ require "concourse/util"
3
+ require "concourse/pipeline"
2
4
  require "yaml"
3
5
  require "tempfile"
4
- require 'term/ansicolor'
5
6
 
6
7
  class Concourse
7
8
  include Rake::DSL
8
- include Term::ANSIColor
9
-
10
- GITIGNORE_FILE = ".gitignore"
11
- GITATTRIBUTES_FILE = ".gitattributes"
9
+ include Concourse::Util
12
10
 
13
11
  # these numbers/names align with public docker image names
14
12
  RUBIES = {
@@ -22,7 +20,7 @@ class Concourse
22
20
 
23
21
  attr_reader :project_name
24
22
  attr_reader :directory
25
- attr_reader :pipeline_filename, :pipeline_erb_filename
23
+ attr_reader :pipelines
26
24
  attr_reader :fly_target
27
25
  attr_reader :secrets_filename
28
26
 
@@ -48,52 +46,39 @@ class Concourse
48
46
  RUBIES[:mri].select { |r| r =~ /rc/ }
49
47
  end
50
48
 
51
- def initialize project_name, options={}
49
+ def initialize project_name, options={}, &block
52
50
  @project_name = project_name
53
51
 
54
52
  @directory = options[:directory] || DEFAULT_DIRECTORY
55
53
  @fly_target = options[:fly_target] || "default"
56
- base_pipeline_erb_filename = options[:pipeline_erb_filename] || "#{project_name}.yml"
57
- base_secrets_filename = options[:secrets_filename] || "private.yml"
58
54
 
59
- @pipeline_filename = File.join(@directory, "#{base_pipeline_erb_filename}.generated")
60
- @pipeline_erb_filename = File.join(@directory, base_pipeline_erb_filename)
55
+ base_secrets_filename = options[:secrets_filename] || "private.yml"
61
56
  @secrets_filename = File.join(@directory, base_secrets_filename)
62
- end
63
-
64
- def erbify document_string, *args
65
- ERB.new(document_string, nil, "%-").result(binding)
66
- end
67
-
68
- def rake_init
69
- FileUtils.mkdir_p File.join(directory, "tasks")
70
- FileUtils.touch pipeline_erb_filename
71
- ensure_in_gitignore secrets_filename
72
- ensure_in_gitignore pipeline_filename
73
- end
74
57
 
75
- def ensure_in_gitignore file_glob
76
- if File.exist?(GITIGNORE_FILE)
77
- if File.read(GITIGNORE_FILE).split("\n").include?(file_glob)
78
- note "found '#{file_glob}' already present in #{GITIGNORE_FILE}"
79
- return
80
- end
58
+ @pipelines = []
59
+ if block
60
+ block.call(self)
61
+ create_tasks!
62
+ else
63
+ add_pipeline(@project_name, (options[:pipeline_erb_filename] || "#{project_name}.yml"))
81
64
  end
82
- note "adding '#{file_glob}' to #{GITIGNORE_FILE}"
83
- File.open(GITIGNORE_FILE, "a") { |f| f.puts file_glob }
84
65
  end
85
66
 
86
- def sh command
87
- running "(in #{Dir.pwd}) #{command}"
88
- super command, verbose: false
67
+ def add_pipeline name, erb_filename
68
+ @pipelines << Concourse::Pipeline.new(name, @directory, erb_filename)
89
69
  end
90
70
 
91
- def running message
92
- print bold, red, "RUNNING: ", reset, message, "\n"
71
+ def pipeline_subcommands command
72
+ pipelines.collect { |p| "#{command}:#{p.name}" }
93
73
  end
94
74
 
95
- def note message
96
- print bold, green, "NOTE: ", reset, message, "\n"
75
+ def rake_init
76
+ FileUtils.mkdir_p File.join(directory, "tasks")
77
+ pipelines.each do |pipeline|
78
+ FileUtils.touch pipeline.erb_filename
79
+ ensure_in_gitignore pipeline.filename
80
+ end
81
+ ensure_in_gitignore secrets_filename
97
82
  end
98
83
 
99
84
  def create_tasks!
@@ -101,11 +86,13 @@ class Concourse
101
86
  mkdir_p directory
102
87
  end
103
88
 
104
- unless File.exist? pipeline_erb_filename
105
- warn "WARNING: concourse template #{pipeline_erb_filename.inspect} does not exist, run `rake concourse:init`"
106
- end
89
+ pipelines.each do |pipeline|
90
+ CLOBBER.include pipeline.filename if defined?(CLOBBER)
107
91
 
108
- CLOBBER.include pipeline_filename if defined?(CLOBBER)
92
+ unless File.exist? pipeline.erb_filename
93
+ warn "WARNING: concourse template #{pipeline.erb_filename.inspect} does not exist, run `rake concourse:init`"
94
+ end
95
+ end
109
96
 
110
97
  namespace :concourse do
111
98
  #
@@ -119,48 +106,67 @@ class Concourse
119
106
  #
120
107
  # pipeline commands
121
108
  #
122
- desc "generate and validate the pipeline file for #{project_name}"
123
- task "generate" do |t|
124
- File.open pipeline_filename, "w" do |f|
125
- f.write erbify(File.read(pipeline_erb_filename))
109
+ desc "generate and validate all pipeline files"
110
+ task "generate" => pipeline_subcommands("generate")
111
+
112
+ pipelines.each do |pipeline|
113
+ desc "generate and validate the #{pipeline.name} pipeline file"
114
+ task "generate:#{pipeline.name}" do
115
+ File.open pipeline.filename, "w" do |f|
116
+ f.write erbify(File.read(pipeline.erb_filename))
117
+ end
118
+ sh "fly validate-pipeline -c #{pipeline.filename}"
126
119
  end
127
- sh "fly validate-pipeline -c #{pipeline_filename}"
128
120
  end
129
121
 
130
- desc "upload the pipeline file for #{project_name}"
131
- task "set" => ["generate"] do |t, args|
132
- options = [
133
- "-p '#{project_name}'",
134
- "-c '#{pipeline_filename}'",
135
- ]
136
- if File.exist? secrets_filename
137
- note "using #{secrets_filename} to resolve template vars"
138
- options << "-l '#{secrets_filename}'"
122
+ desc "upload all pipeline files"
123
+ task "set" => pipeline_subcommands("set")
124
+
125
+ pipelines.each do |pipeline|
126
+ desc "upload the #{pipeline.name} pipeline file"
127
+ task "set:#{pipeline.name}" => "generate:#{pipeline.name}" do
128
+ options = [
129
+ "-p '#{pipeline.name}'",
130
+ "-c '#{pipeline.filename}'",
131
+ ]
132
+ if File.exist? secrets_filename
133
+ note "using #{secrets_filename} to resolve template vars in #{pipeline.filename}"
134
+ options << "-l '#{secrets_filename}'"
135
+ end
136
+ sh "fly -t #{fly_target} set-pipeline #{options.join(" ")}"
139
137
  end
140
- sh "fly -t #{fly_target} set-pipeline #{options.join(" ")}"
141
138
  end
142
139
 
143
140
  %w[expose hide pause unpause destroy].each do |command|
144
- desc "#{command} the #{project_name} pipeline"
145
- task command do |t, args|
146
- sh "fly -t #{fly_target} #{command}-pipeline -p #{project_name}"
141
+ desc "#{command} all pipelines"
142
+ task command => pipeline_subcommands(command)
143
+
144
+ pipelines.each do |pipeline|
145
+ desc "#{command} the #{pipeline.name} pipeline"
146
+ task "#{command}:#{pipeline.name}" do
147
+ sh "fly -t #{fly_target} #{command}-pipeline -p #{pipeline.name}"
148
+ end
147
149
  end
148
150
  end
149
151
 
150
- desc "remove generate pipeline file"
151
- task "clean" do |t|
152
- rm_f pipeline_filename
152
+ desc "remove generated pipeline files"
153
+ task "clean" do
154
+ pipelines.each do |pipeline|
155
+ rm_f pipeline.filename
156
+ end
153
157
  end
154
158
 
155
159
  #
156
160
  # task commands
157
161
  #
158
- desc "list all the available tasks from the #{project_name} pipeline"
162
+ desc "list all the available tasks from the #{project_name} pipelines"
159
163
  task "tasks" => "generate" do
160
164
  tasks = []
161
165
 
162
- each_task do |job, task|
163
- tasks << "#{job["name"]}/#{task["task"]}"
166
+ pipelines.each do |pipeline|
167
+ each_task(pipeline) do |job, task|
168
+ tasks << "#{job["name"]}/#{task["task"]}"
169
+ end
164
170
  end
165
171
 
166
172
  note "Available Concourse tasks for #{project_name} are:"
@@ -174,7 +180,7 @@ class Concourse
174
180
  raise "ERROR: must specify a task name, like `rake #{t.name}[target,taskname]`"
175
181
  end
176
182
 
177
- concourse_task = find_task job_task
183
+ concourse_task = find_task(job_task)
178
184
  raise "ERROR: could not find task `#{job_task}`" unless concourse_task
179
185
 
180
186
  fly_execute_args = args[:fly_execute_args] || Concourse.default_execute_args(concourse_task)
@@ -192,7 +198,7 @@ class Concourse
192
198
  #
193
199
  # builds commands
194
200
  #
195
- desc "abort all running builds for this pipeline"
201
+ desc "abort all running builds for this concourse team"
196
202
  task "abort-builds" do |t, args|
197
203
  `fly -t #{fly_target} builds`.each_line do |line|
198
204
  pipeline_job, build_id, status = *line.split(/\s+/)[1,3]
@@ -206,7 +212,7 @@ class Concourse
206
212
  # worker commands
207
213
  #
208
214
  desc "prune any stalled workers"
209
- task "prune-stalled-workers" do |t, args|
215
+ task "prune-stalled-workers" do
210
216
  `fly -t #{fly_target} workers | fgrep stalled`.each_line do |line|
211
217
  worker_id = line.split.first
212
218
  system("fly -t #{fly_target} prune-worker -w #{worker_id}")
@@ -214,28 +220,4 @@ class Concourse
214
220
  end
215
221
  end
216
222
  end
217
-
218
- def each_job
219
- pipeline = YAML.load_file(pipeline_filename)
220
-
221
- pipeline["jobs"].each do |job|
222
- yield job
223
- end
224
- end
225
-
226
- def each_task
227
- each_job do |job|
228
- job["plan"].each do |task|
229
- yield job, task if task["task"]
230
- end
231
- end
232
- end
233
-
234
- def find_task job_task
235
- job_name, task_name = *job_task.split("/")
236
- each_task do |job, task|
237
- return task if task["task"] == task_name && job["name"] == job_name
238
- end
239
- nil
240
- end
241
223
  end
@@ -0,0 +1,12 @@
1
+ class Concourse
2
+ class Pipeline
3
+ attr_reader :name, :directory, :erb_filename, :filename
4
+
5
+ def initialize name, directory, erb_filename
6
+ @name = name
7
+ @directory = directory
8
+ @erb_filename = File.join(@directory, erb_filename)
9
+ @filename = File.join(@directory, erb_filename + ".generated")
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,64 @@
1
+ require 'term/ansicolor'
2
+
3
+ class Concourse
4
+ module Util
5
+ include Term::ANSIColor
6
+
7
+ GITIGNORE_FILE = ".gitignore"
8
+ GITATTRIBUTES_FILE = ".gitattributes"
9
+
10
+ def ensure_in_gitignore file_glob
11
+ if File.exist?(GITIGNORE_FILE)
12
+ if File.read(GITIGNORE_FILE).split("\n").include?(file_glob)
13
+ note "found '#{file_glob}' already present in #{GITIGNORE_FILE}"
14
+ return
15
+ end
16
+ end
17
+ note "adding '#{file_glob}' to #{GITIGNORE_FILE}"
18
+ File.open(GITIGNORE_FILE, "a") { |f| f.puts file_glob }
19
+ end
20
+
21
+ def sh command
22
+ running "(in #{Dir.pwd}) #{command}"
23
+ super command, verbose: false
24
+ end
25
+
26
+ def running message
27
+ print bold, red, "RUNNING: ", reset, message, "\n"
28
+ end
29
+
30
+ def note message
31
+ print bold, green, "NOTE: ", reset, message, "\n"
32
+ end
33
+
34
+ def erbify document_string, *args
35
+ ERB.new(document_string, nil, "%-").result(binding)
36
+ end
37
+
38
+ def each_job pipeline
39
+ pdata = YAML.load_file(pipeline.filename)
40
+
41
+ pdata["jobs"].each do |job|
42
+ yield job
43
+ end
44
+ end
45
+
46
+ def each_task pipeline
47
+ each_job(pipeline) do |job|
48
+ job["plan"].each do |task|
49
+ yield job, task if task["task"]
50
+ end
51
+ end
52
+ end
53
+
54
+ def find_task job_task
55
+ job_name, task_name = *job_task.split("/")
56
+ pipelines.each do |pipeline|
57
+ each_task(pipeline) do |job, task|
58
+ return task if task["task"] == task_name && job["name"] == job_name
59
+ end
60
+ end
61
+ nil
62
+ end
63
+ end
64
+ end
@@ -2,5 +2,5 @@ require "rake"
2
2
  require "erb"
3
3
 
4
4
  class Concourse
5
- VERSION = "0.22.0"
5
+ VERSION = "0.23.0"
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: concourse
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.22.0
4
+ version: 0.23.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Dalessio
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-01-18 00:00:00.000000000 Z
11
+ date: 2019-01-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: term-ansicolor
@@ -84,6 +84,8 @@ files:
84
84
  - Rakefile
85
85
  - concourse.gemspec
86
86
  - lib/concourse.rb
87
+ - lib/concourse/pipeline.rb
88
+ - lib/concourse/util.rb
87
89
  - lib/concourse/version.rb
88
90
  homepage: https://github.com/flavorjones/concourse-gem
89
91
  licenses: