diff --git a/data/payloads/circleci_project_github_dlang_dmd_2827 b/data/payloads/circleci_project_github_dlang_dmd_2827
new file mode 100644
index 0000000..35fa20d
--- /dev/null
+++ b/data/payloads/circleci_project_github_dlang_dmd_2827
@@ -0,0 +1,483 @@
+{
+ "compare" : null,
+ "previous_successful_build" : {
+ "build_num" : 2826,
+ "status" : "success",
+ "build_time_millis" : 680713
+ },
+ "build_parameters" : null,
+ "oss" : true,
+ "all_commit_details_truncated" : false,
+ "committer_date" : "2017-02-19T00:47:51Z",
+ "steps" : [ {
+ "name" : "Starting the build",
+ "actions" : [ {
+ "truncated" : false,
+ "index" : 0,
+ "parallel" : false,
+ "failed" : null,
+ "infrastructure_fail" : null,
+ "name" : "Starting the build",
+ "bash_command" : null,
+ "status" : "success",
+ "timedout" : null,
+ "continue" : null,
+ "end_time" : "2017-02-19T00:48:55.197Z",
+ "type" : "infrastructure",
+ "truncation_len" : null,
+ "output_url" : "https://circle-production-action-output.s3.amazonaws.com/60721088526a14aa37be8a85-dlang-dmd-0-0?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20170220T005748Z&X-Amz-SignedHeaders=host&X-Amz-Expires=431999&X-Amz-Credential=AKIAIJNI6FA5RIAFFQ7Q%2F20170220%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=b0d2622e4011a94e44d09252202331ae5599c9737168baf93b0b737426655e32",
+ "start_time" : "2017-02-19T00:48:51.429Z",
+ "exit_code" : null,
+ "canceled" : null,
+ "step" : 0,
+ "run_time_millis" : 3768,
+ "has_output" : true
+ } ]
+ }, {
+ "name" : "Start container",
+ "actions" : [ {
+ "truncated" : false,
+ "index" : 0,
+ "parallel" : true,
+ "failed" : null,
+ "infrastructure_fail" : null,
+ "name" : "Start container",
+ "bash_command" : null,
+ "status" : "success",
+ "timedout" : null,
+ "continue" : null,
+ "end_time" : "2017-02-19T00:49:02.246Z",
+ "source" : "config",
+ "type" : "infrastructure",
+ "truncation_len" : null,
+ "output_url" : "https://circle-production-action-output.s3.amazonaws.com/70721088526a14aa77be8a85-dlang-dmd-1-0?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20170220T005748Z&X-Amz-SignedHeaders=host&X-Amz-Expires=431999&X-Amz-Credential=AKIAIJNI6FA5RIAFFQ7Q%2F20170220%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=17fdba6a06b448d6eae45faa70c06d6244ba037a4c0ab2a7ea442256e4f55e74",
+ "start_time" : "2017-02-19T00:48:55.206Z",
+ "exit_code" : 0,
+ "canceled" : null,
+ "step" : 1,
+ "run_time_millis" : 7040,
+ "has_output" : true
+ } ]
+ }, {
+ "name" : "Enable SSH",
+ "actions" : [ {
+ "truncated" : false,
+ "index" : 0,
+ "parallel" : true,
+ "failed" : null,
+ "infrastructure_fail" : null,
+ "name" : "Enable SSH",
+ "bash_command" : null,
+ "status" : "success",
+ "timedout" : null,
+ "continue" : null,
+ "end_time" : "2017-02-19T00:49:03.907Z",
+ "type" : "infrastructure",
+ "truncation_len" : null,
+ "output_url" : "https://circle-production-action-output.s3.amazonaws.com/80721088526a14aae7be8a85-dlang-dmd-2-0?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20170220T005748Z&X-Amz-SignedHeaders=host&X-Amz-Expires=431999&X-Amz-Credential=AKIAIJNI6FA5RIAFFQ7Q%2F20170220%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=d247ac240fdb5d29f28b4de039c261e82ad9383398d9d176d9bb03210736bcf8",
+ "start_time" : "2017-02-19T00:49:02.254Z",
+ "exit_code" : null,
+ "canceled" : null,
+ "step" : 2,
+ "run_time_millis" : 1653,
+ "has_output" : true
+ } ]
+ }, {
+ "name" : "Restore source cache",
+ "actions" : [ {
+ "truncated" : false,
+ "index" : 0,
+ "parallel" : false,
+ "failed" : null,
+ "infrastructure_fail" : null,
+ "name" : "Restore source cache",
+ "bash_command" : null,
+ "status" : "success",
+ "timedout" : null,
+ "continue" : null,
+ "end_time" : "2017-02-19T00:49:06.292Z",
+ "source" : "cache",
+ "type" : "checkout",
+ "truncation_len" : null,
+ "output_url" : "https://circle-production-action-output.s3.amazonaws.com/90721088526a14aaf7be8a85-dlang-dmd-3-0?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20170220T005748Z&X-Amz-SignedHeaders=host&X-Amz-Expires=431999&X-Amz-Credential=AKIAIJNI6FA5RIAFFQ7Q%2F20170220%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=f78a7285f71cd619c3bb00d56eb6e2154bec0864ee65e9db2b4e65415e497ae2",
+ "start_time" : "2017-02-19T00:49:03.915Z",
+ "exit_code" : null,
+ "canceled" : null,
+ "step" : 3,
+ "run_time_millis" : 2377,
+ "has_output" : true
+ } ]
+ }, {
+ "name" : "Checkout using CircleCI fork PR checkout user key: 72:d2:fd:18:4c:f5:15:b1:ab:47:44:65:9d:9b:08:0a",
+ "actions" : [ {
+ "truncated" : false,
+ "index" : 0,
+ "parallel" : true,
+ "failed" : null,
+ "infrastructure_fail" : null,
+ "name" : "Checkout using CircleCI fork PR checkout user key: 72:d2:fd:18:4c:f5:15:b1:ab:47:44:65:9d:9b:08:0a",
+ "bash_command" : null,
+ "status" : "success",
+ "timedout" : null,
+ "continue" : null,
+ "end_time" : "2017-02-19T00:49:09.485Z",
+ "source" : "config",
+ "type" : "checkout",
+ "truncation_len" : null,
+ "output_url" : "https://circle-production-action-output.s3.amazonaws.com/a0721088526a14aa28be8a85-dlang-dmd-4-0?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20170220T005748Z&X-Amz-SignedHeaders=host&X-Amz-Expires=431999&X-Amz-Credential=AKIAIJNI6FA5RIAFFQ7Q%2F20170220%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=12c112e388f72461a416c7c8ae15c78335d386bec18f91f07018e610a7c031d1",
+ "start_time" : "2017-02-19T00:49:06.301Z",
+ "exit_code" : 0,
+ "canceled" : null,
+ "step" : 4,
+ "run_time_millis" : 3184,
+ "has_output" : true
+ } ]
+ }, {
+ "name" : "Configure the build",
+ "actions" : [ {
+ "truncated" : false,
+ "index" : 0,
+ "parallel" : false,
+ "failed" : null,
+ "infrastructure_fail" : null,
+ "name" : "Configure the build",
+ "bash_command" : null,
+ "status" : "success",
+ "timedout" : null,
+ "continue" : null,
+ "end_time" : "2017-02-19T00:49:12.936Z",
+ "source" : "cache",
+ "type" : "machine",
+ "truncation_len" : null,
+ "start_time" : "2017-02-19T00:49:09.493Z",
+ "exit_code" : null,
+ "canceled" : null,
+ "step" : 5,
+ "run_time_millis" : 3443,
+ "has_output" : false
+ } ]
+ }, {
+ "name" : "Suppressing export of environment variables fork PR builds",
+ "actions" : [ {
+ "truncated" : false,
+ "index" : 0,
+ "parallel" : true,
+ "failed" : null,
+ "infrastructure_fail" : null,
+ "name" : "Suppressing export of environment variables fork PR builds",
+ "bash_command" : null,
+ "status" : "success",
+ "timedout" : null,
+ "continue" : null,
+ "end_time" : "2017-02-19T00:49:12.944Z",
+ "source" : "db",
+ "type" : "machine",
+ "truncation_len" : null,
+ "start_time" : "2017-02-19T00:49:12.943Z",
+ "exit_code" : null,
+ "canceled" : null,
+ "step" : 6,
+ "run_time_millis" : 1,
+ "has_output" : false
+ } ]
+ }, {
+ "name" : "Restore cache",
+ "actions" : [ {
+ "truncated" : false,
+ "index" : 0,
+ "parallel" : false,
+ "failed" : null,
+ "infrastructure_fail" : null,
+ "name" : "Restore cache",
+ "bash_command" : null,
+ "status" : "success",
+ "timedout" : null,
+ "continue" : null,
+ "end_time" : "2017-02-19T00:49:20.153Z",
+ "source" : "cache",
+ "type" : "machine",
+ "truncation_len" : null,
+ "output_url" : "https://circle-production-action-output.s3.amazonaws.com/d0721088526a14aa88be8a85-dlang-dmd-7-0?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20170220T005748Z&X-Amz-SignedHeaders=host&X-Amz-Expires=431999&X-Amz-Credential=AKIAIJNI6FA5RIAFFQ7Q%2F20170220%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=e618b2e25e2b9f5667ee863cadb8279e8cbf4c06286a47470585846c192d15e2",
+ "start_time" : "2017-02-19T00:49:12.950Z",
+ "exit_code" : null,
+ "canceled" : null,
+ "step" : 7,
+ "run_time_millis" : 7203,
+ "has_output" : true
+ } ]
+ }, {
+ "name" : "./circleci.sh install-deps",
+ "actions" : [ {
+ "truncated" : false,
+ "index" : 0,
+ "parallel" : true,
+ "failed" : null,
+ "infrastructure_fail" : null,
+ "name" : "./circleci.sh install-deps",
+ "bash_command" : "./circleci.sh install-deps",
+ "status" : "success",
+ "timedout" : null,
+ "continue" : null,
+ "end_time" : "2017-02-19T00:49:21.398Z",
+ "source" : "config",
+ "type" : "dependencies",
+ "truncation_len" : null,
+ "output_url" : "https://circle-production-action-output.s3.amazonaws.com/e0721088526a14aa09be8a85-dlang-dmd-8-0?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20170220T005748Z&X-Amz-SignedHeaders=host&X-Amz-Expires=431999&X-Amz-Credential=AKIAIJNI6FA5RIAFFQ7Q%2F20170220%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=a9168d99914f07cd8e9259e0fa425525b587a1b9793cbda46a1b51f66fe40fd4",
+ "start_time" : "2017-02-19T00:49:20.166Z",
+ "exit_code" : 0,
+ "canceled" : null,
+ "step" : 8,
+ "run_time_millis" : 1232,
+ "has_output" : true
+ } ]
+ }, {
+ "name" : "Save cache",
+ "actions" : [ {
+ "truncated" : false,
+ "index" : 0,
+ "parallel" : false,
+ "failed" : null,
+ "infrastructure_fail" : null,
+ "name" : "Save cache",
+ "bash_command" : null,
+ "status" : "success",
+ "timedout" : null,
+ "continue" : null,
+ "end_time" : "2017-02-19T00:49:24.572Z",
+ "source" : "cache",
+ "type" : "database",
+ "truncation_len" : null,
+ "output_url" : "https://circle-production-action-output.s3.amazonaws.com/f0721088526a14aa19be8a85-dlang-dmd-9-0?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20170220T005748Z&X-Amz-SignedHeaders=host&X-Amz-Expires=431999&X-Amz-Credential=AKIAIJNI6FA5RIAFFQ7Q%2F20170220%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=1f8ca9517fab06baa9962030590c77b420dbd2508e1307e06ca03eafea3e62f8",
+ "start_time" : "2017-02-19T00:49:21.405Z",
+ "exit_code" : null,
+ "canceled" : null,
+ "step" : 9,
+ "run_time_millis" : 3167,
+ "has_output" : true
+ } ]
+ }, {
+ "name" : "./circleci.sh coverage",
+ "actions" : [ {
+ "truncated" : false,
+ "index" : 0,
+ "parallel" : true,
+ "failed" : true,
+ "infrastructure_fail" : null,
+ "name" : "./circleci.sh coverage",
+ "bash_command" : "./circleci.sh coverage",
+ "status" : "timedout",
+ "timedout" : true,
+ "continue" : null,
+ "end_time" : "2017-02-19T01:00:05.670Z",
+ "source" : "config",
+ "type" : "test",
+ "truncation_len" : null,
+ "output_url" : "https://circle-production-action-output.s3.amazonaws.com/01721088526a14aa49be8a85-dlang-dmd-10-0?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20170220T005748Z&X-Amz-SignedHeaders=host&X-Amz-Expires=431999&X-Amz-Credential=AKIAIJNI6FA5RIAFFQ7Q%2F20170220%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=ad0df1b952c38e9471865820906be451bb21c5354fdb2a47a22797172ab66deb",
+ "start_time" : "2017-02-19T00:49:24.580Z",
+ "exit_code" : null,
+ "canceled" : null,
+ "step" : 10,
+ "run_time_millis" : 641090,
+ "has_output" : true
+ } ]
+ }, {
+ "name" : "rm -rf test/runnable/extra-files",
+ "actions" : [ {
+ "truncated" : false,
+ "index" : 0,
+ "parallel" : false,
+ "failed" : null,
+ "infrastructure_fail" : null,
+ "name" : "rm -rf test/runnable/extra-files",
+ "bash_command" : "rm -rf test/runnable/extra-files",
+ "status" : "success",
+ "timedout" : null,
+ "continue" : null,
+ "end_time" : "2017-02-19T01:00:06.612Z",
+ "source" : "config",
+ "type" : "test",
+ "truncation_len" : null,
+ "start_time" : "2017-02-19T01:00:05.686Z",
+ "exit_code" : 0,
+ "canceled" : null,
+ "step" : 11,
+ "run_time_millis" : 926,
+ "has_output" : false
+ } ]
+ }, {
+ "name" : "bash <(curl -s https://codecov.io/bash)",
+ "actions" : [ {
+ "truncated" : false,
+ "index" : 0,
+ "parallel" : false,
+ "failed" : null,
+ "infrastructure_fail" : null,
+ "name" : "bash <(curl -s https://codecov.io/bash)",
+ "bash_command" : "bash <(curl -s https://codecov.io/bash)",
+ "status" : "success",
+ "timedout" : null,
+ "continue" : null,
+ "end_time" : "2017-02-19T01:00:07.647Z",
+ "source" : "config",
+ "type" : "test",
+ "truncation_len" : null,
+ "output_url" : "https://circle-production-action-output.s3.amazonaws.com/5e721088526a14aa61ee8a85-dlang-dmd-12-0?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20170220T005748Z&X-Amz-SignedHeaders=host&X-Amz-Expires=431999&X-Amz-Credential=AKIAIJNI6FA5RIAFFQ7Q%2F20170220%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=b83020e0f21e53fa818292bf72880b12f90f1be006a50e05a062f8fe4dde81d3",
+ "start_time" : "2017-02-19T01:00:06.618Z",
+ "exit_code" : 0,
+ "canceled" : null,
+ "step" : 12,
+ "run_time_millis" : 1029,
+ "has_output" : true
+ } ]
+ }, {
+ "name" : "Collect test metadata",
+ "actions" : [ {
+ "truncated" : false,
+ "index" : 0,
+ "parallel" : true,
+ "failed" : null,
+ "infrastructure_fail" : null,
+ "name" : "Collect test metadata",
+ "bash_command" : null,
+ "status" : "success",
+ "timedout" : null,
+ "continue" : null,
+ "end_time" : "2017-02-19T01:00:09.413Z",
+ "type" : "teardown",
+ "truncation_len" : null,
+ "output_url" : "https://circle-production-action-output.s3.amazonaws.com/7e721088526a14aa71ee8a85-dlang-dmd-13-0?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20170220T005748Z&X-Amz-SignedHeaders=host&X-Amz-Expires=431999&X-Amz-Credential=AKIAIJNI6FA5RIAFFQ7Q%2F20170220%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=748b248a9982f561a2997eaf63dd54e941c6312e66bbb516c34eb7dc12894913",
+ "start_time" : "2017-02-19T01:00:07.654Z",
+ "exit_code" : null,
+ "canceled" : null,
+ "step" : 13,
+ "run_time_millis" : 1759,
+ "has_output" : true
+ } ]
+ }, {
+ "name" : "Collect artifacts",
+ "actions" : [ {
+ "truncated" : false,
+ "index" : 0,
+ "parallel" : true,
+ "failed" : null,
+ "infrastructure_fail" : null,
+ "name" : "Collect artifacts",
+ "bash_command" : null,
+ "status" : "success",
+ "timedout" : null,
+ "continue" : null,
+ "end_time" : "2017-02-19T01:00:16.272Z",
+ "type" : "teardown",
+ "truncation_len" : null,
+ "output_url" : "https://circle-production-action-output.s3.amazonaws.com/9e721088526a14aa91ee8a85-dlang-dmd-14-0?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20170220T005748Z&X-Amz-SignedHeaders=host&X-Amz-Expires=431999&X-Amz-Credential=AKIAIJNI6FA5RIAFFQ7Q%2F20170220%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=8fecdf913a98dcc45516aef7c582841e6d574cf3a437903ff0e33a400ce25eab",
+ "start_time" : "2017-02-19T01:00:09.422Z",
+ "exit_code" : null,
+ "canceled" : null,
+ "step" : 14,
+ "run_time_millis" : 6850,
+ "has_output" : true
+ } ]
+ }, {
+ "name" : "Disable SSH",
+ "actions" : [ {
+ "truncated" : false,
+ "index" : 0,
+ "parallel" : true,
+ "failed" : null,
+ "infrastructure_fail" : null,
+ "name" : "Disable SSH",
+ "bash_command" : null,
+ "status" : "success",
+ "timedout" : null,
+ "continue" : null,
+ "end_time" : "2017-02-19T01:00:16.285Z",
+ "type" : "teardown",
+ "truncation_len" : null,
+ "start_time" : "2017-02-19T01:00:16.281Z",
+ "exit_code" : null,
+ "canceled" : null,
+ "step" : 17,
+ "run_time_millis" : 4,
+ "has_output" : false
+ } ]
+ } ],
+ "body" : "",
+ "usage_queued_at" : "2017-02-19T00:47:24.323Z",
+ "fail_reason" : null,
+ "retry_of" : null,
+ "reponame" : "dmd",
+ "ssh_users" : [ ],
+ "build_url" : "https://circleci.com/gh/dlang/dmd/2827",
+ "parallel" : 1,
+ "failed" : null,
+ "branch" : "pull/6552",
+ "username" : "dlang",
+ "author_date" : "2017-02-19T00:47:51Z",
+ "why" : "github",
+ "user" : {
+ "is_user" : true,
+ "login" : "WalterBright",
+ "avatar_url" : "https://avatars.githubusercontent.com/u/568298?v=3",
+ "name" : "Walter Bright",
+ "vcs_type" : "github",
+ "id" : 568298
+ },
+ "vcs_revision" : "378ec2f7616ec7ca4554c5381b45561473b0c218",
+ "owners" : [ "WalterBright" ],
+ "vcs_tag" : null,
+ "pull_requests" : [ {
+ "head_sha" : "378ec2f7616ec7ca4554c5381b45561473b0c218",
+ "url" : "https://github.com/dlang/dmd/pull/6552"
+ } ],
+ "build_num" : 2827,
+ "infrastructure_fail" : false,
+ "committer_email" : "walter@walterbright.com",
+ "previous" : null,
+ "status" : "timedout",
+ "committer_name" : "Walter Bright",
+ "retries" : null,
+ "subject" : "todt.d: replace use of abytes with toStringSymbol()",
+ "vcs_type" : "github",
+ "timedout" : true,
+ "dont_build" : null,
+ "lifecycle" : "finished",
+ "no_dependency_cache" : false,
+ "stop_time" : "2017-02-19T01:00:16.492Z",
+ "ssh_disabled" : false,
+ "build_time_millis" : 685569,
+ "circle_yml" : {
+ "string" : "dependencies:\n pre:\n - ./circleci.sh install-deps\n cache_directories:\n - \"~/dlang\"\n\ntest:\n override:\n - ./circleci.sh coverage:\n parallel: true\n\n post:\n # CodeCov gets confused by lst files which it can't matched\n - rm -rf test/runnable/extra-files\n - bash <(curl -s https://codecov.io/bash)\n\ngeneral:\n branches:\n ignore:\n - dmd-1.x\n"
+ },
+ "messages" : [ ],
+ "is_first_green_build" : false,
+ "job_name" : null,
+ "start_time" : "2017-02-19T00:48:50.923Z",
+ "canceler" : null,
+ "all_commit_details" : [ {
+ "committer_date" : "2017-02-19T00:47:51Z",
+ "body" : "",
+ "author_date" : "2017-02-19T00:47:51Z",
+ "committer_email" : "walter@walterbright.com",
+ "commit" : "378ec2f7616ec7ca4554c5381b45561473b0c218",
+ "committer_login" : "WalterBright",
+ "committer_name" : "Walter Bright",
+ "subject" : "todt.d: replace use of abytes with toStringSymbol()",
+ "commit_url" : "https://github.com/dlang/dmd/commit/378ec2f7616ec7ca4554c5381b45561473b0c218",
+ "author_login" : "WalterBright",
+ "author_name" : "Walter Bright",
+ "author_email" : "walter@walterbright.com"
+ } ],
+ "outcome" : "timedout",
+ "vcs_url" : "https://github.com/dlang/dmd",
+ "author_name" : "Walter Bright",
+ "node" : [ {
+ "public_ip_addr" : "54.211.139.201",
+ "port" : 64703,
+ "username" : "ubuntu",
+ "image_id" : "s3://lxc-images/circletar-1741-cc586-20160424T232626Z",
+ "ssh_enabled" : null
+ } ],
+ "queued_at" : "2017-02-19T00:48:50.895Z",
+ "canceled" : false,
+ "author_email" : "walter@walterbright.com"
+}
\ No newline at end of file
diff --git a/data/payloads/circleci_project_github_dlang_phobos_1778 b/data/payloads/circleci_project_github_dlang_phobos_1778
new file mode 100644
index 0000000..c422979
--- /dev/null
+++ b/data/payloads/circleci_project_github_dlang_phobos_1778
@@ -0,0 +1,534 @@
+{
+ "compare" : null,
+ "previous_successful_build" : {
+ "build_num" : 1767,
+ "status" : "success",
+ "build_time_millis" : 521777
+ },
+ "build_parameters" : null,
+ "oss" : true,
+ "all_commit_details_truncated" : false,
+ "committer_date" : "2017-02-18T02:47:25Z",
+ "steps" : [ {
+ "name" : "Starting the build",
+ "actions" : [ {
+ "truncated" : false,
+ "index" : 0,
+ "parallel" : false,
+ "failed" : null,
+ "infrastructure_fail" : null,
+ "name" : "Starting the build",
+ "bash_command" : null,
+ "status" : "success",
+ "timedout" : null,
+ "continue" : null,
+ "end_time" : "2017-02-18T02:47:35.897Z",
+ "type" : "infrastructure",
+ "truncation_len" : null,
+ "output_url" : "https://circle-production-action-output.s3.amazonaws.com/dfbc80af324879992c5b7a85-dlang-phobos-0-0?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20170220T003856Z&X-Amz-SignedHeaders=host&X-Amz-Expires=431999&X-Amz-Credential=AKIAIJNI6FA5RIAFFQ7Q%2F20170220%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=219cc983fb65b6cc8b2a7a7b7f35383f547da64ec5dd5745c892fea2a9245780",
+ "start_time" : "2017-02-18T02:47:30.573Z",
+ "exit_code" : null,
+ "canceled" : null,
+ "step" : 0,
+ "run_time_millis" : 5324,
+ "has_output" : true
+ } ]
+ }, {
+ "name" : "Start container",
+ "actions" : [ {
+ "truncated" : false,
+ "index" : 0,
+ "parallel" : true,
+ "failed" : null,
+ "infrastructure_fail" : null,
+ "name" : "Start container",
+ "bash_command" : null,
+ "status" : "success",
+ "timedout" : null,
+ "continue" : null,
+ "end_time" : "2017-02-18T02:47:43.285Z",
+ "source" : "config",
+ "type" : "infrastructure",
+ "truncation_len" : null,
+ "output_url" : "https://circle-production-action-output.s3.amazonaws.com/efbc80af324879997c5b7a85-dlang-phobos-1-0?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20170220T003856Z&X-Amz-SignedHeaders=host&X-Amz-Expires=431999&X-Amz-Credential=AKIAIJNI6FA5RIAFFQ7Q%2F20170220%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=59550b2c136b50676ec874c04aea6be45db6fa234d59304dc8043f363e55f6a6",
+ "start_time" : "2017-02-18T02:47:35.903Z",
+ "exit_code" : 0,
+ "canceled" : null,
+ "step" : 1,
+ "run_time_millis" : 7382,
+ "has_output" : true
+ } ]
+ }, {
+ "name" : "Enable SSH",
+ "actions" : [ {
+ "truncated" : false,
+ "index" : 0,
+ "parallel" : true,
+ "failed" : null,
+ "infrastructure_fail" : null,
+ "name" : "Enable SSH",
+ "bash_command" : null,
+ "status" : "success",
+ "timedout" : null,
+ "continue" : null,
+ "end_time" : "2017-02-18T02:47:45.205Z",
+ "type" : "infrastructure",
+ "truncation_len" : null,
+ "output_url" : "https://circle-production-action-output.s3.amazonaws.com/ffbc80af32487999fc5b7a85-dlang-phobos-2-0?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20170220T003856Z&X-Amz-SignedHeaders=host&X-Amz-Expires=431999&X-Amz-Credential=AKIAIJNI6FA5RIAFFQ7Q%2F20170220%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=2fbb599e06314303c64f697b6af61c0b6b07e06fd6d6522dd6afc5685c57d0f4",
+ "start_time" : "2017-02-18T02:47:43.290Z",
+ "exit_code" : null,
+ "canceled" : null,
+ "step" : 2,
+ "run_time_millis" : 1915,
+ "has_output" : true
+ } ]
+ }, {
+ "name" : "Restore source cache",
+ "actions" : [ {
+ "truncated" : false,
+ "index" : 0,
+ "parallel" : false,
+ "failed" : null,
+ "infrastructure_fail" : null,
+ "name" : "Restore source cache",
+ "bash_command" : null,
+ "status" : "success",
+ "timedout" : null,
+ "continue" : null,
+ "end_time" : "2017-02-18T02:47:48.040Z",
+ "source" : "cache",
+ "type" : "checkout",
+ "truncation_len" : null,
+ "output_url" : "https://circle-production-action-output.s3.amazonaws.com/00cc80af324879991d5b7a85-dlang-phobos-3-0?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20170220T003856Z&X-Amz-SignedHeaders=host&X-Amz-Expires=431999&X-Amz-Credential=AKIAIJNI6FA5RIAFFQ7Q%2F20170220%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=b7e0d7a5f31863745fd4bda0f5a2450d15ae770fe5da5d36c87259f2a8c2a637",
+ "start_time" : "2017-02-18T02:47:45.210Z",
+ "exit_code" : null,
+ "canceled" : null,
+ "step" : 3,
+ "run_time_millis" : 2830,
+ "has_output" : true
+ } ]
+ }, {
+ "name" : "Checkout using CircleCI fork PR checkout user key: 72:d2:fd:18:4c:f5:15:b1:ab:47:44:65:9d:9b:08:0a",
+ "actions" : [ {
+ "truncated" : false,
+ "index" : 0,
+ "parallel" : true,
+ "failed" : null,
+ "infrastructure_fail" : null,
+ "name" : "Checkout using CircleCI fork PR checkout user key: 72:d2:fd:18:4c:f5:15:b1:ab:47:44:65:9d:9b:08:0a",
+ "bash_command" : null,
+ "status" : "success",
+ "timedout" : null,
+ "continue" : null,
+ "end_time" : "2017-02-18T02:47:51.624Z",
+ "source" : "config",
+ "type" : "checkout",
+ "truncation_len" : null,
+ "output_url" : "https://circle-production-action-output.s3.amazonaws.com/10cc80af324879994d5b7a85-dlang-phobos-4-0?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20170220T003856Z&X-Amz-SignedHeaders=host&X-Amz-Expires=431999&X-Amz-Credential=AKIAIJNI6FA5RIAFFQ7Q%2F20170220%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=6d3bc62e0d1b7222ce10b0ac6b21c1f65782639214ce7b4a1838099a4566c294",
+ "start_time" : "2017-02-18T02:47:48.050Z",
+ "exit_code" : 0,
+ "canceled" : null,
+ "step" : 4,
+ "run_time_millis" : 3574,
+ "has_output" : true
+ } ]
+ }, {
+ "name" : "Configure the build",
+ "actions" : [ {
+ "truncated" : false,
+ "index" : 0,
+ "parallel" : false,
+ "failed" : null,
+ "infrastructure_fail" : null,
+ "name" : "Configure the build",
+ "bash_command" : null,
+ "status" : "success",
+ "timedout" : null,
+ "continue" : null,
+ "end_time" : "2017-02-18T02:47:55.053Z",
+ "source" : "cache",
+ "type" : "machine",
+ "truncation_len" : null,
+ "start_time" : "2017-02-18T02:47:51.629Z",
+ "exit_code" : null,
+ "canceled" : null,
+ "step" : 5,
+ "run_time_millis" : 3424,
+ "has_output" : false
+ } ]
+ }, {
+ "name" : "Suppressing export of environment variables fork PR builds",
+ "actions" : [ {
+ "truncated" : false,
+ "index" : 0,
+ "parallel" : true,
+ "failed" : null,
+ "infrastructure_fail" : null,
+ "name" : "Suppressing export of environment variables fork PR builds",
+ "bash_command" : null,
+ "status" : "success",
+ "timedout" : null,
+ "continue" : null,
+ "end_time" : "2017-02-18T02:47:55.062Z",
+ "source" : "db",
+ "type" : "machine",
+ "truncation_len" : null,
+ "start_time" : "2017-02-18T02:47:55.061Z",
+ "exit_code" : null,
+ "canceled" : null,
+ "step" : 6,
+ "run_time_millis" : 1,
+ "has_output" : false
+ } ]
+ }, {
+ "name" : "Restore cache",
+ "actions" : [ {
+ "truncated" : false,
+ "index" : 0,
+ "parallel" : false,
+ "failed" : null,
+ "infrastructure_fail" : null,
+ "name" : "Restore cache",
+ "bash_command" : null,
+ "status" : "success",
+ "timedout" : null,
+ "continue" : null,
+ "end_time" : "2017-02-18T02:48:01.517Z",
+ "source" : "cache",
+ "type" : "machine",
+ "truncation_len" : null,
+ "output_url" : "https://circle-production-action-output.s3.amazonaws.com/40cc80af32487999bd5b7a85-dlang-phobos-7-0?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20170220T003856Z&X-Amz-SignedHeaders=host&X-Amz-Expires=431999&X-Amz-Credential=AKIAIJNI6FA5RIAFFQ7Q%2F20170220%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=5d8d4b64167f0728d326140440625c932c2fa652949a8b38919230dc09619426",
+ "start_time" : "2017-02-18T02:47:55.066Z",
+ "exit_code" : null,
+ "canceled" : null,
+ "step" : 7,
+ "run_time_millis" : 6451,
+ "has_output" : true
+ } ]
+ }, {
+ "name" : "./circleci.sh install-deps",
+ "actions" : [ {
+ "truncated" : false,
+ "index" : 0,
+ "parallel" : true,
+ "failed" : null,
+ "infrastructure_fail" : null,
+ "name" : "./circleci.sh install-deps",
+ "bash_command" : "./circleci.sh install-deps",
+ "status" : "success",
+ "timedout" : null,
+ "continue" : null,
+ "end_time" : "2017-02-18T02:48:03.189Z",
+ "source" : "config",
+ "type" : "dependencies",
+ "truncation_len" : null,
+ "output_url" : "https://circle-production-action-output.s3.amazonaws.com/50cc80af324879991e5b7a85-dlang-phobos-8-0?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20170220T003856Z&X-Amz-SignedHeaders=host&X-Amz-Expires=431999&X-Amz-Credential=AKIAIJNI6FA5RIAFFQ7Q%2F20170220%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=12d3eb7a83a3019b5310e6b1e2cfaa4b12b19dd58081858ad3c1f908736fe454",
+ "start_time" : "2017-02-18T02:48:01.527Z",
+ "exit_code" : 0,
+ "canceled" : null,
+ "step" : 8,
+ "run_time_millis" : 1662,
+ "has_output" : true
+ } ]
+ }, {
+ "name" : "Save cache",
+ "actions" : [ {
+ "truncated" : false,
+ "index" : 0,
+ "parallel" : false,
+ "failed" : null,
+ "infrastructure_fail" : null,
+ "name" : "Save cache",
+ "bash_command" : null,
+ "status" : "success",
+ "timedout" : null,
+ "continue" : null,
+ "end_time" : "2017-02-18T02:48:06.605Z",
+ "source" : "cache",
+ "type" : "database",
+ "truncation_len" : null,
+ "output_url" : "https://circle-production-action-output.s3.amazonaws.com/60cc80af324879993e5b7a85-dlang-phobos-9-0?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20170220T003856Z&X-Amz-SignedHeaders=host&X-Amz-Expires=431999&X-Amz-Credential=AKIAIJNI6FA5RIAFFQ7Q%2F20170220%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=5da80f63c346d36b8f7b89963fe02ef0d73effe52403ea7158bcd62cbf919fff",
+ "start_time" : "2017-02-18T02:48:03.193Z",
+ "exit_code" : null,
+ "canceled" : null,
+ "step" : 9,
+ "run_time_millis" : 3412,
+ "has_output" : true
+ } ]
+ }, {
+ "name" : "./circleci.sh style",
+ "actions" : [ {
+ "truncated" : false,
+ "index" : 0,
+ "parallel" : false,
+ "failed" : null,
+ "infrastructure_fail" : null,
+ "name" : "./circleci.sh style",
+ "bash_command" : "./circleci.sh style",
+ "status" : "success",
+ "timedout" : null,
+ "continue" : null,
+ "end_time" : "2017-02-18T02:48:37.347Z",
+ "source" : "config",
+ "type" : "test",
+ "truncation_len" : null,
+ "output_url" : "https://circle-production-action-output.s3.amazonaws.com/70cc80af324879996e5b7a85-dlang-phobos-10-0?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20170220T003856Z&X-Amz-SignedHeaders=host&X-Amz-Expires=431999&X-Amz-Credential=AKIAIJNI6FA5RIAFFQ7Q%2F20170220%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=f6361244f3167e9f410c1d7d3564424d379a40c4ae3ae563456e036da28cca0b",
+ "start_time" : "2017-02-18T02:48:06.614Z",
+ "exit_code" : 0,
+ "canceled" : null,
+ "step" : 10,
+ "run_time_millis" : 30733,
+ "has_output" : true
+ } ]
+ }, {
+ "name" : "./circleci.sh setup-repos",
+ "actions" : [ {
+ "truncated" : false,
+ "index" : 0,
+ "parallel" : false,
+ "failed" : null,
+ "infrastructure_fail" : null,
+ "name" : "./circleci.sh setup-repos",
+ "bash_command" : "./circleci.sh setup-repos",
+ "status" : "success",
+ "timedout" : null,
+ "continue" : null,
+ "end_time" : "2017-02-18T02:49:00.428Z",
+ "source" : "config",
+ "type" : "test",
+ "truncation_len" : null,
+ "output_url" : "https://circle-production-action-output.s3.amazonaws.com/80cc80af32487999506b7a85-dlang-phobos-11-0?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20170220T003856Z&X-Amz-SignedHeaders=host&X-Amz-Expires=431999&X-Amz-Credential=AKIAIJNI6FA5RIAFFQ7Q%2F20170220%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=c84f0960a42e2f7fa6cb38b6c831b39b09abe1c566f1ba8ec14d330323eea7d4",
+ "start_time" : "2017-02-18T02:48:37.360Z",
+ "exit_code" : 0,
+ "canceled" : null,
+ "step" : 11,
+ "run_time_millis" : 23068,
+ "has_output" : true
+ } ]
+ }, {
+ "name" : "./circleci.sh publictests",
+ "actions" : [ {
+ "truncated" : false,
+ "index" : 0,
+ "parallel" : false,
+ "failed" : null,
+ "infrastructure_fail" : null,
+ "name" : "./circleci.sh publictests",
+ "bash_command" : "./circleci.sh publictests",
+ "status" : "success",
+ "timedout" : null,
+ "continue" : null,
+ "end_time" : "2017-02-18T02:50:51.342Z",
+ "source" : "config",
+ "type" : "test",
+ "truncation_len" : null,
+ "output_url" : "https://circle-production-action-output.s3.amazonaws.com/90cc80af32487999c16b7a85-dlang-phobos-12-0?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20170220T003856Z&X-Amz-SignedHeaders=host&X-Amz-Expires=431999&X-Amz-Credential=AKIAIJNI6FA5RIAFFQ7Q%2F20170220%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=c59922004858df5210665dfb4e12d97b9ba9039c67889af083e6e0012d852de1",
+ "start_time" : "2017-02-18T02:49:00.434Z",
+ "exit_code" : 0,
+ "canceled" : null,
+ "step" : 12,
+ "run_time_millis" : 110908,
+ "has_output" : true
+ } ]
+ }, {
+ "name" : "./circleci.sh coverage",
+ "actions" : [ {
+ "truncated" : false,
+ "index" : 0,
+ "parallel" : true,
+ "failed" : null,
+ "infrastructure_fail" : null,
+ "name" : "./circleci.sh coverage",
+ "bash_command" : "./circleci.sh coverage",
+ "status" : "success",
+ "timedout" : null,
+ "continue" : null,
+ "end_time" : "2017-02-18T02:55:52.311Z",
+ "source" : "config",
+ "type" : "test",
+ "truncation_len" : null,
+ "output_url" : "https://circle-production-action-output.s3.amazonaws.com/f0cc80af32487999b86b7a85-dlang-phobos-13-0?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20170220T003856Z&X-Amz-SignedHeaders=host&X-Amz-Expires=431999&X-Amz-Credential=AKIAIJNI6FA5RIAFFQ7Q%2F20170220%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=663b4a0e7102c5753cebe8281b83dd067bd1e041d6650ea711859fd45f9e5791",
+ "start_time" : "2017-02-18T02:50:51.360Z",
+ "exit_code" : 0,
+ "canceled" : null,
+ "step" : 13,
+ "run_time_millis" : 300951,
+ "has_output" : true
+ } ]
+ }, {
+ "name" : "bash <(curl -s https://codecov.io/bash)",
+ "actions" : [ {
+ "truncated" : false,
+ "index" : 0,
+ "parallel" : false,
+ "failed" : null,
+ "infrastructure_fail" : null,
+ "name" : "bash <(curl -s https://codecov.io/bash)",
+ "bash_command" : "bash <(curl -s https://codecov.io/bash)",
+ "status" : "success",
+ "timedout" : null,
+ "continue" : null,
+ "end_time" : "2017-02-18T02:55:59.411Z",
+ "source" : "config",
+ "type" : "test",
+ "truncation_len" : null,
+ "output_url" : "https://circle-production-action-output.s3.amazonaws.com/65cc80af324879998b7b7a85-dlang-phobos-14-0?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20170220T003856Z&X-Amz-SignedHeaders=host&X-Amz-Expires=431999&X-Amz-Credential=AKIAIJNI6FA5RIAFFQ7Q%2F20170220%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=0cc5e4ac863e10818808a03e27815e61a6bc7cc551e6dc6c76898780b5fd89a2",
+ "start_time" : "2017-02-18T02:55:52.327Z",
+ "exit_code" : 0,
+ "canceled" : null,
+ "step" : 14,
+ "run_time_millis" : 7084,
+ "has_output" : true
+ } ]
+ }, {
+ "name" : "Collect test metadata",
+ "actions" : [ {
+ "truncated" : false,
+ "index" : 0,
+ "parallel" : true,
+ "failed" : null,
+ "infrastructure_fail" : null,
+ "name" : "Collect test metadata",
+ "bash_command" : null,
+ "status" : "success",
+ "timedout" : null,
+ "continue" : null,
+ "end_time" : "2017-02-18T02:56:01.442Z",
+ "type" : "teardown",
+ "truncation_len" : null,
+ "output_url" : "https://circle-production-action-output.s3.amazonaws.com/75cc80af32487999fb7b7a85-dlang-phobos-15-0?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20170220T003856Z&X-Amz-SignedHeaders=host&X-Amz-Expires=431999&X-Amz-Credential=AKIAIJNI6FA5RIAFFQ7Q%2F20170220%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=d00bc536b2d2310d96f74a696c17c643d31de7d594bfac5d69006348bf70aeda",
+ "start_time" : "2017-02-18T02:55:59.417Z",
+ "exit_code" : null,
+ "canceled" : null,
+ "step" : 15,
+ "run_time_millis" : 2025,
+ "has_output" : true
+ } ]
+ }, {
+ "name" : "Collect artifacts",
+ "actions" : [ {
+ "truncated" : false,
+ "index" : 0,
+ "parallel" : true,
+ "failed" : null,
+ "infrastructure_fail" : null,
+ "name" : "Collect artifacts",
+ "bash_command" : null,
+ "status" : "success",
+ "timedout" : null,
+ "continue" : null,
+ "end_time" : "2017-02-18T02:56:09.027Z",
+ "type" : "teardown",
+ "truncation_len" : null,
+ "output_url" : "https://circle-production-action-output.s3.amazonaws.com/85cc80af324879991c7b7a85-dlang-phobos-16-0?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20170220T003856Z&X-Amz-SignedHeaders=host&X-Amz-Expires=431999&X-Amz-Credential=AKIAIJNI6FA5RIAFFQ7Q%2F20170220%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=36eaec6c7ab332ed1bccd35348137092e6338d6f8d672bbdecaa8bf7734ff243",
+ "start_time" : "2017-02-18T02:56:01.447Z",
+ "exit_code" : null,
+ "canceled" : null,
+ "step" : 16,
+ "run_time_millis" : 7580,
+ "has_output" : true
+ } ]
+ }, {
+ "name" : "Disable SSH",
+ "actions" : [ {
+ "truncated" : false,
+ "index" : 0,
+ "parallel" : true,
+ "failed" : null,
+ "infrastructure_fail" : null,
+ "name" : "Disable SSH",
+ "bash_command" : null,
+ "status" : "success",
+ "timedout" : null,
+ "continue" : null,
+ "end_time" : "2017-02-18T02:56:09.035Z",
+ "type" : "teardown",
+ "truncation_len" : null,
+ "start_time" : "2017-02-18T02:56:09.031Z",
+ "exit_code" : null,
+ "canceled" : null,
+ "step" : 19,
+ "run_time_millis" : 4,
+ "has_output" : false
+ } ]
+ } ],
+ "body" : "",
+ "usage_queued_at" : "2017-02-18T02:43:58.178Z",
+ "fail_reason" : null,
+ "retry_of" : null,
+ "reponame" : "phobos",
+ "ssh_users" : [ ],
+ "build_url" : "https://circleci.com/gh/dlang/phobos/1778",
+ "parallel" : 1,
+ "failed" : null,
+ "branch" : "pull/5151",
+ "username" : "dlang",
+ "author_date" : "2017-02-18T02:47:25Z",
+ "why" : "github",
+ "user" : {
+ "is_user" : true,
+ "login" : "wilzbach",
+ "avatar_url" : "https://avatars.githubusercontent.com/u/4370550?v=3",
+ "name" : "Sebastian Wilzbach",
+ "vcs_type" : "github",
+ "id" : 4370550
+ },
+ "vcs_revision" : "c652bce17d242c71875d99e379e37259101ea9fd",
+ "owners" : [ "wilzbach" ],
+ "vcs_tag" : null,
+ "pull_requests" : [ {
+ "head_sha" : "c652bce17d242c71875d99e379e37259101ea9fd",
+ "url" : "https://github.com/dlang/phobos/pull/5151"
+ } ],
+ "build_num" : 1778,
+ "infrastructure_fail" : false,
+ "committer_email" : "seb@wilzba.ch",
+ "previous" : null,
+ "status" : "success",
+ "committer_name" : "Sebastian Wilzbach",
+ "retries" : null,
+ "subject" : "[Static if] replace overload constraints with static if (sorting.d)",
+ "vcs_type" : "github",
+ "timedout" : false,
+ "dont_build" : null,
+ "lifecycle" : "finished",
+ "no_dependency_cache" : false,
+ "stop_time" : "2017-02-18T02:56:09.384Z",
+ "ssh_disabled" : false,
+ "build_time_millis" : 519668,
+ "circle_yml" : {
+ "string" : "dependencies:\n pre:\n - ./circleci.sh install-deps\n cache_directories:\n - \"~/dlang\"\n\ntest:\n override:\n - ./circleci.sh style\n - ./circleci.sh setup-repos\n - ./circleci.sh publictests\n - ./circleci.sh coverage:\n parallel: true\n timeout: 1200\n\n post:\n - bash <(curl -s https://codecov.io/bash)\n"
+ },
+ "messages" : [ ],
+ "is_first_green_build" : false,
+ "job_name" : null,
+ "start_time" : "2017-02-18T02:47:29.716Z",
+ "canceler" : null,
+ "all_commit_details" : [ {
+ "committer_date" : "2017-02-18T02:47:25Z",
+ "body" : "",
+ "author_date" : "2017-02-18T02:47:25Z",
+ "committer_email" : "seb@wilzba.ch",
+ "commit" : "c652bce17d242c71875d99e379e37259101ea9fd",
+ "committer_login" : "wilzbach",
+ "committer_name" : "Sebastian Wilzbach",
+ "subject" : "[Static if] replace overload constraints with static if (sorting.d)",
+ "commit_url" : "https://github.com/dlang/phobos/commit/c652bce17d242c71875d99e379e37259101ea9fd",
+ "author_login" : "wilzbach",
+ "author_name" : "Sebastian Wilzbach",
+ "author_email" : "seb@wilzba.ch"
+ } ],
+ "outcome" : "success",
+ "vcs_url" : "https://github.com/dlang/phobos",
+ "author_name" : "Sebastian Wilzbach",
+ "node" : [ {
+ "public_ip_addr" : "52.14.133.93",
+ "port" : 64786,
+ "username" : "ubuntu",
+ "image_id" : "s3://lxc-images-us-east-2/circletar-1741-cc586-20160424T232626Z",
+ "ssh_enabled" : null
+ } ],
+ "queued_at" : "2017-02-18T02:47:29.677Z",
+ "canceled" : false,
+ "author_email" : "seb@wilzba.ch"
+}
\ No newline at end of file
diff --git a/data/payloads/dtest_results_86959530a962d84f01679c0aa45dd2c9714cc6ac_9f9369c96a0b8b8e4844c6d8d6f3fae9391a1450 b/data/payloads/dtest_results_86959530a962d84f01679c0aa45dd2c9714cc6ac_9f9369c96a0b8b8e4844c6d8d6f3fae9391a1450
new file mode 100644
index 0000000..e6a911b
--- /dev/null
+++ b/data/payloads/dtest_results_86959530a962d84f01679c0aa45dd2c9714cc6ac_9f9369c96a0b8b8e4844c6d8d6f3fae9391a1450
@@ -0,0 +1,11 @@
+
+
+
+
+
Test result - DAutoTest
+
+
+Test result
+
+
+
diff --git a/data/payloads/dtest_results_86959530a962d84f01679c0aa45dd2c9714cc6ac_feb55b1f448c28dfb72ce409f8b1994f097dddb5 b/data/payloads/dtest_results_86959530a962d84f01679c0aa45dd2c9714cc6ac_feb55b1f448c28dfb72ce409f8b1994f097dddb5
new file mode 100644
index 0000000..e0135c4
--- /dev/null
+++ b/data/payloads/dtest_results_86959530a962d84f01679c0aa45dd2c9714cc6ac_feb55b1f448c28dfb72ce409f8b1994f097dddb5
@@ -0,0 +1,11 @@
+
+
+
+
+Test result - DAutoTest
+
+
+Test result
+
+
+
diff --git a/data/payloads/github_repos_dlang_dmd_pulls_6324_reviews b/data/payloads/github_repos_dlang_dmd_pulls_6324_reviews
new file mode 100644
index 0000000..41b42e6
--- /dev/null
+++ b/data/payloads/github_repos_dlang_dmd_pulls_6324_reviews
@@ -0,0 +1,3 @@
+[
+
+]
diff --git a/data/payloads/github_repos_dlang_dmd_status_eb53933e2d0989f6da3edf8581bb3de4acac9f0e b/data/payloads/github_repos_dlang_dmd_status_eb53933e2d0989f6da3edf8581bb3de4acac9f0e
new file mode 100644
index 0000000..0e73d40
--- /dev/null
+++ b/data/payloads/github_repos_dlang_dmd_status_eb53933e2d0989f6da3edf8581bb3de4acac9f0e
@@ -0,0 +1,134 @@
+{
+ "state": "pending",
+ "statuses": [
+ {
+ "url": "https://api.github.com/repos/dlang/dmd/statuses/eb53933e2d0989f6da3edf8581bb3de4acac9f0e",
+ "id": 913326948,
+ "state": "success",
+ "description": "Your tests passed on CircleCI!",
+ "target_url": "https://circleci.com/gh/dlang/dmd/1864?utm_campaign=vcs-integration-link&utm_medium=referral&utm_source=github-build-link",
+ "context": "ci/circleci",
+ "created_at": "2016-12-15T15:30:11Z",
+ "updated_at": "2016-12-15T15:30:11Z"
+ },
+ {
+ "url": "https://api.github.com/repos/dlang/dmd/statuses/eb53933e2d0989f6da3edf8581bb3de4acac9f0e",
+ "id": 913343183,
+ "state": "success",
+ "description": "86.501% (+0.001%) compared to b7d84f8",
+ "target_url": "https://codecov.io/gh/dlang/dmd/compare/b7d84f8c7358d4bdf5518392bcf99831c09faf3b...eb53933e2d0989f6da3edf8581bb3de4acac9f0e",
+ "context": "codecov/project",
+ "created_at": "2016-12-15T15:36:42Z",
+ "updated_at": "2016-12-15T15:36:42Z"
+ },
+ {
+ "url": "https://api.github.com/repos/dlang/dmd/statuses/eb53933e2d0989f6da3edf8581bb3de4acac9f0e",
+ "id": 913343256,
+ "state": "success",
+ "description": "100% of diff hit (target 86.500%)",
+ "target_url": "https://codecov.io/gh/dlang/dmd/compare/b7d84f8c7358d4bdf5518392bcf99831c09faf3b...eb53933e2d0989f6da3edf8581bb3de4acac9f0e",
+ "context": "codecov/patch",
+ "created_at": "2016-12-15T15:36:44Z",
+ "updated_at": "2016-12-15T15:36:44Z"
+ },
+ {
+ "url": "https://api.github.com/repos/dlang/dmd/statuses/eb53933e2d0989f6da3edf8581bb3de4acac9f0e",
+ "id": 913453137,
+ "state": "success",
+ "description": "The Travis CI build passed",
+ "target_url": "https://travis-ci.org/dlang/dmd/builds/184269264",
+ "context": "continuous-integration/travis-ci/pr",
+ "created_at": "2016-12-15T16:20:51Z",
+ "updated_at": "2016-12-15T16:20:51Z"
+ },
+ {
+ "url": "https://api.github.com/repos/dlang/dmd/statuses/eb53933e2d0989f6da3edf8581bb3de4acac9f0e",
+ "id": 928992984,
+ "state": "success",
+ "description": "Documentation OK (no changes)",
+ "target_url": "http://dtest.thecybershadow.net/results/b4d532b2ba83497292a119cb8fcefd3889e04d78/eb53933e2d0989f6da3edf8581bb3de4acac9f0e/",
+ "context": "CyberShadow/DAutoTest",
+ "created_at": "2016-12-26T16:38:15Z",
+ "updated_at": "2016-12-26T16:38:15Z"
+ },
+ {
+ "url": "https://api.github.com/repos/dlang/dmd/statuses/eb53933e2d0989f6da3edf8581bb3de4acac9f0e",
+ "id": 929015869,
+ "state": "pending",
+ "description": "Pass: 4, Pending: 6",
+ "target_url": "https://auto-tester.puremagic.com/pull-history.ghtml?projectid=1&repoid=1&pullid=6324",
+ "context": "auto-tester",
+ "created_at": "2016-12-26T17:16:42Z",
+ "updated_at": "2016-12-26T17:16:42Z"
+ }
+ ],
+ "sha": "eb53933e2d0989f6da3edf8581bb3de4acac9f0e",
+ "total_count": 6,
+ "repository": {
+ "id": 1257070,
+ "name": "dmd",
+ "full_name": "dlang/dmd",
+ "owner": {
+ "login": "dlang",
+ "id": 565913,
+ "avatar_url": "https://avatars.githubusercontent.com/u/565913?v=3",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/dlang",
+ "html_url": "https://github.com/dlang",
+ "followers_url": "https://api.github.com/users/dlang/followers",
+ "following_url": "https://api.github.com/users/dlang/following{/other_user}",
+ "gists_url": "https://api.github.com/users/dlang/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/dlang/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/dlang/subscriptions",
+ "organizations_url": "https://api.github.com/users/dlang/orgs",
+ "repos_url": "https://api.github.com/users/dlang/repos",
+ "events_url": "https://api.github.com/users/dlang/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/dlang/received_events",
+ "type": "Organization",
+ "site_admin": false
+ },
+ "private": false,
+ "html_url": "https://github.com/dlang/dmd",
+ "description": "dmd D Programming Language compiler",
+ "fork": false,
+ "url": "https://api.github.com/repos/dlang/dmd",
+ "forks_url": "https://api.github.com/repos/dlang/dmd/forks",
+ "keys_url": "https://api.github.com/repos/dlang/dmd/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/dlang/dmd/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/dlang/dmd/teams",
+ "hooks_url": "https://api.github.com/repos/dlang/dmd/hooks",
+ "issue_events_url": "https://api.github.com/repos/dlang/dmd/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/dlang/dmd/events",
+ "assignees_url": "https://api.github.com/repos/dlang/dmd/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/dlang/dmd/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/dlang/dmd/tags",
+ "blobs_url": "https://api.github.com/repos/dlang/dmd/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/dlang/dmd/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/dlang/dmd/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/dlang/dmd/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/dlang/dmd/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/dlang/dmd/languages",
+ "stargazers_url": "https://api.github.com/repos/dlang/dmd/stargazers",
+ "contributors_url": "https://api.github.com/repos/dlang/dmd/contributors",
+ "subscribers_url": "https://api.github.com/repos/dlang/dmd/subscribers",
+ "subscription_url": "https://api.github.com/repos/dlang/dmd/subscription",
+ "commits_url": "https://api.github.com/repos/dlang/dmd/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/dlang/dmd/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/dlang/dmd/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/dlang/dmd/issues/comments{/number}",
+ "contents_url": "https://api.github.com/repos/dlang/dmd/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/dlang/dmd/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/dlang/dmd/merges",
+ "archive_url": "https://api.github.com/repos/dlang/dmd/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/dlang/dmd/downloads",
+ "issues_url": "https://api.github.com/repos/dlang/dmd/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/dlang/dmd/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/dlang/dmd/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/dlang/dmd/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/dlang/dmd/labels{/name}",
+ "releases_url": "https://api.github.com/repos/dlang/dmd/releases{/id}",
+ "deployments_url": "https://api.github.com/repos/dlang/dmd/deployments"
+ },
+ "commit_url": "https://api.github.com/repos/dlang/dmd/commits/eb53933e2d0989f6da3edf8581bb3de4acac9f0e",
+ "url": "https://api.github.com/repos/dlang/dmd/commits/eb53933e2d0989f6da3edf8581bb3de4acac9f0e/status"
+}
diff --git a/data/payloads/projecttester_job_dmd_trigger_974 b/data/payloads/projecttester_job_dmd_trigger_974
new file mode 100644
index 0000000..9033b5a
--- /dev/null
+++ b/data/payloads/projecttester_job_dmd_trigger_974
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+ dmd_trigger #974 [Jenkins]Skip to content
+ Build #974
+ (Feb 19, 2017 1:49:04 AM)
+
PR #6552: todt.d: replace use of abyt...
 | No changes. |
 | GitHub pull request #6552 of commit 378ec2f7616ec7ca4554c5381b45561473b0c218, no merge conflicts. |
