is_it_done_yet 0.1.0 → 0.6.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.
- checksums.yaml +5 -5
- data/.github/workflows/ruby.yml +33 -0
- data/.gitignore +5 -2
- data/CHANGELOG.md +32 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +79 -0
- data/README.md +15 -0
- data/Rakefile +5 -4
- data/bin/console +4 -3
- data/config.ru +19 -0
- data/examples/ci-clear +47 -0
- data/examples/ci-deploy +2 -0
- data/examples/ci-post +2 -1
- data/examples/ci-put +54 -0
- data/examples/ci-sync +21 -5
- data/examples/config.ru +11 -1
- data/is_it_done_yet.gemspec +22 -22
- data/lib/is_it_done_yet.rb +4 -89
- data/lib/is_it_done_yet/version.rb +3 -1
- data/lib/is_it_done_yet/web_app.rb +139 -0
- metadata +93 -61
- data/.travis.yml +0 -20
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 3370c312f841a7cb85eacf8a0f52945c3cd662dce2e45788d3c9e60908866ae0
|
|
4
|
+
data.tar.gz: 481779c28ea71076b0c9dd9ffb902d53bf9aa4bc94896608ff6a433bc7c39f6d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7c9e4dc318b6ce443062e9d7dd796e36ead41989e7671ccbe3df0e0ebe99d5cbba4290c5b71408abcf83ff9f622facb6dd07c23194136d741339eb4f1e26ee7c
|
|
7
|
+
data.tar.gz: 032acfa618083162944e0d9253ce094a7682db09a18957b2d925363d1c886d376a1240cf1c9929e14984504d7503007c6f30838f0a18c96f6a8763e41a2d6543
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# This workflow uses actions that are not certified by GitHub.
|
|
2
|
+
# They are provided by a third-party and are governed by
|
|
3
|
+
# separate terms of service, privacy policy, and support
|
|
4
|
+
# documentation.
|
|
5
|
+
# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
|
|
6
|
+
# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
|
|
7
|
+
|
|
8
|
+
name: Ruby
|
|
9
|
+
|
|
10
|
+
on:
|
|
11
|
+
push:
|
|
12
|
+
branches: [ master ]
|
|
13
|
+
pull_request:
|
|
14
|
+
branches: [ master ]
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
test:
|
|
18
|
+
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v2
|
|
23
|
+
- name: Set up Ruby
|
|
24
|
+
# To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
|
|
25
|
+
# change this to (see https://github.com/ruby/setup-ruby#versioning):
|
|
26
|
+
uses: ruby/setup-ruby@v1
|
|
27
|
+
# uses: ruby/setup-ruby@ec106b438a1ff6ff109590de34ddc62c540232e0
|
|
28
|
+
with:
|
|
29
|
+
ruby-version: 2.6
|
|
30
|
+
- name: Install dependencies
|
|
31
|
+
run: bundle install
|
|
32
|
+
- name: Run tests
|
|
33
|
+
run: bundle exec rake
|
data/.gitignore
CHANGED
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# 0.6.0
|
|
2
|
+
|
|
3
|
+
Bumping dependencies
|
|
4
|
+
|
|
5
|
+
# 0.5.0
|
|
6
|
+
|
|
7
|
+
Bumping dependencies
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# 0.4.0
|
|
11
|
+
|
|
12
|
+
Features:
|
|
13
|
+
|
|
14
|
+
* Introduced `PUT /builds/:build_id/nodes/:node_id` which enables CI scripts that update node values for instance when rebuilding.
|
|
15
|
+
|
|
16
|
+
# 0.3.0
|
|
17
|
+
|
|
18
|
+
Features:
|
|
19
|
+
|
|
20
|
+
* Clear state for a build using `DELETE /builds/:build_id`. Useful when a CI build is restarted.
|
|
21
|
+
|
|
22
|
+
Bug fixes:
|
|
23
|
+
|
|
24
|
+
* Posting now adheres to standard REST conventions; returns 201 with no body if successful and 409 if the node already exists.
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
# 0.2.0
|
|
28
|
+
|
|
29
|
+
Features:
|
|
30
|
+
|
|
31
|
+
* Build ids and node ids may now contain any (url-escaped) character.
|
|
32
|
+
- Note that when all nodes of a build are queried, `GET /builds/:build_id`, node ids will appear in their url-unescaped form.
|
data/Gemfile
CHANGED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
is_it_done_yet (0.6.0)
|
|
5
|
+
concurrent-ruby
|
|
6
|
+
json
|
|
7
|
+
rack-contrib
|
|
8
|
+
rack-token_auth
|
|
9
|
+
sinatra (~> 2.0)
|
|
10
|
+
thin
|
|
11
|
+
|
|
12
|
+
GEM
|
|
13
|
+
remote: https://rubygems.org/
|
|
14
|
+
specs:
|
|
15
|
+
byebug (11.0.0)
|
|
16
|
+
coderay (1.1.2)
|
|
17
|
+
concurrent-ruby (1.1.7)
|
|
18
|
+
daemons (1.3.1)
|
|
19
|
+
diff-lcs (1.3)
|
|
20
|
+
eventmachine (1.2.7)
|
|
21
|
+
json (2.3.1)
|
|
22
|
+
knapsack (1.17.1)
|
|
23
|
+
rake
|
|
24
|
+
method_source (0.9.2)
|
|
25
|
+
mustermann (1.1.1)
|
|
26
|
+
ruby2_keywords (~> 0.0.1)
|
|
27
|
+
pry (0.12.2)
|
|
28
|
+
coderay (~> 1.1.0)
|
|
29
|
+
method_source (~> 0.9.0)
|
|
30
|
+
rack (2.2.3)
|
|
31
|
+
rack-contrib (2.2.0)
|
|
32
|
+
rack (~> 2.0)
|
|
33
|
+
rack-protection (2.0.8.1)
|
|
34
|
+
rack
|
|
35
|
+
rack-test (1.1.0)
|
|
36
|
+
rack (>= 1.0, < 3)
|
|
37
|
+
rack-token_auth (0.2.0)
|
|
38
|
+
rack
|
|
39
|
+
rake (13.0.1)
|
|
40
|
+
rspec (3.8.0)
|
|
41
|
+
rspec-core (~> 3.8.0)
|
|
42
|
+
rspec-expectations (~> 3.8.0)
|
|
43
|
+
rspec-mocks (~> 3.8.0)
|
|
44
|
+
rspec-core (3.8.0)
|
|
45
|
+
rspec-support (~> 3.8.0)
|
|
46
|
+
rspec-expectations (3.8.2)
|
|
47
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
48
|
+
rspec-support (~> 3.8.0)
|
|
49
|
+
rspec-mocks (3.8.0)
|
|
50
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
51
|
+
rspec-support (~> 3.8.0)
|
|
52
|
+
rspec-support (3.8.0)
|
|
53
|
+
ruby2_keywords (0.0.2)
|
|
54
|
+
sinatra (2.0.8.1)
|
|
55
|
+
mustermann (~> 1.0)
|
|
56
|
+
rack (~> 2.0)
|
|
57
|
+
rack-protection (= 2.0.8.1)
|
|
58
|
+
tilt (~> 2.0)
|
|
59
|
+
thin (1.7.2)
|
|
60
|
+
daemons (~> 1.0, >= 1.0.9)
|
|
61
|
+
eventmachine (~> 1.0, >= 1.0.4)
|
|
62
|
+
rack (>= 1, < 3)
|
|
63
|
+
tilt (2.0.10)
|
|
64
|
+
|
|
65
|
+
PLATFORMS
|
|
66
|
+
ruby
|
|
67
|
+
|
|
68
|
+
DEPENDENCIES
|
|
69
|
+
bundler
|
|
70
|
+
byebug
|
|
71
|
+
is_it_done_yet!
|
|
72
|
+
knapsack
|
|
73
|
+
pry
|
|
74
|
+
rack-test
|
|
75
|
+
rake
|
|
76
|
+
rspec
|
|
77
|
+
|
|
78
|
+
BUNDLED WITH
|
|
79
|
+
2.1.0.pre.1
|
data/README.md
CHANGED
|
@@ -6,6 +6,8 @@ The intended use case is when you want to use one of the build nodes as a master
|
|
|
6
6
|
|
|
7
7
|
Specifically I built it to allow a travis job at work to do parallel tests with Knapsack and do a deploy if all tests pass.
|
|
8
8
|
|
|
9
|
+
An example Travis build configuration that takes advantage of a deployed `is_it_done_yet` service is available in [examples](exampels/.travis.yml).
|
|
10
|
+
|
|
9
11
|
## Installation
|
|
10
12
|
|
|
11
13
|
Add this line to your application's Gemfile:
|
|
@@ -26,6 +28,19 @@ Or install it yourself as:
|
|
|
26
28
|
|
|
27
29
|
This library includes a Rack application which you can instantiate by doing `IsItDoneYet.build_app`. In the [example Rack config](examples/config.ru) there's a setup with token-based auth middleware. Include a similar `config.ru` at the root of your application and run `bundle exec rackup` to start the web app locally. If you're running it on a cloud service, follow your service's guidelines on deploying Rack applications.
|
|
28
30
|
|
|
31
|
+
The web app provides five endpoints:
|
|
32
|
+
* `POST /builds/:build_id/nodes/:node_id` to write value for node, failing to overwrite.
|
|
33
|
+
- example request body: `{ "build_state" : "ok" }`
|
|
34
|
+
* `PUT /builds/:build_id/nodes/:node_id` to write or overwrite value for node.
|
|
35
|
+
- example request body: `{ "build_state" : "building", "build_state_on_overwrite" : "rebuilding" }`
|
|
36
|
+
* `GET /builds/:build_id`
|
|
37
|
+
- example response body: `{ "build_states": { "51": "bad", "52": "ok" } }`
|
|
38
|
+
* `GET /builds/:build_id/nodes/:node_id`
|
|
39
|
+
- example response body: `{ "build_state": "ok" }`
|
|
40
|
+
* `DELETE /builds/:build_id` to clear state for a build
|
|
41
|
+
|
|
42
|
+
The app keeps the build states in memory. This means that values will be lost after a restart of the service. Further, load balancing across multiple instances will only work if routing to the individual instance is consistent for the same `:build_id` path parameter, but scaling beyond one app instance is not currently a known use case.
|
|
43
|
+
|
|
29
44
|
## Development
|
|
30
45
|
|
|
31
46
|
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.
|
data/Rakefile
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
require "rspec/core/rake_task"
|
|
3
|
-
require 'knapsack'
|
|
1
|
+
# frozen_string_literal: true
|
|
4
2
|
|
|
3
|
+
require 'bundler/gem_tasks'
|
|
4
|
+
require 'rspec/core/rake_task'
|
|
5
|
+
require 'knapsack'
|
|
5
6
|
|
|
6
7
|
RSpec::Core::RakeTask.new(:spec)
|
|
7
8
|
|
|
8
|
-
task :
|
|
9
|
+
task default: :spec
|
|
9
10
|
|
|
10
11
|
Knapsack.load_tasks if defined?(Knapsack)
|
data/bin/console
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
4
|
+
require 'bundler/setup'
|
|
5
|
+
require 'is_it_done_yet'
|
|
5
6
|
|
|
6
7
|
# You can add fixtures and/or initialization code here to make experimenting
|
|
7
8
|
# with your gem easier. You can also use a different console, if you like.
|
|
@@ -10,5 +11,5 @@ require "is_it_done_yet"
|
|
|
10
11
|
# require "pry"
|
|
11
12
|
# Pry.start
|
|
12
13
|
|
|
13
|
-
require
|
|
14
|
+
require 'irb'
|
|
14
15
|
IRB.start(__FILE__)
|
data/config.ru
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'bundler'
|
|
4
|
+
require 'rack/contrib'
|
|
5
|
+
require 'rack/token_auth'
|
|
6
|
+
require 'is_it_done_yet'
|
|
7
|
+
Bundler.require
|
|
8
|
+
|
|
9
|
+
# Shared secret authentication
|
|
10
|
+
use Rack::TokenAuth do |token, _options, _env|
|
|
11
|
+
token == ENV['IIDY_TOKEN']
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Heartbeat endpoint
|
|
15
|
+
map '/health_check' do
|
|
16
|
+
run ->(_env) { [200, { 'Content-Type' => 'text/plain' }, ['success']] }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
run IsItDoneYet.build_app
|
data/examples/ci-clear
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
# Script that clears build status of
|
|
5
|
+
# travis nodes from synchronising service
|
|
6
|
+
|
|
7
|
+
require 'net/http'
|
|
8
|
+
require 'uri'
|
|
9
|
+
require 'json'
|
|
10
|
+
|
|
11
|
+
SLEEP_TIME_SECONDS = 30
|
|
12
|
+
|
|
13
|
+
env_ok = ENV['CI_NODE_INDEX'] &&
|
|
14
|
+
ENV['CI_NODE_TOTAL'] &&
|
|
15
|
+
ENV['IIDY_ENDPOINT'] &&
|
|
16
|
+
ENV['TRAVIS_BUILD_NUMBER'] &&
|
|
17
|
+
ENV['TRAVIS_JOB_NUMBER'] &&
|
|
18
|
+
ENV['IIDY_TOKEN']
|
|
19
|
+
|
|
20
|
+
abort 'Bad env' unless env_ok
|
|
21
|
+
|
|
22
|
+
main_node = ENV['CI_NODE_INDEX'] == '0'
|
|
23
|
+
auth_token = "Token token=\"#{ENV['IIDY_TOKEN']}\""
|
|
24
|
+
|
|
25
|
+
if main_node
|
|
26
|
+
build_id = "is_it_done_yet--#{ENV['TRAVIS_BUILD_NUMBER']}"
|
|
27
|
+
|
|
28
|
+
url = ENV['IIDY_ENDPOINT'] + "/builds/#{build_id}"
|
|
29
|
+
|
|
30
|
+
puts "URL: #{url}"
|
|
31
|
+
|
|
32
|
+
uri = URI(url)
|
|
33
|
+
|
|
34
|
+
request = Net::HTTP::Delete.new(uri)
|
|
35
|
+
request['Authorization'] = auth_token
|
|
36
|
+
|
|
37
|
+
response = Net::HTTP.start(
|
|
38
|
+
uri.hostname,
|
|
39
|
+
uri.port,
|
|
40
|
+
use_ssl: uri.scheme == 'https'
|
|
41
|
+
) { |http| http.request(request) }
|
|
42
|
+
|
|
43
|
+
abort 'Failed to clear results' unless response.code == '204'
|
|
44
|
+
puts 'Successfully cleared results!'
|
|
45
|
+
else
|
|
46
|
+
puts 'Not main node!'
|
|
47
|
+
end
|
data/examples/ci-deploy
CHANGED
data/examples/ci-post
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
# Script that posts build status of
|
|
4
5
|
# travis nodes (from ARGV[0]) to synchronising service
|
|
@@ -46,5 +47,5 @@ else
|
|
|
46
47
|
use_ssl: uri.scheme == 'https'
|
|
47
48
|
) { |http| http.request(request) }
|
|
48
49
|
|
|
49
|
-
abort "Failed to post build status: #{response.code}" unless response.code == '
|
|
50
|
+
abort "Failed to post build status: #{response.code}" unless response.code == '201'
|
|
50
51
|
end
|
data/examples/ci-put
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
# Script that puts build and rebuild status of
|
|
5
|
+
# travis nodes (from ARGV[0] and ARGV[1]) to synchronising service
|
|
6
|
+
require 'net/http'
|
|
7
|
+
require 'uri'
|
|
8
|
+
require 'json'
|
|
9
|
+
|
|
10
|
+
env_ok = ENV['CI_NODE_INDEX'] &&
|
|
11
|
+
ENV['CI_NODE_TOTAL'] &&
|
|
12
|
+
ENV['IIDY_ENDPOINT'] &&
|
|
13
|
+
ENV['TRAVIS_BUILD_NUMBER'] &&
|
|
14
|
+
ENV['TRAVIS_JOB_NUMBER'] &&
|
|
15
|
+
ENV['IIDY_TOKEN']
|
|
16
|
+
|
|
17
|
+
args_ok = !ARGV[0].nil?
|
|
18
|
+
|
|
19
|
+
abort 'Bad env' unless env_ok
|
|
20
|
+
abort 'Bad args' unless args_ok
|
|
21
|
+
|
|
22
|
+
main_node = ENV['CI_NODE_INDEX'] == '0'
|
|
23
|
+
auth_token = "Token token=\"#{ENV['IIDY_TOKEN']}\""
|
|
24
|
+
|
|
25
|
+
if main_node
|
|
26
|
+
puts 'Main node!'
|
|
27
|
+
else
|
|
28
|
+
# publish progress
|
|
29
|
+
build_id = "is_it_done_yet--#{ENV['TRAVIS_BUILD_NUMBER']}"
|
|
30
|
+
node_id = ENV['TRAVIS_JOB_NUMBER']
|
|
31
|
+
|
|
32
|
+
url = ENV['IIDY_ENDPOINT'] +
|
|
33
|
+
"/builds/#{build_id}/nodes/#{node_id}"
|
|
34
|
+
|
|
35
|
+
puts "URL: #{url}"
|
|
36
|
+
|
|
37
|
+
uri = URI(url)
|
|
38
|
+
|
|
39
|
+
request = Net::HTTP::Put.new(uri)
|
|
40
|
+
request['Authorization'] = auth_token
|
|
41
|
+
request.body = {
|
|
42
|
+
build_state: ARGV[0],
|
|
43
|
+
build_state_on_overwrite: ARGV[1]
|
|
44
|
+
}.compact.to_json
|
|
45
|
+
request.content_type = 'application/json'
|
|
46
|
+
|
|
47
|
+
response = Net::HTTP.start(
|
|
48
|
+
uri.hostname,
|
|
49
|
+
uri.port,
|
|
50
|
+
use_ssl: uri.scheme == 'https'
|
|
51
|
+
) { |http| http.request(request) }
|
|
52
|
+
|
|
53
|
+
abort "Failed to put build status: #{response.code}" unless response.code == '204'
|
|
54
|
+
end
|
data/examples/ci-sync
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
# Script that queries build status of
|
|
4
5
|
# travis nodes from synchronising service
|
|
@@ -8,7 +9,9 @@ require 'net/http'
|
|
|
8
9
|
require 'uri'
|
|
9
10
|
require 'json'
|
|
10
11
|
|
|
11
|
-
OK_STATES = %w
|
|
12
|
+
OK_STATES = %w[OK GOOD].freeze
|
|
13
|
+
BUILDING_STATE = 'BUILDING'.freeze
|
|
14
|
+
REBUILDING_STATE = 'REBUILDING'.freeze
|
|
12
15
|
SLEEP_TIME_SECONDS = 30
|
|
13
16
|
|
|
14
17
|
env_ok = ENV['CI_NODE_INDEX'] &&
|
|
@@ -39,10 +42,11 @@ if main_node
|
|
|
39
42
|
expected_size = ENV['CI_NODE_TOTAL'].to_i - 1
|
|
40
43
|
attempts = 0
|
|
41
44
|
success = false
|
|
45
|
+
rebuilding = false
|
|
42
46
|
|
|
43
47
|
loop do
|
|
44
48
|
attempts += 1
|
|
45
|
-
abort 'Failed to fetch results' if attempts > 10
|
|
49
|
+
abort 'Failed to fetch results' if attempts > 10 && !rebuilding
|
|
46
50
|
|
|
47
51
|
puts "Attempt no. #{attempts} at fetching build states"
|
|
48
52
|
|
|
@@ -52,13 +56,25 @@ if main_node
|
|
|
52
56
|
use_ssl: uri.scheme == 'https'
|
|
53
57
|
) { |http| http.request(request) }
|
|
54
58
|
|
|
55
|
-
|
|
59
|
+
unless response.code == '200'
|
|
60
|
+
sleep SLEEP_TIME_SECONDS
|
|
61
|
+
next
|
|
62
|
+
end
|
|
63
|
+
|
|
56
64
|
build_states = JSON.parse(response.body)['build_states']
|
|
57
65
|
|
|
58
66
|
if build_states.size < expected_size
|
|
59
67
|
puts "Some nodes have not reported in yet, \
|
|
60
|
-
|
|
61
|
-
|
|
68
|
+
found #{build_states.size}, \
|
|
69
|
+
expected #{expected_size}, waiting a bit"
|
|
70
|
+
sleep SLEEP_TIME_SECONDS
|
|
71
|
+
next
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
rebuilding = build_states.any?{ |(_k, value)| REBUILDING_STATE == value.upcase }
|
|
75
|
+
building = build_states.any?{ |(_k, value)| BUILDING_STATE == value.upcase }
|
|
76
|
+
if rebuilding || building
|
|
77
|
+
puts 'Nodes are building or rebuilding'
|
|
62
78
|
sleep SLEEP_TIME_SECONDS
|
|
63
79
|
next
|
|
64
80
|
end
|
data/examples/config.ru
CHANGED
|
@@ -1,11 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'bundler'
|
|
2
4
|
require 'rack/contrib'
|
|
3
5
|
require 'rack/token_auth'
|
|
4
6
|
require 'is_it_done_yet'
|
|
5
7
|
Bundler.require
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
# Shared secret authentication
|
|
10
|
+
use Rack::TokenAuth do |token, _options, _env|
|
|
8
11
|
token == ENV['IIDY_TOKEN']
|
|
9
12
|
end
|
|
10
13
|
|
|
14
|
+
# Heartbeat endpoint
|
|
15
|
+
use Rack::Builder.new do
|
|
16
|
+
map '/health_check' do
|
|
17
|
+
run ->(_env) { "success" }
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
11
21
|
run IsItDoneYet.build_app
|
data/is_it_done_yet.gemspec
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
5
|
require 'is_it_done_yet/version'
|
|
5
6
|
|
|
@@ -9,20 +10,16 @@ Gem::Specification.new do |spec|
|
|
|
9
10
|
spec.authors = ['Erik Madsen']
|
|
10
11
|
spec.email = ['beatmadsen@gmail.com']
|
|
11
12
|
|
|
12
|
-
spec.summary = 'Tracks
|
|
13
|
-
spec.description = '
|
|
14
|
-
In case you need to carry out build steps
|
|
15
|
-
in one of the nodes after the other nodes finish, e.g. deploying,
|
|
16
|
-
then you need a way of ascertaining the status of the other nodes.
|
|
17
|
-
This is what is_it_done_yet is for.
|
|
18
|
-
'
|
|
13
|
+
spec.summary = 'Tracks statuses of CI build nodes'
|
|
14
|
+
spec.description = 'In case you need to carry out build steps in one of the nodes of your CI project after the other nodes finish, e.g. deploying, then you need a way of ascertaining the status of the other nodes. This is what is_it_done_yet is for.'
|
|
19
15
|
spec.homepage = 'http://www.github.com/beatmadsen/is_it_done_yet'
|
|
20
16
|
spec.license = 'MIT'
|
|
17
|
+
spec.required_ruby_version = '>= 2.0'
|
|
21
18
|
|
|
22
19
|
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
|
23
20
|
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
|
24
21
|
if spec.respond_to?(:metadata)
|
|
25
|
-
spec.metadata['allowed_push_host'] =
|
|
22
|
+
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
|
26
23
|
else
|
|
27
24
|
raise 'RubyGems 2.0 or newer is required to protect against ' \
|
|
28
25
|
'public gem pushes.'
|
|
@@ -30,23 +27,26 @@ Gem::Specification.new do |spec|
|
|
|
30
27
|
|
|
31
28
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
|
32
29
|
f.match(%r{^(test|spec|features)/}) ||
|
|
33
|
-
f.match(/knapsack/)
|
|
30
|
+
f.match(/knapsack/) ||
|
|
31
|
+
f.match(/travis/)
|
|
34
32
|
end
|
|
35
33
|
spec.bindir = 'bin'
|
|
36
34
|
spec.require_paths = ['lib']
|
|
37
35
|
|
|
38
36
|
# Always
|
|
39
|
-
spec.add_dependency 'concurrent-ruby'
|
|
40
|
-
spec.add_dependency '
|
|
41
|
-
spec.add_dependency '
|
|
42
|
-
spec.add_dependency 'rack-
|
|
43
|
-
spec.add_dependency '
|
|
44
|
-
spec.add_dependency '
|
|
37
|
+
spec.add_dependency 'concurrent-ruby'
|
|
38
|
+
spec.add_dependency 'json'
|
|
39
|
+
spec.add_dependency 'rack-contrib'
|
|
40
|
+
spec.add_dependency 'rack-token_auth'
|
|
41
|
+
spec.add_dependency 'sinatra', '~> 2.0'
|
|
42
|
+
spec.add_dependency 'thin'
|
|
45
43
|
|
|
46
44
|
# Development
|
|
47
|
-
spec.add_development_dependency 'bundler'
|
|
48
|
-
spec.add_development_dependency '
|
|
49
|
-
spec.add_development_dependency '
|
|
50
|
-
spec.add_development_dependency '
|
|
51
|
-
spec.add_development_dependency '
|
|
45
|
+
spec.add_development_dependency 'bundler'
|
|
46
|
+
spec.add_development_dependency 'byebug'
|
|
47
|
+
spec.add_development_dependency 'knapsack'
|
|
48
|
+
spec.add_development_dependency 'pry'
|
|
49
|
+
spec.add_development_dependency 'rack-test'
|
|
50
|
+
spec.add_development_dependency 'rake'
|
|
51
|
+
spec.add_development_dependency 'rspec'
|
|
52
52
|
end
|
data/lib/is_it_done_yet.rb
CHANGED
|
@@ -1,96 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'is_it_done_yet/version'
|
|
2
|
-
require '
|
|
3
|
-
require 'concurrent'
|
|
4
|
-
require 'json'
|
|
5
|
-
require 'time'
|
|
4
|
+
require 'is_it_done_yet/web_app'
|
|
6
5
|
require 'rack/contrib'
|
|
6
|
+
require 'rack'
|
|
7
7
|
|
|
8
8
|
module IsItDoneYet
|
|
9
|
-
class WebApp < ::Sinatra::Base
|
|
10
|
-
UNKNOWN_NODE = { errors: ['Unknown Node'] }.to_json
|
|
11
|
-
UNKNOWN_BUILD = { errors: ['Unknown Build'] }.to_json
|
|
12
|
-
NO_BUILD_STATE = { errors: ['You forgot build state'] }.to_json
|
|
13
|
-
TTL_SECONDS = 24 * 60 * 60
|
|
14
|
-
|
|
15
|
-
configure do
|
|
16
|
-
set :state, ::Concurrent::Map.new
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
helpers do
|
|
20
|
-
private
|
|
21
|
-
|
|
22
|
-
def key(build_id, node_id)
|
|
23
|
-
"#{build_id}|#{node_id}"
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def house_keeping
|
|
27
|
-
expired_keys =
|
|
28
|
-
settings.state.each_pair.with_object([]) do |(key, (_b, time)), acc|
|
|
29
|
-
acc << key if time < Time.now - TTL_SECONDS
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
expired_keys.each { |key| settings.state.delete(key) }
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def store(key, value)
|
|
36
|
-
settings.state[key] = [value, Time.now]
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def retrieve(key)
|
|
40
|
-
build_state, _t = settings.state[key]
|
|
41
|
-
build_state
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def retrieve_all(prefix)
|
|
45
|
-
settings.state
|
|
46
|
-
.each_pair
|
|
47
|
-
.select { |(key, _v)| key.start_with?(prefix) }
|
|
48
|
-
.map { |(key, (build_state, _t))| [key.split('|')[1], build_state] }
|
|
49
|
-
.to_h
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
before do
|
|
54
|
-
house_keeping
|
|
55
|
-
|
|
56
|
-
content_type :json
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
get '/builds/:build_id/nodes/:node_id' do
|
|
60
|
-
build_id, node_id = params.values_at('build_id', 'node_id')
|
|
61
|
-
k = key(build_id, node_id)
|
|
62
|
-
|
|
63
|
-
build_state = retrieve(k)
|
|
64
|
-
|
|
65
|
-
halt 404, UNKNOWN_NODE unless build_state
|
|
66
|
-
|
|
67
|
-
content_type :json
|
|
68
|
-
{ build_state: build_state }.to_json
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
get '/builds/:build_id' do
|
|
72
|
-
build_id = params['build_id']
|
|
73
|
-
|
|
74
|
-
build_states = retrieve_all(build_id)
|
|
75
|
-
|
|
76
|
-
halt 404, UNKNOWN_BUILD unless build_states
|
|
77
|
-
|
|
78
|
-
content_type :json
|
|
79
|
-
{ build_states: build_states }.to_json
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
post '/builds/:build_id/nodes/:node_id' do
|
|
83
|
-
build_state = params['build_state']
|
|
84
|
-
halt 400, NO_BUILD_STATE unless build_state
|
|
85
|
-
|
|
86
|
-
build_id, node_id = params.values_at('build_id', 'node_id')
|
|
87
|
-
k = key(build_id, node_id)
|
|
88
|
-
store(k, build_state)
|
|
89
|
-
|
|
90
|
-
200
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
|
|
94
9
|
def self.build_app
|
|
95
10
|
Rack::Builder.app do
|
|
96
11
|
use Rack::PostBodyContentTypeParser
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'is_it_done_yet/version'
|
|
4
|
+
require 'sinatra'
|
|
5
|
+
require 'concurrent'
|
|
6
|
+
require 'json'
|
|
7
|
+
require 'time'
|
|
8
|
+
require 'rack/contrib'
|
|
9
|
+
|
|
10
|
+
module IsItDoneYet
|
|
11
|
+
class WebApp < ::Sinatra::Base
|
|
12
|
+
UNKNOWN_NODE = { errors: ['Unknown Node'] }.to_json
|
|
13
|
+
ALREADY_EXISTS = { errors: ['Node already exists'] }.to_json
|
|
14
|
+
UNKNOWN_BUILD = { errors: ['Unknown Build'] }.to_json
|
|
15
|
+
NO_BUILD_STATE = { errors: ['You forgot build state'] }.to_json
|
|
16
|
+
TTL_SECONDS = 24 * 60 * 60
|
|
17
|
+
|
|
18
|
+
configure do
|
|
19
|
+
set :state, ::Concurrent::Map.new
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
helpers do
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def key(build_id, node_id)
|
|
26
|
+
[build_id, node_id].freeze
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def house_keeping
|
|
30
|
+
expired_keys =
|
|
31
|
+
settings.state.each_pair.with_object([]) do |(key, (_b, time)), acc|
|
|
32
|
+
acc << key if time < Time.now - TTL_SECONDS
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
expired_keys.each { |key| settings.state.delete(key) }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def store(key, value)
|
|
39
|
+
settings.state[key] = [value, Time.now]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def merge(key:, value_if_absent:, value_if_present:)
|
|
43
|
+
settings.state.merge_pair(key, [value_if_absent, Time.now]) do
|
|
44
|
+
[value_if_present, Time.now]
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def retrieve(key)
|
|
49
|
+
build_state, _t = settings.state[key]
|
|
50
|
+
build_state
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def retrieve_all(build_id)
|
|
54
|
+
settings.state
|
|
55
|
+
.each_pair
|
|
56
|
+
.select { |((b, _n), _v)| build_id == b }
|
|
57
|
+
.map { |((_b, node_id), (build_state, _t))| [node_id, build_state] }
|
|
58
|
+
.to_h
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def clear_nodes(build_id)
|
|
62
|
+
state = settings.state
|
|
63
|
+
keys_for_build = state.keys.select { |(b, _n)| b == build_id }
|
|
64
|
+
keys_for_build.each { |key| state.delete(key) }
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
before do
|
|
69
|
+
house_keeping
|
|
70
|
+
|
|
71
|
+
content_type :json
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
get '/builds/:build_id/nodes/:node_id' do
|
|
75
|
+
build_id, node_id = params.values_at('build_id', 'node_id')
|
|
76
|
+
k = key(build_id, node_id)
|
|
77
|
+
|
|
78
|
+
build_state = retrieve(k)
|
|
79
|
+
|
|
80
|
+
halt 404, UNKNOWN_NODE unless build_state
|
|
81
|
+
|
|
82
|
+
{ build_state: build_state }.to_json
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
get '/builds/:build_id' do
|
|
86
|
+
build_id = params['build_id']
|
|
87
|
+
|
|
88
|
+
build_states = retrieve_all(build_id)
|
|
89
|
+
|
|
90
|
+
halt 404, UNKNOWN_BUILD if build_states.to_a.empty?
|
|
91
|
+
|
|
92
|
+
{ build_states: build_states }.to_json
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
delete '/builds/:build_id' do
|
|
96
|
+
build_id = params['build_id']
|
|
97
|
+
|
|
98
|
+
clear_nodes(build_id)
|
|
99
|
+
|
|
100
|
+
204
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
post '/builds/:build_id/nodes/:node_id' do
|
|
104
|
+
build_state = params['build_state']
|
|
105
|
+
halt 400, NO_BUILD_STATE unless build_state
|
|
106
|
+
|
|
107
|
+
build_id, node_id = params.values_at('build_id', 'node_id')
|
|
108
|
+
k = key(build_id, node_id)
|
|
109
|
+
halt 409, ALREADY_EXISTS if retrieve(k)
|
|
110
|
+
|
|
111
|
+
store(k, build_state)
|
|
112
|
+
|
|
113
|
+
201
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Example:
|
|
117
|
+
# PUT /builds/42/nodes/13?build_state=BUILDING&build_state_on_overwrite=REBUILDING
|
|
118
|
+
put '/builds/:build_id/nodes/:node_id' do
|
|
119
|
+
build_state, build_state_on_overwrite =
|
|
120
|
+
params.values_at('build_state', 'build_state_on_overwrite')
|
|
121
|
+
halt 400, NO_BUILD_STATE unless build_state
|
|
122
|
+
|
|
123
|
+
build_id, node_id = params.values_at('build_id', 'node_id')
|
|
124
|
+
k = key(build_id, node_id)
|
|
125
|
+
|
|
126
|
+
if build_state_on_overwrite
|
|
127
|
+
merge(
|
|
128
|
+
key: k,
|
|
129
|
+
value_if_absent: build_state,
|
|
130
|
+
value_if_present: build_state_on_overwrite
|
|
131
|
+
)
|
|
132
|
+
else
|
|
133
|
+
store(k, build_state)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
204
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
metadata
CHANGED
|
@@ -1,196 +1,229 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: is_it_done_yet
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Erik Madsen
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2020-08-15 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: concurrent-ruby
|
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
|
16
16
|
requirements:
|
|
17
|
-
- - "
|
|
17
|
+
- - ">="
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '
|
|
19
|
+
version: '0'
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
|
-
- - "
|
|
24
|
+
- - ">="
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '
|
|
26
|
+
version: '0'
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
|
-
name:
|
|
28
|
+
name: json
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
|
-
- - "
|
|
31
|
+
- - ">="
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '
|
|
33
|
+
version: '0'
|
|
34
34
|
type: :runtime
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
|
-
- - "
|
|
38
|
+
- - ">="
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: '
|
|
40
|
+
version: '0'
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
|
-
name:
|
|
42
|
+
name: rack-contrib
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
44
44
|
requirements:
|
|
45
|
-
- - "
|
|
45
|
+
- - ">="
|
|
46
46
|
- !ruby/object:Gem::Version
|
|
47
|
-
version: '
|
|
47
|
+
version: '0'
|
|
48
48
|
type: :runtime
|
|
49
49
|
prerelease: false
|
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
51
|
requirements:
|
|
52
|
-
- - "
|
|
52
|
+
- - ">="
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
|
-
version: '
|
|
54
|
+
version: '0'
|
|
55
55
|
- !ruby/object:Gem::Dependency
|
|
56
|
-
name: rack-
|
|
56
|
+
name: rack-token_auth
|
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
|
58
58
|
requirements:
|
|
59
|
-
- - "
|
|
59
|
+
- - ">="
|
|
60
60
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '
|
|
61
|
+
version: '0'
|
|
62
62
|
type: :runtime
|
|
63
63
|
prerelease: false
|
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
65
|
requirements:
|
|
66
|
-
- - "
|
|
66
|
+
- - ">="
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: '
|
|
68
|
+
version: '0'
|
|
69
69
|
- !ruby/object:Gem::Dependency
|
|
70
|
-
name:
|
|
70
|
+
name: sinatra
|
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
|
72
72
|
requirements:
|
|
73
73
|
- - "~>"
|
|
74
74
|
- !ruby/object:Gem::Version
|
|
75
|
-
version: '0
|
|
75
|
+
version: '2.0'
|
|
76
76
|
type: :runtime
|
|
77
77
|
prerelease: false
|
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
79
|
requirements:
|
|
80
80
|
- - "~>"
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
|
-
version: '0
|
|
82
|
+
version: '2.0'
|
|
83
83
|
- !ruby/object:Gem::Dependency
|
|
84
|
-
name:
|
|
84
|
+
name: thin
|
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
|
86
86
|
requirements:
|
|
87
|
-
- - "
|
|
87
|
+
- - ">="
|
|
88
88
|
- !ruby/object:Gem::Version
|
|
89
|
-
version: '
|
|
89
|
+
version: '0'
|
|
90
90
|
type: :runtime
|
|
91
91
|
prerelease: false
|
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
|
93
93
|
requirements:
|
|
94
|
-
- - "
|
|
94
|
+
- - ">="
|
|
95
95
|
- !ruby/object:Gem::Version
|
|
96
|
-
version: '
|
|
96
|
+
version: '0'
|
|
97
97
|
- !ruby/object:Gem::Dependency
|
|
98
98
|
name: bundler
|
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
|
100
100
|
requirements:
|
|
101
|
-
- - "
|
|
101
|
+
- - ">="
|
|
102
102
|
- !ruby/object:Gem::Version
|
|
103
|
-
version: '
|
|
103
|
+
version: '0'
|
|
104
104
|
type: :development
|
|
105
105
|
prerelease: false
|
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
|
107
107
|
requirements:
|
|
108
|
-
- - "
|
|
108
|
+
- - ">="
|
|
109
109
|
- !ruby/object:Gem::Version
|
|
110
|
-
version: '
|
|
110
|
+
version: '0'
|
|
111
111
|
- !ruby/object:Gem::Dependency
|
|
112
|
-
name:
|
|
112
|
+
name: byebug
|
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
|
114
114
|
requirements:
|
|
115
|
-
- - "
|
|
115
|
+
- - ">="
|
|
116
116
|
- !ruby/object:Gem::Version
|
|
117
|
-
version: '
|
|
117
|
+
version: '0'
|
|
118
118
|
type: :development
|
|
119
119
|
prerelease: false
|
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
|
121
121
|
requirements:
|
|
122
|
-
- - "
|
|
122
|
+
- - ">="
|
|
123
123
|
- !ruby/object:Gem::Version
|
|
124
|
-
version: '
|
|
124
|
+
version: '0'
|
|
125
125
|
- !ruby/object:Gem::Dependency
|
|
126
|
-
name:
|
|
126
|
+
name: knapsack
|
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
|
128
128
|
requirements:
|
|
129
|
-
- - "
|
|
129
|
+
- - ">="
|
|
130
130
|
- !ruby/object:Gem::Version
|
|
131
|
-
version: '
|
|
131
|
+
version: '0'
|
|
132
132
|
type: :development
|
|
133
133
|
prerelease: false
|
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
|
135
135
|
requirements:
|
|
136
|
-
- - "
|
|
136
|
+
- - ">="
|
|
137
|
+
- !ruby/object:Gem::Version
|
|
138
|
+
version: '0'
|
|
139
|
+
- !ruby/object:Gem::Dependency
|
|
140
|
+
name: pry
|
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
|
142
|
+
requirements:
|
|
143
|
+
- - ">="
|
|
144
|
+
- !ruby/object:Gem::Version
|
|
145
|
+
version: '0'
|
|
146
|
+
type: :development
|
|
147
|
+
prerelease: false
|
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
149
|
+
requirements:
|
|
150
|
+
- - ">="
|
|
137
151
|
- !ruby/object:Gem::Version
|
|
138
|
-
version: '
|
|
152
|
+
version: '0'
|
|
139
153
|
- !ruby/object:Gem::Dependency
|
|
140
154
|
name: rack-test
|
|
141
155
|
requirement: !ruby/object:Gem::Requirement
|
|
142
156
|
requirements:
|
|
143
|
-
- - "
|
|
157
|
+
- - ">="
|
|
144
158
|
- !ruby/object:Gem::Version
|
|
145
|
-
version: '0
|
|
159
|
+
version: '0'
|
|
146
160
|
type: :development
|
|
147
161
|
prerelease: false
|
|
148
162
|
version_requirements: !ruby/object:Gem::Requirement
|
|
149
163
|
requirements:
|
|
150
|
-
- - "
|
|
164
|
+
- - ">="
|
|
151
165
|
- !ruby/object:Gem::Version
|
|
152
|
-
version: '0
|
|
166
|
+
version: '0'
|
|
153
167
|
- !ruby/object:Gem::Dependency
|
|
154
|
-
name:
|
|
168
|
+
name: rake
|
|
155
169
|
requirement: !ruby/object:Gem::Requirement
|
|
156
170
|
requirements:
|
|
157
|
-
- - "
|
|
171
|
+
- - ">="
|
|
158
172
|
- !ruby/object:Gem::Version
|
|
159
|
-
version: '
|
|
173
|
+
version: '0'
|
|
160
174
|
type: :development
|
|
161
175
|
prerelease: false
|
|
162
176
|
version_requirements: !ruby/object:Gem::Requirement
|
|
163
177
|
requirements:
|
|
164
|
-
- - "
|
|
178
|
+
- - ">="
|
|
179
|
+
- !ruby/object:Gem::Version
|
|
180
|
+
version: '0'
|
|
181
|
+
- !ruby/object:Gem::Dependency
|
|
182
|
+
name: rspec
|
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
|
184
|
+
requirements:
|
|
185
|
+
- - ">="
|
|
165
186
|
- !ruby/object:Gem::Version
|
|
166
|
-
version: '
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
187
|
+
version: '0'
|
|
188
|
+
type: :development
|
|
189
|
+
prerelease: false
|
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
191
|
+
requirements:
|
|
192
|
+
- - ">="
|
|
193
|
+
- !ruby/object:Gem::Version
|
|
194
|
+
version: '0'
|
|
195
|
+
description: In case you need to carry out build steps in one of the nodes of your
|
|
196
|
+
CI project after the other nodes finish, e.g. deploying, then you need a way of
|
|
197
|
+
ascertaining the status of the other nodes. This is what is_it_done_yet is for.
|
|
171
198
|
email:
|
|
172
199
|
- beatmadsen@gmail.com
|
|
173
200
|
executables: []
|
|
174
201
|
extensions: []
|
|
175
202
|
extra_rdoc_files: []
|
|
176
203
|
files:
|
|
204
|
+
- ".github/workflows/ruby.yml"
|
|
177
205
|
- ".gitignore"
|
|
178
206
|
- ".rspec"
|
|
179
|
-
-
|
|
207
|
+
- CHANGELOG.md
|
|
180
208
|
- CODE_OF_CONDUCT.md
|
|
181
209
|
- Gemfile
|
|
210
|
+
- Gemfile.lock
|
|
182
211
|
- LICENSE.txt
|
|
183
212
|
- README.md
|
|
184
213
|
- Rakefile
|
|
185
214
|
- bin/console
|
|
186
215
|
- bin/setup
|
|
216
|
+
- config.ru
|
|
217
|
+
- examples/ci-clear
|
|
187
218
|
- examples/ci-deploy
|
|
188
219
|
- examples/ci-post
|
|
220
|
+
- examples/ci-put
|
|
189
221
|
- examples/ci-sync
|
|
190
222
|
- examples/config.ru
|
|
191
223
|
- is_it_done_yet.gemspec
|
|
192
224
|
- lib/is_it_done_yet.rb
|
|
193
225
|
- lib/is_it_done_yet/version.rb
|
|
226
|
+
- lib/is_it_done_yet/web_app.rb
|
|
194
227
|
homepage: http://www.github.com/beatmadsen/is_it_done_yet
|
|
195
228
|
licenses:
|
|
196
229
|
- MIT
|
|
@@ -204,16 +237,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
204
237
|
requirements:
|
|
205
238
|
- - ">="
|
|
206
239
|
- !ruby/object:Gem::Version
|
|
207
|
-
version: '0'
|
|
240
|
+
version: '2.0'
|
|
208
241
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
209
242
|
requirements:
|
|
210
243
|
- - ">="
|
|
211
244
|
- !ruby/object:Gem::Version
|
|
212
245
|
version: '0'
|
|
213
246
|
requirements: []
|
|
214
|
-
|
|
215
|
-
rubygems_version: 2.6.11
|
|
247
|
+
rubygems_version: 3.1.0.pre1
|
|
216
248
|
signing_key:
|
|
217
249
|
specification_version: 4
|
|
218
|
-
summary: Tracks
|
|
250
|
+
summary: Tracks statuses of CI build nodes
|
|
219
251
|
test_files: []
|
data/.travis.yml
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
sudo: false
|
|
2
|
-
language: ruby
|
|
3
|
-
cache: bundler
|
|
4
|
-
rvm:
|
|
5
|
-
- 2.4.1
|
|
6
|
-
before_install: gem install bundler -v 1.14.6
|
|
7
|
-
bundler_args: --without production
|
|
8
|
-
|
|
9
|
-
env:
|
|
10
|
-
global:
|
|
11
|
-
- MY_GLOBAL_VAR=123
|
|
12
|
-
- CI_NODE_TOTAL=2
|
|
13
|
-
matrix:
|
|
14
|
-
- CI_NODE_INDEX=0
|
|
15
|
-
- CI_NODE_INDEX=1
|
|
16
|
-
|
|
17
|
-
script: bundle exec rake knapsack:rspec && examples/ci-sync && examples/ci-deploy
|
|
18
|
-
|
|
19
|
-
after_success: examples/ci-post OK
|
|
20
|
-
after_failure: examples/ci-post FAILED
|