Skip to content

Commit

Permalink
Merge pull request #112 from DeterminateSystems/decouple-github-token…
Browse files Browse the repository at this point in the history
…-and-github-actions

Decouple `--github-token` and `is_github_actions` logic
  • Loading branch information
cole-h authored Feb 23, 2024
2 parents 35301db + 2f11097 commit d079d46
Showing 1 changed file with 55 additions and 48 deletions.
103 changes: 55 additions & 48 deletions src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ impl clap::builder::TypedValueParser for U64ToNoneParser {

impl FlakeHubPushCli {
#[tracing::instrument(skip_all)]
pub(crate) fn populate_missing_from_github(&mut self) {
pub(crate) fn populate_from_github_actions_environment(&mut self) {
if self.git_root.0.is_none() {
let env_key = "GITHUB_WORKSPACE";
if let Ok(env_val) = std::env::var(env_key) {
Expand Down Expand Up @@ -301,11 +301,10 @@ impl FlakeHubPushCli {
let span = tracing::Span::current();
tracing::trace!("Executing");

let is_github_actions =
self.github_token.0.is_some() || std::env::var("GITHUB_ACTION").ok().is_some();
let is_github_actions = std::env::var("GITHUB_ACTION").ok().is_some();
if is_github_actions {
tracing::debug!("Running inside Github Actions, will enrich with GitHub API data and push with authorized Github bearer token");
self.populate_missing_from_github()
tracing::debug!("Running inside Github Actions, enriching arguments with GitHub Actions environment data");
self.populate_from_github_actions_environment()
}

let Self {
Expand Down Expand Up @@ -428,19 +427,15 @@ impl FlakeHubPushCli {
revision,
} = RevisionInfo::from_git_root(&git_root)?;

let upload_bearer_token = if is_github_actions {
let github_token = if let Some(github_token) = &github_token.0 {
github_token.clone()
} else {
std::env::var("GITHUB_TOKEN")
.wrap_err("Could not determine Github token, pass `--github-token`")?
};
let github_graphql_data_result = if let Some(github_token) = &github_token.0 {
tracing::debug!("Got Github token, enriching with GitHub API data");

let github_api_client = build_http_client().build()?;

// Take the opportunity to be able to populate/encrich data from the GitHub API since we need it for project/owner_id anywys
let github_graphql_data_result = GithubGraphqlDataQuery::get(
&github_api_client,
&github_token,
github_token,
&project_owner,
&project_name,
&revision,
Expand Down Expand Up @@ -477,7 +472,7 @@ impl FlakeHubPushCli {
tracing::warn!(
"SPDX identifier `{}` was passed via argument, but GitHub's API suggests it may be `{}`",
spdx_expression.as_ref().map(|v| v.to_string()).unwrap_or_else(|| "None".to_string()),
github_graphql_data_result.spdx_identifier.unwrap_or_else(|| "None".to_string()),
github_graphql_data_result.spdx_identifier.clone().unwrap_or_else(|| "None".to_string()),
)
}
spdx_expression
Expand All @@ -486,47 +481,59 @@ impl FlakeHubPushCli {
// Extend the labels provided by the user with those from GitHub.
labels = labels
.into_iter()
.chain(github_graphql_data_result.topics.into_iter())
.chain(github_graphql_data_result.topics.iter().cloned())
.collect::<HashSet<String>>();

match jwt_issuer_uri.0 {
None => get_actions_id_bearer_token(&host)
.await
.wrap_err("Getting upload bearer token from GitHub")?,

Some(jwt_issuer_uri) => {
let client = build_http_client().build()?;
let mut claims = github_actions_oidc_claims::Claims::make_dummy();
// FIXME: we should probably fill in more of these claims.
claims.aud = "flakehub-localhost".to_string();
claims.iss = "flakehub-push-dev".to_string();
claims.repository = repository.clone();
claims.repository_owner = project_owner.to_string();
Some(github_graphql_data_result)
} else {
None
};

let upload_bearer_token = match jwt_issuer_uri.0 {
None if is_github_actions => get_actions_id_bearer_token(&host)
.await
.wrap_err("Getting upload bearer token from GitHub")?,
None => {
// TODO: Accept a `--flakehub-token` arg to use a bearer token once FlakeHub supports it.
return Err(eyre!(
"`flakehub-push` currently only runs inside Github Actions"
));
}
Some(jwt_issuer_uri) => {
tracing::warn!("Running in a development-only context, pushing to https://api.flakehub.com will not work!");
let client = build_http_client().build()?;

let mut claims = github_actions_oidc_claims::Claims::make_dummy();
// FIXME: we should probably fill in more of these claims.
claims.aud = "flakehub-localhost".to_string();
claims.iss = "flakehub-push-dev".to_string();
claims.repository = repository.clone();
claims.repository_owner = project_owner.to_string();

if let Some(github_graphql_data_result) = github_graphql_data_result {
claims.repository_id = github_graphql_data_result.project_id.to_string();
claims.repository_owner_id = github_graphql_data_result.owner_id.to_string();
} else {
return Err(eyre!("No populated GitHub API data (`--github-token` was likely not passed), cannot create the required JWT"));
}

let response = client
.post(jwt_issuer_uri)
.header("Content-Type", "application/json")
.json(&claims)
.send()
.await
.wrap_err("Sending request to JWT issuer")?;
#[derive(serde::Deserialize)]
struct Response {
token: String,
}
let response_deserialized: Response = response
.json()
.await
.wrap_err("Getting token from JWT issuer's response")?;
response_deserialized.token
let response = client
.post(jwt_issuer_uri)
.header("Content-Type", "application/json")
.json(&claims)
.send()
.await
.wrap_err("Sending request to JWT issuer")?;
#[derive(serde::Deserialize)]
struct Response {
token: String,
}
let response_deserialized: Response = response
.json()
.await
.wrap_err("Getting token from JWT issuer's response")?;
response_deserialized.token
}
} else {
return Err(eyre!(
"`flakehub-push` currently only runs inside Github Actions"
));
};

// Here we merge explicitly user-supplied labels and the labels ("topics")
Expand Down

0 comments on commit d079d46

Please sign in to comment.