robot_sweatshop 0.4.7 → 0.4.9

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
  SHA1:
3
- metadata.gz: 7f1852d96c663c8d61e07123a2bf84162ba15698
4
- data.tar.gz: 5b592ff4da66bb363625e9beeeb3dd0c64c8e85c
3
+ metadata.gz: 0117fcc7d8e0d91f24a08a46a8b7e24f4cd0b65b
4
+ data.tar.gz: e01c0e51398d698e8dc4d7a56f53c77fb35955e5
5
5
  SHA512:
6
- metadata.gz: ecdb8c16cbee4b20c667745c251953edc3850b59110ed850413a62c9454102c7455021c599af4b3b780f5acf3488d93b3d88c04d48877be6cd57b5c4a488aca8
7
- data.tar.gz: ee78994a812f67a8623051e77f4252ea3c8b8f9746230861494e74f18bdb9a2718ab76dc4552b5eb296244993879b70b61980b74cba1e147310e683f651e459e
6
+ metadata.gz: 1255a647775979d5da1d5fb2be512e23af38979b6aba58dd37906c45e1da4f25a34d72d0b31e48a13a50f2e08b8661b2da611c1bbb76ce98ffde092e8490599a
7
+ data.tar.gz: 8dda97b15749001ff014e0500bf37663cffad1201d1f91066f057068b68fc752913b87ff638aa67e0386541c075def54d4c8f8e305ff7433e9382e4eda658698
data/Gemfile.lock CHANGED
@@ -1,11 +1,12 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- robot_sweatshop (0.4.6)
4
+ robot_sweatshop (0.4.8)
5
5
  bundler
6
6
  commander
7
7
  configatron
8
8
  contracts
9
+ erubis
9
10
  exponential-backoff
10
11
  eye
11
12
  ezmq
@@ -33,6 +34,7 @@ GEM
33
34
  docile (1.1.5)
34
35
  domain_name (0.5.24)
35
36
  unf (>= 0.0.5, < 1.0.0)
37
+ erubis (2.7.0)
36
38
  exponential-backoff (0.0.2)
37
39
  eye (0.6.4)
38
40
  celluloid (~> 0.15.0)
@@ -44,7 +46,7 @@ GEM
44
46
  ffi-rzmq (~> 2.0)
45
47
  faker (1.4.3)
46
48
  i18n (~> 0.5)
47
- ffi (1.9.8)
49
+ ffi (1.9.9)
48
50
  ffi-rzmq (2.0.4)
49
51
  ffi-rzmq-core (>= 1.0.1)
50
52
  ffi-rzmq-core (1.0.3)
@@ -62,10 +64,13 @@ GEM
62
64
  i18n (0.7.0)
63
65
  json (1.8.3)
64
66
  kintama (0.1.13)
67
+ mini_portile (0.6.2)
65
68
  moneta (0.8.0)
66
69
  nio4r (1.1.0)
70
+ nokogiri (1.6.6.2)
71
+ mini_portile (~> 0.6.0)
67
72
  oj (2.12.9)
68
- rack (1.6.1)
73
+ rack (1.6.4)
69
74
  rack-protection (1.5.3)
70
75
  rack
71
76
  rainbow (2.0.0)
@@ -106,6 +111,7 @@ PLATFORMS
106
111
  DEPENDENCIES
107
112
  http
108
113
  kintama
114
+ nokogiri
109
115
  rake
110
116
  robot_sweatshop!
111
117
  simplecov
data/README.md CHANGED
@@ -6,44 +6,53 @@
6
6
 
7
7
  Robot Sweatshop is a single-purpose CI server that runs collections of arbitrary scripts when it needs to, usually when new code is pushed. There's no assumptions about what you want to report, what front-end you need, or even what repositories you want to clone because you can do that better than I can. It's just you, your code, and the scripts that test and deploy it.
8
8
 
9
- # Quick start
9
+ ## Quick start
10
10
 
