diff --git a/build_common.rs b/build_common.rs new file mode 100644 index 000000000..906acdbc1 --- /dev/null +++ b/build_common.rs @@ -0,0 +1,22 @@ +use std::process::Command; + +/// Expose the liana version. If the `LIANA_VERSION` environment variable is set, we are in release, +/// so we use that, otherwise use the git hash. +pub fn expose_liana_version() { + if let Some(version) = std::env::var_os("LIANA_VERSION") { + println!("cargo:rustc-env=LIANA_VERSION={}", version.to_string_lossy()); + } else { + let git_hash = get_git_hash(); + println!("cargo:rustc-env=GIT_HASH={}", git_hash); + } +} + +/// Fetch the short git commit hash. +pub fn get_git_hash() -> String { + let output = Command::new("git") + .args(["rev-parse", "--short", "HEAD"]) + .output() + .expect("Git command should succeed."); + + String::from_utf8_lossy(&output.stdout).trim().to_string() +} diff --git a/contrib/release/release.sh b/contrib/release/release.sh index 4bca7b0f8..c1868933a 100755 --- a/contrib/release/release.sh +++ b/contrib/release/release.sh @@ -8,6 +8,7 @@ set -ex VERSION="${VERSION:-"12.0"}" +export LIANA_VERSION="$VERSION" LIANA_PREFIX="liana-$VERSION" LINUX_DIR_NAME="$LIANA_PREFIX-x86_64-linux-gnu" LINUX_ARCHIVE="$LINUX_DIR_NAME.tar.gz" @@ -42,7 +43,7 @@ create_dir "$BUILD_DIR" OUT_DIR="$BUILD_DIR" ./contrib/reproducible/guix/guix-build.sh -nix build .#release +LIANA_VERSION="$VERSION" nix build .#release --impure NIX_BUILD_DIR="$(nix path-info .#release)" #Create the Linux archive and Debian binary package. diff --git a/flake.nix b/flake.nix index 0e37cef0d..2c03fcba2 100644 --- a/flake.nix +++ b/flake.nix @@ -55,6 +55,10 @@ pkgsCross.mingwW64.windows.pthreads ]; + preBuild = '' + export LIANA_VERSION=${builtins.getEnv "LIANA_VERSION"} + ''; + installPhaseCommand = '' mkdir -p $out/x86_64-pc-windows-gnu cp target/x86_64-pc-windows-gnu/release/liana-gui.exe $out/x86_64-pc-windows-gnu @@ -74,6 +78,8 @@ ]; preBuild = '' + export LIANA_VERSION=${builtins.getEnv "LIANA_VERSION"} + export SDKROOT=${pkgs.darwin.xcode_12_2}/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk export XDG_CACHE_HOME=$TMPDIR/xdg_cache @@ -108,6 +114,8 @@ ]; preBuild = '' + export LIANA_VERSION=${builtins.getEnv "LIANA_VERSION"} + export SDKROOT=${pkgs.darwin.xcode_12_2}/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk export XDG_CACHE_HOME=$TMPDIR/xdg_cache diff --git a/liana-gui/build.rs b/liana-gui/build.rs new file mode 100644 index 000000000..2aea0dc2e --- /dev/null +++ b/liana-gui/build.rs @@ -0,0 +1,5 @@ +include!("../build_common.rs"); + +fn main() { + expose_liana_version(); +} diff --git a/liana-gui/src/app/view/settings/mod.rs b/liana-gui/src/app/view/settings/mod.rs index 7a931a165..fb25d4d02 100644 --- a/liana-gui/src/app/view/settings/mod.rs +++ b/liana-gui/src/app/view/settings/mod.rs @@ -19,13 +19,6 @@ use lianad::config::BitcoindRpcAuth; use super::{dashboard, message::*}; -use liana_ui::{ - component::{badge, button, card, form, separation, text::*, tooltip::tooltip}, - icon, - theme::{self}, - widget::*, -}; - use crate::{ app::{ cache::Cache, @@ -41,6 +34,13 @@ use crate::{ electrum::{self, validate_domain_checkbox}, }, }; +use liana_ui::{ + component::{badge, button, card, form, separation, text::*, tooltip::tooltip}, + icon, + theme::{self}, + widget::*, +}; +use lianad::LIANA_VERSION; fn header(title: &str, msg: SettingsMessage) -> Row<'static, Message> { Row::new() @@ -300,7 +300,7 @@ pub fn about_section<'a>( .push( Row::new().push(Space::with_width(Length::Fill)).push( Column::new() - .push(text(format!("liana-gui v{}", crate::VERSION))) + .push(text(format!("liana-gui v{}", LIANA_VERSION))) .push_maybe( lianad_version.map(|version| text(format!("lianad v{}", version))), ), diff --git a/liana-gui/src/backup.rs b/liana-gui/src/backup.rs index 4c8214607..721c26a27 100644 --- a/liana-gui/src/backup.rs +++ b/liana-gui/src/backup.rs @@ -9,6 +9,7 @@ use liana::{ use lianad::{ bip329, commands::{CoinStatus, ListCoinsEntry}, + LIANA_VERSION, }; use serde::{Deserialize, Serialize}; use serde_json::Value; @@ -31,17 +32,12 @@ use crate::{ installer::Context, services::connect::client::backend::api::DEFAULT_LIMIT, utils::now, - VERSION, }; const CONFIG_KEY: &str = "config"; const SETTINGS_KEY: &str = "settings"; const LIANA_VERSION_KEY: &str = "liana_version"; -pub fn liana_version() -> String { - format!("{}.{}", VERSION.major, VERSION.minor) -} - #[derive(Serialize, Deserialize, Clone, PartialEq, Eq)] pub struct Backup { #[serde(default, skip_serializing_if = "Option::is_none")] @@ -139,7 +135,7 @@ impl Backup { account.timestamp = Some(now); account .proprietary - .insert(LIANA_VERSION_KEY.to_string(), liana_version().into()); + .insert(LIANA_VERSION_KEY.to_string(), LIANA_VERSION.into()); ctx.keys.iter().for_each(|(k, s)| { account.keys.insert(*k, s.to_backup()); @@ -166,7 +162,7 @@ impl Backup { sender: &UnboundedSender, ) -> Result { let mut proprietary = serde_json::Map::new(); - proprietary.insert(LIANA_VERSION_KEY.to_string(), liana_version().into()); + proprietary.insert(LIANA_VERSION_KEY.to_string(), LIANA_VERSION.into()); let name = wallet.name.clone(); let descriptor = wallet.main_descriptor.to_string(); diff --git a/liana-gui/src/gui/mod.rs b/liana-gui/src/gui/mod.rs index 460dc31e8..0cfa6cbfb 100644 --- a/liana-gui/src/gui/mod.rs +++ b/liana-gui/src/gui/mod.rs @@ -28,7 +28,6 @@ use crate::{ launcher, logger::setup_logger, services::fiat::{Currency, PriceSource}, - VERSION, }; use iced::window::Id; @@ -93,7 +92,7 @@ async fn ctrl_c() -> Result<(), ()> { impl GUI { pub fn title(&self) -> String { - format!("Liana v{}", VERSION) + format!("Liana v{}", lianad::LIANA_VERSION) } pub fn new((config, log_level): (Config, Option)) -> (GUI, Task) { diff --git a/liana-gui/src/main.rs b/liana-gui/src/main.rs index 08d806c8c..ac2e9327e 100644 --- a/liana-gui/src/main.rs +++ b/liana-gui/src/main.rs @@ -18,8 +18,8 @@ use liana_gui::{ dir::LianaDirectory, gui::{Config, GUI}, node::bitcoind::delete_all_bitcoind_locks_for_process, - VERSION, }; +use lianad::LIANA_VERSION; #[derive(Debug, PartialEq)] enum Arg { @@ -31,7 +31,7 @@ fn parse_args(args: Vec) -> Result, Box> { let mut res = Vec::new(); if args.len() > 1 && (args[1] == "--version" || args[1] == "-v") { - eprintln!("{}", VERSION); + eprintln!("{}", LIANA_VERSION); process::exit(1); } diff --git a/liana-gui/test_assets/liana-backup-2025-06-23T13-23-54.json b/liana-gui/test_assets/liana-backup-2025-06-23T13-23-54.json index e90e4c217..55291d7a5 100644 --- a/liana-gui/test_assets/liana-backup-2025-06-23T13-23-54.json +++ b/liana-gui/test_assets/liana-backup-2025-06-23T13-23-54.json @@ -43,7 +43,7 @@ "log_level": null, "start_internal_bitcoind": false }, - "liana_version": "11.0", + "liana_version": "12.0", "settings": { "alias": "My Liana Regtest wallet", "descriptor_checksum": "jz5sm0xn", diff --git a/lianad/build.rs b/lianad/build.rs new file mode 100644 index 000000000..2aea0dc2e --- /dev/null +++ b/lianad/build.rs @@ -0,0 +1,5 @@ +include!("../build_common.rs"); + +fn main() { + expose_liana_version(); +} diff --git a/lianad/src/bin/daemon.rs b/lianad/src/bin/daemon.rs index dcc756bdb..11bd66e93 100644 --- a/lianad/src/bin/daemon.rs +++ b/lianad/src/bin/daemon.rs @@ -5,10 +5,10 @@ use std::{ process, thread, time, }; -use lianad::{config::Config, setup_panic_hook, DaemonHandle, VERSION}; +use lianad::{config::Config, setup_panic_hook, DaemonHandle, LIANA_VERSION}; fn print_help_exit(code: i32) { - eprintln!("lianad version {}", VERSION); + eprintln!("lianad version {}", LIANA_VERSION); eprintln!("A TOML configuration file is required to run lianad. By default lianad looks for a 'config.toml' file in its data directory. A different one may be provided like so: '--conf '."); eprintln!("A documented sample is available at 'contrib/lianad_config_example.toml' in the source tree (https://github.com/wizardsardine/liana/blob/v1.0/contrib/lianad_config_example.toml)."); eprintln!("The default data directory path is a 'liana/' folder in the XDG standard configuration directory for all OSes but Linux ones, where it's '~/.liana/'."); @@ -16,7 +16,7 @@ fn print_help_exit(code: i32) { } fn print_version() { - eprintln!("{}", VERSION); + eprintln!("{}", LIANA_VERSION); process::exit(0); } diff --git a/lianad/src/commands/mod.rs b/lianad/src/commands/mod.rs index 1ff60886d..e2f695a08 100644 --- a/lianad/src/commands/mod.rs +++ b/lianad/src/commands/mod.rs @@ -9,7 +9,7 @@ use crate::{ database::{Coin, DatabaseConnection, DatabaseInterface}, miniscript::bitcoin::absolute::LockTime, poller::PollerMessage, - DaemonControl, VERSION, + DaemonControl, LIANA_VERSION, }; pub use crate::database::{CoinStatus, LabelItem}; @@ -329,7 +329,7 @@ impl DaemonControl { .rescan_timestamp .map(|_| self.bitcoin.rescan_progress().unwrap_or(1.0)); GetInfoResult { - version: VERSION.to_string(), + version: LIANA_VERSION.to_string(), network: self.config.bitcoin_config.network, block_height, sync: self.bitcoin.sync_progress().rounded_up_progress(), diff --git a/lianad/src/lib.rs b/lianad/src/lib.rs index d24c2539b..07f591355 100644 --- a/lianad/src/lib.rs +++ b/lianad/src/lib.rs @@ -67,18 +67,22 @@ pub fn setup_panic_hook() { })); } +const fn get_version() -> &'static str { + if let Some(version) = option_env!("LIANA_VERSION") { + version + } else { + env!("GIT_HASH") + } +} + +pub const LIANA_VERSION: &str = get_version(); + #[derive(Debug, Clone)] pub struct Version { pub major: u32, pub minor: u32, } -impl fmt::Display for Version { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}.{}-dev", self.major, self.minor) - } -} - pub const VERSION: Version = Version { major: 12, minor: 0, diff --git a/tests/test_rpc.py b/tests/test_rpc.py index 1179761f7..2a9cd9e24 100644 --- a/tests/test_rpc.py +++ b/tests/test_rpc.py @@ -26,7 +26,6 @@ def test_getinfo(lianad): res = lianad.rpc.getinfo() assert "timestamp" in res.keys() - assert res["version"] == "12.0-dev" assert res["network"] == "regtest" wait_for(lambda: lianad.rpc.getinfo()["block_height"] == 101) res = lianad.rpc.getinfo()