rlyx 0.3.1

rlyx is a fast release manager that automatically bumps versions, creates changelogs, tags commits, and publishes GitHub releases across JS, Rust, and Python projects with first class monorepos support.
Documentation
use crate::{git, ui};
use anyhow::{anyhow, Result};

fn looks_like_release_commit(s: &str) -> bool {
    let ls = s.to_ascii_lowercase();
    ls.contains("bump")
        || ls.contains("release")
        || ls.starts_with("docs(changelog):")
}

pub async fn run(_owner_repo: &str, remote: bool) -> Result<()> {
    ui::section("rollback");

    let tags_at_head = git::tags_pointing_at_head();
    if tags_at_head.is_empty() {
        ui::info("no tag at head");
    } else {
        for t in &tags_at_head {
            ui::info(&format!("tag at head: {}", t));
        }
    }

    let last = git::last_commit_subject().unwrap_or_default();
    ui::info(&format!("last commit: {}", last));

    if remote {
        for t in &tags_at_head {
            let _ = git::delete_remote_tag(t);
        }
        if !tags_at_head.is_empty() {
            ui::ok("remote tags removed if they existed");
        }
    }

    for t in &tags_at_head {
        let _ = git::delete_local_tag(t);
        ui::ok(&format!("deleted local tag {}", t));
    }

    let mut popped = 0usize;
    if looks_like_release_commit(&last) {
        git::reset_hard("HEAD^")?;
        popped += 1;
        ui::ok("reverted last release commit");
        let second = git::last_commit_subject().unwrap_or_default();
        if looks_like_release_commit(&second) {
            git::reset_hard("HEAD^")?;
            popped += 1;
            ui::ok("reverted secondary release commit");
        }
    } else {
        ui::warn(
            "last commit does not look like a release commit; no reset done",
        );
    }

    if remote && popped > 0 {
        if let Some(_br) = git::current_branch() {
            git::push_force_with_lease()?;
            ui::ok("forced branch update to remote");
        } else {
            return Err(anyhow!(
                "failed to detect current branch for remote push"
            ));
        }
    }

    ui::ok("rollback completed");
    Ok(())
}