Skip to content

Commit 6a6aeab

Browse files
committed
build: inject version via environment variable to reduce rebuilds
1 parent 87977cd commit 6a6aeab

File tree

12 files changed

+72
-37
lines changed

12 files changed

+72
-37
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

academy/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ academy_persistence_postgres.workspace = true
3636
academy_shared_contracts.workspace = true
3737
academy_shared_impl.workspace = true
3838
academy_templates_impl.workspace = true
39+
academy_utils.workspace = true
3940
anyhow.workspace = true
4041
chrono.workspace = true
4142
clap.workspace = true

academy/src/main.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use academy::commands::{
22
admin::AdminCommand, email::EmailCommand, jwt::JwtCommand, migrate::MigrateCommand,
33
serve::serve, tasks::TaskCommand,
44
};
5+
use academy_utils::academy_version;
56
use anyhow::Context;
67
use clap::{CommandFactory, Parser, Subcommand};
78
use clap_complete::Shell;
@@ -31,7 +32,7 @@ async fn main() -> anyhow::Result<()> {
3132
sentry::init((
3233
sentry_config.dsn.as_str(),
3334
sentry::ClientOptions {
34-
release: Some(env!("CARGO_PKG_VERSION").into()),
35+
release: Some(academy_version().into()),
3536
attach_stacktrace: true,
3637
..Default::default()
3738
},
@@ -55,7 +56,7 @@ async fn main() -> anyhow::Result<()> {
5556
}
5657

5758
#[derive(Debug, Parser)]
58-
#[command(version)]
59+
#[command(version = academy_version())]
5960
struct Cli {
6061
#[command(subcommand)]
6162
command: Command,

academy_api/rest/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use academy_core_session_contracts::SessionFeatureService;
1313
use academy_core_user_contracts::UserFeatureService;
1414
use academy_di::Build;
1515
use academy_models::auth::{AccessToken, InternalToken};
16-
use academy_utils::Apply;
16+
use academy_utils::{academy_version, Apply};
1717
use aide::{
1818
axum::ApiRouter,
1919
openapi::{Components, Info, OpenApi, ReferenceOr, SecurityScheme, Tag},
@@ -82,7 +82,7 @@ where
8282
let mut api = OpenApi {
8383
info: Info {
8484
title: "Bootstrap Academy Backend".into(),
85-
version: env!("CARGO_PKG_VERSION").into(),
85+
version: academy_version().into(),
8686
description: Some(format!("GitHub: [{0}]({0})", env!("CARGO_PKG_REPOSITORY"))),
8787
..Default::default()
8888
},

academy_extern/impl/src/http.rs

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
1-
use std::ops::Deref;
2-
3-
pub const USER_AGENT: &str = concat!(
4-
"Bootstrap Academy Backend (",
5-
env!("CARGO_PKG_HOMEPAGE"),
6-
", ",
7-
env!("CARGO_PKG_REPOSITORY"),
8-
", Version ",
9-
env!("CARGO_PKG_VERSION"),
10-
")"
11-
);
1+
use std::{ops::Deref, sync::LazyLock};
2+
3+
use academy_utils::academy_version;
4+
5+
pub static USER_AGENT: LazyLock<String> = LazyLock::new(|| {
6+
let homepage = env!("CARGO_PKG_HOMEPAGE");
7+
let repository = env!("CARGO_PKG_REPOSITORY");
8+
let version = academy_version();
9+
10+
format!("Bootstrap Academy Backend ({homepage}, {repository}, Version {version})")
11+
});
1212

1313
const _: () = {
1414
assert!(!env!("CARGO_PKG_HOMEPAGE").is_empty());
1515
assert!(!env!("CARGO_PKG_REPOSITORY").is_empty());
16-
assert!(!env!("CARGO_PKG_VERSION").is_empty());
1716
};
1817

1918
#[derive(Debug, Clone)]
@@ -31,7 +30,7 @@ impl Default for HttpClient {
3130
fn default() -> Self {
3231
Self(
3332
reqwest::Client::builder()
34-
.user_agent(USER_AGENT)
33+
.user_agent(&*USER_AGENT)
3534
.build()
3635
.unwrap(),
3736
)

academy_extern/impl/src/oauth2.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ async fn http_client(
122122
) -> Result<oauth2::HttpResponse, oauth2::reqwest::AsyncHttpClientError> {
123123
request.headers.insert(
124124
oauth2::http::header::USER_AGENT,
125-
oauth2::http::HeaderValue::from_static(USER_AGENT),
125+
oauth2::http::HeaderValue::from_static(&USER_AGENT),
126126
);
127127
oauth2::reqwest::async_http_client(request).await
128128
}

academy_testing/src/main.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ use url::Url;
88
const _: () = {
99
assert!(!env!("CARGO_PKG_HOMEPAGE").is_empty());
1010
assert!(!env!("CARGO_PKG_REPOSITORY").is_empty());
11-
assert!(!env!("CARGO_PKG_VERSION").is_empty());
1211
};
1312

1413
#[tokio::main]

academy_utils/src/lib.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,20 @@ mod macros;
22
pub mod patch;
33
pub mod serde;
44

5+
use std::sync::LazyLock;
6+
57
pub use academy_utils_derive::trace_instrument;
68

9+
static ACADEMY_VERSION: LazyLock<&str> = LazyLock::new(|| {
10+
std::env::var("ACADEMY_VERSION")
11+
.map(|x| &*x.leak())
12+
.unwrap_or("0.0.0-dev")
13+
});
14+
15+
pub fn academy_version() -> &'static str {
16+
&ACADEMY_VERSION
17+
}
18+
719
pub trait Apply: Sized {
820
/// Apply the function `f` with a mutable reference to `self`.
921
///

nix/module.nix

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,16 @@ self: {
44
pkgs,
55
...
66
}: let
7-
package = self.packages.${pkgs.system}.default;
87
settingsFormat = pkgs.formats.toml {};
98
in {
109
options.services.academy.backend = {
1110
enable = lib.mkEnableOption "Bootstrap Academy Backend";
1211

12+
package = lib.mkOption {
13+
type = lib.types.package;
14+
default = self.packages.${pkgs.system}.default;
15+
};
16+
1317
localDatabase = lib.mkOption {
1418
type = lib.types.bool;
1519
default = true;
@@ -50,8 +54,8 @@ in {
5054
ACADEMY_CONFIG = builtins.concatStringsSep ":" (cfg.extraConfigFiles ++ [settings]);
5155

5256
wrapper = pkgs.stdenvNoCC.mkDerivation {
53-
inherit (package) pname version;
54-
src = package;
57+
inherit (cfg.package) pname version;
58+
src = cfg.package;
5559
nativeBuildInputs = [pkgs.makeWrapper];
5660
installPhase = ''
5761
cp -r . $out
@@ -83,7 +87,7 @@ in {
8387
// {
8488
wantedBy = ["multi-user.target"];
8589
script = ''
86-
${package}/bin/academy serve
90+
${cfg.package}/bin/academy serve
8791
'';
8892
};
8993
}
@@ -95,7 +99,7 @@ in {
9599
// {
96100
startAt = schedule;
97101
script = ''
98-
${package}/bin/academy task ${task}
102+
${cfg.package}/bin/academy task ${task}
99103
'';
100104
};
101105
})

nix/packages.nix

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
pkgs,
88
system,
99
self,
10+
stdenv,
11+
makeWrapper,
1012
}: let
1113
toolchain = fenix.packages.${system}.stable;
1214

@@ -17,6 +19,22 @@
1719
rev = self.sourceInfo.shortRev or self.sourceInfo.dirtyShortRev;
1820
in "${year}.${month}.${day}+${rev}";
1921

22+
setVersion = drv:
23+
stdenv.mkDerivation {
24+
inherit (drv) pname;
25+
inherit version;
26+
dontUnpack = true;
27+
nativeBuildInputs = [makeWrapper];
28+
installPhase = ''
29+
cp -a ${drv} $out
30+
chmod -R +w $out
31+
for bin in $out/bin/*; do
32+
wrapProgram $bin --set ACADEMY_VERSION ${lib.escapeShellArg version}
33+
done
34+
'';
35+
passthru.unwrapped = drv;
36+
};
37+
2038
crateDirs = lib.pipe ../. [
2139
builtins.readDir
2240
builtins.attrNames
@@ -45,7 +63,6 @@
4563
mergeOverrideSets = a: b: a // b // (builtins.mapAttrs (k: _: mergeOverrides a.${k} b.${k}) (lib.intersectAttrs a b));
4664

4765
defaultOverrides = lib.genAttrs workspaceMembers (crate: attrs: {
48-
inherit version;
4966
preBuild = ''
5067
${attrs.preBuild or ""}
5168
export CARGO_PKG_HOMEPAGE=${lib.escapeShellArg cargoToml.workspace.package.homepage}
@@ -92,7 +109,8 @@
92109
});
93110
defaultCrateOverrides = mergeOverrideSets pkgs.defaultCrateOverrides crateOverrides;
94111
};
95-
in {
96-
default = cargoNix.workspaceMembers.academy.build;
97-
testing = cargoNix.workspaceMembers.academy_testing.build;
98-
}
112+
in
113+
builtins.mapAttrs (_: setVersion) {
114+
default = cargoNix.workspaceMembers.academy.build;
115+
testing = cargoNix.workspaceMembers.academy_testing.build;
116+
}

0 commit comments

Comments
 (0)