diff --git a/.travis.yml b/.travis.yml index 2bd5168..5b25b5f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,11 +3,15 @@ os: - linux language: d d: + - dmd-nightly - dmd-beta - dmd + - ldc-beta - ldc matrix: + allow_failures: + - d: ldc include: - d: dmd-2.070.2 # the deployment compiler env: COVERAGE=true diff --git a/dub.sdl b/dub.sdl index 705165b..d2207d0 100644 --- a/dub.sdl +++ b/dub.sdl @@ -4,7 +4,7 @@ copyright "Copyright © 2015, Martin Nowak" authors "Martin Nowak" dependency "vibe-d" version="~>0.7.30" configuration "default" { - versions "VibeDefaultMain" + versions "VibeCustomMain" targetType "executable" } configuration "unittest" { diff --git a/source/dlangbot/app.d b/source/dlangbot/app.d index fcd892d..f12cb40 100644 --- a/source/dlangbot/app.d +++ b/source/dlangbot/app.d @@ -7,10 +7,10 @@ public import dlangbot.bugzilla : bugzillaURL; public import dlangbot.github : githubAPIURL, githubAuth, hookSecret; public import dlangbot.trello : trelloAPIURL, trelloAuth, trelloSecret; -string cronDailySecret; - import std.datetime : Clock, days, Duration, minutes, seconds, SysTime; +import vibe.core.args; +import vibe.core.core; import vibe.core.log; import vibe.data.json; import vibe.http.client : HTTPClient; @@ -29,32 +29,6 @@ Duration prInactivityDur = 90.days; // PRs with no activity within X days will g enum trelloHookURL = "https://dlang-bot.herokuapp.com/trello_hook"; -version(unittest){} else -shared static this() -{ - import std.process : environment; - import vibe.core.args : readOption; - - auto settings = new HTTPServerSettings; - settings.port = 8080; - readOption("port|p", &settings.port, "Sets the port used for serving."); - startServer(settings); - - githubAuth = "token "~environment["GH_TOKEN"]; - trelloSecret = environment["TRELLO_SECRET"]; - trelloAuth = "key="~environment["TRELLO_KEY"]~"&token="~environment["TRELLO_TOKEN"]; - hookSecret = environment["GH_HOOK_SECRET"]; - cronDailySecret = environment["CRON_DAILY_SECRET"]; - - // workaround for stupid openssl.conf on Heroku - if (environment.get("DYNO") !is null) - { - HTTPClient.setTLSSetupCallback((ctx) { - ctx.useTrustedCertificateFile("/etc/ssl/certs/ca-certificates.crt"); - }); - } -} - void startServer(HTTPServerSettings settings) { import vibe.core.core : vibeVersionString; @@ -71,7 +45,6 @@ void startServer(HTTPServerSettings settings) .post("/github_hook", &githubHook) .match(HTTPMethod.HEAD, "/trello_hook", (req, res) => res.writeVoidBody) .post("/trello_hook", &trelloHook) - .get("/cron_daily", &cronDaily) ; HTTPClient.setUserAgentString("dlang-bot vibe.d/"~vibeVersionString); @@ -152,19 +125,13 @@ void githubHook(HTTPServerRequest req, HTTPServerResponse res) //============================================================================== -void cronDaily(HTTPServerRequest req, HTTPServerResponse res) +void cronDaily() { - enforceBadRequest(req.query.length > 0, "No repo slugs provided"); - enforceHTTP(req.query.get("secret") == cronDailySecret, - HTTPStatus.unauthorized, "Invalid or no secret provided"); - - foreach (ref slug; req.query.getAll("repo")) + foreach (repo; ["dlang/phobos"]) { - logInfo("running cron.daily for: %s", slug); - runTaskHelper(&searchForInactivePrs, slug, prInactivityDur); + logInfo("running cron.daily for: %s", repo); + searchForInactivePrs(repo, prInactivityDur); } - - return res.writeBody("OK"); } //============================================================================== @@ -213,3 +180,39 @@ void handlePR(string action, PullRequest* _pr) if (runTrello) updateTrelloCard(action, pr.htmlURL, refs, descs); } + +//============================================================================== + +version (unittest) {} +else void main(string[] args) +{ + import std.process : environment; + import vibe.core.args : readOption; + + githubAuth = "token "~environment["GH_TOKEN"]; + trelloSecret = environment["TRELLO_SECRET"]; + trelloAuth = "key="~environment["TRELLO_KEY"]~"&token="~environment["TRELLO_TOKEN"]; + hookSecret = environment["GH_HOOK_SECRET"]; + + // workaround for stupid openssl.conf on Heroku + if (environment.get("DYNO") !is null) + { + HTTPClient.setTLSSetupCallback((ctx) { + ctx.useTrustedCertificateFile("/etc/ssl/certs/ca-certificates.crt"); + }); + } + + bool runDailyCron; + auto settings = new HTTPServerSettings; + settings.port = 8080; + readOption("port|p", &settings.port, "Sets the port used for serving."); + readOption("cron-daily", &runDailyCron, "Run daily cron tasks."); + if (!finalizeCommandLineOptions()) + return; + if (runDailyCron) + return cronDaily(); + + startServer(settings); + lowerPrivileges(); + runEventLoop(); +} diff --git a/source/dlangbot/github.d b/source/dlangbot/github.d index 274294d..e2f554d 100644 --- a/source/dlangbot/github.d +++ b/source/dlangbot/github.d @@ -420,7 +420,7 @@ struct PullRequest } Branch base, head; enum State { open, closed } - enum MergeableState { clean, dirty, unstable, unknown } + enum MergeableState { clean, dirty, unstable, blocked, unknown } @byName State state; uint number; string title; diff --git a/test/cronjob.d b/test/cronjob.d index d94dfab..2bea385 100644 --- a/test/cronjob.d +++ b/test/cronjob.d @@ -47,5 +47,6 @@ unittest }, ); - openUrl("/cron_daily?repo=dlang/phobos&secret=" ~ cronDailySecret, "OK"); + import dlangbot.app : cronDaily; + cronDaily(); } diff --git a/test/utils.d b/test/utils.d index 6e3bb65..753f3c1 100644 --- a/test/utils.d +++ b/test/utils.d @@ -29,7 +29,6 @@ shared static this() githubAuth = "GH_DUMMY_AUTH_TOKEN"; hookSecret = "GH_DUMMY_HOOK_SECRET"; trelloAuth = "key=01234&token=abcde"; - cronDailySecret = "dummyCronSecret"; // start our hook server auto settings = new HTTPServerSettings; @@ -124,9 +123,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); } } @@ -168,18 +170,19 @@ struct APIExpectation } } -APIExpectation[] apiExpectations; +__gshared APIExpectation[] apiExpectations; void setAPIExpectations(Args...)(Args args) { import std.functional : toDelegate; import std.traits : Parameters; + synchronized { apiExpectations.length = 0; foreach (i, arg; args) { static if (is(Args[i] : string)) { - apiExpectations ~= APIExpectation(arg); + apiExpectations ~= APIExpectation(arg); } else { @@ -200,6 +203,7 @@ void setAPIExpectations(Args...)(Args args) apiExpectations[$ - 1].reqHandler is null, "Either provide a reqHandler or a jsonHandler"); } } + } } void postGitHubHook(string payload, string eventType = "pull_request",