11
11
  - install [ZMQ as described in the EZMQ gem](https://github.com/colstrom/ezmq#operating-system-notes)
12
12
  - `gem install robot_sweatshop`
13
13
  - `sweatshop start`
14
14
  - `sweatshop job example --auto`
15
- - `curl -d '' localhost:8080/run/example`
16
- - `cat .robot_sweatshop/log/job-worker.log`
15
+ - `curl -d '' localhost:10555/run/example`
16
+ - `cat .robot_sweatshop/log/worker.log`
17
17
 
18
- # Usage
18
+ ## Usage
19
19
 
20
20
  Drop the `--auto` flag to create the job interactively. You can specify which branches will trigger the job, which commands will be run, and any environment variables you might need. See [the wiki](https://github.com/JScott/robot_sweatshop/wiki/Job-configuration) for more details.
21
21
 
22
22
  Robot Sweatshop uses [Eye](https://github.com/kostya/eye) to handle its processes so you can use its commandline tool to monitor their status.
23
23
 
24
- # Configuration
24
+ Oh yeah, and there's a front end in case you want to run and watch jobs without using a console. By default it runs on port 10554.
25
+
26
+ ## The implicit job
27
+
28
+ Just like Travis-CI will look for `.travis.yml`, Robot Sweatshop will look for `.robot_sweatshop.yaml` at the end of a job and run the job within immediately after. See [the wiki](https://github.com/JScott/robot_sweatshop/wiki/Implicit-jobs) for more details on how you might utilize this.
29
+
30
+ This is useful because it allows you to have a more centralized source of truth for building and testing your code. You can set up your canonical testing definition in your repository and have it pulled down for any server that runs it.
31
+
32
+ ## Configuration
25
33
 
26
34
  By default, Robot Sweatshop looks in your current working path to configure and run. You can supply a custom configuration with `sweatshop config [local|user|system]`. See [the wiki](https://github.com/JScott/robot_sweatshop/wiki) for more information.
27
35
 
28
- # Supported payload formats
36
+ ## Supported payload formats
29
37
 
30
38
  - Github (application/json format only)
31
39
  - Bitbucket
32
40
  - JSON
33
41
  - Empty
34
42
 
35
- # Security
43
+ ## Security
36
44
 
37
45
  You probably don't want to run Robot Sweatshop as a sudo user. Create a testing user and group and run `sweatshop start` as them.
38
46
 
39
- # Roadmap
47
+ ## Roadmap
40
48
 
41
49
  1.0
42
50
 
43
- - Mascot
51
+ - Mascot/logo
44
52
 
45
53
  1.1
46
54
 
55
+ - Use something appropriate than TCP for ZMQ connections
47
56
  - Easier way to run multiple workers
48
57
  - Push/pull out node that worker streams output to
49
58
  - Add worker tags to output so it can all go to one file
data/Rakefile CHANGED
@@ -1,5 +1,13 @@
1
- require 'bundler/setup'
1
+ require 'terminal-announce'
2
+ require 'rake'
2
3
 
3
4
  task :test do
4
5
  require_relative 'test/all'
5
6
  end
7
+
8
+ task :build do
9
+ Announce.info 'Building and installing local gem...'
10
+ puts `rm -rf robot_sweatshop-*.gem`
11
+ puts `gem build robot_sweatshop.gemspec --force`
12
+ puts `gem install robot_sweatshop-*.gem`
13
+ end
data/bin/sweatshop CHANGED
@@ -7,7 +7,7 @@ require 'robot_sweatshop/config'
7
7
  require 'robot_sweatshop/create-config-directories'
8
8
 
9
9
  program :name, 'Robot Sweatshop'
10
- program :version, '0.4.7'
10
+ program :version, '0.4.9'
11
11
  program :description, 'A lightweight, nonopinionated CI server'
12
12
  program :help, 'Author', 'Justin Scott <jvscott@gmail.com>'
13
13
 
data/bin/sweatshop-input CHANGED
@@ -7,7 +7,7 @@ require 'robot_sweatshop/connections'
7
7
  using ExtendedEZMQ
8
8
 
9
9
  configure do
10
- set :port, configatron.http_port
10
+ set :port, configatron.input_port
11
11
  set :bind, configatron.http_bind
12
12
  set :run, true
13
13
  set :conveyor, EZMQ::Client.new(port: configatron.conveyor_port)
@@ -16,7 +16,7 @@ configure do
16
16
  end
17
17
 
18
18
  get '/' do
19
- 'Everything\'s on schedule!'
19
+ 'Usage: POST /run/<job-name>'
20
20
  end
21
21
 
22
22
  post '/run/:job_name' do
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+ require 'sinatra'
3
+ require 'sinatra/cross_origin'
4
+ require 'robot_sweatshop/config'
5
+ require 'robot_sweatshop/overseer'
6
+
7
+ helpers OverseerHelper
8
+
9
+ configure do
10
+ set :port, configatron.overseer_port
11
+ set :bind, configatron.http_bind
12
+ set :run, true
13
+ enable :cross_origin if configatron.http_cross_origin
14
+ end
15
+
16
+ get '/' do
17
+ frontpage
18
+ end
19
+
20
+ get '/log' do
21
+ redirect to('/'), 303 if params[:for].nil?
22
+ process = params[:for]
23
+ log_page_for process
24
+ end
data/bin/sweatshop-worker CHANGED
@@ -27,19 +27,19 @@ def ensure_shell_for(command)
27
27
  "#{command};"
28
28
  end
29
29
 
30
- Contract Hash, String => Maybe[IO]
31
- def stream_command(context, command)
30
+ Contract String, Hash => Maybe[IO]
31
+ def stream(command, with_context:)
32
32
  command = ensure_shell_for command
33
- IO.popen(context, command) do |stream|
34
- puts stream.gets until stream.eof? # TODO: stdout not being tested properly
33
+ IO.popen(with_context, command) do |stream|
34
+ puts stream.gets until stream.eof?
35
35
  end
36
36
  end
37
37
 
38
- Contract Hash, String => nil
39
- def execute(context, command)
38
+ Contract String, Hash => nil
39
+ def execute(command, context)
40
40
  puts "Executing '#{command}'"
41
41
  begin
42
- stream_command context, command
42
+ stream command, with_context: context
43
43
  rescue Errno::ENOENT => error
44
44
  puts error.message
45
45
  end
@@ -52,6 +52,19 @@ def finish(id)
52
52
  puts "Job finished.\n\n"
53
53
  end
54
54
 
55
+ Contract Array, Hash => Any
56
+ def run(commands, with_context: {})
57
+ commands.each { |command| execute command, with_context }
58
+ end
59
+
60
+ Contract None => Any
61
+ def run_implicit_job
62
+ implicit_job_file = '.robot_sweatshop.yaml'
63
+ return unless File.exist? implicit_job_file
64
+ implicit_job = YAML.load_file implicit_job_file
65
+ run implicit_job['commands'], with_context: implicit_job['environment']
66
+ end
67
+
55
68
  puts 'Starting'
56
69
  @sockets = {
57
70
  conveyor: EZMQ::Client.new(port: configatron.conveyor_port),
@@ -62,8 +75,8 @@ puts 'Starting'
62
75
  @sockets[:puller].listen do |data|
63
76
  puts "Running: #{data}"
64
77
  from_workspace named: data[:job_name] do
65
- context = data[:context] || {}
66
- data[:commands].each { |command| execute context, command }
78
+ run data[:commands], with_context: data[:context]
79
+ run_implicit_job
67
80
  end
68
81
  finish data[:job_id]
69
82
  end
data/config.defaults.yaml CHANGED
@@ -5,11 +5,12 @@ job_path: .robot_sweatshop/jobs
5
5
  workspace_path: .robot_sweatshop/workspaces
6
6
  database_path: .robot_sweatshop/db
7
7
  scripts_path: .robot_sweatshop/scripts
8
- http_port: 8080
9
8
  http_bind: 0.0.0.0
10
9
  http_cross_origin: true
11
- conveyor_port: 5555
12
- payload_parser_port: 5556
13
- job_dictionary_port: 5557
14
- worker_port: 5558
10
+ overseer_port: 10554
11
+ input_port: 10555
12
+ conveyor_port: 10556
13
+ payload_parser_port: 10557
14
+ job_dictionary_port: 10558
15
+ worker_port: 10559
15
16
  job_timeout_length: 300 # 5 minutes
data/docs/README.md CHANGED
@@ -4,6 +4,12 @@
4
4
 
5
5
  # Message Data Schema
6
6
 
7
+ ## overseer
8
+
9
+ ```
10
+ POST payload /run/:job
11
+ ```
12
+
7
13
  ## input
8
14
 
9
15
  ```
@@ -1,11 +1,12 @@
1
1
  digraph architecture {
2
- label="Robot Sweatshop Processes"
2
+ label="Robot Sweatshop process interaction"
3
3
  labelloc="top"
4
4
 
5
+ O [label="Overseer",shape=box]
5
6
  I [label="Input"]
6
7
  A [label="Assembler"]
7
8
  W [label="Worker"]
8
- subgraph cluster_0 {
9
+ subgraph cluster_services {
9
10
  label="Req/Rep Services"
10
11
  labelloc="bottom"
11
12
  style="dashed"
@@ -14,9 +15,13 @@ digraph architecture {
14
15
  D [label="Job Dictionary"]
15
16
  }
16
17
 
17
- I->C [taillabel="1..*"]
18
+ O->I
19
+ I->C
18
20
  A->C [dir="both"]
19
21
  A->P [dir="both"]
20
22
  A->D [dir="both"]
21
23
  A->W [headlabel="1..*",labeldistance=2]
24
+ W->C
25
+
26
+ { rank=same; I W A }
22
27
  }
Binary file
@@ -4,16 +4,7 @@ module CLI
4
4
  # Methods for creating and editing jobs
5
5
  module Job
6
6
  def self.default
7
- "---
8
- # branch_whitelist:
9
- # - master
10
-
11
- commands:
12
- - echo \"Hello $WORLD!\"
13
-
14
- environment:
15
- WORLD: Earth
16
- "
7
+ File.read "#{__dir__}/../templates/default_job.yaml"
17
8
  end
18
9
 
19
10
  def self.path_for(job)
@@ -0,0 +1,35 @@
1
+ require 'erubis'
2
+
3
+ # Helper methods for the Overseer Sinatra server
4
+ module OverseerHelper
5
+ def log_list
6
+ %w(assembler conveyor input job-dictionary payload-parser worker)
7
+ end
8
+
9
+ def job_list
10
+ log_path = File.expand_path "#{configatron.job_path}"
11
+ p log_path, Dir.glob("#{log_path}/*.yaml")
12
+ Dir.glob("#{log_path}/*.yaml").map { |path| File.basename path, '.yaml' }
13
+ end
14
+
15
+ def frontpage
16
+ context = {
17
+ jobs: job_list,
18
+ logs: log_list,
19
+ input_port: configatron.input_port
20
+ }
21
+ template = File.read "#{__dir__}/templates/index.html.eruby"
22
+ eruby = Erubis::Eruby.new template
23
+ eruby.result context
24
+ end
25
+
26
+ def log_page_for(process)
27
+ context = {
28
+ process: process,
29
+ raw_log: File.read("#{configatron.logfile_path}/#{process}.log")
30
+ }
31
+ template = File.read "#{__dir__}/templates/log.html.eruby"
32
+ eruby = Erubis::Eruby.new template
33
+ eruby.result context
34
+ end
35
+ end
@@ -0,0 +1,9 @@
1
+ ---
2
+ # branch_whitelist:
3
+ # - master
4
+
5
+ commands:
6
+ - echo "Hello $WORLD!"
7
+
8
+ environment:
9
+ WORLD: Earth
@@ -0,0 +1,45 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <title>Robot Sweatshop</title>
6
+ <script type="text/javascript" src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
7
+ <script>
8
+ var QueueJob = function() {
9
+ var job = $('select#job').val();
10
+ var data = $('textarea#data').val();
11
+ console.log("http://localhost:<%= input_port %>/run/"+job);
12
+ $.post("http://localhost:<%= input_port %>/run/"+job, data);
13
+ }
14
+ </script>
15
+ <style>
16
+ button { background-color: #00db00; padding: 10px 20px; font-size: 1.2em; }
17
+ </style>
18
+ </head>
19
+
20
+ <body>
21
+ <h1>Robot Sweatshop</h1>
22
+
23
+ <h2>Big Green Button</h2>
24
+ <form class="job_runner">
25
+ <label for="job">Select job</label>
26
+ <select id="job">
27
+ <% for job in jobs %>
28
+ <option value="<%= job %>"><%= job %></option>
29
+ <% end %>
30
+ </select>
31
+ <br><br>
32
+ <label for="data">Data payload</label>
33
+ <textarea id="data">{}</textarea>
34
+ <br><br>
35
+ <button type="button" onclick="QueueJob()">Queue Job</button>
36
+ </form>
37
+
38
+ <h2>Logs</h2>
39
+ <ul>
40
+ <% for log in logs %>
41
+ <li><a href="/log?for=<%= log %>"><%= log %></a></li>
42
+ <% end %>
43
+ </ul>
44
+ </body>
45
+ </html>
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <title>Robot Sweatshop - <%= process %> log</title>
6
+ </head>
7
+
8
+ <body>
9
+ <h1>Raw <%= process %> log</h1>
10
+ <a href="/">Back</a>
11
+ <pre class="raw_log"><%= raw_log %></pre>
12
+ <a href="#">Top</a>
13
+ </body>
14
+ </html>
@@ -2,3 +2,4 @@ require_relative 'robot_sweatshop/config'
2
2
  require_relative 'robot_sweatshop/payload'
3
3
  require_relative 'robot_sweatshop/cli'
4
4
  require_relative 'robot_sweatshop/connections'
5
+ require_relative 'robot_sweatshop/overseer'
data/robot_sweatshop.eye CHANGED
@@ -36,6 +36,12 @@ Eye.application :robot_sweatshop do
36
36
  end
37
37
  end
38
38
 
39
+ process :overseer do
40
+ pid_file "#{PID_PATH}/overseer.pid"
41
+ stdall "#{LOG_PATH}/overseer.log"
42
+ start_command "#{__dir__}/bin/sweatshop-overseer"
43
+ daemonize true
44
+ end
39
45
  process :input do
40
46
  pid_file "#{PID_PATH}/input.pid"
41
47
  stdall "#{LOG_PATH}/input.log"
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |gem|
2
2
  gem.name = 'robot_sweatshop'
3
- gem.version = '0.4.7'
3
+ gem.version = '0.4.9'
4
4
  gem.licenses = 'MIT'
5
5
  gem.authors = ['Justin Scott']
6
6
  gem.email = 'jvscott@gmail.com'
@@ -28,9 +28,11 @@ Gem::Specification.new do |gem|
28
28
  gem.add_runtime_dependency 'stubborn_queue'
29
29
  gem.add_runtime_dependency 'oj'
30
30
  gem.add_runtime_dependency 'exponential-backoff'
31
+ gem.add_runtime_dependency 'erubis'
31
32
 
32
33
  gem.add_development_dependency 'rake'
33
34
  gem.add_development_dependency 'kintama'
34
35
  gem.add_development_dependency 'http'
35
36
  gem.add_development_dependency 'simplecov'
37
+ gem.add_development_dependency 'nokogiri'
36
38
  end
data/test/all.rb CHANGED
@@ -1,3 +1,5 @@
1
+ require 'terminal-announce'
2
+
1
3
  # Because of needing to isolate processes, I can't run all tests in one call.
2
4
  # This means that I have multiple sets of results which isn't nice, but the
3
5
  # tests are largely for the sake of TDD anyway.
@@ -23,6 +25,7 @@ tests = %w(
23
25
  job_dictionary
24
26
  assembler
25
27
  worker
28
+ overseer
26
29
  end-to-end
27
30
  )
28
31
  exit_statuses = []
@@ -30,6 +33,13 @@ exit_statuses = []
30
33
  tests.each do |name|
31
34
  exit_statuses.push run_test(name)
32
35
  end
33
- exit 1 unless non_zero(exit_statuses).empty?
34
-
35
- puts "Everything passed successfully" # TODO: announce gem
36
+ if non_zero(exit_statuses).empty?
37
+ Announce.success 'Everything passed'
38
+ else
39
+ failed_tests = tests.each_with_index.select do |test, index|
40
+ exit_statuses[index] != 0
41
+ end
42
+ failed_tests.map! { |test| test[0] }
43
+ Announce.failure "Tests failed: #{failed_tests.join ', '}"
44
+ exit 1
45
+ end
@@ -0,0 +1,50 @@
1
+ require 'bundler/setup'
2
+ require 'kintama'
3
+ require 'timeout'
4
+ require 'http'
5
+ require 'nokogiri'
6
+ require_relative 'shared/scaffolding'
7
+ require_relative 'shared/helpers'
8
+ $stdout.sync = true
9
+
10
+ Kintama.on_start do
11
+ @pids = TestProcess.start %w(overseer)
12
+ sleep $a_while
13
+ end
14
+
15
+ Kintama.on_finish do
16
+ TestProcess.stop @pids
17
+ end
18
+
19
+ given 'the Overseer' do
20
+ include OverseerHelper
21
+
22
+ context '/' do
23
+ setup { Timeout.timeout($a_while) { @response = HTTP.get overseer_url } }
24
+ should('respond') { assert_equal 200, @response.code }
25
+ should('link to process logs') do
26
+ page = Nokogiri::HTML(@response.to_s)
27
+ links = page.css('a').select { |link| link.text.include? 'worker' }
28
+ assert_not_equal 0, links.count
29
+ end
30
+ should('have a form for running jobs') do
31
+ page = Nokogiri::HTML(@response.to_s)
32
+ form = page.css('form.job_runner')
33
+ assert_not_equal 0, form.count
34
+ end
35
+ end
36
+ context '/log' do
37
+ setup { Timeout.timeout($a_while) { @response = HTTP.get overseer_url('log') } }
38
+ should('redirect') { assert_equal 303, @response.code }
39
+ end
40
+ context '/log?for=worker' do
41
+ setup { Timeout.timeout($a_while) { @response = HTTP.get overseer_url('log?for=worker') } }
42
+ should('respond') { assert_equal 200, @response.code }
43
+ should('show logs from file') do
44
+ page = Nokogiri::HTML(@response.to_s)
45
+ log = File.read "#{configatron.logfile_path}/worker.log"
46
+ output = page.css('.raw_log').first
47
+ assert_equal log, output.text, 'Expected raw log output'
48
+ end
49
+ end
50
+ end
@@ -11,7 +11,7 @@ module InputHelper
11
11
  end
12
12
 
13
13
  def input_url(for_job: 'test_job')
14
- "http://localhost:#{configatron.http_port}/run/#{for_job}"
14
+ "http://localhost:#{configatron.input_port}/run/#{for_job}"
15
15
  end
16
16
 
17
17
  def conveyor_enqueue(type)
@@ -33,6 +33,14 @@ module InputHelper
33
33
  }
34
34
  end
35
35
 
36
+ def implicit_job
37
+ job = {
38
+ 'commands' => ['echo $this >> test.txt'],
39
+ 'environment' => { 'this' => 'implicit'}
40
+ }
41
+ YAML.dump job
42
+ end
43
+
36
44
  def worker_push
37
45
  {
38
46
  commands: [
@@ -40,7 +48,8 @@ module InputHelper
40
48
  'echo $custom > test.txt',
41
49
  'custom_script',
42
50
  'custom_script >> test.txt',
43
- 'bad command about nothing'
51
+ 'bad command about nothing',
52
+ "echo '#{implicit_job}' > .robot_sweatshop.yaml"
44
53
  ],
45
54
  context: {
46
55
  'PATH' => "#{ENV['PATH']}:#{File.expand_path configatron.scripts_path}",
@@ -0,0 +1,8 @@
1
+ require 'bundler/setup'
2
+ require 'robot_sweatshop/config'
3
+
4
+ module OverseerHelper
5
+ def overseer_url(path = '')
6
+ "http://localhost:#{configatron.overseer_port}/#{path}"
7
+ end
8
+ end
@@ -1,5 +1,6 @@
1
1
  require_relative 'helpers/input'
2
2
  require_relative 'helpers/output'
3
+ require_relative 'helpers/overseer'
3
4
 
4
5
  $a_moment = 0.2
5
- $a_while = 1
6
+ $a_while = 1.0
data/test/worker_spec.rb CHANGED
@@ -56,6 +56,10 @@ describe 'the Worker' do
56
56
  assert_match /custom/, File.read(worker_output)
57
57
  end
58
58
 
59
+ should 'run implicit jobs' do
60
+ assert_match /implicit/, File.read(worker_output)
61
+ end
62
+
59
63
  should 'tell the conveyor that job is complete' do
60
64
  assert_equal 'finish', @worker_data[:method]
61
65
  assert_kind_of Fixnum, @worker_data[:data]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: robot_sweatshop
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.7
4
+ version: 0.4.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Scott
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-15 00:00:00.000000000 Z
11
+ date: 2015-07-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -192,6 +192,20 @@ dependencies:
192
192
  - - ">="
193
193
  - !ruby/object:Gem::Version
194
194
  version: '0'
195
+ - !ruby/object:Gem::Dependency
196
+ name: erubis
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ type: :runtime
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: '0'
195
209
  - !ruby/object:Gem::Dependency
196
210
  name: rake
197
211
  requirement: !ruby/object:Gem::Requirement
@@ -248,6 +262,20 @@ dependencies:
248
262
  - - ">="
249
263
  - !ruby/object:Gem::Version
250
264
  version: '0'
265
+ - !ruby/object:Gem::Dependency
266
+ name: nokogiri
267
+ requirement: !ruby/object:Gem::Requirement
268
+ requirements:
269
+ - - ">="
270
+ - !ruby/object:Gem::Version
271
+ version: '0'
272
+ type: :development
273
+ prerelease: false
274
+ version_requirements: !ruby/object:Gem::Requirement
275
+ requirements:
276
+ - - ">="
277
+ - !ruby/object:Gem::Version
278
+ version: '0'
251
279
  description: A lightweight, nonopinionated CI server.
252
280
  email: jvscott@gmail.com
253
281
  executables:
@@ -256,6 +284,7 @@ executables:
256
284
  - sweatshop-conveyor
257
285
  - sweatshop-input
258
286
  - sweatshop-job-dictionary
287
+ - sweatshop-overseer
259
288
  - sweatshop-payload-parser
260
289
  - sweatshop-worker
261
290
  extensions: []
@@ -273,6 +302,7 @@ files:
273
302
  - bin/sweatshop-conveyor
274
303
  - bin/sweatshop-input
275
304
  - bin/sweatshop-job-dictionary
305
+ - bin/sweatshop-overseer
276
306
  - bin/sweatshop-payload-parser
277
307
  - bin/sweatshop-worker
278
308
  - config.defaults.yaml
@@ -288,11 +318,15 @@ files:
288
318
  - lib/robot_sweatshop/config.rb
289
319
  - lib/robot_sweatshop/connections.rb
290
320
  - lib/robot_sweatshop/create-config-directories.rb
321
+ - lib/robot_sweatshop/overseer.rb
291
322
  - lib/robot_sweatshop/payload.rb
292
323
  - lib/robot_sweatshop/payload/bitbucket.rb
293
324
  - lib/robot_sweatshop/payload/github.rb
294
325
  - lib/robot_sweatshop/payload/json.rb
295
326
  - lib/robot_sweatshop/payload/payload.rb
327
+ - lib/robot_sweatshop/templates/default_job.yaml
328
+ - lib/robot_sweatshop/templates/index.html.eruby
329
+ - lib/robot_sweatshop/templates/log.html.eruby
296
330
  - robot_sweatshop.eye
297
331
  - robot_sweatshop.gemspec
298
332
  - test/README.md
@@ -310,10 +344,12 @@ files:
310
344
  - test/end-to-end_spec.rb
311
345
  - test/input_spec.rb
312
346
  - test/job_dictionary_spec.rb
347
+ - test/overseer_spec.rb
313
348
  - test/payload_parser_spec.rb
314
349
  - test/shared/helpers.rb
315
350
  - test/shared/helpers/input.rb
316
351
  - test/shared/helpers/output.rb
352
+ - test/shared/helpers/overseer.rb
317
353
  - test/shared/scaffolding.rb
318
354
  - test/shared/stub.rb
319
355
  - test/worker_spec.rb
@@ -353,6 +389,7 @@ test_files:
353
389
  - test/shared/helpers.rb
354
390
  - test/shared/helpers/input.rb
355
391
  - test/shared/helpers/output.rb
392
+ - test/shared/helpers/overseer.rb
356
393
  - test/shared/scaffolding.rb
357
394
  - test/shared/stub.rb
358
395
  has_rdoc: