From 37046b4d3d89a276ad486dd9aa6a046af41702a8 Mon Sep 17 00:00:00 2001 From: librelois <c@elo.tf> Date: Fri, 3 Jun 2022 16:09:11 +0200 Subject: [PATCH] feat(xtask): add subcommand release-runtime --- Cargo.lock | 15 +++ xtask/Cargo.toml | 5 + xtask/res/runtime_release_notes.template | 18 +++ xtask/src/main.rs | 6 + xtask/src/release_runtime.rs | 139 +++++++++++++++++++++++ 5 files changed, 183 insertions(+) create mode 100644 xtask/res/runtime_release_notes.template create mode 100644 xtask/src/release_runtime.rs diff --git a/Cargo.lock b/Cargo.lock index ef1ee7c1b..a0c66aad6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5202,6 +5202,16 @@ version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" +[[package]] +name = "placeholder" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a488674d1157858898c95280e599d63584bb2daf3a11031ce5e76887d666c16" +dependencies = [ + "lazy_static", + "regex", +] + [[package]] name = "platforms" version = "2.0.0" @@ -9000,9 +9010,14 @@ dependencies = [ "anyhow", "clap", "frame-metadata", + "hex", + "memmap2 0.5.0", "parity-scale-codec", + "placeholder", "run_script", "scale-info", + "serde", + "serde_json", "version-compare", "version_check", ] diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index 43fefae3b..86498acee 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -17,7 +17,12 @@ anyhow = "1.0.32" clap = { version = "3.0", features = ["derive"] } codec = { package = "parity-scale-codec", version = "2", default-features = false, features = ["derive", "full", "bit-vec"] } frame-metadata = "14.0.0" +hex = "0.4" +memmap2 = "0.5.0" +placeholder = "1.1.3" run_script = "0.6.3" scale-info = { version = "1.0.0", features = ["bit-vec"] } +serde = "1" +serde_json = "1.0" version_check = "0.9.2" version-compare = "0.0.11" diff --git a/xtask/res/runtime_release_notes.template b/xtask/res/runtime_release_notes.template new file mode 100644 index 000000000..c33733ede --- /dev/null +++ b/xtask/res/runtime_release_notes.template @@ -0,0 +1,18 @@ +# Runtimes + +The runtimes have been built using [{srtool_version}](https://github.com/paritytech/srtool) and `{rustc_version}`. + +## ÄžDev + +``` +ðŸ‹ï¸ Runtime Size: {runtime_human_size} ({runtime_size} bytes) +🔥 Core Version: {core_version} +🗜 Compressed: Yes: {compression_percent} % +🎠Metadata version: {metadata_version} +ðŸ—³ï¸ system.setCode hash: {proposal_hash} +#ï¸âƒ£ Blake2-256 hash: {blake2_256} +``` + +# Changes + +{changes} diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 0873750f8..85cf639b4 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -15,6 +15,7 @@ // along with Substrate-Libre-Currency. If not, see <https://www.gnu.org/licenses/>. mod gen_calls_doc; +mod release_runtime; use anyhow::Result; use clap::Parser; @@ -37,6 +38,8 @@ enum DuniterXTaskCommand { }, /// Generate calls documentation GenCallsDoc, + /// Release a new runtime + ReleaseRuntime { spec_version: u32 }, /// Execute unit tests and integration tests /// End2tests are skipped Test, @@ -60,6 +63,9 @@ fn main() -> Result<()> { match args.command { DuniterXTaskCommand::Build { production } => build(production), DuniterXTaskCommand::GenCallsDoc => gen_calls_doc::gen_calls_doc(), + DuniterXTaskCommand::ReleaseRuntime { spec_version } => { + release_runtime::release_runtime(spec_version) + } DuniterXTaskCommand::Test => test(), } } diff --git a/xtask/src/release_runtime.rs b/xtask/src/release_runtime.rs new file mode 100644 index 000000000..2cc175c5c --- /dev/null +++ b/xtask/src/release_runtime.rs @@ -0,0 +1,139 @@ +// Copyright 2021 Axiom-Team +// +// This file is part of Substrate-Libre-Currency. +// +// Substrate-Libre-Currency is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, version 3 of the License. +// +// Substrate-Libre-Currency is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with Substrate-Libre-Currency. If not, see <https://www.gnu.org/licenses/>. + +use anyhow::{anyhow, Context, Result}; +use serde::Deserialize; +use std::io::Read; +use std::process::Command; + +#[derive(Deserialize)] +struct Srtool { + gen: String, + rustc: String, + runtimes: SrtoolRuntimes, +} + +#[derive(Deserialize)] +struct SrtoolRuntimes { + compact: SrtoolRuntime, + compressed: SrtoolRuntime, +} + +#[derive(Deserialize)] +struct SrtoolRuntime { + subwasm: SrtoolRuntimeSubWasm, +} + +#[derive(Deserialize)] +struct SrtoolRuntimeSubWasm { + core_version: String, + metadata_version: u32, + size: u32, + blake2_256: String, + proposal_hash: String, +} + +pub(super) fn release_runtime(_spec_version: u32) -> Result<()> { + // Get current dir + let pwd = std::env::current_dir()? + .into_os_string() + .into_string() + .map_err(|_| anyhow!("Fail to read current dir path: invalid utf8 string!"))?; + + // TODO: check spec_version in the code and bump if necessary (with a commit) + + // TODO: create and push a git tag runtime-{spec_version} + + // Build the new runtime + println!("Build gdev-runtime… (take a while)"); + let output = Command::new("docker") + .args([ + "run", + "-i", + "--rm", + "-e", + "PACKAGE=gdev-runtime", + "-e", + "RUNTIME_DIR=runtime/gdev", + "-v", + &format!("{}:/build", pwd), + "paritytech/srtool:1.60.0", + "build", + "--app", + "--json", + "-cM", + ]) + .output()?; + + // Read the srtool json output + let srtool: Srtool = serde_json::from_str( + std::str::from_utf8(&output.stdout)? + .lines() + .last() + .ok_or(anyhow!("empty srtool output"))?, + ) + .with_context(|| "Fail to parse srtool json output")?; + + // Generate release notes + let release_notes = + gen_release_notes(srtool).with_context(|| "Fail to generate release notes")?; + + // TODO: Call gitlab API to publish the release notes (and upload the wasm) + println!("{}", release_notes); + + Ok(()) +} + +fn gen_release_notes(srtool: Srtool) -> Result<String> { + // Read template file + const RELEASE_NOTES_TEMPLATE_FILEPATH: &str = "xtask/res/runtime_release_notes.template"; + let mut file = std::fs::File::open(RELEASE_NOTES_TEMPLATE_FILEPATH)?; + let mut template = String::new(); + file.read_to_string(&mut template)?; + + // Prepare srtool values + let uncompressed_size = srtool.runtimes.compact.subwasm.size; + let wasm = srtool.runtimes.compressed.subwasm; + let compression_percent = (1.0 - (wasm.size as f64 / uncompressed_size as f64)) * 100.0; + + // TODO: get changes (list of MRs) from gitlab API + let changes = String::new(); + + // Fill template values + let mut values = std::collections::HashMap::new(); + values.insert("srtool_version".to_owned(), srtool.gen); + values.insert("rustc_version".to_owned(), srtool.rustc); + values.insert( + "runtime_human_size".to_owned(), + format!("{} KB", wasm.size / 1_024), + ); + values.insert("runtime_size".to_owned(), wasm.size.to_string()); + values.insert("core_version".to_owned(), wasm.core_version); + values.insert( + "compression_percent".to_owned(), + format!("{:.2}", compression_percent), + ); + values.insert( + "metadata_version".to_owned(), + wasm.metadata_version.to_string(), + ); + values.insert("proposal_hash".to_owned(), wasm.proposal_hash); + values.insert("blake2_256".to_owned(), wasm.blake2_256); + values.insert("changes".to_owned(), changes); + + // Render template + placeholder::render(&template, &values).map_err(|e| anyhow!("Fail to render template: {}", e)) +} -- GitLab