Merge pull request #349 from NixOS/github-token
GitHub token vending machine
This commit is contained in:
commit
da348bdacc
4
ofborg/Cargo.lock
generated
4
ofborg/Cargo.lock
generated
|
@ -1,3 +1,5 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.5.3"
|
||||
|
@ -245,7 +247,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
[[package]]
|
||||
name = "hubcaps"
|
||||
version = "0.3.16"
|
||||
source = "git+https://github.com/grahamc/hubcaps.git#a7477f35f9dbc33a34f4486593f3725b4e523028"
|
||||
source = "git+https://github.com/grahamc/hubcaps.git#1c5da1e60ee2d0d69188d83da048e7328aae05b9"
|
||||
dependencies = [
|
||||
"error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"frank_jwt 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
|
@ -20,7 +20,7 @@ serde_derive = "1.0"
|
|||
serde_json = "1.0"
|
||||
tempfile = "2.2.0"
|
||||
hubcaps = { git = "https://github.com/grahamc/hubcaps.git" }
|
||||
#hubcaps = { path = "../hubcaps/" } # for testing patches
|
||||
#hubcaps = { path = "../../../grahamc/hubcaps/" } # for testing patches
|
||||
hyper = "0.10.*"
|
||||
hyper-native-tls = "0.2.4"
|
||||
lru-cache = "0.1.1"
|
||||
|
|
|
@ -62,7 +62,7 @@ fn main() {
|
|||
channel
|
||||
.consume(
|
||||
worker::new(tasks::githubcommentposter::GitHubCommentPoster::new(
|
||||
cfg.github_app(),
|
||||
cfg.github_app_vendingmachine(),
|
||||
)),
|
||||
easyamqp::ConsumeConfig {
|
||||
queue: "build-results".to_owned(),
|
||||
|
|
|
@ -3,14 +3,13 @@ use hyper::net::HttpsConnector;
|
|||
use hyper::Client;
|
||||
use hyper_native_tls::NativeTlsClient;
|
||||
use nix::Nix;
|
||||
use ofborg::acl;
|
||||
use serde_json;
|
||||
use std::collections::HashMap;
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use ofborg::acl;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Config {
|
||||
pub runner: RunnerConfig,
|
||||
|
@ -115,17 +114,12 @@ impl Config {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn github_app(&self) -> Github {
|
||||
let conf = self.github_app.clone().unwrap();
|
||||
Github::new(
|
||||
"github.com/grahamc/ofborg (app)",
|
||||
// tls configured hyper client
|
||||
Client::with_connector(HttpsConnector::new(NativeTlsClient::new().unwrap())),
|
||||
Credentials::InstallationToken(InstallationTokenGenerator::new(
|
||||
conf.installation_id,
|
||||
JWTCredentials::new(conf.app_id, conf.private_key),
|
||||
)),
|
||||
)
|
||||
pub fn github_app_vendingmachine(&self) -> GithubAppVendingMachine {
|
||||
GithubAppVendingMachine {
|
||||
conf: self.github_app.clone().unwrap(),
|
||||
id_cache: HashMap::new(),
|
||||
client_cache: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn nix(&self) -> Nix {
|
||||
|
@ -169,3 +163,61 @@ pub fn load(filename: &Path) -> Config {
|
|||
|
||||
deserialized
|
||||
}
|
||||
|
||||
pub struct GithubAppVendingMachine {
|
||||
conf: GithubAppConfig,
|
||||
id_cache: HashMap<(String, String), Option<i32>>,
|
||||
client_cache: HashMap<i32, Github>,
|
||||
}
|
||||
|
||||
impl GithubAppVendingMachine {
|
||||
fn useragent(&self) -> &'static str {
|
||||
"github.com/grahamc/ofborg (app)"
|
||||
}
|
||||
|
||||
fn jwt(&self) -> JWTCredentials {
|
||||
JWTCredentials::new(self.conf.app_id, self.conf.private_key.clone())
|
||||
}
|
||||
|
||||
fn install_id_for_repo(&mut self, owner: &str, repo: &str) -> Option<i32> {
|
||||
let useragent = self.useragent();
|
||||
let jwt = self.jwt();
|
||||
|
||||
let key = (owner.to_owned(), repo.to_owned());
|
||||
|
||||
*self.id_cache.entry(key).or_insert_with(|| {
|
||||
info!("Looking up install ID for {}/{}", owner, repo);
|
||||
|
||||
let lookup_gh = Github::new(
|
||||
useragent,
|
||||
Client::with_connector(HttpsConnector::new(NativeTlsClient::new().unwrap())),
|
||||
Credentials::JWT(jwt),
|
||||
);
|
||||
|
||||
match lookup_gh.app().find_repo_installation(owner, repo) {
|
||||
Ok(install_id) => {
|
||||
debug!("Received install ID {:#?}", install_id);
|
||||
Some(install_id.id)
|
||||
}
|
||||
Err(e) => {
|
||||
warn!("Error during install ID lookup: {:#?}", e);
|
||||
None
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn for_repo<'a>(&'a mut self, owner: &str, repo: &str) -> Option<&'a Github> {
|
||||
let useragent = self.useragent();
|
||||
let jwt = self.jwt();
|
||||
let install_id = self.install_id_for_repo(owner, repo)?;
|
||||
|
||||
Some(self.client_cache.entry(install_id).or_insert_with(|| {
|
||||
Github::new(
|
||||
useragent,
|
||||
Client::with_connector(HttpsConnector::new(NativeTlsClient::new().unwrap())),
|
||||
Credentials::InstallationToken(InstallationTokenGenerator::new(install_id, jwt)),
|
||||
)
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -313,6 +313,7 @@ impl<E: stats::SysEvents + 'static> worker::SimpleWorker for EvaluationWorker<E>
|
|||
})
|
||||
.all(|status| status == Ok(()));
|
||||
|
||||
info!("Finished evaluations");
|
||||
let mut response: worker::Actions = vec![];
|
||||
|
||||
if eval_results {
|
||||
|
@ -320,6 +321,10 @@ impl<E: stats::SysEvents + 'static> worker::SimpleWorker for EvaluationWorker<E>
|
|||
.all_evaluations_passed(&Path::new(&refpath), &mut overall_status);
|
||||
match ret {
|
||||
Ok(builds) => {
|
||||
info!(
|
||||
"Scheduling build jobs {:#?} on arches {:#?}",
|
||||
builds, auto_schedule_build_archs
|
||||
);
|
||||
for buildjob in builds {
|
||||
for arch in auto_schedule_build_archs.iter() {
|
||||
let (exchange, routingkey) = arch.as_build_destination();
|
||||
|
@ -341,6 +346,7 @@ impl<E: stats::SysEvents + 'static> worker::SimpleWorker for EvaluationWorker<E>
|
|||
}
|
||||
}
|
||||
Err(e) => {
|
||||
info!("Failed after all the evaluations passed");
|
||||
if self
|
||||
.handle_strategy_err(Err(e), &gists, &mut overall_status)
|
||||
.is_err()
|
||||
|
@ -350,6 +356,8 @@ impl<E: stats::SysEvents + 'static> worker::SimpleWorker for EvaluationWorker<E>
|
|||
}
|
||||
}
|
||||
|
||||
info!("Just about done...");
|
||||
|
||||
overall_status.set_with_description("^.^!", hubcaps::statuses::State::Success);
|
||||
} else {
|
||||
overall_status
|
||||
|
@ -358,6 +366,7 @@ impl<E: stats::SysEvents + 'static> worker::SimpleWorker for EvaluationWorker<E>
|
|||
|
||||
self.events.notify(Event::TaskEvaluationCheckComplete);
|
||||
|
||||
info!("done!");
|
||||
self.actions().done(&job, response)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,20 +5,20 @@ use serde_json;
|
|||
|
||||
use amqp::protocol::basic::{BasicProperties, Deliver};
|
||||
use chrono::{DateTime, Utc};
|
||||
use hubcaps;
|
||||
use hubcaps::checks::{CheckRunOptions, CheckRunState, Conclusion, Output};
|
||||
use message::buildjob::{BuildJob, QueuedBuildJobs};
|
||||
use ofborg::config::GithubAppVendingMachine;
|
||||
use ofborg::message::buildresult::{BuildResult, BuildStatus, LegacyBuildResult};
|
||||
use ofborg::message::Repo;
|
||||
use ofborg::worker;
|
||||
|
||||
pub struct GitHubCommentPoster {
|
||||
github: hubcaps::Github,
|
||||
github_vend: GithubAppVendingMachine,
|
||||
}
|
||||
|
||||
impl GitHubCommentPoster {
|
||||
pub fn new(github: hubcaps::Github) -> GitHubCommentPoster {
|
||||
GitHubCommentPoster { github }
|
||||
pub fn new(github_vend: GithubAppVendingMachine) -> GitHubCommentPoster {
|
||||
GitHubCommentPoster { github_vend }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,9 @@ impl worker::SimpleWorker for GitHubCommentPoster {
|
|||
println!(":{:?}", check);
|
||||
|
||||
let check_create_attempt = self
|
||||
.github
|
||||
.github_vend
|
||||
.for_repo(&repo.owner, &repo.name)
|
||||
.unwrap()
|
||||
.repo(repo.owner.clone(), repo.name.clone())
|
||||
.checkruns()
|
||||
.create(&check);
|
||||
|
|
Loading…
Reference in a new issue