summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Hofmann <Johannes.Hofmann@gmx.de>2026-10-27 07:55:43 +0100
committerJohannes Hofmann <Johannes.Hofmann@gmx.de>2026-10-27 07:55:47 +0100
commitb899c72b79d2e909abf6230239d3c9377fc58899 (patch)
tree3c84d6eb69a5366d95fc85f04fa92d1ac7345b4d
parent7d31997bd9118351e8a849d2101c5aacc0aae78b (diff)
build: single source of truth for the version
Version now lives only in [workspace.package] in the root Cargo.toml; all three crates inherit it via version.workspace = true (this also fixes gipfel-core, which had drifted to 0.1.0 while the others were 0.5.4). edition/license are inherited the same way. The About dialog now reads env!("CARGO_PKG_VERSION") instead of a hardcoded string. A new test (changelog_top_matches_version) asserts the top gipfel-X.Y.Z entry in ChangeLog equals the crate version, so the manifest, the About dialog and the ChangeLog cannot drift apart. AGENTS.md gains a "Releasing a new version" section documenting the flow (bump workspace version, add ChangeLog entry, tag, git archive source tarball).
-rw-r--r--AGENTS.md29
-rw-r--r--Cargo.lock6
-rw-r--r--Cargo.toml9
-rw-r--r--crates/gipfel-app/Cargo.toml6
-rw-r--r--crates/gipfel-app/src/main.rs24
-rw-r--r--crates/gipfel-cli/Cargo.toml6
-rw-r--r--crates/gipfel-core/Cargo.toml6
7 files changed, 73 insertions, 13 deletions
diff --git a/AGENTS.md b/AGENTS.md
index f8992c7..29a4029 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -123,6 +123,35 @@ models. If you regenerate, re-run the golden tests immediately.
`dirs` + exe-relative) and font fallback, then get libcosmic itself to compile
for `x86_64-pc-windows-gnu` (upstream does not test Windows).
+## Releasing a new version
+
+The version has a **single source of truth**: `[workspace.package] version` in
+the root `Cargo.toml`. All three crates inherit it (`version.workspace = true`),
+and the app's **About dialog** reads it at compile time via
+`env!("CARGO_PKG_VERSION")`. Do **not** hardcode a version anywhere else.
+
+To cut a release `X.Y.Z`:
+
+1. Bump `version` in `[workspace.package]` (root `Cargo.toml`). That updates all
+ three crates and the About dialog at once.
+2. Add a new entry at the **top** of `ChangeLog`:
+ ```
+ gipfel-X.Y.Z
+ * one line per user-visible change
+ ```
+ The test `gipfel-app: changelog_top_matches_version` fails if the top
+ `gipfel-X.Y.Z` line does not equal the crate version, so the manifest and the
+ ChangeLog cannot drift apart.
+3. `cargo test --lib --test golden` (with `GIPFEL_DATA` set) — must be green.
+4. Commit, then tag: `git tag vX.Y.Z`.
+5. Build the **source** tarball (tracked files only, no build artifacts):
+ ```sh
+ git archive --format=tar.gz --prefix=gipfel-X.Y.Z/ \
+ -o ~/gipfel-X.Y.Z.tar.gz vX.Y.Z
+ ```
+ Recipients build with `cargo build --release`. For a fully offline tarball,
+ run `cargo vendor --versioned-dirs vendor/` and commit `vendor/` first.
+
## Do / Don't
- ✅ Run `cargo test --lib --test golden` (with `GIPFEL_DATA` set) after any
diff --git a/Cargo.lock b/Cargo.lock
index 7518c3d..dca1d66 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1744,7 +1744,7 @@ dependencies = [
[[package]]
name = "gipfel-app"
-version = "0.1.0"
+version = "0.5.4"
dependencies = [
"cosmic-text",
"fontdb",
@@ -1757,14 +1757,14 @@ dependencies = [
[[package]]
name = "gipfel-cli"
-version = "0.1.0"
+version = "0.5.4"
dependencies = [
"gipfel-core",
]
[[package]]
name = "gipfel-core"
-version = "0.1.0"
+version = "0.5.4"
dependencies = [
"dirs",
"image",
diff --git a/Cargo.toml b/Cargo.toml
index 3a99088..d293395 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -2,6 +2,15 @@
resolver = "2"
members = ["crates/gipfel-core", "crates/gipfel-cli", "crates/gipfel-app"]
+# Single source of truth for metadata inherited by every crate via
+# `version.workspace = true` etc. Bump `version` here on release; the
+# About dialog and all crates follow. A test enforces the ChangeLog top
+# entry matches this version.
+[workspace.package]
+version = "0.5.4"
+edition = "2021"
+license = "GPL-2.0-or-later"
+
[workspace.dependencies]
kamadak-exif = "0.6"
quick-xml = { version = "0.41", default-features = false }
diff --git a/crates/gipfel-app/Cargo.toml b/crates/gipfel-app/Cargo.toml
index 00cf451..f16f1c0 100644
--- a/crates/gipfel-app/Cargo.toml
+++ b/crates/gipfel-app/Cargo.toml
@@ -1,9 +1,9 @@
[package]
name = "gipfel-app"
-version = "0.5.4"
-edition = "2021"
+version.workspace = true
+edition.workspace = true
description = "gipfel - photogrammetry for mountain images"
-license = "GPL-2.0-or-later"
+license.workspace = true
[[bin]]
name = "gipfel"
diff --git a/crates/gipfel-app/src/main.rs b/crates/gipfel-app/src/main.rs
index 967e68d..12e2845 100644
--- a/crates/gipfel-app/src/main.rs
+++ b/crates/gipfel-app/src/main.rs
@@ -1526,7 +1526,7 @@ impl Gipfel {
fn view_about<'a>(&self) -> Element<'a, Message> {
widget::dialog()
.title("About gipfel")
- .body("gipfel 0.5.4")
+ .body(format!("gipfel {}", env!("CARGO_PKG_VERSION")))
.control(widget::text("Annotate mountain panoramas."))
.control(widget::text("by Johannes Hofmann")) .primary_action(widget::button::suggested("Close").on_press(Message::About(false)))
.is_overlay(false)
@@ -1802,4 +1802,26 @@ mod tests {
let (_, y_back) = pan.project_point(0.0, top).unwrap();
assert!((y_back + 100.0).abs() < 0.01);
}
+
+ /// Release drift guard: the top `gipfel-X.Y.Z` entry in the ChangeLog must
+ /// match the crate version (inherited from `[workspace.package]`). This
+ /// catches a bump of one but not the other. The About dialog reads the same
+ /// `CARGO_PKG_VERSION`, so all three stay in lockstep.
+ #[test]
+ fn changelog_top_matches_version() {
+ let path = concat!(env!("CARGO_MANIFEST_DIR"), "/../../ChangeLog");
+ let text = std::fs::read_to_string(path)
+ .expect("ChangeLog not found at the workspace root");
+ let top = text
+ .lines()
+ .map(str::trim)
+ .find_map(|l| l.strip_prefix("gipfel-"))
+ .expect("ChangeLog has no `gipfel-X.Y.Z` entry");
+ assert_eq!(
+ top,
+ env!("CARGO_PKG_VERSION"),
+ "ChangeLog top entry is `gipfel-{top}` but crate version is {}",
+ env!("CARGO_PKG_VERSION")
+ );
+ }
}
diff --git a/crates/gipfel-cli/Cargo.toml b/crates/gipfel-cli/Cargo.toml
index 0a07982..b1369fa 100644
--- a/crates/gipfel-cli/Cargo.toml
+++ b/crates/gipfel-cli/Cargo.toml
@@ -1,9 +1,9 @@
[package]
name = "gipfel-cli"
-version = "0.5.4"
-edition = "2021"
+version.workspace = true
+edition.workspace = true
description = "gipfel command line tools (export-position, export-hills)"
-license = "GPL-2.0-or-later"
+license.workspace = true
[[bin]]
name = "gipfel-cli"
diff --git a/crates/gipfel-core/Cargo.toml b/crates/gipfel-core/Cargo.toml
index d8ddfd9..6a66516 100644
--- a/crates/gipfel-core/Cargo.toml
+++ b/crates/gipfel-core/Cargo.toml
@@ -1,9 +1,9 @@
[package]
name = "gipfel-core"
-version = "0.1.0"
-edition = "2021"
+version.workspace = true
+edition.workspace = true
description = "Port of gipfel's computational core (hills, panorama, projections, least-squares fit, metadata)"
-license = "GPL-2.0-or-later"
+license.workspace = true
[dependencies]
kamadak-exif.workspace = true