Age | Commit message (Collapse) | Author |
|
Make the logs less noisy and don't output 'debug' or 'trace' logs.
|
|
These were useful during development and in bug hunting, but I get the
sense that they'd be more annoying in production. Change these to
`debug` log messages.
|
|
This error handler now lives inside a `thread::spawn()` rather than
inside the HTTP request handler, so we shouldn't return an HTTP response
here.
|
|
This `thread::spawn()` call was moved outside the function and into
`main()`. We can remove it now.
|
|
I had changed these when I was having trouble passing the values through
my double-closure, but now that that's settles, we can revert these
types to the way they were before and get rid of the unnecessary
`to_owned()` transformations.
|
|
Turns out the easiest way to share these variables between both closures
really is to clone them.
Thanks to 'durka42' on Mozilla#rust-beginners for explaining the problem
to me. In durka's words:
> both closures are required to be 'static
> so you can't send references across
> and the router handler has to be callable multiple times so you can't consume anything (that's the error you got)
It's also possible to share references using Arc, but that seems more
complicated than it's worth here. Just do the copy and be done with it.
|
|
Instead of wrapping the inside of the function in a thread, put the
thread on the outside, in `main()`. This is an effort to try to get
around the `move`/lifetime issues I was having with the previous
version.
Add some extra logging so we have a better idea what's going on when.
Remove the `expects` I had added and put the `Result` returns back.
In `main()`, wrap the call to `find_and_track_build_and_update_status()`
in a thread and sleep before calling it. This allows us to give Jenkins
some time to warm up and create a job for our commit before we go ahead
and try to request it from its API. Otherwise, if we kick off the
Jenkins fetch too soon, our statuses aren't going to get updated because
the job won't have been created and thus won't have been found on the
`get_jobs()` call.
Had to add some ugly `clone()`s to get around `move` compiler errors
here. Next step is figuring out how to clean that up.
|
|
Try to put the whole function inside a thread. This doesn't work because
of move problems. The reason for wrapping things in a thread is so I can
add a `sleep` at the top of the function.
We want to sleep before even making our first request to Jenkins because
it seems like we're making the request too early, before the job has
been created. This prevents the GitHub status from being set.
|
|
Comment out HTTP response logging from Jenkins because those may be
coming back all right. Actually I might want to leave the log from
`request_job()` now that I think about it. Add some additional logging
on `update_commit_status()` to hopefully try to see why it's not getting
called all the time.
|
|
Log the HTTP response bodies to see if there's something we can gather
from our connected services' API responses.
|
|
By default, 'stderrlog' uses the `Error` level (which I found out by
inspecting the source here:
https://docs.rs/stderrlog/0.2.3/src/stderrlog/lib.rs.html#242-253).
Increase the log verbosity to `Trace` to hopefully give us more
information to act on. Bug hunting.
|
|
Add COPYING file and license notices to sources.
|
|
|
|
Make it clear that we want to run on local localhost (and not
"0.0.0.0").
|
|
Initialise a new 'stderrlog' and log all errors to the log.
|
|
I had used `to_owned()` previously in other projects, but after looking
up the difference (again probably), I decided that it seems better to
use `to_owned()`.
References:
https://users.rust-lang.org/t/to-string-vs-to-owned-for-string-literals/1441/6
http://www.lowlevelmanager.com/2016/02/rust-tostring-vs-toowned-for-string.html
|
|
Realised that the reason why I was getting a dead code warning from
`Job::new` was not just because I wasn't using it, but because I was
meant to use it somewhere. Remove the duplicate work going on in
`request_job()` and replace it with a call to `Job::new()` instead.
|
|
Now that `update_commit_status()` takes the GitHub API token as an
argument, pass in a fake one in our test.
|
|
Now that the Jenkins API URL is getting passed in via command line and
function argument, update the tests to pass it in directly.
Remove the test/non-test versions of `jenkins_url` from
`find_and_track_build_and_update_status()` because we can pass in the
mock URL directly to the `get_jobs()` and `request_job()` functions in
tests.
Make the `jenkins_url` argument to
`find_and_track_build_and_update_status()` not a reference so that we
don't have to reset it in the function to a `to_owned()` version.
|
|
Take the GitHub API token as a parameter and pass it through from
`find_and_track_build_and_update_status()`.
|
|
Get rid of the static, global `API_URL`, and replace it with the Jenkins
URL that gets passed into `find_and_track_build_and_update_status()`.
This necessitated adding a new URL argument to `get_jobs()` and
`request_job()`. Starting to wonder if I should be creating a struct to
hold the URL and client that I can attach these functions to as methods,
but for now I'll leave them alone.
|
|
Now that `get_jobs()` and `request_job()` take a
`jenkins_request_client()`, update the tests to ensure we're calling
them properly.
|
|
Remove the hard-coded user ID and token values. Instead, take these from
arguments to the function.
In order to not have to pass those arguments through to both `get_jobs()`
and `request_job()`, make a new private function that builds a 'reqwest'
client with the required auth header.
|
|
Pass logins & tokens for API communication into this function. Since
this is the entry point into everything else, it seemed to make sense to
have it be the thing that took the config.
Ended up not making a Config struct to be simple. I guess.
|
|
Remove the hard-coded port and use the one passed in via command line
option (or the default one).
|
|
Add options for:
* Jenkins URL
* Jenkins username
* Jenkins token
* GitHub token
* Port
Add a help option for usage information. All options except "port" are
required. Didn't use `reqopt` because that panics when you try to ask
for help without the required options. Now, when trying to run without a
required option, the usage help is printed. Maybe we should have an
error message instead.
|
|
Update our failing test suite to work with our new return types now that
many of our functions return `Result`s. Since these are tests, we handle
them by panicking with error messages.
|
|
Make these panic messages more meaningful by adding some contextual
information.
|
|
Catch `Result` errors in the spawned thread by panicking with `expect`.
Couldn't figure out how to use `expect` with a custom value, in the case
of `request_job`.
|
|
Now that our functions return `Result`s for errors instead of panicking,
we need to handle these errors. For now, just respond with a 500. We'll
also want to log the errors though.
|
|
Return errors as `Result`s instead of panicking.
Inside the thread, we can't return a result, so we need to panic errors.
These should be picked up as `Result`s from a `thread.join()`.
|
|
Eliminate `.unwrap()` by returning a `Result`. The
`JsonValue::take_string`s return `Options`, so if they're `None`, just
fill the struct with the default for `String`, which is `""` empty
string.
|
|
Return a `Result` from `update_commit_status()` to eliminate our
`.unwrap()` calls.
|
|
Authenticate our GitHub request with an `Authorization` header and API
token.
|
|
I got an unused variable warning on line 142 when I "reset" job at the
end of the loop. But actually, I wasn't resetting it, I was creating a
new variable in the inner scope.
In order to update the `job` used by the `while` loop, I think we need
to make `job` a mutable variable and then set it at the end of the loop.
|
|
|
|
Convert our dummy test route to a real one that will handle webhooks
coming from GitHub. It will parse the POST body data and create a
`CommitRef` from it. That `CommitRef` then gets passed to
`find_and_track_build_and_update_status()` to update the pull request
status based on Jenkins' build results.
A 202 response seemed apt here. Quoting
https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html:
> 10.2.3 202 Accepted
>
> The request has been accepted for processing, but the processing has
> not been completed. The request might or might not eventually be acted
> upon, as it might be disallowed when processing actually takes place.
> There is no facility for re-sending a status code from an asynchronous
> operation such as this.
|
|
I had originally written this method to parse the payload from the
`PushEvent` GitHub webhook, but I now decided that I'd rather listen to
the `PullRequestEvent` webhook. It'll mean less traffic and eliminates
the work of updating GitHub commit statuses when they're not really
going to be seen.
|
|
I just looked at `CommitRef`'s definition and realised that it includes
the repo name already. Whoops, turns out we didn't need this.
Probably didn't occur to me because I decided not to write a test for
`find_and_track_build_and_update_status` since it seemed like too much
of a pain.
|
|
By using a while loop on the status being 'pending', we can get rid of a
level of nesting.
|
|
Inside the thread, while the job is pending, poll the job on Jenkins
until either its status changes (to success or failed), or until 20
minutes have passed.
|
|
Now that a bunch of function signatures have been rewritten to take
references, update the tests to pass the correct arguments.
|
|
I had a bunch of compilation errors in this function because I wasn't
borrowing correctly. Fix the errors with borrows by reference, and
copying strings.
Here are the errors for reference:
error[E0373]: closure may outlive the current function, but it borrows `job`, which is owned by the current function
--> src/jenkins.rs:89:27
|
89 | thread::spawn(|| {
| ^^ may outlive borrowed value `job`
...
94 | job.result.commit_status(),
| --- `job` is borrowed here
|
help: to force the closure to take ownership of `job` (and any other referenced variables), use the `move` keyword
|
89 | thread::spawn(move || {
| ^^^^^^^
error[E0373]: closure may outlive the current function, but it borrows `job_url`, which is owned by the current function
--> src/jenkins.rs:89:27
|
89 | thread::spawn(|| {
| ^^ may outlive borrowed value `job_url`
...
96 | job_url.clone(),
| ------- `job_url` is borrowed here
|
help: to force the closure to take ownership of `job_url` (and any other referenced variables), use the `move` keyword
|
89 | thread::spawn(move || {
| ^^^^^^^
error[E0382]: use of moved value: `commit_ref`
--> src/jenkins.rs:88:32
|
88 | if job_for_commit(job, commit_ref) {
| ^^^^^^^^^^ value moved here in previous iteration of loop
|
= note: move occurs because `commit_ref` has type `pull_request::CommitRef`, which does not implement the `Copy` trait
error[E0382]: capture of moved value: `commit_ref`
--> src/jenkins.rs:93:21
|
88 | if job_for_commit(job, commit_ref) {
| ---------- value moved here
...
93 | commit_ref,
| ^^^^^^^^^^ value captured here after move
|
= note: move occurs because `commit_ref` has type `pull_request::CommitRef`, which does not implement the `Copy` trait
error[E0382]: capture of moved value: `job`
--> src/jenkins.rs:89:27
|
88 | if job_for_commit(job, commit_ref) {
| --- value moved here
89 | thread::spawn(|| {
| ^^ value captured here after move
|
= note: move occurs because `job` has type `jenkins::Job`, which does not implement the `Copy` trait
error[E0382]: capture of moved value: `job_url`
--> src/jenkins.rs:89:27
|
85 | let job = request_job(job_url);
| ------- value moved here
...
89 | thread::spawn(|| {
| ^^ value captured here after move
|
= note: move occurs because `job_url` has type `std::string::String`, which does not implement the `Copy` trait
|
|
A new method that establishes correspondences between Jenkins statuses
and GitHub statuses, so we can pass a GitHub `CommitStatus` to
`update_commit_status` given a `Job`.
|
|
Now that the organisation name (rather, owner of a GitHub project) is
stored in `CommitRef`, we don't need to pass it in explicitly.
|
|
This field stores the "owner" of the commit on GitHub, in other words, a
user or organisation. Storing that information in this struct makes it
easier to pass around.
|
|
I wasn't thinking straight in 26b74edece4546378c8a853cc70f7388f20ff0c6.
Instead of taking a repo name, we need to take an organisation/user
name. The repo name we already have from `commit_ref.repo`. We were
missing the org to be able to properly construct the GitHub API URL.
Pass `organization_name` name around from
`find_and_track_build_and_update_status`.
|
|
This function should take a repo name so we can pass that information to
`get_jobs`, as well as `update_commit_status`.
Also add types to the parameters which I apparently didn't think to do
the first time.
|
|
Pass a repo name explicitly in an argument to the function. We now have
the values we need to be able to properly construct a URL to POST to.
Update our HTTP request to send the params as JSON and include the
"Accept" header that GitHub recommends adding
(https://developer.github.com/v3/#current-version) based on the code
examples in
https://docs.rs/reqwest/0.8.1/reqwest/header/struct.Accept.html#examples.
|
|
Use `thread::spawn` and update the GitHub commit status. Write an
outline for how to handle polling for changes and updating the GitHub
commit status on success or failure (or timeout).
|