generated from PlexSheep/rs-base
in THEORY maybe we could release if we ask nicely
cargo devel CI / cargo CI (push) Successful in 2m3s
Details
cargo devel CI / cargo CI (push) Successful in 2m3s
Details
This commit is contained in:
parent
2c26a65a65
commit
7d4a3986a9
|
@ -15,6 +15,7 @@ api:
|
|||
github:
|
||||
type: github
|
||||
endpoint: https://github.com
|
||||
repository: autocrate
|
||||
auth:
|
||||
user: PlexSheep
|
||||
pass:
|
||||
|
@ -22,6 +23,7 @@ api:
|
|||
cscherr:
|
||||
type: forgejo
|
||||
endpoint: https://git.cscherr.de
|
||||
repository: autocrate
|
||||
auth:
|
||||
user: PlexSheep
|
||||
pass:
|
||||
|
|
|
@ -25,6 +25,7 @@ async-trait = "0.1.77"
|
|||
# cargo = "0.76.0"
|
||||
clap = { version = "4.4.18", features = ["derive", "help"] }
|
||||
clap-verbosity-flag = "2.1.2"
|
||||
futures = "0.3.30"
|
||||
git2 = "0.18.1"
|
||||
libpt = { version = "0.3.11", features = ["log"] }
|
||||
reqwest = "0.11.24"
|
||||
|
|
|
@ -107,6 +107,8 @@ pub struct Api {
|
|||
/// May be left empty if the Api does not need auth or the auth is part of the
|
||||
/// [endpoint](Api::endpoint) [Url].
|
||||
pub auth: Option<ApiAuth>,
|
||||
/// Name of the repository on the Git server, as git itself has no concept of repository name
|
||||
pub repository: String
|
||||
}
|
||||
impl YamlConfigSection for Api {
|
||||
fn check(&self) -> Result<()> {
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
use git2;
|
||||
|
||||
use crate::{config::Config, error::Result};
|
||||
|
||||
pub async fn tag(_cfg: &Config) -> Result<String> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub async fn push(_cfg: &Config) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub async fn get_commit_sig(_cfg: &Config) -> Result<String> {
|
||||
todo!()
|
||||
}
|
|
@ -4,3 +4,4 @@ pub mod error;
|
|||
pub mod publish;
|
||||
pub mod release;
|
||||
pub mod serverapi;
|
||||
pub mod git;
|
||||
|
|
|
@ -7,7 +7,7 @@ use autocrate::{
|
|||
error::*,
|
||||
publish::publish,
|
||||
release::release,
|
||||
serverapi::init_servers,
|
||||
serverapi::ApiCollection,
|
||||
};
|
||||
|
||||
#[tokio::main]
|
||||
|
@ -20,10 +20,12 @@ async fn main() -> Result<()> {
|
|||
println!("{}", Changelog::build(&cfg)?);
|
||||
}
|
||||
Commands::Release { .. } => {
|
||||
let mut apis = init_servers(&cfg).await?;
|
||||
// TODO: check if repo is dirty and create a commit with a given option
|
||||
let mut apis = ApiCollection::build(&cfg).await?;
|
||||
release(&cfg, &mut apis).await?;
|
||||
}
|
||||
Commands::Publish { .. } => {
|
||||
// TODO: check if repo is dirty and create a commit with a given option
|
||||
publish(&cfg).await?;
|
||||
}
|
||||
Commands::Version {} => {
|
||||
|
|
|
@ -1,5 +1,13 @@
|
|||
use crate::{config::Config, error::*, serverapi::ApiCollection};
|
||||
use crate::{
|
||||
config::Config,
|
||||
error::*,
|
||||
git::{get_commit_sig, push, tag},
|
||||
serverapi::ApiCollection,
|
||||
};
|
||||
|
||||
use futures::{self, stream::FuturesUnordered, StreamExt};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Hash)]
|
||||
pub struct ReleaseContext {
|
||||
pub draft: bool,
|
||||
pub prerelease: bool,
|
||||
|
@ -10,13 +18,39 @@ pub struct ReleaseContext {
|
|||
pub commit_sig: String,
|
||||
}
|
||||
|
||||
pub async fn release(cfg: &Config, _apis: &mut ApiCollection) -> Result<()> {
|
||||
// TODO: git tag
|
||||
// TODO: push to each server
|
||||
pub async fn release(cfg: &Config, apis: &mut ApiCollection) -> Result<()> {
|
||||
let tag: String = tag(cfg).await?;
|
||||
let commit_sig = get_commit_sig(cfg).await?;
|
||||
push(cfg).await?; // we assume that we only need to push the current branch to the singular
|
||||
// remote, expecting that the repositories are somehow mirrored
|
||||
// TODO: push to multiple remotes?
|
||||
|
||||
// TODO: release to each server
|
||||
tag(cfg).await?;
|
||||
todo!();
|
||||
let mut results = FuturesUnordered::new();
|
||||
for api in apis.iter_mut() {
|
||||
// TODO: check that auth exists
|
||||
let specific_rc = ReleaseContext {
|
||||
draft: true,
|
||||
prerelease: true,
|
||||
username: api
|
||||
.get_cfg()
|
||||
.clone()
|
||||
.auth
|
||||
.expect("no auth but trying to publish")
|
||||
.user,
|
||||
repository: api.get_cfg().repository.clone(),
|
||||
text: String::from("TODO: ADD TEXT VARIABLE SOMEHOW"),
|
||||
tag: tag.clone(),
|
||||
commit_sig: commit_sig.clone(),
|
||||
};
|
||||
results.push(api.push_release(specific_rc));
|
||||
}
|
||||
|
||||
// wait for the release requests to finish
|
||||
while let Some(result) = results.next().await {
|
||||
if result.is_err() {
|
||||
return Err(result.unwrap_err());
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: check that the release is made
|
||||
// TODO: generate artifacts
|
||||
|
@ -25,7 +59,3 @@ pub async fn release(cfg: &Config, _apis: &mut ApiCollection) -> Result<()> {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn tag(_cfg: &Config) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ impl ServerApi for Forgejo {
|
|||
async fn init(&mut self, _cfg: &Config) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
async fn push_release(&mut self, rc: &ReleaseContext) -> Result<()> {
|
||||
async fn push_release(&mut self, rc: ReleaseContext) -> Result<()> {
|
||||
let raw_url = format!(
|
||||
"{}/api/v1/repos/{}/{}/releases",
|
||||
self.cfg.endpoint, rc.username, rc.repository
|
||||
|
@ -74,10 +74,11 @@ impl ServerApi for Forgejo {
|
|||
.map_err(ServerApiError::from)?;
|
||||
Ok(())
|
||||
}
|
||||
async fn push_release_artifact(&mut self, _rc: &ReleaseContext) -> Result<()> {
|
||||
async fn push_release_artifact(&mut self, _rc: ReleaseContext) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
async fn push_pkg(&mut self, _pc: &PublishContext) -> Result<()> {
|
||||
async fn push_pkg(&mut self, _pc: PublishContext) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
fn get_cfg(&self) -> &Api {&self.cfg}
|
||||
}
|
||||
|
|
|
@ -14,15 +14,16 @@ impl ServerApi for Gitea {
|
|||
async fn init(&mut self, _cfg: &Config) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
async fn push_release(&mut self, _rc: &ReleaseContext) -> Result<()> {
|
||||
async fn push_release(&mut self, _rc: ReleaseContext) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
async fn push_release_artifact(&mut self, _rc: &ReleaseContext) -> Result<()> {
|
||||
async fn push_release_artifact(&mut self, _rc: ReleaseContext) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
async fn push_pkg(&mut self, _pc: &PublishContext) -> Result<()> {
|
||||
async fn push_pkg(&mut self, _pc: PublishContext) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
fn get_cfg(&self) -> &Api {&self.cfg}
|
||||
}
|
||||
|
||||
impl Gitea {
|
||||
|
|
|
@ -14,15 +14,16 @@ impl ServerApi for Github {
|
|||
async fn init(&mut self, _cfg: &Config) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
async fn push_release(&mut self, _rc: &ReleaseContext) -> Result<()> {
|
||||
async fn push_release(&mut self, _rc: ReleaseContext) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
async fn push_release_artifact(&mut self, _rc: &ReleaseContext) -> Result<()> {
|
||||
async fn push_release_artifact(&mut self, _rc: ReleaseContext) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
async fn push_pkg(&mut self, _pc: &PublishContext) -> Result<()> {
|
||||
async fn push_pkg(&mut self, _pc: PublishContext) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
fn get_cfg(&self) -> &Api {&self.cfg}
|
||||
}
|
||||
|
||||
impl Github {
|
||||
|
|
|
@ -14,15 +14,16 @@ impl ServerApi for Gitlab {
|
|||
async fn init(&mut self, _cfg: &Config) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
async fn push_release(&mut self, _rc: &ReleaseContext) -> Result<()> {
|
||||
async fn push_release(&mut self, _rc: ReleaseContext) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
async fn push_release_artifact(&mut self, _rc: &ReleaseContext) -> Result<()> {
|
||||
async fn push_release_artifact(&mut self, _rc: ReleaseContext) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
async fn push_pkg(&mut self, _pc: &PublishContext) -> Result<()> {
|
||||
async fn push_pkg(&mut self, _pc: PublishContext) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
fn get_cfg(&self) -> &Api {&self.cfg}
|
||||
}
|
||||
|
||||
impl Gitlab {
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
use std::{
|
||||
ops::{Deref, DerefMut},
|
||||
slice::Iter,
|
||||
};
|
||||
|
||||
use async_trait::async_trait;
|
||||
use reqwest::ClientBuilder;
|
||||
|
||||
use crate::{
|
||||
config::{ApiType, Config},
|
||||
config::{ApiType, Config, self},
|
||||
error::*,
|
||||
publish::PublishContext,
|
||||
release::ReleaseContext,
|
||||
|
@ -18,7 +23,6 @@ use github::*;
|
|||
use gitlab::*;
|
||||
|
||||
pub static USER_AGENT: &str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION"),);
|
||||
pub type ApiCollection = Vec<Box<dyn ServerApi>>;
|
||||
|
||||
// NOTE: in stable rust, traits can normally not contain async methods,
|
||||
// see [here](https://stackoverflow.com/questions/65921581/how-can-i-define-an-async-method-in-a-trait).
|
||||
|
@ -26,35 +30,74 @@ pub type ApiCollection = Vec<Box<dyn ServerApi>>;
|
|||
#[async_trait]
|
||||
pub trait ServerApi {
|
||||
async fn init(&mut self, cfg: &Config) -> Result<()>;
|
||||
async fn push_release(&mut self, rc: &ReleaseContext) -> Result<()>;
|
||||
async fn push_release_artifact(&mut self, rc: &ReleaseContext) -> Result<()>;
|
||||
async fn push_pkg(&mut self, pc: &PublishContext) -> Result<()>;
|
||||
async fn push_release(&mut self, rc: ReleaseContext) -> Result<()>;
|
||||
async fn push_release_artifact(&mut self, rc: ReleaseContext) -> Result<()>;
|
||||
async fn push_pkg(&mut self, pc: PublishContext) -> Result<()>;
|
||||
fn get_cfg(&self) -> &config::Api;
|
||||
}
|
||||
|
||||
pub(crate) type ApiCollectionInner = Vec<Box<dyn ServerApi>>;
|
||||
|
||||
pub struct ApiCollection {
|
||||
collection: ApiCollectionInner,
|
||||
}
|
||||
|
||||
impl ApiCollection {
|
||||
pub async fn build(cfg: &Config) -> Result<Self> {
|
||||
let mut collection: ApiCollectionInner = ApiCollectionInner::new();
|
||||
for api in &cfg.yaml.api {
|
||||
match api.1.server_type {
|
||||
ApiType::Gitea => {
|
||||
collection.push(Box::new(Gitea::build(api.1).await?));
|
||||
}
|
||||
ApiType::Gitlab => {
|
||||
collection.push(Box::new(Gitlab::build(api.1).await?));
|
||||
}
|
||||
ApiType::Github => {
|
||||
collection.push(Box::new(Github::build(api.1).await?));
|
||||
}
|
||||
ApiType::Forgejo => {
|
||||
collection.push(Box::new(Forgejo::build(api.1).await?));
|
||||
}
|
||||
}
|
||||
}
|
||||
for api in collection.iter_mut() {
|
||||
api.init(cfg).await?;
|
||||
}
|
||||
Ok(ApiCollection { collection })
|
||||
}
|
||||
|
||||
pub fn collection(&self) -> &ApiCollectionInner {
|
||||
self.collection.as_ref()
|
||||
}
|
||||
|
||||
pub fn collection_mut(&mut self) -> &mut ApiCollectionInner {
|
||||
self.collection.as_mut()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn client_builder() -> ClientBuilder {
|
||||
ClientBuilder::new().user_agent(USER_AGENT)
|
||||
}
|
||||
|
||||
pub async fn init_servers(cfg: &Config) -> Result<ApiCollection> {
|
||||
let mut collection: ApiCollection = ApiCollection::new();
|
||||
for api in &cfg.yaml.api {
|
||||
match api.1.server_type {
|
||||
ApiType::Gitea => {
|
||||
collection.push(Box::new(Gitea::build(api.1).await?));
|
||||
}
|
||||
ApiType::Gitlab => {
|
||||
collection.push(Box::new(Gitlab::build(api.1).await?));
|
||||
}
|
||||
ApiType::Github => {
|
||||
collection.push(Box::new(Github::build(api.1).await?));
|
||||
}
|
||||
ApiType::Forgejo => {
|
||||
collection.push(Box::new(Forgejo::build(api.1).await?));
|
||||
}
|
||||
}
|
||||
// trait iimplementations for easy use of ApiCollection follow
|
||||
impl IntoIterator for ApiCollection {
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.collection.into_iter()
|
||||
}
|
||||
type Item = Box<dyn ServerApi>;
|
||||
type IntoIter = std::vec::IntoIter<Self::Item>;
|
||||
}
|
||||
|
||||
impl Deref for ApiCollection {
|
||||
type Target = [Box<dyn ServerApi>];
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.collection[..]
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for ApiCollection {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.collection[..]
|
||||
}
|
||||
for api in collection.iter_mut() {
|
||||
api.init(cfg).await?;
|
||||
}
|
||||
Ok(collection)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue