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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
# File 'lib/build_buddy/builder.rb', line 23
def start_build(build_data)
def expand_vars(s)
s.gsub(/\$([a-zA-Z_]+[a-zA-Z0-9_]*)|\$\{(.+)\}/) { ENV[$1||$2] }
end
@build_data = build_data
@build_output_dir = File.join(Config.build_output_dir, @build_data._id.to_s)
@metrics_file_name = File.join(@build_output_dir, 'metrics.yaml')
@log_file_name = File.join(@build_output_dir, "log.txt")
FileUtils.mkdir(@build_output_dir)
File.new(@metrics_file_name, 'w').close
repo_parts = @build_data.repo_full_name.split('/')
git_repo_owner = repo_parts[0]
git_repo_name = repo_parts[1]
env = {}
build_script = %q(#!/bin/bash
if [[ -z "$BB_GIT_REPO_OWNER" || -z "$BB_GIT_REPO_NAME" || -z "$BB_BUILD_SCRIPT" ]]; then
echo Must set BB_GIT_REPO_OWNER, BB_GIT_REPO_NAME, BB_GIT_PULL_REQUEST and BB_BUILD_SCRIPT before calling
exit 1
fi
)
case build_data.type
when :pull_request
build_script += %q(
if [[ -z "$BB_GIT_PULL_REQUEST" ]]; then
echo Must set BB_GIT_PULL_REQUEST before calling
fi
)
when :branch
build_script += %q(
if [[ -z "$BB_GIT_BRANCH" ]]; then
echo Must set BB_GIT_BRANCH before calling
fi
)
else
raise "Unknown build type"
end
build_script += %q(
if [[ -d ${BB_GIT_REPO_NAME} ]]; then
echo WARNING: Deleting old clone directory $(pwd)/${BB_GIT_REPO_NAME}
rm -rf ${BB_GIT_REPO_NAME}
fi
echo Pulling sources to $(pwd)/${BB_GIT_REPO_NAME}
if ! git clone [email protected]:${BB_GIT_REPO_OWNER}/${BB_GIT_REPO_NAME}.git ${BB_GIT_REPO_NAME}; then
echo ERROR: Unable to clone repository
exit 1
fi
cd ${BB_GIT_REPO_NAME}
)
build_root_dir = nil
case build_data.type
when :pull_request
build_root_dir = expand_vars(Config.pull_request_root_dir)
env.merge!({
"BB_GIT_PULL_REQUEST" => build_data.pull_request.to_s,
"BB_BUILD_SCRIPT" => Config.pull_request_build_script
})
build_script += %q(
echo Switching to pr/${BB_GIT_PULL_REQUEST} branch
git config --add remote.origin.fetch '+refs/pull/*/head:refs/remotes/origin/pr/*'
git fetch -q origin
git checkout pr/$BB_GIT_PULL_REQUEST
)
when :branch
build_root_dir = expand_vars(Config.branch_root_dir)
env.merge!({
"BB_GIT_BRANCH" => build_data.branch.to_s,
"BB_BUILD_SCRIPT" => Config.branch_build_script
})
build_script += %q(
echo Switching to ${BB_GIT_BRANCH} branch
git checkout ${BB_GIT_BRANCH}
)
end
build_script += %q(
source ${BB_BUILD_SCRIPT}
)
env.merge!({
"BB_GIT_REPO_OWNER" => git_repo_owner,
"BB_GIT_REPO_NAME" => git_repo_name,
"BB_METRICS_DATA_FILE" => @metrics_file_name,
"BB_BUILD_OUTPUT_DIR" => @build_output_dir,
"BB_MONGO_URI" => Config.mongo_uri,
"RBENV_DIR" => nil,
"RBENV_VERSION" => nil,
"RBENV_HOOK_PATH" => nil,
"RBENV_ROOT" => nil,
"PATH" => ENV['PATH'].split(':').select { |v| !v.match(/\.rbenv\/versions|Cellar\/rbenv/) }.join(':'),
})
unless build_data.flags.nil?
build_data.flags.each do |flag|
env["BB_BUILD_FLAG_#{flag.to_s.upcase}"] = '1'
end
end
@build_data.start_time = Time.now.utc
clone_dir = File.join(build_root_dir, git_repo_owner)
FileUtils.mkdir_p(clone_dir)
script_filename = File.join(clone_dir, "build-buddy-bootstrap.sh")
File.write(script_filename, build_script)
if @build_data.type == :pull_request
Celluloid::Actor[:gitter].async.set_status(
build_data.repo_full_name, build_data.repo_sha, :pending, "Build has started",
build_data.server_log_uri)
end
Bundler.with_clean_env do
@pid = Process.spawn(env, "bash #{script_filename}", :pgroup => true, :chdir => clone_dir, [:out, :err] => @log_file_name)
@gid = Process.getpgid(@pid)
end
info "Running build script (pid #{@pid}, gid #{@gid}) : Log #{@log_file_name}"
if @watcher
@watcher.terminate
end
@watcher = Watcher.new(@pid)
@watcher.async.watch_pid
end
|