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:
|
github:
|
||||||
type: github
|
type: github
|
||||||
endpoint: https://github.com
|
endpoint: https://github.com
|
||||||
|
repository: autocrate
|
||||||
auth:
|
auth:
|
||||||
user: PlexSheep
|
user: PlexSheep
|
||||||
pass:
|
pass:
|
||||||
|
@ -22,6 +23,7 @@ api:
|
||||||
cscherr:
|
cscherr:
|
||||||
type: forgejo
|
type: forgejo
|
||||||
endpoint: https://git.cscherr.de
|
endpoint: https://git.cscherr.de
|
||||||
|
repository: autocrate
|
||||||
auth:
|
auth:
|
||||||
user: PlexSheep
|
user: PlexSheep
|
||||||
pass:
|
pass:
|
||||||
|
|
|
@ -25,6 +25,7 @@ async-trait = "0.1.77"
|
||||||
# cargo = "0.76.0"
|
# cargo = "0.76.0"
|
||||||
clap = { version = "4.4.18", features = ["derive", "help"] }
|
clap = { version = "4.4.18", features = ["derive", "help"] }
|
||||||
clap-verbosity-flag = "2.1.2"
|
clap-verbosity-flag = "2.1.2"
|
||||||
|
futures = "0.3.30"
|
||||||
git2 = "0.18.1"
|
git2 = "0.18.1"
|
||||||
libpt = { version = "0.3.11", features = ["log"] }
|
libpt = { version = "0.3.11", features = ["log"] }
|
||||||
reqwest = "0.11.24"
|
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
|
/// May be left empty if the Api does not need auth or the auth is part of the
|
||||||
/// [endpoint](Api::endpoint) [Url].
|
/// [endpoint](Api::endpoint) [Url].
|
||||||
pub auth: Option<ApiAuth>,
|
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 {
|
impl YamlConfigSection for Api {
|
||||||
fn check(&self) -> Result<()> {
|
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 publish;
|
||||||
pub mod release;
|
pub mod release;
|
||||||
pub mod serverapi;
|
pub mod serverapi;
|
||||||
|
pub mod git;
|
||||||
|
|
|
@ -7,7 +7,7 @@ use autocrate::{
|
||||||
error::*,
|
error::*,
|
||||||
publish::publish,
|
publish::publish,
|
||||||
release::release,
|
release::release,
|
||||||
serverapi::init_servers,
|
serverapi::ApiCollection,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
|
@ -20,10 +20,12 @@ async fn main() -> Result<()> {
|
||||||
println!("{}", Changelog::build(&cfg)?);
|
println!("{}", Changelog::build(&cfg)?);
|
||||||
}
|
}
|
||||||
Commands::Release { .. } => {
|
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?;
|
release(&cfg, &mut apis).await?;
|
||||||
}
|
}
|
||||||
Commands::Publish { .. } => {
|
Commands::Publish { .. } => {
|
||||||
|
// TODO: check if repo is dirty and create a commit with a given option
|
||||||
publish(&cfg).await?;
|
publish(&cfg).await?;
|
||||||
}
|
}
|
||||||
Commands::Version {} => {
|
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 struct ReleaseContext {
|
||||||
pub draft: bool,
|
pub draft: bool,
|
||||||
pub prerelease: bool,
|
pub prerelease: bool,
|
||||||
|
@ -10,13 +18,39 @@ pub struct ReleaseContext {
|
||||||
pub commit_sig: String,
|
pub commit_sig: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn release(cfg: &Config, _apis: &mut ApiCollection) -> Result<()> {
|
pub async fn release(cfg: &Config, apis: &mut ApiCollection) -> Result<()> {
|
||||||
// TODO: git tag
|
let tag: String = tag(cfg).await?;
|
||||||
// TODO: push to each server
|
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
|
let mut results = FuturesUnordered::new();
|
||||||
tag(cfg).await?;
|
for api in apis.iter_mut() {
|
||||||
todo!();
|
// 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: check that the release is made
|
||||||
// TODO: generate artifacts
|
// TODO: generate artifacts
|
||||||
|
@ -25,7 +59,3 @@ pub async fn release(cfg: &Config, _apis: &mut ApiCollection) -> Result<()> {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn tag(_cfg: &Config) -> Result<()> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ impl ServerApi for Forgejo {
|
||||||
async fn init(&mut self, _cfg: &Config) -> Result<()> {
|
async fn init(&mut self, _cfg: &Config) -> Result<()> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
async fn push_release(&mut self, rc: &ReleaseContext) -> Result<()> {
|
async fn push_release(&mut self, rc: ReleaseContext) -> Result<()> {
|
||||||
let raw_url = format!(
|
let raw_url = format!(
|
||||||
"{}/api/v1/repos/{}/{}/releases",
|
"{}/api/v1/repos/{}/{}/releases",
|
||||||
self.cfg.endpoint, rc.username, rc.repository
|
self.cfg.endpoint, rc.username, rc.repository
|
||||||
|
@ -74,10 +74,11 @@ impl ServerApi for Forgejo {
|
||||||
.map_err(ServerApiError::from)?;
|
.map_err(ServerApiError::from)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
async fn push_release_artifact(&mut self, _rc: &ReleaseContext) -> Result<()> {
|
async fn push_release_artifact(&mut self, _rc: ReleaseContext) -> Result<()> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
async fn push_pkg(&mut self, _pc: &PublishContext) -> Result<()> {
|
async fn push_pkg(&mut self, _pc: PublishContext) -> Result<()> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
fn get_cfg(&self) -> &Api {&self.cfg}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,15 +14,16 @@ impl ServerApi for Gitea {
|
||||||
async fn init(&mut self, _cfg: &Config) -> Result<()> {
|
async fn init(&mut self, _cfg: &Config) -> Result<()> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
async fn push_release(&mut self, _rc: &ReleaseContext) -> Result<()> {
|
async fn push_release(&mut self, _rc: ReleaseContext) -> Result<()> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
async fn push_release_artifact(&mut self, _rc: &ReleaseContext) -> Result<()> {
|
async fn push_release_artifact(&mut self, _rc: ReleaseContext) -> Result<()> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
async fn push_pkg(&mut self, _pc: &PublishContext) -> Result<()> {
|
async fn push_pkg(&mut self, _pc: PublishContext) -> Result<()> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
fn get_cfg(&self) -> &Api {&self.cfg}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Gitea {
|
impl Gitea {
|
||||||
|
|
|
@ -14,15 +14,16 @@ impl ServerApi for Github {
|
||||||
async fn init(&mut self, _cfg: &Config) -> Result<()> {
|
async fn init(&mut self, _cfg: &Config) -> Result<()> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
async fn push_release(&mut self, _rc: &ReleaseContext) -> Result<()> {
|
async fn push_release(&mut self, _rc: ReleaseContext) -> Result<()> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
async fn push_release_artifact(&mut self, _rc: &ReleaseContext) -> Result<()> {
|
async fn push_release_artifact(&mut self, _rc: ReleaseContext) -> Result<()> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
async fn push_pkg(&mut self, _pc: &PublishContext) -> Result<()> {
|
async fn push_pkg(&mut self, _pc: PublishContext) -> Result<()> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
fn get_cfg(&self) -> &Api {&self.cfg}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Github {
|
impl Github {
|
||||||
|
|
|
@ -14,15 +14,16 @@ impl ServerApi for Gitlab {
|
||||||
async fn init(&mut self, _cfg: &Config) -> Result<()> {
|
async fn init(&mut self, _cfg: &Config) -> Result<()> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
async fn push_release(&mut self, _rc: &ReleaseContext) -> Result<()> {
|
async fn push_release(&mut self, _rc: ReleaseContext) -> Result<()> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
async fn push_release_artifact(&mut self, _rc: &ReleaseContext) -> Result<()> {
|
async fn push_release_artifact(&mut self, _rc: ReleaseContext) -> Result<()> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
async fn push_pkg(&mut self, _pc: &PublishContext) -> Result<()> {
|
async fn push_pkg(&mut self, _pc: PublishContext) -> Result<()> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
fn get_cfg(&self) -> &Api {&self.cfg}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Gitlab {
|
impl Gitlab {
|
||||||
|
|
|
@ -1,8 +1,13 @@
|
||||||
|
use std::{
|
||||||
|
ops::{Deref, DerefMut},
|
||||||
|
slice::Iter,
|
||||||
|
};
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use reqwest::ClientBuilder;
|
use reqwest::ClientBuilder;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
config::{ApiType, Config},
|
config::{ApiType, Config, self},
|
||||||
error::*,
|
error::*,
|
||||||
publish::PublishContext,
|
publish::PublishContext,
|
||||||
release::ReleaseContext,
|
release::ReleaseContext,
|
||||||
|
@ -18,7 +23,6 @@ use github::*;
|
||||||
use gitlab::*;
|
use gitlab::*;
|
||||||
|
|
||||||
pub static USER_AGENT: &str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION"),);
|
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,
|
// 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).
|
// 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]
|
#[async_trait]
|
||||||
pub trait ServerApi {
|
pub trait ServerApi {
|
||||||
async fn init(&mut self, cfg: &Config) -> Result<()>;
|
async fn init(&mut self, cfg: &Config) -> Result<()>;
|
||||||
async fn push_release(&mut self, rc: &ReleaseContext) -> Result<()>;
|
async fn push_release(&mut self, rc: ReleaseContext) -> Result<()>;
|
||||||
async fn push_release_artifact(&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_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 {
|
pub fn client_builder() -> ClientBuilder {
|
||||||
ClientBuilder::new().user_agent(USER_AGENT)
|
ClientBuilder::new().user_agent(USER_AGENT)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn init_servers(cfg: &Config) -> Result<ApiCollection> {
|
// trait iimplementations for easy use of ApiCollection follow
|
||||||
let mut collection: ApiCollection = ApiCollection::new();
|
impl IntoIterator for ApiCollection {
|
||||||
for api in &cfg.yaml.api {
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
match api.1.server_type {
|
self.collection.into_iter()
|
||||||
ApiType::Gitea => {
|
}
|
||||||
collection.push(Box::new(Gitea::build(api.1).await?));
|
type Item = Box<dyn ServerApi>;
|
||||||
}
|
type IntoIter = std::vec::IntoIter<Self::Item>;
|
||||||
ApiType::Gitlab => {
|
}
|
||||||
collection.push(Box::new(Gitlab::build(api.1).await?));
|
|
||||||
}
|
impl Deref for ApiCollection {
|
||||||
ApiType::Github => {
|
type Target = [Box<dyn ServerApi>];
|
||||||
collection.push(Box::new(Github::build(api.1).await?));
|
fn deref(&self) -> &Self::Target {
|
||||||
}
|
&self.collection[..]
|
||||||
ApiType::Forgejo => {
|
}
|
||||||
collection.push(Box::new(Forgejo::build(api.1).await?));
|
}
|
||||||
}
|
|
||||||
}
|
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