Subproject Builds
\ No newline at end of file
diff --git a/data/payloads/projecttester_job_phobos_trigger_343 b/data/payloads/projecttester_job_phobos_trigger_343
new file mode 100644
index 0000000..18ec1f0
--- /dev/null
+++ b/data/payloads/projecttester_job_phobos_trigger_343
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+ phobos_trigger #343 [Jenkins]Skip to content
+ Build #343
+ (Feb 18, 2017 4:30:05 AM)
+
PR #5151: [Static if] replace overloa...
 | No changes. |
 | GitHub pull request #5151 of commit c652bce17d242c71875d99e379e37259101ea9fd, no merge conflicts. |
Subproject Builds
\ No newline at end of file
diff --git a/data/payloads/travis_repos_dlang_dmd_builds_203056613 b/data/payloads/travis_repos_dlang_dmd_builds_203056613
new file mode 100644
index 0000000..b168381
--- /dev/null
+++ b/data/payloads/travis_repos_dlang_dmd_builds_203056613
@@ -0,0 +1 @@
+{"build":{"id":203056613,"repository_id":318556,"commit_id":58164361,"number":"7903","event_type":"pull_request","pull_request":true,"pull_request_title":"todt.d: replace use of abytes with toStringSymbol()","pull_request_number":6552,"config":{"language":"d","d":["dmd","gdc","ldc"],"script":"./travis.sh","sudo":false,"addons":{"apt":{"packages":["g++-multilib","gdb","libcurl3-gnutls:i386"]}},"env":["MODEL=32","MODEL=64"],"matrix":{"include":[{"os":"osx","d":"dmd","env":"MODEL=32","dist":"precise"},{"os":"osx","d":"dmd","env":"MODEL=64","dist":"precise"}],"exclude":[{"d":"gdc","env":"MODEL=32"}]},".result":"configured","group":"stable","dist":"precise"},"state":"errored","started_at":"2017-02-19T00:49:00Z","finished_at":"2017-02-19T01:22:42Z","duration":3878,"job_ids":[203056614,203056615,203056616,203056619,203056620,203056622,203056623]},"commit":{"id":58164361,"sha":"9b58ff577eeadc52c2138dba52cdf63844a58e6f","branch":"master","branch_is_default":true,"message":"todt.d: replace use of abytes with toStringSymbol()","committed_at":"2017-02-19T00:47:51Z","author_name":"Walter Bright","author_email":"walter@walterbright.com","committer_name":"Walter Bright","committer_email":"walter@walterbright.com","compare_url":"https://github.com/dlang/dmd/pull/6552"},"jobs":[{"id":203056614,"repository_id":318556,"build_id":203056613,"commit_id":58164361,"log_id":148696963,"state":"passed","number":"7903.1","config":{"language":"d","d":"dmd","script":"./travis.sh","sudo":false,"addons":{"apt":{"packages":["g++-multilib","gdb","libcurl3-gnutls:i386"]}},"env":"MODEL=32",".result":"configured","group":"stable","dist":"precise","os":"linux"},"started_at":"2017-02-19T00:49:20Z","finished_at":"2017-02-19T01:02:57Z","queue":"builds.docker","allow_failure":false,"tags":null,"annotation_ids":[]},{"id":203056615,"repository_id":318556,"build_id":203056613,"commit_id":58164361,"log_id":148696964,"state":"failed","number":"7903.2","config":{"language":"d","d":"dmd","script":"./travis.sh","sudo":false,"addons":{"apt":{"packages":["g++-multilib","gdb","libcurl3-gnutls:i386"]}},"env":"MODEL=64",".result":"configured","group":"stable","dist":"precise","os":"linux"},"started_at":"2017-02-19T00:49:03Z","finished_at":"2017-02-19T00:50:58Z","queue":"builds.docker","allow_failure":false,"tags":null,"annotation_ids":[]},{"id":203056616,"repository_id":318556,"build_id":203056613,"commit_id":58164361,"log_id":148696965,"state":"failed","number":"7903.3","config":{"language":"d","d":"gdc","script":"./travis.sh","sudo":false,"addons":{"apt":{"packages":["g++-multilib","gdb","libcurl3-gnutls:i386"]}},"env":"MODEL=64",".result":"configured","group":"stable","dist":"precise","os":"linux"},"started_at":"2017-02-19T00:49:00Z","finished_at":"2017-02-19T00:51:08Z","queue":"builds.docker","allow_failure":false,"tags":null,"annotation_ids":[]},{"id":203056619,"repository_id":318556,"build_id":203056613,"commit_id":58164361,"log_id":148696966,"state":"passed","number":"7903.4","config":{"language":"d","d":"ldc","script":"./travis.sh","sudo":false,"addons":{"apt":{"packages":["g++-multilib","gdb","libcurl3-gnutls:i386"]}},"env":"MODEL=32",".result":"configured","group":"stable","dist":"precise","os":"linux"},"started_at":"2017-02-19T00:49:01Z","finished_at":"2017-02-19T01:02:52Z","queue":"builds.docker","allow_failure":false,"tags":null,"annotation_ids":[]},{"id":203056620,"repository_id":318556,"build_id":203056613,"commit_id":58164361,"log_id":148696968,"state":"failed","number":"7903.5","config":{"language":"d","d":"ldc","script":"./travis.sh","sudo":false,"addons":{"apt":{"packages":["g++-multilib","gdb","libcurl3-gnutls:i386"]}},"env":"MODEL=64",".result":"configured","group":"stable","dist":"precise","os":"linux"},"started_at":"2017-02-19T00:49:03Z","finished_at":"2017-02-19T00:50:57Z","queue":"builds.docker","allow_failure":false,"tags":null,"annotation_ids":[]},{"id":203056622,"repository_id":318556,"build_id":203056613,"commit_id":58164361,"log_id":148696969,"state":"passed","number":"7903.6","config":{"language":"d","d":"dmd","script":"./travis.sh","sudo":false,"addons":{"apt":{"packages":["g++-multilib","gdb","libcurl3-gnutls:i386"]}},"env":"MODEL=32",".result":"configured","os":"osx"},"started_at":"2017-02-19T00:52:25Z","finished_at":"2017-02-19T01:22:42Z","queue":"builds.macstadium6","allow_failure":false,"tags":null,"annotation_ids":[]},{"id":203056623,"repository_id":318556,"build_id":203056613,"commit_id":58164361,"log_id":148696971,"state":"errored","number":"7903.7","config":{"language":"d","d":"dmd","script":"./travis.sh","sudo":false,"addons":{"apt":{"packages":["g++-multilib","gdb","libcurl3-gnutls:i386"]}},"env":"MODEL=64",".result":"configured","os":"osx"},"started_at":"2017-02-19T00:52:13Z","finished_at":"2017-02-19T00:53:09Z","queue":"builds.macstadium6","allow_failure":false,"tags":null,"annotation_ids":[]}],"annotations":[]}
\ No newline at end of file
diff --git a/source/dlangbot/app.d b/source/dlangbot/app.d
index 281b001..36c54d4 100644
--- a/source/dlangbot/app.d
+++ b/source/dlangbot/app.d
@@ -4,6 +4,7 @@ import dlangbot.bugzilla, dlangbot.github, dlangbot.travis, dlangbot.trello,
dlangbot.utils;
public import dlangbot.bugzilla : bugzillaURL;
+public import dlangbot.ci : dTestAPI, circleCiAPI, projectTesterAPI;
public import dlangbot.github : githubAPIURL, githubAuth, hookSecret;
public import dlangbot.travis : travisAPIURL;
public import dlangbot.trello : trelloAPIURL, trelloAuth, trelloSecret;
@@ -20,6 +21,7 @@ import vibe.stream.operations : readAllUTF8;
bool runAsync = true;
bool runTrello = true;
+bool runPRReview = true;
Duration timeBetweenFullPRChecks = 5.minutes; // this should never be larger 30 mins on heroku
Throttler!(typeof(&searchForAutoMergePrs)) prThrottler;
@@ -135,7 +137,11 @@ void githubHook(HTTPServerRequest req, HTTPServerResponse res)
string state = json["state"].get!string;
// no need to trigger the checker for failure/pending
if (state == "success")
+ {
prThrottler(repoSlug);
+ if (runPRReview)
+ checkPRForReviewNeed(repoSlug, json);
+ }
return res.writeBody("handled");
case "pull_request":
diff --git a/source/dlangbot/ci.d b/source/dlangbot/ci.d
new file mode 100644
index 0000000..123804a
--- /dev/null
+++ b/source/dlangbot/ci.d
@@ -0,0 +1,169 @@
+module dlangbot.ci;
+
+import dlangbot.github;
+
+import vibe.core.log;
+import vibe.http.client : HTTPClientRequest, requestHTTP;
+
+import std.conv : to;
+import std.format : format;
+import std.regex : matchFirst, regex;
+import std.exception;
+import std.variant : Nullable;
+
+// list of used APIs (overwritten by the test suite)
+string dTestAPI = "http://dtest.dlang.io";
+string circleCiAPI = "https://circleci.com/api/v1.1";
+string projectTesterAPI = "https://ci.dawg.eu";
+
+// only since 2.073
+auto nullable(T)(T t) { return Nullable!T(t); }
+
+/**
+There's no way to get the PR number from a GitHub status event (or other API
+endpoints).
+Hence we have to check the sender for this information.
+*/
+Nullable!uint getPRForStatus(string repoSlug, string url, string context)
+{
+ Nullable!uint prNumber;
+
+ try {
+ logDebug("getPRNumber (repo: %s, ci: %s)", repoSlug, context);
+ switch (context) {
+ case "auto-tester":
+ prNumber = checkAutoTester(url);
+ break;
+ case "ci/circleci":
+ prNumber = checkCircleCi(url);
+ break;
+ case "continuous-integration/travis-ci/pr":
+ prNumber = checkTravisCi(url);
+ break;
+ case "CyberShadow/DAutoTest":
+ prNumber = checkDTest(url);
+ break;
+ case "Project Tester":
+ prNumber = checkProjectTester(url);
+ break;
+ // CodeCov provides no way atm
+ default:
+ }
+ } catch (Exception e) {
+ logDebug("PR number for: %s (by CI: %s) couldn't be detected", repoSlug, context);
+ logDebug("Exception", e);
+ }
+
+ return prNumber;
+}
+
+class PRDetectionException : Exception
+{
+ this()
+ {
+ super("Failure to detected PR number");
+ }
+}
+
+Nullable!uint checkCircleCi(string url)
+{
+ import std.algorithm.iteration : splitter;
+ import std.array : array;
+ import std.range : back, retro;
+
+ // https://circleci.com/gh/dlang/dmd/2827?utm_campaign=v...
+ static circleCiRe = regex(`circleci.com/gh/(.*)/([0-9]+)`);
+ Nullable!uint pr;
+
+ auto m = url.matchFirst(circleCiRe);
+ enforce(!m.empty);
+
+ string repoSlug = m[1];
+ ulong buildNumber = m[2].to!ulong;
+
+ auto resp = requestHTTP("%s/project/github/%s/%d"
+ .format(circleCiAPI, repoSlug, buildNumber)).readJson;
+ if (auto prs = resp["pull_requests"][])
+ {
+ pr = prs[0]["url"].get!string
+ .splitter("/")
+ .array // TODO: splitter is not bidirectional
+ // https://issues.dlang.org/show_bug.cgi?id=17047
+ .back.to!uint;
+ }
+ // branch in upstream
+ return pr;
+}
+
+
+Nullable!uint checkTravisCi(string url)
+{
+ import dlangbot.travis : getPRNumber;
+
+ // https://travis-ci.org/dlang/dmd/builds/203056613
+ static travisCiRe = regex(`travis-ci.org/(.*)/builds/([0-9]+)`);
+ Nullable!uint pr;
+
+ auto m = url.matchFirst(travisCiRe);
+ enforce(!m.empty);
+
+ string repoSlug = m[1];
+ ulong buildNumber = m[2].to!ulong;
+
+ return getPRNumber(repoSlug, buildNumber);
+}
+
+// tests PRs only
+auto checkAutoTester(string url)
+{
+ // https://auto-tester.puremagic.com/pull-history.ghtml?projectid=1&repoid=1&pullid=6552
+ static autoTesterRe = regex(`pullid=([0-9]+)`);
+
+ auto m = url.matchFirst(autoTesterRe);
+ enforce(!m.empty);
+ return m[1].to!uint.nullable;
+}
+
+// tests PRs only
+auto checkDTest(string url)
+{
+ import vibe.stream.operations : readAllUTF8;
+
+ // http://dtest.dlang.io/results/f3f364ddcf96e98d1a6566b04b130c3f8b37a25f/378ec2f7616ec7ca4554c5381b45561473b0c218/
+ static dTestRe = regex(`results/([0-9a-f]+)/([0-9a-f]+)`);
+ static dTestReText = regex(`.*Pull request.*= 2)
+ {
+ logInfo("repo(%s): No review found", repoSlug);
+ // do the cool stuff here
+ pr.addLabels(["needs review"]);
+ }
+ else if (reviews.length > 0)
+ {
+ pr.removeLabel("needs review");
+ }
+ }
+}
diff --git a/source/dlangbot/travis.d b/source/dlangbot/travis.d
index 03cbc91..1f50d91 100644
--- a/source/dlangbot/travis.d
+++ b/source/dlangbot/travis.d
@@ -4,22 +4,31 @@ string travisAPIURL = "https://api.travis-ci.org";
string travisAuth;
import vibe.core.log;
+import vibe.http.client : requestHTTP, HTTPClientRequest;
+import vibe.http.common : HTTPMethod;
+
+import std.functional : toDelegate;
+import std.format : format;
+import std.variant : Nullable;
//==============================================================================
// Dedup Travis-CI builds
//==============================================================================
+void travisAuthReq(scope HTTPClientRequest req)
+{
+ req.headers["Accept"] = "application/vnd.travis-ci.2+json";
+ req.headers["Authorization"] = travisAuth;
+}
+
void cancelBuild(size_t buildId)
{
- import std.format : format;
- import vibe.http.client : requestHTTP;
- import vibe.http.common : HTTPMethod;
import vibe.stream.operations : readAllUTF8;
auto url = "%s/builds/%s/cancel".format(travisAPIURL, buildId);
requestHTTP(url, (scope req) {
- req.headers["Authorization"] = travisAuth;
req.method = HTTPMethod.POST;
+ travisAuthReq(req);
}, (scope res) {
if (res.statusCode / 100 == 2)
logInfo("Canceled Build %s\n", buildId);
@@ -32,9 +41,7 @@ void cancelBuild(size_t buildId)
void dedupTravisBuilds(string action, string repoSlug, uint pullRequestNumber)
{
import std.algorithm.iteration : filter;
- import std.format : format;
import std.range : drop;
- import vibe.http.client : requestHTTP;
if (action != "synchronize" && action != "merged")
return;
@@ -49,10 +56,7 @@ void dedupTravisBuilds(string action, string repoSlug, uint pullRequestNumber)
}
auto url = "%s/repos/%s/builds?event_type=pull_request".format(travisAPIURL, repoSlug);
- auto activeBuildsForPR = requestHTTP(url, (scope req) {
- req.headers["Authorization"] = travisAuth;
- req.headers["Accept"] = "application/vnd.travis-ci.2+json";
- })
+ auto activeBuildsForPR = requestHTTP(url, (&travisAuthReq).toDelegate)
.readJson["builds"][]
.filter!(b => activeState(b["state"].get!string))
.filter!(b => b["pull_request_number"].get!uint == pullRequestNumber);
@@ -63,4 +67,16 @@ void dedupTravisBuilds(string action, string repoSlug, uint pullRequestNumber)
cancelBuild(b["id"].get!size_t);
}
+Nullable!uint getPRNumber(string repoSlug, ulong buildId)
+{
+ Nullable!uint pr;
+
+ auto url = "%s/repos/%s/builds/%s".format(travisAPIURL, repoSlug, buildId);
+ auto res = requestHTTP(url, (&travisAuthReq).toDelegate)
+ .readJson["build"];
+ if (res["event_type"] == "pull_request")
+ pr = res["pull_request_number"].get!uint;
+
+ return pr;
+}
diff --git a/test/ci.d b/test/ci.d
new file mode 100644
index 0000000..14367e5
--- /dev/null
+++ b/test/ci.d
@@ -0,0 +1,74 @@
+import utils;
+
+// manual test
+unittest
+{
+ import std.typecons : Tuple;
+
+ alias Entry = Tuple!(string, "repoSlug", int, "pr", string, "context", string, "url");
+
+ auto urls = [
+ Entry("dlang/phobos", 5151, "Project Tester", "https://ci.dawg.eu/job/phobos_trigger/343/"),
+ Entry("dlang/phobos", 5131, "CyberShadow/DAutoTest", "http://dtest.dlang.io/results/86959530a962d84f01679c0aa45dd2c9714cc6ac/feb55b1f448c28dfb72ce409f8b1994f097dddb5/"),
+ Entry("dlang/phobos", 5151, "auto-tester", "https://auto-tester.puremagic.com/pull-history.ghtml?projectid=1&repoid=3&pullid=5151"),
+ Entry("dlang/phobos", 5151, "ci/circleci", "https://circleci.com/gh/dlang/phobos/1778?utm_campaign=vcs-integration-link&utm_medium=referral&utm_source=github-build-link"),
+ Entry("dlang/phobos", -1, "codecov/patch ", "https://codecov.io/gh/dlang/phobos/compare/395ae88ac75ee0c03f6475ad4a5b073cfaf4e084...c652bce17d242c71875d99e379e37259101ea9fd"),
+ Entry("dlang/phobos", -1, "codecov/project", "https://codecov.io/gh/dlang/phobos/compare/395ae88ac75ee0c03f6475ad4a5b073cfaf4e084...c652bce17d242c71875d99e379e37259101ea9fd"),
+ Entry("dlang/dmd", 6552, "continuous-integration/travis-ci/pr", "https://travis-ci.org/dlang/dmd/builds/203056613"),
+ Entry("dlang/dmd", 6553, "CyberShadow/DAutoTest", "http://dtest.dlang.io/results/86959530a962d84f01679c0aa45dd2c9714cc6ac/9f9369c96a0b8b8e4844c6d8d6f3fae9391a1450/"),
+ Entry("dlang/dmd", 6552, "Project Tester", "https://ci.dawg.eu/job/dmd_trigger/974/"),
+ Entry("dlang/dmd", 6552, "auto-tester", "https://auto-tester.puremagic.com/pull-history.ghtml?projectid=1&repoid=1&pullid=6552"),
+ Entry("dlang/dmd", 6552, "ci/circleci", "https://circleci.com/gh/dlang/dmd/2827?utm_campaign=vcs-integration-link&utm_medium=referral&utm_source=github-build-link"),
+ ];
+
+ setAPIExpectations(
+ "/projecttester/job/phobos_trigger/343/",
+ "/dtest/results/86959530a962d84f01679c0aa45dd2c9714cc6ac/feb55b1f448c28dfb72ce409f8b1994f097dddb5/",
+ "/circleci/project/github/dlang/phobos/1778",
+ "/travis/repos/dlang/dmd/builds/203056613",
+ "/dtest/results/86959530a962d84f01679c0aa45dd2c9714cc6ac/9f9369c96a0b8b8e4844c6d8d6f3fae9391a1450/",
+ "/projecttester/job/dmd_trigger/974/",
+ "/circleci/project/github/dlang/dmd/2827",
+ );
+
+ import dlangbot.ci : getPRForStatus;
+ foreach (i, e; urls)
+ {
+ auto pr = getPRForStatus(e.repoSlug, e.url, e.context);
+ if (e.pr >= 0)
+ assert(pr == e.pr);
+ }
+}
+
+// send hooks
+unittest
+{
+ prThrottler.reset;
+ runPRReview = true;
+ scope(exit) runPRReview = false;
+
+ setAPIExpectations(
+ "/github/repos/dlang/dmd/issues?state=open&labels=auto-merge", (ref Json j) {
+ j = Json.emptyArray;
+ },
+ "/github/repos/dlang/dmd/issues?state=open&labels=auto-merge-squash", (ref Json j) {
+ j = Json.emptyArray;
+ },
+ "/github/repos/dlang/dmd/status/eb53933e2d0989f6da3edf8581bb3de4acac9f0e",
+ "/github/repos/dlang/dmd/pulls/6324/reviews",
+ "/github/repos/dlang/dmd/issues/6324/labels",
+ (scope HTTPServerRequest req, scope HTTPServerResponse res){
+ assert(req.method == HTTPMethod.POST);
+ assert(req.json[].length == 1);
+ assert(req.json[0] == "needs review");
+ res.statusCode = 200;
+ res.writeVoidBody;
+ }
+ );
+
+ postGitHubHook("dlang_dmd_status_6324.json", "status",
+ (ref Json j, scope HTTPClientRequest req){
+ j["state"] = "success";
+ }
+ );
+}
diff --git a/test/status.d b/test/status.d
index 92f9e6e..7164795 100644
--- a/test/status.d
+++ b/test/status.d
@@ -3,6 +3,7 @@ import utils;
// send pending status event -> no action
unittest
{
+ prThrottler.reset;
setAPIExpectations();
postGitHubHook("dlang_dmd_status_6324.json", "status");
diff --git a/test/utils.d b/test/utils.d
index 30a02be..ac576ba 100644
--- a/test/utils.d
+++ b/test/utils.d
@@ -11,6 +11,8 @@ public import vibe.http.server : HTTPServerRequest, HTTPServerResponse;
public import std.functional : toDelegate;
public import vibe.data.json : deserializeJson, Json;
public import std.datetime : SysTime;
+public import std.stdio : writeln, writefln;
+public import std.format : format;
// existing dlang bot comment -> update comment
@@ -65,6 +67,12 @@ void startFakeAPIServer()
trelloAPIURL = fakeAPIServerURL ~ "/trello";
travisAPIURL = fakeAPIServerURL ~ "/travis";
bugzillaURL = fakeAPIServerURL ~ "/bugzilla";
+ dTestAPI = fakeAPIServerURL ~ "/dtest";
+ circleCiAPI = fakeAPIServerURL ~ "/circleci";
+ projectTesterAPI = fakeAPIServerURL ~ "/projecttester";
+
+ // only enable this for the specific CI tests (don't spam the other tests)
+ runPRReview = false;
}
// serves saved GitHub API payloads
@@ -95,6 +103,10 @@ auto payloadServer(scope HTTPServerRequest req, scope HTTPServerResponse res)
return expectation.reqHandler(req, res);
string filePath = buildPath(payloadDir, req.requestURL[1 .. $].replace("/", "_"));
+ // remove trailing slashes
+ if (filePath[$ - 1] == '_')
+ filePath = filePath.dropBackOne;
+
if (!filePath.exists)
{
assert(0, "Please create payload: " ~ filePath);
@@ -112,9 +124,12 @@ auto payloadServer(scope HTTPServerRequest req, scope HTTPServerResponse res)
if (expectation.jsonHandler !is null)
expectation.jsonHandler(payloadJson);
- payload = payloadJson.toString;
+ return res.writeJsonBody(payloadJson);
+ }
+ else
+ {
+ return res.writeBody(payload);
}
- return res.writeBody(payload);
}
}
@@ -159,10 +174,15 @@ struct APIExpectation
APIExpectation[] apiExpectations;
void setAPIExpectations(Args...)(Args args)
+{
+ apiExpectations.length = 0;
+ addAPIExpectations(args);
+}
+
+void addAPIExpectations(Args...)(Args args)
{
import std.functional : toDelegate;
import std.traits : Parameters;
- apiExpectations.length = 0;
foreach (i, arg; args)
{
static if (is(Args[i] : string))