support pulling, refactor git module
This commit is contained in:
parent
2c098d4f23
commit
bc608f7ddc
|
@ -11,10 +11,11 @@ pub(crate) async fn run(
|
||||||
let repo = git2::Repository::open(".")?;
|
let repo = git2::Repository::open(".")?;
|
||||||
let tag = tag.unwrap_or(version::read_version("VERSION".into())?);
|
let tag = tag.unwrap_or(version::read_version("VERSION".into())?);
|
||||||
let desc = changelog::read(fname.clone(), tag.clone())?;
|
let desc = changelog::read(fname.clone(), tag.clone())?;
|
||||||
|
let sig = git2::Signature::now(&common.username, &common.email)?;
|
||||||
|
|
||||||
if !git::has_tag(&repo, tag.clone())? {
|
if !git::has_tag(&repo, tag.clone())? {
|
||||||
git::tag_version(&repo, tag.clone(), desc.clone())?;
|
git::tag_version(&repo, tag.clone(), desc.clone(), &sig)?;
|
||||||
let _ = git::push_tags(&repo);
|
let _ = git::push(&repo, common.token.clone(), git::TAGS);
|
||||||
} else
|
} else
|
||||||
/* The tag already exists */
|
/* The tag already exists */
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,18 +9,30 @@ pub(crate) struct Common {
|
||||||
/// The gitea server to connect to
|
/// The gitea server to connect to
|
||||||
#[structopt(short, long, env = "GITEA_SERVER")]
|
#[structopt(short, long, env = "GITEA_SERVER")]
|
||||||
pub server: String,
|
pub server: String,
|
||||||
|
|
||||||
/// The gitea token to authenticate with
|
/// The gitea token to authenticate with
|
||||||
#[structopt(long, env = "GITEA_TOKEN")]
|
#[structopt(long, env = "GITEA_TOKEN")]
|
||||||
pub token: String,
|
pub token: String,
|
||||||
|
|
||||||
/// The gitea user to authenticate as
|
/// The gitea user to authenticate as
|
||||||
#[structopt(short, long, env = "GITEA_AUTH_USER")]
|
#[structopt(short, long, env = "GITEA_AUTH_USER")]
|
||||||
pub auth_user: String,
|
pub auth_user: String,
|
||||||
|
|
||||||
/// The owner of the gitea repo
|
/// The owner of the gitea repo
|
||||||
#[structopt(short, long, env = "GITEA_OWNER")]
|
#[structopt(short, long, env = "GITEA_OWNER")]
|
||||||
pub owner: String,
|
pub owner: String,
|
||||||
|
|
||||||
/// The gitea repo to operate on
|
/// The gitea repo to operate on
|
||||||
#[structopt(short, long, env = "GITEA_REPO")]
|
#[structopt(short, long, env = "GITEA_REPO")]
|
||||||
pub repo: String,
|
pub repo: String,
|
||||||
|
|
||||||
|
/// Git signature email
|
||||||
|
#[structopt(long, short = "E", env = "SIGNATURE_EMAIL", default_value = "domo@tulpa.dev")]
|
||||||
|
pub email: String,
|
||||||
|
|
||||||
|
/// Git signature username
|
||||||
|
#[structopt(long, short = "U", env = "SIGNATURE_NAME", default_value = "Domo Arigato")]
|
||||||
|
pub username: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(StructOpt, Debug, Clone)]
|
#[derive(StructOpt, Debug, Clone)]
|
||||||
|
@ -29,12 +41,15 @@ pub(crate) struct DroneEnv {
|
||||||
/// push URL
|
/// push URL
|
||||||
#[structopt(long, env = "DRONE_GIT_HTTP_URL")]
|
#[structopt(long, env = "DRONE_GIT_HTTP_URL")]
|
||||||
pub push_url: String,
|
pub push_url: String,
|
||||||
|
|
||||||
/// repo owner
|
/// repo owner
|
||||||
#[structopt(long, env = "DRONE_REPO_OWNER")]
|
#[structopt(long, env = "DRONE_REPO_OWNER")]
|
||||||
pub owner: String,
|
pub owner: String,
|
||||||
|
|
||||||
/// repo name
|
/// repo name
|
||||||
#[structopt(long, env = "DRONE_REPO_NAME")]
|
#[structopt(long, env = "DRONE_REPO_NAME")]
|
||||||
pub repo: String,
|
pub repo: String,
|
||||||
|
|
||||||
/// branch
|
/// branch
|
||||||
#[structopt(long, env = "DRONE_REPO_BRANCH")]
|
#[structopt(long, env = "DRONE_REPO_BRANCH")]
|
||||||
pub branch: String,
|
pub branch: String,
|
||||||
|
@ -43,18 +58,30 @@ pub(crate) struct DroneEnv {
|
||||||
/// auth username
|
/// auth username
|
||||||
#[structopt(long, env = "PLUGIN_AUTH_USERNAME")]
|
#[structopt(long, env = "PLUGIN_AUTH_USERNAME")]
|
||||||
pub auth_user: String,
|
pub auth_user: String,
|
||||||
|
|
||||||
/// Gitea server
|
/// Gitea server
|
||||||
#[structopt(long, env = "PLUGIN_GITEA_SERVER")]
|
#[structopt(long, env = "PLUGIN_GITEA_SERVER")]
|
||||||
pub server: String,
|
pub server: String,
|
||||||
|
|
||||||
/// Gitea token
|
/// Gitea token
|
||||||
#[structopt(long, env = "PLUGIN_GITEA_TOKEN")]
|
#[structopt(long, env = "PLUGIN_GITEA_TOKEN")]
|
||||||
pub token: String,
|
pub token: String,
|
||||||
|
|
||||||
/// CHANGELOG path
|
/// CHANGELOG path
|
||||||
#[structopt(long, env = "PLUGIN_CHANGELOG_PATH", default_value = "./CHANGELOG.md")]
|
#[structopt(long, env = "PLUGIN_CHANGELOG_PATH", default_value = "./CHANGELOG.md")]
|
||||||
pub changelog_path: PathBuf,
|
pub changelog_path: PathBuf,
|
||||||
|
|
||||||
/// Default branch name
|
/// Default branch name
|
||||||
#[structopt(long, env = "PLUGIN_DEFAULT_BRANCH")]
|
#[structopt(long, env = "PLUGIN_DEFAULT_BRANCH")]
|
||||||
pub default_branch: Option<String>,
|
pub default_branch: Option<String>,
|
||||||
|
|
||||||
|
/// Git signature email
|
||||||
|
#[structopt(long, short = "E", env = "PLUGIN_SIGNATURE_EMAIL", default_value = "domo@tulpa.dev")]
|
||||||
|
pub email: String,
|
||||||
|
|
||||||
|
/// Git signature username
|
||||||
|
#[structopt(long, short = "U", env = "PLUGIN_SIGNATURE_NAME", default_value = "Domo Arigato")]
|
||||||
|
pub username: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<Common> for DroneEnv {
|
impl Into<Common> for DroneEnv {
|
||||||
|
@ -65,6 +92,8 @@ impl Into<Common> for DroneEnv {
|
||||||
auth_user: self.auth_user,
|
auth_user: self.auth_user,
|
||||||
owner: self.owner,
|
owner: self.owner,
|
||||||
repo: self.repo,
|
repo: self.repo,
|
||||||
|
email: self.email,
|
||||||
|
username: self.username,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
84
src/git.rs
84
src/git.rs
|
@ -1,22 +1,77 @@
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use git2::{Repository, Signature};
|
use git2::{Repository, Signature};
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
pub(crate) fn push_tags(repo: &Repository) -> Result<()> {
|
pub const TAGS: &'static [&'static str] = &["refs/tags/*:refs/tags/*"];
|
||||||
|
|
||||||
|
pub fn pull(repo: &Repository, token: String, what: &[&str]) -> Result<()> {
|
||||||
let mut remote = repo.find_remote("origin")?;
|
let mut remote = repo.find_remote("origin")?;
|
||||||
remote.connect(git2::Direction::Push)?;
|
let mut fo = git2::FetchOptions::new();
|
||||||
remote.push(&["refs/tags/*:refs/tags/*"], None)?;
|
|
||||||
|
let mut callbacks = git2::RemoteCallbacks::new();
|
||||||
|
callbacks.credentials(|_u, _username, allowed_types| {
|
||||||
|
if allowed_types.contains(git2::CredentialType::SSH_KEY) {
|
||||||
|
let user = "git";
|
||||||
|
git2::Cred::ssh_key_from_agent(user)
|
||||||
|
} else {
|
||||||
|
git2::Cred::userpass_plaintext(&token, "")
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
fo.remote_callbacks(callbacks);
|
||||||
|
|
||||||
|
remote.connect(git2::Direction::Fetch)?;
|
||||||
|
remote.fetch(what, Some(&mut fo), None)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn tag_version(repo: &Repository, tag: String, desc: String) -> Result<()> {
|
pub fn push(repo: &Repository, token: String, what: &[&str]) -> Result<()> {
|
||||||
let sig = &Signature::now("Gitea Release Tool", "gitea-release@tulpa.dev")?;
|
let mut remote = repo.find_remote("origin")?;
|
||||||
|
let mut po = git2::PushOptions::new();
|
||||||
|
|
||||||
|
let mut callbacks = git2::RemoteCallbacks::new();
|
||||||
|
callbacks.credentials(|_u, _username, allowed_types| {
|
||||||
|
if allowed_types.contains(git2::CredentialType::SSH_KEY) {
|
||||||
|
let user = "git";
|
||||||
|
git2::Cred::ssh_key_from_agent(user)
|
||||||
|
} else {
|
||||||
|
git2::Cred::userpass_plaintext(&token, "")
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
po.remote_callbacks(callbacks);
|
||||||
|
|
||||||
|
remote.connect(git2::Direction::Push)?;
|
||||||
|
remote.push(what, Some(&mut po))?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn commit(
|
||||||
|
repo: &Repository,
|
||||||
|
sig: &git2::Signature,
|
||||||
|
msg: &str,
|
||||||
|
files: &[&str],
|
||||||
|
) -> Result<()> {
|
||||||
|
let mut index = repo.index()?;
|
||||||
|
for file in files {
|
||||||
|
index.add_path(Path::new(file))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let oid = index.write_tree()?;
|
||||||
|
let tree = repo.find_tree(oid)?;
|
||||||
|
repo.commit(Some("HEAD"), &sig, &sig, &msg, &tree, &[])?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tag_version(repo: &Repository, tag: String, desc: String, sig: &git2::Signature) -> Result<()> {
|
||||||
let obj = repo.revparse_single("HEAD")?;
|
let obj = repo.revparse_single("HEAD")?;
|
||||||
repo.tag(&tag, &obj, &sig, &desc, false)?;
|
repo.tag(&tag, &obj, &sig, &desc, false)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn has_tag(repo: &Repository, tag: String) -> Result<bool> {
|
pub fn has_tag(repo: &Repository, tag: String) -> Result<bool> {
|
||||||
let tags = repo.tag_names(Some(&tag))?;
|
let tags = repo.tag_names(Some(&tag))?;
|
||||||
|
|
||||||
for tag_obj in tags.iter() {
|
for tag_obj in tags.iter() {
|
||||||
|
@ -37,7 +92,7 @@ pub(crate) fn has_tag(repo: &Repository, tag: String) -> Result<bool> {
|
||||||
mod tests {
|
mod tests {
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use git2::*;
|
use git2::*;
|
||||||
use std::{fs::File, io::Write, path::Path};
|
use std::{fs::File, io::Write};
|
||||||
use tempfile::tempdir;
|
use tempfile::tempdir;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -48,22 +103,11 @@ mod tests {
|
||||||
let mut fout = File::create(&dir.path().join("VERSION"))?;
|
let mut fout = File::create(&dir.path().join("VERSION"))?;
|
||||||
write!(fout, "{}", TAG)?;
|
write!(fout, "{}", TAG)?;
|
||||||
drop(fout);
|
drop(fout);
|
||||||
let mut index = repo.index()?;
|
|
||||||
index.add_path(Path::new("VERSION"))?;
|
|
||||||
let oid = index.write_tree()?;
|
|
||||||
let tree = repo.find_tree(oid)?;
|
|
||||||
|
|
||||||
let sig = &Signature::now("Gitea Release Tool", "gitea-release@tulpa.dev")?;
|
let sig = &Signature::now("Gitea Release Tool", "gitea-release@tulpa.dev")?;
|
||||||
repo.commit(
|
super::commit(&repo, &sig, "test commit please ignore", &["VERSION"])?;
|
||||||
Some("HEAD"),
|
|
||||||
&sig,
|
|
||||||
&sig,
|
|
||||||
"test commit please ignore",
|
|
||||||
&tree,
|
|
||||||
&[],
|
|
||||||
)?;
|
|
||||||
|
|
||||||
super::tag_version(&repo, TAG.into(), format!("version {}", TAG))?;
|
super::tag_version(&repo, TAG.into(), format!("version {}", TAG), &sig)?;
|
||||||
assert!(super::has_tag(&repo, TAG.into())?);
|
assert!(super::has_tag(&repo, TAG.into())?);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
Loading…
Reference in New Issue