httpd: Show private projects in project listing
We check if the `SocketAddr` from the request is equal to `127.0.0.1` and if so we also list private repos.
This commit is contained in:
parent
e703bad294
commit
b64fc22c18
|
|
@ -66,6 +66,7 @@ impl Context {
|
||||||
Ok(project::Info {
|
Ok(project::Info {
|
||||||
payload,
|
payload,
|
||||||
delegates,
|
delegates,
|
||||||
|
visibility: doc.visibility,
|
||||||
head,
|
head,
|
||||||
issues,
|
issues,
|
||||||
patches,
|
patches,
|
||||||
|
|
@ -185,7 +186,7 @@ mod project {
|
||||||
use radicle::cob;
|
use radicle::cob;
|
||||||
use radicle::git::Oid;
|
use radicle::git::Oid;
|
||||||
use radicle::identity::project::Project;
|
use radicle::identity::project::Project;
|
||||||
use radicle::identity::Id;
|
use radicle::identity::{Id, Visibility};
|
||||||
use radicle::prelude::Did;
|
use radicle::prelude::Did;
|
||||||
|
|
||||||
/// Project info.
|
/// Project info.
|
||||||
|
|
@ -196,6 +197,7 @@ mod project {
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub payload: Project,
|
pub payload: Project,
|
||||||
pub delegates: NonEmpty<Did>,
|
pub delegates: NonEmpty<Did>,
|
||||||
|
pub visibility: Visibility,
|
||||||
pub head: Oid,
|
pub head: Oid,
|
||||||
pub patches: cob::patch::PatchCounts,
|
pub patches: cob::patch::PatchCounts,
|
||||||
pub issues: cob::issue::IssueCounts,
|
pub issues: cob::issue::IssueCounts,
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
use axum::extract::State;
|
use std::net::SocketAddr;
|
||||||
|
|
||||||
|
use axum::extract::{ConnectInfo, State};
|
||||||
use axum::response::IntoResponse;
|
use axum::response::IntoResponse;
|
||||||
use axum::routing::get;
|
use axum::routing::get;
|
||||||
use axum::{Json, Router};
|
use axum::{Json, Router};
|
||||||
|
|
||||||
use radicle::cob::issue::Issues;
|
use radicle::cob::issue::Issues;
|
||||||
use radicle::cob::patch::Patches;
|
use radicle::cob::patch::Patches;
|
||||||
use radicle::identity::{Did, DocAt};
|
use radicle::identity::{Did, Visibility};
|
||||||
use radicle::node::routing::Store;
|
use radicle::node::routing::Store;
|
||||||
use radicle::storage::{ReadRepository, ReadStorage};
|
use radicle::storage::{ReadRepository, ReadStorage};
|
||||||
|
|
||||||
|
|
@ -27,6 +29,7 @@ pub fn router(ctx: Context) -> Router {
|
||||||
/// List all projects which delegate is a part of.
|
/// List all projects which delegate is a part of.
|
||||||
/// `GET /delegates/:delegate/projects`
|
/// `GET /delegates/:delegate/projects`
|
||||||
async fn delegates_projects_handler(
|
async fn delegates_projects_handler(
|
||||||
|
ConnectInfo(addr): ConnectInfo<SocketAddr>,
|
||||||
State(ctx): State<Context>,
|
State(ctx): State<Context>,
|
||||||
Path(delegate): Path<Did>,
|
Path(delegate): Path<Did>,
|
||||||
Query(qs): Query<PaginationQuery>,
|
Query(qs): Query<PaginationQuery>,
|
||||||
|
|
@ -36,27 +39,31 @@ async fn delegates_projects_handler(
|
||||||
let per_page = per_page.unwrap_or(10);
|
let per_page = per_page.unwrap_or(10);
|
||||||
let storage = &ctx.profile.storage;
|
let storage = &ctx.profile.storage;
|
||||||
let routing = &ctx.profile.routing()?;
|
let routing = &ctx.profile.routing()?;
|
||||||
let projects = storage
|
let mut projects = storage
|
||||||
.inventory()?
|
.repositories()?
|
||||||
|
.into_iter()
|
||||||
|
.filter(|id| match &id.doc.visibility {
|
||||||
|
Visibility::Private { .. } => addr.ip().is_loopback(),
|
||||||
|
Visibility::Public => true,
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
projects.sort_by_key(|p| p.rid);
|
||||||
|
|
||||||
|
let infos = projects
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|id| {
|
.filter_map(|id| {
|
||||||
let Ok(repo) = storage.repository(id) else {
|
if !id.doc.delegates.iter().any(|d| *d == delegate) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let Ok(repo) = storage.repository(id.rid) else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
let Ok((_, head)) = repo.head() else {
|
let Ok((_, head)) = repo.head() else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
let Ok(DocAt { doc, .. }) = repo.identity_doc() else {
|
let Ok(payload) = id.doc.project() else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
let Ok(payload) = doc.project() else {
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
|
|
||||||
if !doc.delegates.iter().any(|d| *d == delegate) {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let Ok(issues) = Issues::open(&repo) else {
|
let Ok(issues) = Issues::open(&repo) else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
@ -70,16 +77,17 @@ async fn delegates_projects_handler(
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
let delegates = doc.delegates;
|
let delegates = id.doc.delegates;
|
||||||
let trackings = routing.count(&id).unwrap_or_default();
|
let trackings = routing.count(&id.rid).unwrap_or_default();
|
||||||
|
|
||||||
Some(Info {
|
Some(Info {
|
||||||
payload,
|
payload,
|
||||||
delegates,
|
delegates,
|
||||||
|
visibility: id.doc.visibility,
|
||||||
head,
|
head,
|
||||||
issues,
|
issues,
|
||||||
patches,
|
patches,
|
||||||
id,
|
id: id.rid,
|
||||||
trackings,
|
trackings,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
@ -87,11 +95,14 @@ async fn delegates_projects_handler(
|
||||||
.take(per_page)
|
.take(per_page)
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
Ok::<_, Error>(Json(projects))
|
Ok::<_, Error>(Json(infos))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod routes {
|
mod routes {
|
||||||
|
use std::net::SocketAddr;
|
||||||
|
|
||||||
|
use axum::extract::connect_info::MockConnectInfo;
|
||||||
use axum::http::StatusCode;
|
use axum::http::StatusCode;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
|
|
@ -100,7 +111,72 @@ mod routes {
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_delegates_projects() {
|
async fn test_delegates_projects() {
|
||||||
let tmp = tempfile::tempdir().unwrap();
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
let app = super::router(test::seed(tmp.path()));
|
let seed = test::seed(tmp.path());
|
||||||
|
let app = super::router(seed.clone())
|
||||||
|
.layer(MockConnectInfo(SocketAddr::from(([127, 0, 0, 1], 8080))));
|
||||||
|
let response = get(
|
||||||
|
&app,
|
||||||
|
"/delegates/did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/projects",
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
assert_eq!(response.status(), StatusCode::OK);
|
||||||
|
assert_eq!(
|
||||||
|
response.json().await,
|
||||||
|
json!([
|
||||||
|
{
|
||||||
|
"name": "hello-world-private",
|
||||||
|
"description": "Private Rad repository for tests",
|
||||||
|
"defaultBranch": "master",
|
||||||
|
"delegates": [
|
||||||
|
"did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
|
||||||
|
],
|
||||||
|
"visibility": {
|
||||||
|
"type": "private",
|
||||||
|
},
|
||||||
|
"head": "d26ed310ed140fbef2a066aa486cf59a0f9f7812",
|
||||||
|
"patches": {
|
||||||
|
"open": 0,
|
||||||
|
"draft": 0,
|
||||||
|
"archived": 0,
|
||||||
|
"merged": 0,
|
||||||
|
},
|
||||||
|
"issues": {
|
||||||
|
"open": 0,
|
||||||
|
"closed": 0,
|
||||||
|
},
|
||||||
|
"id": "rad:zLuTzcmoWMcdK37xqArS8eckp9vK",
|
||||||
|
"trackings": 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hello-world",
|
||||||
|
"description": "Rad repository for tests",
|
||||||
|
"defaultBranch": "master",
|
||||||
|
"delegates": ["did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"],
|
||||||
|
"visibility": {
|
||||||
|
"type": "public"
|
||||||
|
},
|
||||||
|
"head": HEAD,
|
||||||
|
"patches": {
|
||||||
|
"open": 1,
|
||||||
|
"draft": 0,
|
||||||
|
"archived": 0,
|
||||||
|
"merged": 0,
|
||||||
|
},
|
||||||
|
"issues": {
|
||||||
|
"open": 1,
|
||||||
|
"closed": 0,
|
||||||
|
},
|
||||||
|
"id": RID,
|
||||||
|
"trackings": 0,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
);
|
||||||
|
|
||||||
|
let app = super::router(seed).layer(MockConnectInfo(SocketAddr::from((
|
||||||
|
[192, 168, 13, 37],
|
||||||
|
8080,
|
||||||
|
))));
|
||||||
let response = get(
|
let response = get(
|
||||||
&app,
|
&app,
|
||||||
"/delegates/did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/projects",
|
"/delegates/did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/projects",
|
||||||
|
|
@ -116,6 +192,9 @@ mod routes {
|
||||||
"description": "Rad repository for tests",
|
"description": "Rad repository for tests",
|
||||||
"defaultBranch": "master",
|
"defaultBranch": "master",
|
||||||
"delegates": ["did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"],
|
"delegates": ["did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"],
|
||||||
|
"visibility": {
|
||||||
|
"type": "public"
|
||||||
|
},
|
||||||
"head": HEAD,
|
"head": HEAD,
|
||||||
"patches": {
|
"patches": {
|
||||||
"open": 1,
|
"open": 1,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
use std::collections::{BTreeMap, HashMap};
|
use std::collections::{BTreeMap, HashMap};
|
||||||
|
use std::net::SocketAddr;
|
||||||
|
|
||||||
use axum::extract::{DefaultBodyLimit, State};
|
use axum::extract::{ConnectInfo, DefaultBodyLimit, State};
|
||||||
use axum::handler::Handler;
|
use axum::handler::Handler;
|
||||||
use axum::http::{header, HeaderValue};
|
use axum::http::{header, HeaderValue};
|
||||||
use axum::response::IntoResponse;
|
use axum::response::IntoResponse;
|
||||||
|
|
@ -14,7 +15,7 @@ use serde_json::{json, Value};
|
||||||
use tower_http::set_header::SetResponseHeaderLayer;
|
use tower_http::set_header::SetResponseHeaderLayer;
|
||||||
|
|
||||||
use radicle::cob::{issue, patch, Embed, Label, Uri};
|
use radicle::cob::{issue, patch, Embed, Label, Uri};
|
||||||
use radicle::identity::{Did, DocAt, Id};
|
use radicle::identity::{Did, Id, Visibility};
|
||||||
use radicle::node::routing::Store;
|
use radicle::node::routing::Store;
|
||||||
use radicle::node::AliasStore;
|
use radicle::node::AliasStore;
|
||||||
use radicle::node::NodeId;
|
use radicle::node::NodeId;
|
||||||
|
|
@ -75,6 +76,7 @@ pub fn router(ctx: Context) -> Router {
|
||||||
/// List all projects.
|
/// List all projects.
|
||||||
/// `GET /projects`
|
/// `GET /projects`
|
||||||
async fn project_root_handler(
|
async fn project_root_handler(
|
||||||
|
ConnectInfo(addr): ConnectInfo<SocketAddr>,
|
||||||
State(ctx): State<Context>,
|
State(ctx): State<Context>,
|
||||||
Query(qs): Query<PaginationQuery>,
|
Query(qs): Query<PaginationQuery>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
|
|
@ -83,21 +85,26 @@ async fn project_root_handler(
|
||||||
let per_page = per_page.unwrap_or(10);
|
let per_page = per_page.unwrap_or(10);
|
||||||
let storage = &ctx.profile.storage;
|
let storage = &ctx.profile.storage;
|
||||||
let routing = &ctx.profile.routing()?;
|
let routing = &ctx.profile.routing()?;
|
||||||
let projects = storage
|
let mut projects = storage
|
||||||
.inventory()?
|
.repositories()?
|
||||||
|
.into_iter()
|
||||||
|
.filter(|id| match &id.doc.visibility {
|
||||||
|
Visibility::Private { .. } => addr.ip().is_loopback(),
|
||||||
|
Visibility::Public => true,
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
projects.sort_by_key(|p| p.rid);
|
||||||
|
|
||||||
|
let infos = projects
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|id| {
|
.filter_map(|id| {
|
||||||
let Ok(repo) = storage.repository(id) else {
|
let Ok(repo) = storage.repository(id.rid) else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
let Ok((_, head)) = repo.head() else {
|
let Ok((_, head)) = repo.head() else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
let Ok(DocAt { doc, .. }) = repo.identity_doc() else {
|
let Ok(payload) = id.doc.project() else {
|
||||||
return None;
|
|
||||||
};
|
|
||||||
|
|
||||||
let Ok(payload) = doc.project() else {
|
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
let Ok(issues) = issue::Issues::open(&repo) else {
|
let Ok(issues) = issue::Issues::open(&repo) else {
|
||||||
|
|
@ -112,16 +119,17 @@ async fn project_root_handler(
|
||||||
let Ok(patches) = patches.counts() else {
|
let Ok(patches) = patches.counts() else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
let delegates = doc.delegates;
|
let delegates = id.doc.delegates;
|
||||||
let trackings = routing.count(&id).unwrap_or_default();
|
let trackings = routing.count(&id.rid).unwrap_or_default();
|
||||||
|
|
||||||
Some(Info {
|
Some(Info {
|
||||||
payload,
|
payload,
|
||||||
delegates,
|
delegates,
|
||||||
head,
|
head,
|
||||||
|
visibility: id.doc.visibility,
|
||||||
issues,
|
issues,
|
||||||
patches,
|
patches,
|
||||||
id,
|
id: id.rid,
|
||||||
trackings,
|
trackings,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
@ -129,7 +137,7 @@ async fn project_root_handler(
|
||||||
.take(per_page)
|
.take(per_page)
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
Ok::<_, Error>(Json(projects))
|
Ok::<_, Error>(Json(infos))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get project metadata.
|
/// Get project metadata.
|
||||||
|
|
@ -990,7 +998,10 @@ async fn patch_handler(
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod routes {
|
mod routes {
|
||||||
|
use std::net::SocketAddr;
|
||||||
|
|
||||||
use axum::body::Body;
|
use axum::body::Body;
|
||||||
|
use axum::extract::connect_info::MockConnectInfo;
|
||||||
use axum::http::StatusCode;
|
use axum::http::StatusCode;
|
||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
@ -1000,7 +1011,68 @@ mod routes {
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_projects_root() {
|
async fn test_projects_root() {
|
||||||
let tmp = tempfile::tempdir().unwrap();
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
let app = super::router(seed(tmp.path()));
|
let seed = seed(tmp.path());
|
||||||
|
let app = super::router(seed.clone())
|
||||||
|
.layer(MockConnectInfo(SocketAddr::from(([127, 0, 0, 1], 8080))));
|
||||||
|
let response = get(&app, "/projects").await;
|
||||||
|
|
||||||
|
assert_eq!(response.status(), StatusCode::OK);
|
||||||
|
assert_eq!(
|
||||||
|
response.json().await,
|
||||||
|
json!([
|
||||||
|
{
|
||||||
|
"name": "hello-world-private",
|
||||||
|
"description": "Private Rad repository for tests",
|
||||||
|
"defaultBranch": "master",
|
||||||
|
"delegates": [
|
||||||
|
"did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
|
||||||
|
],
|
||||||
|
"visibility": {
|
||||||
|
"type": "private",
|
||||||
|
},
|
||||||
|
"head": "d26ed310ed140fbef2a066aa486cf59a0f9f7812",
|
||||||
|
"patches": {
|
||||||
|
"open": 0,
|
||||||
|
"draft": 0,
|
||||||
|
"archived": 0,
|
||||||
|
"merged": 0,
|
||||||
|
},
|
||||||
|
"issues": {
|
||||||
|
"open": 0,
|
||||||
|
"closed": 0,
|
||||||
|
},
|
||||||
|
"id": "rad:zLuTzcmoWMcdK37xqArS8eckp9vK",
|
||||||
|
"trackings": 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hello-world",
|
||||||
|
"description": "Rad repository for tests",
|
||||||
|
"defaultBranch": "master",
|
||||||
|
"delegates": [DID],
|
||||||
|
"visibility": {
|
||||||
|
"type": "public"
|
||||||
|
},
|
||||||
|
"head": HEAD,
|
||||||
|
"patches": {
|
||||||
|
"open": 1,
|
||||||
|
"draft": 0,
|
||||||
|
"archived": 0,
|
||||||
|
"merged": 0,
|
||||||
|
},
|
||||||
|
"issues": {
|
||||||
|
"open": 1,
|
||||||
|
"closed": 0,
|
||||||
|
},
|
||||||
|
"id": RID,
|
||||||
|
"trackings": 0,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
);
|
||||||
|
|
||||||
|
let app = super::router(seed).layer(MockConnectInfo(SocketAddr::from((
|
||||||
|
[192, 168, 13, 37],
|
||||||
|
8080,
|
||||||
|
))));
|
||||||
let response = get(&app, "/projects").await;
|
let response = get(&app, "/projects").await;
|
||||||
|
|
||||||
assert_eq!(response.status(), StatusCode::OK);
|
assert_eq!(response.status(), StatusCode::OK);
|
||||||
|
|
@ -1012,6 +1084,9 @@ mod routes {
|
||||||
"description": "Rad repository for tests",
|
"description": "Rad repository for tests",
|
||||||
"defaultBranch": "master",
|
"defaultBranch": "master",
|
||||||
"delegates": [DID],
|
"delegates": [DID],
|
||||||
|
"visibility": {
|
||||||
|
"type": "public"
|
||||||
|
},
|
||||||
"head": HEAD,
|
"head": HEAD,
|
||||||
"patches": {
|
"patches": {
|
||||||
"open": 1,
|
"open": 1,
|
||||||
|
|
@ -1044,6 +1119,9 @@ mod routes {
|
||||||
"description": "Rad repository for tests",
|
"description": "Rad repository for tests",
|
||||||
"defaultBranch": "master",
|
"defaultBranch": "master",
|
||||||
"delegates": [DID],
|
"delegates": [DID],
|
||||||
|
"visibility": {
|
||||||
|
"type": "public"
|
||||||
|
},
|
||||||
"head": HEAD,
|
"head": HEAD,
|
||||||
"patches": {
|
"patches": {
|
||||||
"open": 1,
|
"open": 1,
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use std::collections::BTreeSet;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
@ -107,6 +108,45 @@ fn seed_with_signer<G: Signer>(dir: &Path, profile: radicle::Profile, signer: &G
|
||||||
RoutingStore::Table::open(routing_db).unwrap();
|
RoutingStore::Table::open(routing_db).unwrap();
|
||||||
AddressStore::Book::open(addresses_db).unwrap();
|
AddressStore::Book::open(addresses_db).unwrap();
|
||||||
|
|
||||||
|
let workdir = dir.join("hello-world-private");
|
||||||
|
fs::create_dir_all(&workdir).unwrap();
|
||||||
|
|
||||||
|
// add commits to workdir (repo)
|
||||||
|
let mut opts = git2::RepositoryInitOptions::new();
|
||||||
|
opts.initial_head(DEFAULT_BRANCH);
|
||||||
|
let repo = git2::Repository::init_opts(&workdir, &opts).unwrap();
|
||||||
|
let tree = radicle::git::write_tree(
|
||||||
|
Path::new("README"),
|
||||||
|
"Hello Private World!\n".as_bytes(),
|
||||||
|
&repo,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let sig_time = git2::Time::new(1673001014, 0);
|
||||||
|
let sig = git2::Signature::new("Alice Liddell", "alice@radicle.xyz", &sig_time).unwrap();
|
||||||
|
|
||||||
|
repo.commit(Some("HEAD"), &sig, &sig, "Initial commit\n", &tree, &[])
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// rad init
|
||||||
|
let repo = git2::Repository::open(&workdir).unwrap();
|
||||||
|
let name = "hello-world-private".to_string();
|
||||||
|
let description = "Private Rad repository for tests".to_string();
|
||||||
|
let branch = RefString::try_from(DEFAULT_BRANCH).unwrap();
|
||||||
|
let visibility = Visibility::Private {
|
||||||
|
allow: BTreeSet::default(),
|
||||||
|
};
|
||||||
|
radicle::rad::init(
|
||||||
|
&repo,
|
||||||
|
&name,
|
||||||
|
&description,
|
||||||
|
branch,
|
||||||
|
visibility,
|
||||||
|
signer,
|
||||||
|
&profile.storage,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let workdir = dir.join("hello-world");
|
let workdir = dir.join("hello-world");
|
||||||
|
|
||||||
env::set_var("RAD_COMMIT_TIME", TIMESTAMP.to_string());
|
env::set_var("RAD_COMMIT_TIME", TIMESTAMP.to_string());
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue