diff --git a/Cargo.lock b/Cargo.lock index ee4bd94..131413a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -341,6 +341,7 @@ dependencies = [ "structopt", "tempfile", "tokio", + "url", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 5df99d0..a0e53c4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ serde_json = "1.0" serde = { version = "1.0", features = ["derive"] } structopt = { version = "0.3", default-features = false } tokio = { version = "0.2", features = ["macros"] } +url = "2" [dev-dependencies] tempfile = "3" diff --git a/TODO.org b/TODO.org index ca94436..d03a939 100644 --- a/TODO.org +++ b/TODO.org @@ -14,6 +14,7 @@ ** DONE upload CLOSED: [2020-05-30 Sat 15:15] +** TODO drone plugin * Core Features ** DONE Gitea API client CLOSED: [2020-05-30 Sat 10:52] diff --git a/src/cmd/drone_plugin.rs b/src/cmd/drone_plugin.rs new file mode 100644 index 0000000..a37a8e1 --- /dev/null +++ b/src/cmd/drone_plugin.rs @@ -0,0 +1,30 @@ +use crate::cmd::*; +use anyhow::Result; +use git2::Repository; +use url::Url; + +pub(crate) async fn run(env: DroneEnv) -> Result<()> { + if env.branch != "master" { + return Ok(()); + } + + let common: Common = env.clone().into(); + let repo = Repository::open(".")?; + let mut u = Url::parse(&env.push_url)?; + u.set_username(&env.auth_user).unwrap(); + u.set_password(Some(&env.token)).unwrap(); + repo.remote_delete("origin")?; + repo.remote("origin", u.as_str())?; + + release::run( + common, + env.changelog_path, + None, + ReleaseMeta { + name: None, + draft: false, + pre_release: false, + }, + ) + .await +} diff --git a/src/cmd/mod.rs b/src/cmd/mod.rs index d82459f..00d4c2b 100644 --- a/src/cmd/mod.rs +++ b/src/cmd/mod.rs @@ -1,6 +1,154 @@ +use std::path::PathBuf; +use structopt::StructOpt; + pub(crate) mod delete; pub(crate) mod download; +pub(crate) mod drone_plugin; pub(crate) mod edit; pub(crate) mod info; pub(crate) mod release; pub(crate) mod upload; + +#[derive(StructOpt, Debug)] +pub(crate) struct Common { + /// The gitea server to connect to + #[structopt(short, long, env = "GITEA_SERVER")] + pub server: String, + /// The gitea token to authenticate with + #[structopt(long, env = "GITEA_TOKEN")] + pub token: String, + /// The gitea user to authenticate as + #[structopt(short, long, env = "GITEA_AUTH_USER")] + pub auth_user: String, + /// The owner of the gitea repo + #[structopt(short, long, env = "GITEA_OWNER")] + pub owner: String, + /// The gitea repo to operate on + #[structopt(short, long, env = "GITEA_REPO")] + pub repo: String, +} + +#[derive(StructOpt, Debug, Clone)] +pub(crate) struct DroneEnv { + /// push URL + #[structopt(env="DRONE_GIT_HTTP_URL")] + pub push_url: String, + /// repo owner + #[structopt(env="DRONE_REPO_OWNER")] + pub owner: String, + /// repo name + #[structopt(env="DRONE_REPO_NAME")] + pub repo: String, + /// auth username + #[structopt(env="AUTH_USERNAME")] + pub auth_user: String, + /// Gitea server + #[structopt(env="GITEA_SERVER")] + pub server: String, + /// Gitea token + #[structopt(env="GITEA_TOKEN")] + pub token: String, + /// CHANGELOG path + #[structopt(env="CHANGELOG_PATH", default_value="./CHANGELOG.md")] + pub changelog_path: PathBuf, + /// branch + #[structopt(env="DRONE_REPO_BRANCH")] + pub branch: String, +} + +impl Into for DroneEnv { + fn into(self) -> Common { + Common { + server: self.server, + token: self.token, + auth_user: self.auth_user, + owner: self.owner, + repo: self.repo, + } + } +} + +#[derive(StructOpt, Debug)] +pub(crate) struct ReleaseMeta { + /// Release name + #[structopt(short, long)] + pub name: Option, + /// Draft release + #[structopt(long)] + pub draft: bool, + /// Pre-release (not suitable for production) + #[structopt(short, long)] + pub pre_release: bool, +} + +#[derive(StructOpt, Debug)] +#[structopt(about = "Gitea release assistant")] +pub(crate) enum Cmd { + /// Delete a given release from Gitea + Delete { + #[structopt(flatten)] + common: Common, + /// The version tag to operate on + #[structopt(short, long)] + tag: String, + }, + /// Downloads release artifacts + Download { + #[structopt(flatten)] + common: Common, + /// File to download + fname: Option, + /// The version tag to operate on + #[structopt(short, long)] + tag: String, + }, + /// Runs the release process as a drone plugin + DronePlugin { + #[structopt(flatten)] + env: DroneEnv, + }, + /// Edits a release's description, name and other flags + Edit { + #[structopt(flatten)] + common: Common, + /// Release description + #[structopt(short, long)] + description: Option, + #[structopt(flatten)] + release_meta: ReleaseMeta, + /// The version tag to operate on + tag: String, + }, + /// Gets release info + Info { + #[structopt(flatten)] + common: Common, + #[structopt(long, short)] + json: bool, + /// The version tag to operate on + #[structopt(short, long)] + tag: Option, + }, + /// Create a new tag and release on Gitea + Release { + #[structopt(flatten)] + common: Common, + /// Changelog file to read from to create the release description + #[structopt(short, long, default_value = "./CHANGELOG.md")] + changelog: PathBuf, + /// The version tag to operate on + tag: Option, + #[structopt(flatten)] + release_meta: ReleaseMeta, + }, + /// Uploads release artifacts to Gitea + Upload { + #[structopt(flatten)] + common: Common, + /// The version tag to operate on + #[structopt(short, long)] + tag: String, + /// The location of the file on the disk + fname: PathBuf, + }, +} diff --git a/src/main.rs b/src/main.rs index bf66167..d7bdaaa 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,29 +9,12 @@ mod git; mod gitea; mod version; -#[derive(StructOpt, Debug)] -pub(crate) struct Common { - /// The gitea server to connect to - #[structopt(short, long, env = "GITEA_SERVER")] - server: String, - /// The gitea token to authenticate with - #[structopt(long, env = "GITEA_TOKEN")] - token: String, - /// The gitea user to authenticate as - #[structopt(short, long, env = "GITEA_AUTH_USER")] - auth_user: String, - /// The owner of the gitea repo - #[structopt(short, long, env = "GITEA_OWNER")] - owner: String, - /// The gitea repo to operate on - #[structopt(short, long, env = "GITEA_REPO")] - repo: String, -} +pub(crate) use cmd::*; // Name your user agent after your app? static APP_USER_AGENT: &str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION")); -pub(crate) fn client(c: &Common) -> Result { +pub(crate) fn client(c: &cmd::Common) -> Result { let mut headers = header::HeaderMap::new(); let auth = format!("token {}", &c.token); let auth = auth.as_str(); @@ -42,94 +25,15 @@ pub(crate) fn client(c: &Common) -> Result { .build()?) } -#[derive(StructOpt, Debug)] -pub(crate) struct ReleaseMeta { - /// Release name - #[structopt(short, long)] - name: Option, - /// Draft release - #[structopt(long)] - draft: bool, - /// Pre-release (not suitable for production) - #[structopt(short, long)] - pre_release: bool, -} - -#[derive(StructOpt, Debug)] -#[structopt(about = "Gitea release assistant")] -pub(crate) enum Cmd { - /// Delete a given release from Gitea - Delete { - #[structopt(flatten)] - common: Common, - /// The version tag to operate on - #[structopt(short, long)] - tag: String, - }, - /// Downloads release artifacts - Download { - #[structopt(flatten)] - common: Common, - /// File to download - fname: Option, - /// The version tag to operate on - #[structopt(short, long)] - tag: String, - }, - /// Edits a release's description, name and other flags - Edit { - #[structopt(flatten)] - common: Common, - /// Release description - #[structopt(short, long)] - description: Option, - #[structopt(flatten)] - release_meta: ReleaseMeta, - /// The version tag to operate on - tag: String, - }, - /// Gets release info - Info { - #[structopt(flatten)] - common: Common, - #[structopt(long, short)] - json: bool, - /// The version tag to operate on - #[structopt(short, long)] - tag: Option, - }, - /// Create a new tag and release on Gitea - Release { - #[structopt(flatten)] - common: Common, - /// Changelog file to read from to create the release description - #[structopt(short, long, default_value = "./CHANGELOG.md")] - changelog: PathBuf, - /// The version tag to operate on - tag: Option, - #[structopt(flatten)] - release_meta: ReleaseMeta, - }, - /// Uploads release artifacts to Gitea - Upload { - #[structopt(flatten)] - common: Common, - /// The version tag to operate on - #[structopt(short, long)] - tag: String, - /// The location of the file on the disk - fname: PathBuf, - }, -} - #[tokio::main] async fn main() -> Result<()> { let _ = kankyo::init(); - let cmd = Cmd::from_args(); + let cmd = cmd::Cmd::from_args(); match cmd { Cmd::Delete { common, tag } => cmd::delete::run(common, tag).await, Cmd::Download { common, fname, tag } => cmd::download::run(common, fname, tag).await, + Cmd::DronePlugin { env } => cmd::drone_plugin::run(env).await, Cmd::Edit { common, description,