diff --git a/crates/collab/src/api.rs b/crates/collab/src/api.rs index f5663db2472549d5780b86a9223f6b15cc5b7e13..7a1e4f2b50da252ca8942e55971c0e1a0cbd52fd 100644 --- a/crates/collab/src/api.rs +++ b/crates/collab/src/api.rs @@ -19,9 +19,9 @@ use axum::{ Extension, Json, Router, }; use axum_extra::response::ErasedJson; -use chrono::SecondsFormat; +use chrono::{NaiveDateTime, SecondsFormat}; use serde::{Deserialize, Serialize}; -use std::sync::Arc; +use std::sync::{Arc, OnceLock}; use tower::ServiceBuilder; pub use extensions::fetch_extensions_from_blob_store_periodically; @@ -162,6 +162,17 @@ async fn check_is_contributor( Query(params): Query, ) -> Result> { let params = params.as_contributor_selector()?; + + if RenovateBot::is_renovate_bot(¶ms) { + return Ok(Json(CheckIsContributorResponse { + signed_at: Some( + RenovateBot::created_at() + .and_utc() + .to_rfc3339_opts(SecondsFormat::Millis, true), + ), + })); + } + Ok(Json(CheckIsContributorResponse { signed_at: app .db @@ -171,6 +182,36 @@ async fn check_is_contributor( })) } +/// The Renovate bot GitHub user (`renovate[bot]`). +/// +/// https://api.github.com/users/renovate[bot] +struct RenovateBot; + +impl RenovateBot { + const LOGIN: &'static str = "renovate[bot]"; + const USER_ID: i32 = 29139614; + + /// Returns the `created_at` timestamp for the Renovate bot user. + fn created_at() -> &'static NaiveDateTime { + static CREATED_AT: OnceLock = OnceLock::new(); + CREATED_AT.get_or_init(|| { + chrono::DateTime::parse_from_rfc3339("2017-06-02T07:04:12Z") + .expect("failed to parse 'created_at' for 'renovate[bot]'") + .naive_utc() + }) + } + + /// Returns whether the given contributor selector corresponds to the Renovate bot user. + fn is_renovate_bot(contributor: &ContributorSelector) -> bool { + match contributor { + ContributorSelector::GitHubLogin { github_login } => github_login == Self::LOGIN, + ContributorSelector::GitHubUserId { github_user_id } => { + github_user_id == &Self::USER_ID + } + } + } +} + async fn add_contributor( Extension(app): Extension>, extract::Json(params): extract::Json,