This repository has been archived by the owner on Jun 9, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
/
model.rb
110 lines (100 loc) · 3.61 KB
/
model.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#
# Copyright 2015, Noah Kantrowitz
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require 'sequel'
require 'travis'
module Nightlies
class Model
def self.db
@db ||= Sequel.connect(ENV['DATABASE_URL'])
end
def self.schema!
db.create_table(:nightlies) do
primary_key :id
String :username
String :owner
String :name
String :travis_token
Time :last_nightly # Because the API doesn't see API-initiated builds.
unique [:owner, :name]
end
end
def self.enable!(user, repo_id, slug)
owner, name = slug.split('/', 2)
values = {owner: owner, name: name, username: user.login, travis_token: user.attribs['travis_token']}
if db[:nightlies].filter(id: repo_id).update(values) == 0
db[:nightlies].insert(values.merge(id: repo_id))
end
end
def self.disable!(user, repo_id)
db[:nightlies].filter(id: repo_id).update(travis_token: nil)
end
def self.by_id(repo_id)
db[:nightlies].filter(id: repo_id).first
end
def self.run!
failure = true
db[:nightlies].each do |data|
begin
# Skip disabled repos.
next unless data[:travis_token]
slug = "#{data[:owner]}/#{data[:name]}"
puts "[#{slug}] Checking."
travis = Travis::Client.new(access_token: data[:travis_token])
repo = travis.repo(slug)
# Could speed this up in the future.
last_push_build = repo.builds(event_type: 'push').first
last_api_build = repo.builds(event_type: 'api').first
if (last_push_build && last_push_build.pending?) || (last_api_build && last_api_build.pending?)
# Currently building, we're done here.
puts "[#{slug}] Already building."
next
end
build_times = [data[:last_nightly] || Time.at(0)]
build_times << last_push_build.finished_at if last_push_build
build_times << last_api_build.finished_at if last_api_build
last_build_time = build_times.max
# Check if it has been 23.5 hours since the last build. The 0.5 is so
# that if the last build was kicked off by us slightly more than 24
# hours ago, we don't drift back by an hour each day.
if Time.now - last_build_time > 60*60*23.5
puts "[#{slug}] Requesting a build, last build time #{last_build_time}."
self.run_build!(travis, slug)
db[:nightlies].filter(id: data[:id]).update(last_nightly: Time.now)
end
# If any succeed then we probably aren't globally down.
failure = false
rescue Exception => ex
puts "[#{slug}] ERROR: #{ex}"
end
end
raise "All builds failed" if failure
end
def self.run_build!(travis, slug)
encoded_slug = slug.gsub(/\//, '%2F')
url = "/repo/#{encoded_slug}/requests"
body = {
request: {
branch: 'master',
message: "Nightly build for #{slug} via nightli.es.",
},
}
headers = {
'Travis-API-Version' => 3,
}
travis.post_raw(url, body, headers)
end
end
end