feat: versionnement automatique basé sur git (build number + hash)
- build.rs génère version dynamique : X.Y.Z+build.N-abc1234 - Version injectée dans l'API (IMAGOD_BUILD_VERSION) et pages HTML - Suffixe -dirty si modifications non commitées - replace_all_versions() consomme le suffixe build metadata - Suppression auto-changelog — reste manuel pour contrôle qualité
This commit is contained in:
@@ -3,14 +3,21 @@
|
||||
//! Exécuté à chaque `cargo build`. Garantit que :
|
||||
//! 1. changelog.html est généré depuis CHANGELOG.md
|
||||
//! 2. help.html est généré depuis ROADMAP.md
|
||||
//! 3. Le badge version dans index.html suit la version Cargo.toml
|
||||
//! 3. Le badge version dans index.html suit la version calculée
|
||||
//! 4. La version est auto-générée : base Cargo.toml + compteur commits git
|
||||
//! 5. CHANGELOG.md reçoit une entrée vide pour la nouvelle version si absente
|
||||
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
use std::process::Command;
|
||||
|
||||
fn main() {
|
||||
let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
|
||||
let version = env!("CARGO_PKG_VERSION");
|
||||
let base_version = env!("CARGO_PKG_VERSION");
|
||||
|
||||
// Version dynamique = version de base + numéro de build (compteur commits git)
|
||||
let version = compute_version(base_version, manifest_dir);
|
||||
|
||||
let frontend_dir = manifest_dir.join("src/frontend");
|
||||
|
||||
// === changelog.html depuis CHANGELOG.md ===
|
||||
@@ -23,7 +30,7 @@ fn main() {
|
||||
let html = simple_md_to_html(&md);
|
||||
let tmpl = fs::read_to_string(&changelog_tmpl).unwrap_or_default();
|
||||
let page = tmpl
|
||||
.replace("{{VERSION}}", version)
|
||||
.replace("{{VERSION}}", &version)
|
||||
.replace("{{CHANGELOG_CONTENT}}", &html);
|
||||
fs::write(&changelog_out, &page).ok();
|
||||
println!("cargo:rerun-if-changed=CHANGELOG.md");
|
||||
@@ -40,7 +47,7 @@ fn main() {
|
||||
let html = simple_md_to_html(&md);
|
||||
let tmpl = fs::read_to_string(&help_tmpl).unwrap_or_default();
|
||||
let page = tmpl
|
||||
.replace("{{VERSION}}", version)
|
||||
.replace("{{VERSION}}", &version)
|
||||
.replace("{{HELP_CONTENT}}", &html);
|
||||
fs::write(&help_out, &page).ok();
|
||||
println!("cargo:rerun-if-changed=ROADMAP.md");
|
||||
@@ -52,12 +59,64 @@ fn main() {
|
||||
if index_path.exists() {
|
||||
let mut content = fs::read_to_string(&index_path).unwrap_or_default();
|
||||
// Remplacer tous les badges de version vX.Y.Z par la version courante
|
||||
content = replace_all_versions(&content, version);
|
||||
content = replace_all_versions(&content, &version);
|
||||
fs::write(&index_path, &content).ok();
|
||||
println!("cargo:rerun-if-changed=src/frontend/index.html");
|
||||
}
|
||||
|
||||
println!("cargo:info=✅ Pages HTML générées pour imagod-web v{version}");
|
||||
// Injecter la version dynamique dans le code Rust (utilisable via env!("IMAGOD_BUILD_VERSION"))
|
||||
println!("cargo:rustc-env=IMAGOD_BUILD_VERSION={version}");
|
||||
}
|
||||
|
||||
/// Calcule la version dynamique : base + compteur de commits git
|
||||
fn compute_version(base: &str, manifest_dir: &Path) -> String {
|
||||
// Récupérer le compteur de commits
|
||||
let commit_count = Command::new("git")
|
||||
.args(["rev-list", "--count", "HEAD"])
|
||||
.current_dir(manifest_dir)
|
||||
.output()
|
||||
.ok()
|
||||
.and_then(|o| String::from_utf8(o.stdout).ok())
|
||||
.map(|s| s.trim().to_string())
|
||||
.unwrap_or_else(|| "0".to_string());
|
||||
|
||||
// Récupérer le hash court du commit
|
||||
let short_hash = Command::new("git")
|
||||
.args(["rev-parse", "--short=7", "HEAD"])
|
||||
.current_dir(manifest_dir)
|
||||
.output()
|
||||
.ok()
|
||||
.and_then(|o| String::from_utf8(o.stdout).ok())
|
||||
.map(|s| s.trim().to_string())
|
||||
.unwrap_or_else(|| "unknown".to_string());
|
||||
|
||||
// Vérifier si le working tree est dirty
|
||||
let dirty = Command::new("git")
|
||||
.args(["diff", "--quiet"])
|
||||
.current_dir(manifest_dir)
|
||||
.status()
|
||||
.map(|s| !s.success())
|
||||
.unwrap_or(false);
|
||||
|
||||
let suffix = if dirty { "-dirty" } else { "" };
|
||||
|
||||
format!("{}+build.{}-{}{}", base, commit_count, short_hash, suffix)
|
||||
}
|
||||
|
||||
/// Module minimal pour la date du jour (zéro dépendance externe)
|
||||
mod chrono_lite {
|
||||
use std::process::Command;
|
||||
|
||||
pub fn today() -> String {
|
||||
Command::new("date")
|
||||
.args(["+%d %B %Y"])
|
||||
.output()
|
||||
.ok()
|
||||
.and_then(|o| String::from_utf8(o.stdout).ok())
|
||||
.map(|s| s.trim().to_string())
|
||||
.unwrap_or_else(|| "Date inconnue".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
/// Mini convertisseur Markdown → HTML (zéro dépendance)
|
||||
@@ -293,6 +352,13 @@ fn replace_all_versions(html: &str, version: &str) -> String {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Consommer le suffixe build metadata (+ ou - suivi d'alphanum/dots/tirets)
|
||||
while j < chars.len() && (chars[j] == '+' || chars[j] == '-') {
|
||||
j += 1;
|
||||
while j < chars.len() && (chars[j].is_alphanumeric() || chars[j] == '.' || chars[j] == '-') {
|
||||
j += 1;
|
||||
}
|
||||
}
|
||||
if dots >= 1 {
|
||||
// C'est une version — remplacer
|
||||
result.push_str(&format!("v{version}"));
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Changelog — imagod-web v0.2.0</title>
|
||||
<title>Changelog — imagod-web v0.2.0+build.21-e867dad-dirty</title>
|
||||
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🖼️</text></svg>">
|
||||
<style>
|
||||
* { margin:0; padding:0; box-sizing:border-box; }
|
||||
@@ -37,7 +37,7 @@ footer { text-align:center; color:#484f58; font-size:0.8rem; padding:2rem; }
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1>📋 imagod-web <span class="version-badge">v0.2.0</span></h1>
|
||||
<h1>📋 imagod-web <span class="version-badge">v0.2.0+build.21-e867dad-dirty</span></h1>
|
||||
<nav>
|
||||
<a href="/">🖼️ Galerie</a>
|
||||
<a href="/changelog" class="active">📋 Changelog</a>
|
||||
@@ -107,6 +107,6 @@ footer { text-align:center; color:#484f58; font-size:0.8rem; padding:2rem; }
|
||||
<h2>Légende des tags</h2>
|
||||
|
||||
</main>
|
||||
<footer>imagod-web v0.2.0 — <a href="https://git.dracodev.net/Projets/imagod-web">Gitea</a></footer>
|
||||
<footer>imagod-web v0.2.0+build.21-e867dad-dirty — <a href="https://git.dracodev.net/Projets/imagod-web">Gitea</a></footer>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Aide & Roadmap — imagod-web v0.2.0</title>
|
||||
<title>Aide & Roadmap — imagod-web v0.2.0+build.21-e867dad-dirty</title>
|
||||
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🖼️</text></svg>">
|
||||
<style>
|
||||
* { margin:0; padding:0; box-sizing:border-box; }
|
||||
@@ -37,7 +37,7 @@ footer { text-align:center; color:#484f58; font-size:0.8rem; padding:2rem; }
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1>❓ imagod-web <span class="version-badge">v0.2.0</span></h1>
|
||||
<h1>❓ imagod-web <span class="version-badge">v0.2.0+build.21-e867dad-dirty</span></h1>
|
||||
<nav>
|
||||
<a href="/">🖼️ Galerie</a>
|
||||
<a href="/changelog">📋 Changelog</a>
|
||||
@@ -169,6 +169,6 @@ footer { text-align:center; color:#484f58; font-size:0.8rem; padding:2rem; }
|
||||
<p>5. <strong>Corriger le backend Imago</strong> (thumbnails, upload, stockage)</p>
|
||||
|
||||
</main>
|
||||
<footer>imagod-web v0.2.0 — <a href="https://git.dracodev.net/Projets/imagod-web">Gitea</a></footer>
|
||||
<footer>imagod-web v0.2.0+build.21-e867dad-dirty — <a href="https://git.dracodev.net/Projets/imagod-web">Gitea</a></footer>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -465,7 +465,7 @@
|
||||
<button class="btn" id="clear-btn" style="display:none">✕</button>
|
||||
</div>
|
||||
<button class="btn accent" id="header-upload-btn" onclick="document.getElementById('drop-zone').scrollIntoView({behavior:'smooth'}); document.getElementById('file-input').click()">📤 Upload</button>
|
||||
<span class="version-badge" id="version-badge">v0.2.0</span>
|
||||
<span class="version-badge" id="version-badge">v0.2.0+build.21-e867dad-dirty</span>
|
||||
</div>
|
||||
|
||||
<!-- ─── Navigation ─── -->
|
||||
|
||||
@@ -118,7 +118,7 @@ async fn health_check() -> &'static str {
|
||||
/// Retourne la version de l'application et des infos utiles
|
||||
async fn version() -> Json<serde_json::Value> {
|
||||
Json(serde_json::json!({
|
||||
"version": env!("CARGO_PKG_VERSION"),
|
||||
"version": env!("IMAGOD_BUILD_VERSION"),
|
||||
"name": env!("CARGO_PKG_NAME"),
|
||||
"description": env!("CARGO_PKG_DESCRIPTION"),
|
||||
"repository": env!("CARGO_PKG_REPOSITORY"),
|
||||
|
||||
Reference in New Issue
Block a user