bakery: add stable/beta/dev build tracks
Adds a track concept to bakery (separate from the existing bakery/pacman distribution channel): stable (unchanged tag-triggered releases), beta (deliberate beta-v* tag promotion), and dev (published on every push to dev). Each track gets its own signed index + artifact tree under dl.breadway.dev so stable's paths and existing installs are untouched. - bakery: new Track type, a global track preference in installed.json (defaults to stable via serde, no migration needed), `bakery track show`/`set`, a BAKERY_INDEX_BASE_URL override for testing, and a real semver comparison in `update` (was a plain string-equality check before). ANSI-colored/aligned CLI output (TTY + NO_COLOR aware). - gen-index.sh: TRACK env var selects which subtree to read/write. - CI: dev-bakery.yml/beta-bakery.yml/dev-bread-theme.yml/beta-bread-theme.yml publish those two products on the new tracks; dev/beta skip the GitHub Release upload step (no per-commit release spam). - docs/release-channels.md documents the three-track policy.
This commit is contained in:
parent
db2fa3c4b4
commit
4ac54c610d
15 changed files with 771 additions and 67 deletions
60
bakery/src/ui.rs
Normal file
60
bakery/src/ui.rs
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
use crate::track::Track;
|
||||
use std::io::IsTerminal;
|
||||
|
||||
pub const RESET: &str = "\x1b[0m";
|
||||
pub const BOLD: &str = "\x1b[1m";
|
||||
pub const DIM: &str = "\x1b[2m";
|
||||
pub const RED: &str = "\x1b[31m";
|
||||
pub const GREEN: &str = "\x1b[32m";
|
||||
pub const YELLOW: &str = "\x1b[33m";
|
||||
pub const CYAN: &str = "\x1b[36m";
|
||||
pub const MAGENTA: &str = "\x1b[35m";
|
||||
|
||||
/// Colors are on only when stdout is a real terminal and `NO_COLOR` isn't
|
||||
/// set — the ecosystem's existing CLI (breadcrumbs) hardcodes ANSI
|
||||
/// unconditionally, which leaks escape codes into piped/logged output; this
|
||||
/// is the hardening fix for that gap.
|
||||
pub fn colors_enabled() -> bool {
|
||||
std::env::var_os("NO_COLOR").is_none() && std::io::stdout().is_terminal()
|
||||
}
|
||||
|
||||
pub fn style(s: &str, code: &str) -> String {
|
||||
if colors_enabled() {
|
||||
format!("{code}{s}{RESET}")
|
||||
} else {
|
||||
s.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
/// `" [beta]"` / `" [dev]"`, colored — empty string for `Stable` so the
|
||||
/// common-case output is unchanged.
|
||||
pub fn track_badge(track: Track) -> String {
|
||||
match track {
|
||||
Track::Stable => String::new(),
|
||||
Track::Beta => format!(" {}", style("[beta]", YELLOW)),
|
||||
Track::Dev => format!(" {}", style("[dev]", MAGENTA)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ok(s: &str) -> String {
|
||||
style(&format!("✓ {s}"), GREEN)
|
||||
}
|
||||
|
||||
pub fn fail(s: &str) -> String {
|
||||
style(&format!("✗ {s}"), RED)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn stable_badge_is_empty() {
|
||||
assert_eq!(track_badge(Track::Stable), "");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dev_badge_is_nonempty() {
|
||||
assert!(!track_badge(Track::Dev).is_empty());
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue