Do so that meilisearch versions get downloaded

This commit is contained in:
Mubelotix
2025-08-25 15:16:26 +02:00
parent c98efe18c9
commit d649732acd
3 changed files with 151 additions and 8 deletions

View File

@ -5,6 +5,7 @@ use anyhow::{bail, Context};
use cargo_metadata::semver::Version;
use clap::Parser;
mod versions;
mod workload;
pub use workload::TestWorkload;
@ -51,7 +52,7 @@ async fn run_inner(args: TestDeriveArgs) -> anyhow::Result<()> {
)
.with_context(|| format!("error parsing {} as JSON", workload_file.display()))?;
let Workload::Test(workload) = workload else {
let Workload::Test(mut workload) = workload else {
bail!("workload file {} is not a test workload", workload_file.display());
};

View File

@ -0,0 +1,115 @@
use std::collections::BTreeMap;
use crate::common::assets::{Asset, AssetFormat};
use anyhow::Context;
use cargo_metadata::semver::Version;
use serde::Deserialize;
async fn get_sha256(version: &Version, asset_name: &str) -> anyhow::Result<String> {
#[derive(Deserialize)]
struct GithubReleaseAsset {
name: String,
digest: String,
}
#[derive(Deserialize)]
struct GithubRelease {
assets: Vec<GithubReleaseAsset>,
}
let url =
format!("https://api.github.com/repos/meilisearch/meilisearch/releases/tags/v{version}");
let data: GithubRelease = reqwest::get(url).await?.json().await?;
let digest = data
.assets
.into_iter()
.find(|asset| asset.name.as_str() == asset_name)
.with_context(|| format!("asset {asset_name} not found in release v{version}"))?
.digest;
let sha256 =
digest.strip_prefix("sha256:").map(|s| s.to_string()).context("invalid sha256 format")?;
Ok(sha256)
}
async fn add_asset(assets: &mut BTreeMap<String, Asset>, version: &Version) -> anyhow::Result<()> {
let arch;
// linux-aarch64
#[cfg(all(target_os = "linux", target_arch = "aarch64"))]
{
arch = "linux-aarch64";
}
// linux-amd64
#[cfg(all(target_os = "linux", target_arch = "x86_64"))]
{
arch = "linux-amd64";
}
// macos-amd64
#[cfg(all(target_os = "macos", target_arch = "x86_64"))]
{
arch = "macos-amd64";
}
// macos-apple-silicon
#[cfg(all(target_os = "macos", target_arch = "aarch64"))]
{
arch = "macos-apple-silicon";
}
// windows-amd64
#[cfg(all(target_os = "windows", target_arch = "x86_64"))]
{
arch = "windows-amd64";
}
if arch.is_empty() {
anyhow::bail!("unsupported platform");
}
let local_filename = format!("meilisearch-{version}-{arch}");
if assets.contains_key(&local_filename) {
return Ok(());
}
let filename = format!("meilisearch-{arch}");
// Try to get the sha256 but it may fail if Github is rate limiting us
let sha256 = match get_sha256(version, &filename).await {
Ok(sha256) => Some(sha256),
Err(err) => {
eprintln!("⚠️ Warning: could not get sha256 from GitHub: {err}. Proceeding without integrity check.");
None
}
};
let url = format!(
"https://github.com/meilisearch/meilisearch/releases/download/v{version}/{filename}"
);
let asset = Asset {
local_location: Some(local_filename.clone()),
remote_location: Some(url),
format: AssetFormat::Raw,
sha256,
};
assets.insert(local_filename, asset);
Ok(())
}
pub async fn expand_assets_with_versions(
assets: &mut BTreeMap<String, Asset>,
versions: &[Version],
) -> anyhow::Result<()> {
for version in versions {
add_asset(assets, version).await?;
}
Ok(())
}

View File

@ -8,19 +8,41 @@ use crate::{
client::Client,
command::{run_commands, Command},
},
test::TestDeriveArgs,
test::{versions::expand_assets_with_versions, TestDeriveArgs},
};
#[derive(Clone)]
pub enum VersionOrLatest {
Version(Version),
Latest,
}
impl<'a> Deserialize<'a> for VersionOrLatest {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'a>,
{
let s: &str = Deserialize::deserialize(deserializer)?;
if s.eq_ignore_ascii_case("latest") {
Ok(VersionOrLatest::Latest)
} else {
let version = Version::parse(s).map_err(serde::de::Error::custom)?;
Ok(VersionOrLatest::Version(version))
}
}
}
#[derive(Deserialize)]
#[serde(untagged)]
pub enum CommandOrUpgrade {
Command(Command),
Upgrade { upgrade: Version },
Upgrade { upgrade: VersionOrLatest },
}
enum CommandOrUpgradeVec {
Commands(Vec<Command>),
Upgrade(Version),
Upgrade(VersionOrLatest),
}
/// A test workload.
@ -34,17 +56,15 @@ pub struct TestWorkload {
impl TestWorkload {
pub async fn run(
&self,
&mut self,
args: &TestDeriveArgs,
assets_client: &Client,
meili_client: &Client,
) -> anyhow::Result<()> {
// Fetch assets
fetch_assets(assets_client, &self.assets, &args.common.asset_folder).await?;
// Group commands between upgrades
let mut commands_or_upgrade = Vec::new();
let mut current_commands = Vec::new();
let mut all_versions = vec![args.initial_version.clone()];
for command_or_upgrade in &self.commands {
match command_or_upgrade {
CommandOrUpgrade::Command(command) => current_commands.push(command.clone()),
@ -54,10 +74,17 @@ impl TestWorkload {
current_commands = Vec::new();
}
commands_or_upgrade.push(CommandOrUpgradeVec::Upgrade(upgrade.clone()));
if let VersionOrLatest::Version(upgrade) = upgrade {
all_versions.push(upgrade.clone());
}
}
}
}
// Fetch assets
expand_assets_with_versions(&mut self.assets, &all_versions).await?;
fetch_assets(assets_client, &self.assets, &args.common.asset_folder).await?;
for command_or_upgrade in commands_or_upgrade {
match command_or_upgrade {
CommandOrUpgradeVec::Commands(commands) => {