generated from PlexSheep/rs-base
pass enum
cargo devel CI / cargo CI (push) Successful in 4m4s
Details
cargo devel CI / cargo CI (push) Successful in 4m4s
Details
This commit is contained in:
parent
f12f5763d1
commit
bd04eea9cc
|
@ -16,11 +16,13 @@ api:
|
|||
type: github
|
||||
endpoint: https://github.com
|
||||
auth:
|
||||
user: myUserName
|
||||
pass: token_superimportantsecret
|
||||
myserv:
|
||||
type: gitea
|
||||
user: PlexSheep
|
||||
pass:
|
||||
env: TOKEN_GH
|
||||
cscherr:
|
||||
type: forgejo
|
||||
endpoint: https://git.cscherr.de
|
||||
auth:
|
||||
user: myUserName
|
||||
pass: importantsecrettoken
|
||||
user: PlexSheep
|
||||
pass:
|
||||
env: TOKEN_CSCHERR
|
||||
|
|
39
README.md
39
README.md
|
@ -65,21 +65,24 @@ locally, making it readily accessible through your command line interfaces.
|
|||
Create a YAML file named `.autocrate.yml` (or `.yaml`) in the root of your Git
|
||||
repository. It should contain the following parameters (replace the placeholders):
|
||||
|
||||
| Parent | Key | Value | Explanation |
|
||||
|-----------------|--------------|----------------------------------------------------------------------------------|------------------------------------------------------------------------------|
|
||||
| (root) | `changelog` | list of keys with this as parent (`git-log` etc) | information on how a changelog is generated |
|
||||
| `changelog` | `enable` | `true`/`false` | If false, no changelog will be generated |
|
||||
| `changelog` | `git-log` | `true`/`false` | should a changelog be generated with `git log`? |
|
||||
| (root) | `uses` | list of keys with this as parent (`cargo` etc) | Marks features to be used by Autocrate |
|
||||
| `uses` | `cargo` | list of keys with this as parent (`publish` etc) | tells us that your project uses cargo |
|
||||
| `cargo` | `publish` | `true`/`false` | should we publish crates? |
|
||||
| `cargo` | `registries` | registries see [this](https://doc.rust-lang.org/cargo/reference/registries.html) | A list of registries we should publish to. If empty defaults to `crates.io`. |
|
||||
| (root) | `api` | list of names, which each have the same keys | defines the api we talk to |
|
||||
| `api.NAME` | `type` | one of `gitea`,`github`,`gitlab` (currently only support for `gitea` | Let's us know which api type we are talking to |
|
||||
| `api.NAME` | `endpoint` | Base URL of the target server | Let's us know which api type we are talking to |
|
||||
| `api.NAME` | `auth` | list of keys with this as parent (`user` and `pass`) | We probably need authentication on the target server |
|
||||
| `api.NAME.auth` | `user` | a string | Which user should we try to authenticate as |
|
||||
| `api.NAME.auth` | `pass` | a string | A secret for authentication o the server, probably a token |
|
||||
| Parent | Key | Value | Explanation |
|
||||
|----------------------|--------------|----------------------------------------------------------------------------------|------------------------------------------------------------------------------|
|
||||
| (root) | `changelog` | list of keys with this as parent (`git-log` etc) | information on how a changelog is generated |
|
||||
| `changelog` | `enable` | `true`/`false` | If false, no changelog will be generated |
|
||||
| `changelog` | `git-log` | `true`/`false` | should a changelog be generated with `git log`? |
|
||||
| (root) | `uses` | list of keys with this as parent (`cargo` etc) | Marks features to be used by Autocrate |
|
||||
| `uses` | `cargo` | list of keys with this as parent (`publish` etc) | tells us that your project uses cargo |
|
||||
| `cargo` | `publish` | `true`/`false` | should we publish crates? |
|
||||
| `cargo` | `registries` | registries see [this](https://doc.rust-lang.org/cargo/reference/registries.html) | A list of registries we should publish to. If empty defaults to `crates.io`. |
|
||||
| (root) | `api` | list of names, which each have the same keys | defines the api we talk to |
|
||||
| `api.NAME` | `type` | one of `gitea`,`github`,`gitlab` (currently only support for `gitea` | Let's us know which api type we are talking to |
|
||||
| `api.NAME` | `endpoint` | Base URL of the target server | Let's us know which api type we are talking to |
|
||||
| `api.NAME` | `auth` | list of keys with this as parent (`user` and `pass`) | We probably need authentication on the target server |
|
||||
| `api.NAME.auth` | `user` | a string | Which user should we try to authenticate as |
|
||||
| `api.NAME.auth` | `pass` | contains either of `text`, `env` or `file` | sets the secret for authentication with this server |
|
||||
| `api.NAME.auth.pass` | `text` | a authentication pass as clear text | A secret for authentication of the server, probably a token |
|
||||
| `api.NAME.auth.pass` | `env` | env var which contains the token | A secret for authentication of the server, probably a token |
|
||||
| `api.NAME.auth.pass` | `file` | file var which contains the token | A secret for authentication of the server, probably a token |
|
||||
|
||||
An example `.autocrate.yaml` could look like this:
|
||||
|
||||
|
@ -102,13 +105,15 @@ api:
|
|||
endpoint: https://github.com
|
||||
auth:
|
||||
user: PlexSheep
|
||||
pass: token_superimportantsecret
|
||||
pass:
|
||||
text: token_superimportantsecret
|
||||
cscherr:
|
||||
type: gitea
|
||||
endpoint: https://git.cscherr.de
|
||||
auth:
|
||||
user: PlexSheep
|
||||
pass: Bearer importantsecrettoken
|
||||
pass:
|
||||
file: secrettoken.txt
|
||||
```
|
||||
|
||||
After Autocrate has been bootstrapped, you it will be released and published
|
||||
|
|
|
@ -38,6 +38,7 @@ pub struct Cli {
|
|||
#[derive(Debug, Clone, Subcommand)]
|
||||
pub enum Commands {
|
||||
Changelog {},
|
||||
/// Create a new release on the server
|
||||
Release {
|
||||
// FIXME: allow taking a message like this:
|
||||
// `autocrate changelog -m arg1 arg2 arg3`
|
||||
|
@ -55,15 +56,26 @@ pub enum Commands {
|
|||
//
|
||||
// TODO:
|
||||
// integrate a CHANGELOG.md file
|
||||
//
|
||||
/// Message body of the release
|
||||
#[arg(short, long)]
|
||||
message: Option<Vec<String>>,
|
||||
|
||||
/// generate and add a changelog
|
||||
changelog: bool,
|
||||
|
||||
/// publish after releasing
|
||||
publish: bool,
|
||||
},
|
||||
/// Publish to a package registry
|
||||
Publish {
|
||||
// see Commands::Release { message }
|
||||
#[arg(short, long)]
|
||||
message: Option<Vec<String>>,
|
||||
},
|
||||
///
|
||||
Version {},
|
||||
Init {},
|
||||
}
|
||||
|
||||
impl Display for Commands {
|
||||
|
@ -76,6 +88,7 @@ impl Display for Commands {
|
|||
Self::Release { .. } => "Release",
|
||||
Self::Publish { .. } => "Publish",
|
||||
Self::Version { .. } => "Version",
|
||||
Self::Init { .. } => "Init",
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
@ -9,8 +9,8 @@ use crate::error::*;
|
|||
|
||||
pub mod cli;
|
||||
pub mod packages;
|
||||
use packages::*;
|
||||
use cli::Cli;
|
||||
use packages::*;
|
||||
|
||||
pub trait YamlConfigSection: Debug + Clone + for<'a> Deserialize<'a> {
|
||||
fn check(&self) -> Result<()>;
|
||||
|
@ -50,25 +50,56 @@ impl YamlConfigSection for Uses {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
pub enum Pass {
|
||||
/// pass specified as plainext
|
||||
Text(String),
|
||||
/// pass to be loaded from an env var
|
||||
Env(String),
|
||||
/// pass to be loaded from a file
|
||||
File(PathBuf),
|
||||
}
|
||||
impl Pass {
|
||||
/// Get the pass, extracting from the underlying source
|
||||
fn get_pass(&self) -> Result<String> {
|
||||
self.check()?;
|
||||
Ok(match self {
|
||||
Self::Text(pass) => pass.clone(),
|
||||
Self::Env(key) => std::env::var(key).map_err(|err| ConfigError::from(err))?,
|
||||
Self::File(file) => std::fs::read_to_string(file)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
impl YamlConfigSection for Pass {
|
||||
fn check(&self) -> Result<()> {
|
||||
match self {
|
||||
Self::Text(_) => (),
|
||||
Self::Env(envvar) => {
|
||||
if !std::env::var(envvar)
|
||||
.map_err(ConfigError::from)?
|
||||
.is_empty()
|
||||
{
|
||||
} else {
|
||||
return Err(ConfigError::EnvNotSet(envvar.clone()).into());
|
||||
}
|
||||
}
|
||||
Self::File(file) => {
|
||||
if !file.exists() {
|
||||
return Err(ConfigError::PassFileDoesNotExist(file.clone()).into());
|
||||
}
|
||||
}
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
pub struct ApiAuth {
|
||||
pub user: String,
|
||||
pub pass: Option<String>,
|
||||
pub pass_file: Option<PathBuf>,
|
||||
pub pass: Pass,
|
||||
}
|
||||
impl YamlConfigSection for ApiAuth {
|
||||
fn check(&self) -> Result<()> {
|
||||
if self.pass.is_some() && self.pass_file.is_some() {
|
||||
let err = ConfigError::YamlApiAuthBothPass(self.clone()).into();
|
||||
error!("{err}");
|
||||
return Err(err);
|
||||
}
|
||||
if self.pass_file.is_some() {
|
||||
let file = self.pass_file.clone().unwrap();
|
||||
if !file.exists() {
|
||||
return Err(ConfigError::PassFileDoesNotExist(file).into());
|
||||
}
|
||||
}
|
||||
self.pass.check()?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use std::{path::PathBuf, process::ExitStatus, string::FromUtf8Error};
|
||||
use std::{env::VarError, path::PathBuf, process::ExitStatus, string::FromUtf8Error};
|
||||
|
||||
use anyhow;
|
||||
use thiserror::Error;
|
||||
|
@ -45,4 +45,8 @@ pub enum ConfigError {
|
|||
YamlApiAuthBothPass(ApiAuth),
|
||||
#[error("password provided as file, but does not exist: {0}")]
|
||||
PassFileDoesNotExist(PathBuf),
|
||||
#[error("config requires environment variable {0}, but {0} is not set")]
|
||||
EnvNotSet(String),
|
||||
#[error("Bad value for environment variable: {0}")]
|
||||
BadEnv(#[from] VarError),
|
||||
}
|
||||
|
|
|
@ -32,6 +32,10 @@ async fn main() -> Result<()> {
|
|||
// TODO: version select automated
|
||||
todo!()
|
||||
}
|
||||
Commands::Init { .. } => {
|
||||
// TODO: create a basic autocrate yaml
|
||||
todo!()
|
||||
}
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{config::Config, error::*, serverapi::ApiCollection};
|
||||
|
||||
pub async fn release(_cfg: &Config, _apis: &mut ApiCollection) -> Result<()> {
|
||||
pub async fn release(cfg: &Config, apis: &mut ApiCollection) -> Result<()> {
|
||||
// TODO: git tag
|
||||
// TODO: push to each server
|
||||
|
||||
|
|
|
@ -15,9 +15,13 @@ impl ServerApi for Forgejo {
|
|||
async fn push_release(&mut self) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
async fn push_release_artifact(&mut self) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
async fn push_pkg(&mut self, pkg_type: PackageType) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl Forgejo {
|
||||
|
|
|
@ -15,6 +15,9 @@ impl ServerApi for Gitea {
|
|||
async fn push_release(&mut self) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
async fn push_release_artifact(&mut self) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
async fn push_pkg(&mut self, pkg_type: PackageType) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
|
|
|
@ -15,6 +15,9 @@ impl ServerApi for Github {
|
|||
async fn push_release(&mut self) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
async fn push_release_artifact(&mut self) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
async fn push_pkg(&mut self, pkg_type: PackageType) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
|
|
|
@ -15,6 +15,9 @@ impl ServerApi for Gitlab {
|
|||
async fn push_release(&mut self) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
async fn push_release_artifact(&mut self) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
async fn push_pkg(&mut self, pkg_type: PackageType) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue