|
@@ -528,7 +528,7 @@ class RunCi {
|
|
static var sysDir(default, never) = cwd + "sys/";
|
|
static var sysDir(default, never) = cwd + "sys/";
|
|
static var optDir(default, never) = cwd + "optimization/";
|
|
static var optDir(default, never) = cwd + "optimization/";
|
|
static var miscDir(default, never) = cwd + "misc/";
|
|
static var miscDir(default, never) = cwd + "misc/";
|
|
- static var gitInfo(get, null):{repo:String, branch:String, commit:String, date:String};
|
|
|
|
|
|
+ static var gitInfo(get, null):{repo:String, branch:String, commit:String, timestamp:Float, date:String};
|
|
static function get_gitInfo() return if (gitInfo != null) gitInfo else gitInfo = {
|
|
static function get_gitInfo() return if (gitInfo != null) gitInfo else gitInfo = {
|
|
repo: switch (ci) {
|
|
repo: switch (ci) {
|
|
case TravisCI:
|
|
case TravisCI:
|
|
@@ -547,12 +547,14 @@ class RunCi {
|
|
commandResult("git", ["rev-parse", "--abbrev-ref", "HEAD"]).stdout.trim();
|
|
commandResult("git", ["rev-parse", "--abbrev-ref", "HEAD"]).stdout.trim();
|
|
},
|
|
},
|
|
commit: commandResult("git", ["rev-parse", "HEAD"]).stdout.trim(),
|
|
commit: commandResult("git", ["rev-parse", "HEAD"]).stdout.trim(),
|
|
|
|
+ timestamp: Std.parseFloat(commandResult("git", ["show", "-s", "--format=%ct", "HEAD"]).stdout),
|
|
date: {
|
|
date: {
|
|
var gitTime = commandResult("git", ["show", "-s", "--format=%ct", "HEAD"]).stdout;
|
|
var gitTime = commandResult("git", ["show", "-s", "--format=%ct", "HEAD"]).stdout;
|
|
var tzd = {
|
|
var tzd = {
|
|
var z = Date.fromTime(0);
|
|
var z = Date.fromTime(0);
|
|
z.getHours() * 60 * 60 * 1000 + z.getMinutes() * 60 * 1000;
|
|
z.getHours() * 60 * 60 * 1000 + z.getMinutes() * 60 * 1000;
|
|
}
|
|
}
|
|
|
|
+ // make time in the UTC time zone
|
|
var time = Date.fromTime(Std.parseFloat(gitTime) * 1000 - tzd);
|
|
var time = Date.fromTime(Std.parseFloat(gitTime) * 1000 - tzd);
|
|
DateTools.format(time, "%FT%TZ");
|
|
DateTools.format(time, "%FT%TZ");
|
|
}
|
|
}
|
|
@@ -608,6 +610,135 @@ class RunCi {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ static function saveOutput():Void {
|
|
|
|
+ if (Sys.getEnv("HAXECI_GH_TOKEN") == null) {
|
|
|
|
+ infoMsg("Missing HAXECI_GH_TOKEN. Will not save output.");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ changeDirectory(repoDir);
|
|
|
|
+ var haxe_output = Path.join([repoDir, "haxe-output"]);
|
|
|
|
+ var gitInfo = gitInfo;
|
|
|
|
+ var TEST = Sys.getEnv("TEST");
|
|
|
|
+ var TRAVIS_OS_NAME = Sys.getEnv("TRAVIS_OS_NAME");
|
|
|
|
+ var haxe_output_branch = '${gitInfo.branch}_travisci_${TRAVIS_OS_NAME}_${TEST}';
|
|
|
|
+ var haxe_output_repo = "github.com/HaxeFoundation/haxe-output.git";
|
|
|
|
+
|
|
|
|
+ function haxeCommitTime(sha:String):Float {
|
|
|
|
+ var cwd = Sys.getCwd();
|
|
|
|
+ Sys.setCwd(repoDir);
|
|
|
|
+ var time = Std.parseFloat(commandResult("git", ["show", "-s", "--pretty=%ct", sha]).stdout);
|
|
|
|
+ Sys.setCwd(cwd);
|
|
|
|
+ return time;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ function save():Void {
|
|
|
|
+ // prepare haxe-output repo
|
|
|
|
+ runCommand("git", ["clone", 'https://${Sys.getEnv("HAXECI_GH_TOKEN")}@${haxe_output_repo}', haxe_output]);
|
|
|
|
+ changeDirectory(haxe_output);
|
|
|
|
+ runCommand("git", ["config", "user.email", "[email protected]"]);
|
|
|
|
+ runCommand("git", ["config", "user.name", "Haxe CI Bot"]);
|
|
|
|
+
|
|
|
|
+ // check to see whether the haxe repo branch has been created in haxe-output
|
|
|
|
+ var firstOutputBranch = switch (Sys.command("git", ["ls-remote", "--exit-code", "origin", haxe_output_branch])) {
|
|
|
|
+ case 0: false;
|
|
|
|
+ case 2: true;
|
|
|
|
+ case exitcode: throw "unknown exit code: " + exitcode;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // switch to the branch
|
|
|
|
+ if (firstOutputBranch) {
|
|
|
|
+ runCommand("git", ["checkout", "-B", haxe_output_branch]);
|
|
|
|
+ } else {
|
|
|
|
+ runCommand("git", ["checkout", "-B", haxe_output_branch, "--track", "origin/" + haxe_output_branch]);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // check to see whether this will be the first push of this haxe repo commit
|
|
|
|
+ var firstOutputCommit = firstOutputBranch || {
|
|
|
|
+ var lastLog = commandResult("git", ["show", "-s", "--pretty=format:%B", "HEAD"]).stdout;
|
|
|
|
+ var commitRe = ~/[a-f0-9]{40}/;
|
|
|
|
+ if (!commitRe.match(lastLog))
|
|
|
|
+ throw "No commit sha found in log: " + lastLog;
|
|
|
|
+ var lastCommit = commitRe.matched(0);
|
|
|
|
+
|
|
|
|
+ // check to see whether this commit is newer than the last pushed one
|
|
|
|
+ // in case e.g. the current build is a rebuild of an old commit
|
|
|
|
+ if (haxeCommitTime(lastCommit) > gitInfo.timestamp) {
|
|
|
|
+ throw "There exists output with a later commit in the haxe-output repo.";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ lastCommit != gitInfo.commit;
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ // Remove all the old output first.
|
|
|
|
+ // It is because there may be files no longer emitted by the current build.
|
|
|
|
+ if (firstOutputCommit) {
|
|
|
|
+ runCommand("rm", ["-rf", "tests"]);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // get the outputs by listing the files/folders ignored by git
|
|
|
|
+ changeDirectory(cwd);
|
|
|
|
+ var stdout = {
|
|
|
|
+ var proc = new Process("git", ["status", "--ignored", "--porcelain", cwd]);
|
|
|
|
+ var out = proc.stdout.readAll().toString();
|
|
|
|
+ proc.close();
|
|
|
|
+ out;
|
|
|
|
+ };
|
|
|
|
+ var outputs = stdout.split("\n")
|
|
|
|
+ .filter(function(s) return s.startsWith("!! "))
|
|
|
|
+ .map(function(s) return s.substr("!! ".length));
|
|
|
|
+
|
|
|
|
+ // copy all the outputs to haxe-output
|
|
|
|
+ FileSystem.createDirectory(haxe_output);
|
|
|
|
+ for (item in outputs) {
|
|
|
|
+ var orig = Path.join([repoDir, item]);
|
|
|
|
+ var dest = Path.join([haxe_output, item]);
|
|
|
|
+ if (FileSystem.isDirectory(orig)) {
|
|
|
|
+ FileSystem.createDirectory(dest);
|
|
|
|
+ } else {
|
|
|
|
+ FileSystem.createDirectory(Path.directory(dest));
|
|
|
|
+ }
|
|
|
|
+ runCommand("cp", ["-rf", orig, dest]);
|
|
|
|
+ }
|
|
|
|
+ changeDirectory(haxe_output);
|
|
|
|
+ runCommand("git", ["add", haxe_output]);
|
|
|
|
+ var commitMsg = [
|
|
|
|
+ '-m', '${Sys.getEnv("TRAVIS_JOB_NUMBER")} ${TEST} https://github.com/HaxeFoundation/haxe/commit/${gitInfo.commit}',
|
|
|
|
+ '-m', 'https://travis-ci.org/HaxeFoundation/haxe/jobs/${Sys.getEnv("TRAVIS_JOB_ID")}',
|
|
|
|
+ ];
|
|
|
|
+ runCommand("git", ["commit", "-q", "--allow-empty"].concat(commitMsg));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // try save() for 5 times because the push may fail when the another build push at the same time
|
|
|
|
+ var pushError = false;
|
|
|
|
+ for (i in 0...5) {
|
|
|
|
+ try {
|
|
|
|
+ save();
|
|
|
|
+ } catch (e:Dynamic) {
|
|
|
|
+ infoMsg(e);
|
|
|
|
+ pushError = false;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ var pushResult = commandResult("git", ["push", "origin", haxe_output_branch]);
|
|
|
|
+ if (pushResult.exitCode == 0) {
|
|
|
|
+ successMsg("push to haxe-output succeed");
|
|
|
|
+ pushError = false;
|
|
|
|
+ break;
|
|
|
|
+ } else {
|
|
|
|
+ failMsg("push to haxe-output failed");
|
|
|
|
+ failMsg(pushResult.stderr);
|
|
|
|
+ pushError = true;
|
|
|
|
+
|
|
|
|
+ runCommand("rm", ["-rf", haxe_output]);
|
|
|
|
+
|
|
|
|
+ Sys.sleep(Std.random(10));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (pushError) {
|
|
|
|
+ Sys.exit(1);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
static function main():Void {
|
|
static function main():Void {
|
|
Sys.putEnv("OCAMLRUNPARAM", "b");
|
|
Sys.putEnv("OCAMLRUNPARAM", "b");
|
|
|
|
|
|
@@ -894,6 +1025,20 @@ class RunCi {
|
|
throw "unknown target: " + t;
|
|
throw "unknown target: " + t;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ if (
|
|
|
|
+ (switch [ci, systemName] {
|
|
|
|
+ case [TravisCI, "Linux"]: true;
|
|
|
|
+ case _: false;
|
|
|
|
+ })
|
|
|
|
+ &&
|
|
|
|
+ Lambda.exists(tests, function(t) return switch (t) {
|
|
|
|
+ case Js | Cpp | Cs | Java | Php | Python: true;
|
|
|
|
+ case _: false;
|
|
|
|
+ })
|
|
|
|
+ ) {
|
|
|
|
+ saveOutput();
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
static function testHxTemplo() {
|
|
static function testHxTemplo() {
|