Skip to content

Commit fbc6f8e

Browse files
authored
Merge pull request #144 from filecoin-project/feat/auto-clone-repo
Added WIP create secret
2 parents 3aa8b90 + d479125 commit fbc6f8e

File tree

9 files changed

+89
-19
lines changed

9 files changed

+89
-19
lines changed

.github/workflows/deploy_to_prod.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ jobs:
5151
"environment": {
5252
"GH_PRIVATE_KEY": "${{secrets.GH_PRIVATE_KEY}}",
5353
"GITHUB_APP_ID": "${{vars.GH_APP_ID}}",
54+
"GITHUB_INSTALLATION_ID": "${{vars.GH_INSTALLATION_ID}}",
5455
"FILPLUS_ENV": "prod",
5556
"RUST_LOG": "debug",
5657
"BOT_USER": "${{vars.BOT_USER}}",

.github/workflows/deploy_to_staging.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ jobs:
6969
"GH_PRIVATE_KEY": "${{secrets.GH_PRIVATE_KEY}}",
7070
"DB_URL": "${{secrets.DB_URL}}",
7171
"GITHUB_APP_ID": "${{vars.GH_APP_ID}}",
72+
"GITHUB_INSTALLATION_ID": "${{vars.GH_INSTALLATION_ID}}",
7273
"FILPLUS_ENV": "prod",
7374
"RUST_LOG": "debug",
7475
"BOT_USER": "${{vars.BOT_USER}}",

.github/workflows/end_to_end_tests.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@ jobs:
1111
end_to_end_tests:
1212
name: Perform end-to-end tests
1313
runs-on: ubuntu-latest
14+
environment: staging
1415

1516
steps:
1617
- uses: actions/checkout@v3
1718
- name: Run tests
1819
env:
19-
GH_PRIVATE_KEY: ${{ secrets.GH_STAGING_PRIVATE_KEY }}
20-
DB_URL: ${{secrets.STAGING_DB_URL}}
21-
run: cargo test -- --nocapture
20+
GH_PRIVATE_KEY: ${{ secrets.GH_PRIVATE_KEY }}
21+
DB_URL: ${{secrets.DB_URL}}
22+
run: cargo test -- --nocapture

fplus-database/src/config.rs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
1-
use log::warn;
1+
use std::env;
2+
use log::error;
23

34
/**
4-
* Get an environment variable or a default value
5+
* Get an environment variable or exit the program if not set
56
*
67
* # Arguments
7-
* @param key: &str - The environment variable key
8-
* @param default: &str - The default value
8+
* * `key` - The environment variable key
99
*
1010
* # Returns
11-
* @return String - The value of the environment variable or the default value
11+
* * The value of the environment variable
12+
*
13+
* # Panics
14+
* * Exits the program if the environment variable is not set
1215
*/
13-
pub fn get_env_var_or_default(key: &str, default: &str) -> String {
14-
match std::env::var(key) {
16+
pub fn get_env_or_throw(key: &str) -> String {
17+
match env::var(key) {
1518
Ok(val) => val,
1619
Err(_) => {
17-
warn!("{} not set, using default value: {}", key, default);
18-
default.to_string()
20+
error!("Environment variable '{}' not set. Exiting program.", key);
21+
std::process::exit(1);
1922
}
2023
}
21-
}
24+
}

fplus-database/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ pub mod config;
55
use sea_orm::{Database, DatabaseConnection, DbErr};
66
use once_cell::sync::Lazy;
77
use std::sync::Mutex;
8-
use crate::config::get_env_var_or_default;
8+
use crate::config::get_env_or_throw;
99

1010
/**
1111
* The global database connection
@@ -29,7 +29,7 @@ pub fn init() {
2929
* @return Result<DatabaseConnection, sea_orm::DbErr> - The result of the operation
3030
*/
3131
pub async fn setup() -> Result<(), DbErr> {
32-
let database_url = get_env_var_or_default("DB_URL", "");
32+
let database_url = get_env_or_throw("DB_URL");
3333
let db_conn = Database::connect(&database_url).await?;
3434
let mut db_conn_global = DB_CONN.lock().unwrap();
3535
*db_conn_global = Some(db_conn);

fplus-lib/Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ http = "0.2.9"
1414
hyper = "0.14.26"
1515
hyper-rustls = "0.24.0"
1616
jsonwebtoken = "8.3.0"
17-
octocrab = "0.25.1"
17+
octocrab = "0.26.0"
1818
serde = { version = "1.0.164", features = ["derive", "std",
1919
"serde_derive", "alloc", "rc"] }
2020
env_logger = "0.10.0"
@@ -27,7 +27,8 @@ reqwest = { version = "0.11.18", features = ["json"] }
2727
futures = "0.3.28"
2828
tokio = { version = "1.32.0", features = ["rt", "macros"] }
2929
uuidv4 = "1.0.0"
30-
rayon = "1.8.0"
30+
rayon = "1.8.0"
3131
log = "0.4.20"
3232
once_cell = "1.19.0"
33+
libsodium-sys-stable = "1.20.4"
3334
fplus-database = { path = "../fplus-database", version = "1.0.19"}

fplus-lib/src/config.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,14 @@ pub fn default_env_vars() -> &'static HashMap<&'static str, &'static str> {
99
m.insert("GITHUB_OWNER", "filecoin-project");
1010
m.insert("GITHUB_REPO", "filecoin-plus-falcon");
1111
m.insert("GITHUB_APP_ID", "826129");
12-
m.insert("GITHUB_INSTALLATION_ID", "48206379");
12+
m.insert("GITHUB_INSTALLATION_ID", "48299904");
1313
m.insert("RUST_LOG", "info");
1414
m.insert("RUST_BACKTRACE", "1");
1515
m.insert("DB_URL", "");
1616
m.insert("ALLOCATOR_GOVERNANCE_REPO", "Allocator-Governance-Staging");
1717
m.insert("ALLOCATOR_GOVERNANCE_OWNER", "fidlabs");
1818
m.insert("BOT_USER", "filplus-allocators-staging-bot[bot]");
19+
m.insert("BACKEND_URL", "https://fp-core.dp04sa0tdc6pk.us-east-1.cs.amazonlightsail.com");
1920

2021
m
2122
})

fplus-lib/src/core/allocator/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ pub async fn is_allocator_repo_created(owner: &str, repo: &str) -> Result<bool,
9494
pub async fn create_allocator_repo(owner: &str, repo: &str) -> Result<(), LDNError> {
9595
let gh = github_async_new(owner.to_string(), repo.to_string()).await;
9696
let mut dirs = Vec::new();
97+
let backend_url = get_env_var_or_default("BACKEND_URL");
98+
gh.create_or_update_secret("BACKEND_URL", &backend_url).await.map_err(|e| {
99+
LDNError::Load(format!("Failed to create or update secret in GitHub. Reason: {}", e))
100+
})?;
97101
dirs.push("".to_string());
98102

99103
while dirs.len() > 0 {

fplus-lib/src/external_services/github.rs

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,16 @@ use hyper_rustls::HttpsConnectorBuilder;
77
use octocrab::auth::AppAuth;
88
use octocrab::models::issues::{Comment, Issue};
99
use octocrab::models::pulls::PullRequest;
10-
use octocrab::models::repos::{Branch, ContentItems, FileDeletion, FileUpdate};
10+
use octocrab::models::repos::{Branch, ContentItems, FileDeletion, FileUpdate, secrets::CreateRepositorySecret};
1111
use octocrab::models::{InstallationId, IssueState, Label};
1212
use octocrab::params::{pulls::State as PullState, State};
1313
use octocrab::service::middleware::base_uri::BaseUriLayer;
1414
use octocrab::service::middleware::extra_headers::ExtraHeadersLayer;
1515
use octocrab::{AuthState, Error as OctocrabError, Octocrab, OctocrabBuilder, Page};
16+
use libsodium_sys as sodium;
17+
18+
use base64::{encode, decode};
19+
1620
use serde::{Deserialize, Serialize};
1721
use std::sync::Arc;
1822

@@ -134,6 +138,7 @@ impl GithubWrapper {
134138
let client = hyper::Client::builder()
135139
.pool_idle_timeout(std::time::Duration::from_secs(15))
136140
.build(connector);
141+
137142
let key = jsonwebtoken::EncodingKey::from_rsa_pem(gh_private_key.as_bytes()).unwrap();
138143
let octocrab = OctocrabBuilder::new_empty()
139144
.with_service(client)
@@ -730,4 +735,57 @@ impl GithubWrapper {
730735

731736
Ok(contents_items)
732737
}
738+
739+
/**
740+
* Create or update a secret in the repository
741+
* This function will receive the secret name and value and will create or update the secret in the repository
742+
* The secret value will be encrypted using the public key of the repository, as required by the GitHub API
743+
* More information here: https://docs.github.com/en/rest/actions/secrets?apiVersion=2022-11-28#create-or-update-a-repository-secret
744+
*/
745+
pub async fn create_or_update_secret(
746+
&self,
747+
secret_name: &str,
748+
secret_value: &str,
749+
) -> Result<(), OctocrabError> {
750+
let pk = self
751+
.inner
752+
.repos(&self.owner, &self.repo)
753+
.secrets()
754+
.get_public_key()
755+
.await?;
756+
757+
let pk_bytes = match decode(pk.key) {
758+
Ok(bytes) => bytes,
759+
Err(e) => {
760+
log::error!("Failed to decode public key: {:?}", e);
761+
return Ok(());
762+
}
763+
};
764+
assert_eq!(pk_bytes.len(), sodium::crypto_box_PUBLICKEYBYTES as usize, "Invalid public key length");
765+
//Create a buffer to store the encrypted secret
766+
let mut encrypted_secret = vec![0u8; sodium::crypto_box_SEALBYTES as usize + secret_value.len()];
767+
//Encrypt the secret using the public key
768+
let _encrypt_res = unsafe {
769+
sodium::crypto_box_seal(
770+
encrypted_secret.as_mut_ptr(),
771+
secret_value.as_ptr(),
772+
secret_value.len() as u64,
773+
pk_bytes.as_ptr(),
774+
)
775+
};
776+
//Encode the encrypted secret to base64
777+
let encrypted_secret_base64 = encode(&encrypted_secret);
778+
779+
//Encrypt using libsodium
780+
let _create_secret_res = self
781+
.inner
782+
.repos(&self.owner, &self.repo)
783+
.secrets()
784+
.create_or_update_secret(secret_name, &CreateRepositorySecret{
785+
key_id: &pk.key_id,
786+
encrypted_value: &encrypted_secret_base64,
787+
})
788+
.await?;
789+
Ok(())
790+
}
733791
}

0 commit comments

Comments
 (0)