Skip to content

Commit 4753aa8

Browse files
authored
templates check: Add --stabilise flag to make renders reproducible (#5214)
2 parents 2b9ae44 + f678334 commit 4753aa8

File tree

13 files changed

+231
-131
lines changed

13 files changed

+231
-131
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.

crates/cli/src/commands/server.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,8 @@ impl Options {
166166
&url_builder,
167167
// Don't use strict mode in production yet
168168
false,
169+
// Don't stabilise in production
170+
false,
169171
)
170172
.await?;
171173
shutdown.register_reloadable(&templates);

crates/cli/src/commands/templates.rs

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use std::{fmt::Write, process::ExitCode};
88

99
use anyhow::{Context as _, bail};
1010
use camino::Utf8PathBuf;
11+
use chrono::DateTime;
1112
use clap::Parser;
1213
use figment::Figment;
1314
use mas_config::{
@@ -34,14 +35,20 @@ enum Subcommand {
3435
/// The directory must either not exist or be empty.
3536
#[arg(long = "out-dir")]
3637
out_dir: Option<Utf8PathBuf>,
38+
39+
/// Attempt to remove 'unstable' template input data such as asset
40+
/// hashes, in order to make renders more reproducible between
41+
/// versions.
42+
#[arg(long = "stabilise")]
43+
stabilise: bool,
3744
},
3845
}
3946

4047
impl Options {
4148
pub async fn run(self, figment: &Figment) -> anyhow::Result<ExitCode> {
4249
use Subcommand as SC;
4350
match self.subcommand {
44-
SC::Check { out_dir } => {
51+
SC::Check { out_dir, stabilise } => {
4552
let _span = info_span!("cli.templates.check").entered();
4653

4754
let template_config = TemplatesConfig::extract_or_default(figment)
@@ -59,9 +66,17 @@ impl Options {
5966
let captcha_config = CaptchaConfig::extract_or_default(figment)
6067
.map_err(anyhow::Error::from_boxed)?;
6168

62-
let clock = SystemClock::default();
63-
// XXX: we should disallow SeedableRng::from_entropy
64-
let mut rng = rand_chacha::ChaChaRng::from_entropy();
69+
let now = if stabilise {
70+
DateTime::from_timestamp_secs(1_446_823_992).unwrap()
71+
} else {
72+
SystemClock::default().now()
73+
};
74+
let rng = if stabilise {
75+
rand_chacha::ChaChaRng::from_seed([42; 32])
76+
} else {
77+
// XXX: we should disallow SeedableRng::from_entropy
78+
rand_chacha::ChaChaRng::from_entropy()
79+
};
6580
let url_builder =
6681
mas_router::UrlBuilder::new("https://example.com/".parse()?, None, None);
6782
let site_config = site_config_from_config(
@@ -75,11 +90,13 @@ impl Options {
7590
let templates = templates_from_config(
7691
&template_config,
7792
&site_config,
78-
&url_builder, // Use strict mode in template checks
93+
&url_builder,
94+
// Use strict mode in template checks
7995
true,
96+
stabilise,
8097
)
8198
.await?;
82-
let all_renders = templates.check_render(clock.now(), &mut rng)?;
99+
let all_renders = templates.check_render(now, &rng)?;
83100

84101
if let Some(out_dir) = out_dir {
85102
// Save renders to disk.

crates/cli/src/commands/worker.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ impl Options {
5858
&url_builder,
5959
// Don't use strict mode on task workers for now
6060
false,
61+
// Don't stabilise in production
62+
false,
6163
)
6264
.await?;
6365

crates/cli/src/util.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,11 +233,12 @@ pub async fn templates_from_config(
233233
site_config: &SiteConfig,
234234
url_builder: &UrlBuilder,
235235
strict: bool,
236+
stabilise: bool,
236237
) -> Result<Templates, anyhow::Error> {
237238
Templates::load(
238239
config.path.clone(),
239240
url_builder.clone(),
240-
config.assets_manifest.clone(),
241+
(!stabilise).then(|| config.assets_manifest.clone()),
241242
config.translations_path.clone(),
242243
site_config.templates_branding(),
243244
site_config.templates_features(),

crates/handlers/src/test_utils.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ impl TestState {
172172
let templates = Templates::load(
173173
workspace_root.join("templates"),
174174
url_builder.clone(),
175-
workspace_root.join("frontend/dist/manifest.json"),
175+
Some(workspace_root.join("frontend/dist/manifest.json")),
176176
workspace_root.join("translations"),
177177
site_config.templates_branding(),
178178
site_config.templates_features(),

crates/templates/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ http.workspace = true
2525
minijinja-contrib.workspace = true
2626
minijinja.workspace = true
2727
rand.workspace = true
28+
rand_chacha.workspace = true
2829
serde_json.workspace = true
2930
serde_urlencoded.workspace = true
3031
serde.workspace = true
@@ -42,3 +43,6 @@ mas-i18n.workspace = true
4243
mas-iana.workspace = true
4344
mas-router.workspace = true
4445
mas-spa.workspace = true
46+
47+
[dev-dependencies]
48+
rand_chacha.workspace = true

0 commit comments

Comments
 (0)