Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • nodes/rust/duniter-v2s
  • llaq/lc-core-substrate
  • pini-gh/duniter-v2s
  • vincentux/duniter-v2s
  • mildred/duniter-v2s
  • d0p1/duniter-v2s
  • bgallois/duniter-v2s
  • Nicolas80/duniter-v2s
8 results
Show changes
......@@ -14,7 +14,7 @@ let
rev = "1fe6ed37fd9beb92afe90671c0c2a662a03463dd";
};
nixpkgs = import pinned { overlays = [ mozillaOverlay ]; };
rust-nightly = with nixpkgs; ((rustChannelOf { date = "2021-03-01"; channel = "nightly"; }).rust.override {
rust-nightly = with nixpkgs; ((rustChannelOf { date = "2022-04-20"; channel = "nightly"; }).rust.override {
targets = [ "wasm32-unknown-unknown" ];
});
in
......
[package]
authors = ["elois <elois@duniter.org>"]
description = "Duniter-v2s xtask"
edition = "2018"
edition = "2021"
license = "AGPL-3.0"
name = "xtask"
repository = "https://git.duniter.org/nodes/rust/duniter-v2s"
......@@ -15,14 +15,17 @@ name = "xtask"
[dependencies]
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"
codec = { package = "parity-scale-codec", version = "3.1.5", default-features = false, features = ["derive", "full", "bit-vec"] }
frame-metadata = "15.0.0"
graphql_client = "0.10.0"
hex = "0.4"
memmap2 = "0.5.0"
placeholder = "1.1.3"
reqwest = { version = "0.11.11", features = ["json"] }
run_script = "0.6.3"
scale-info = { version = "1.0.0", features = ["bit-vec"] }
serde = "1"
scale-info = { version = "2.1.1", features = ["bit-vec"] }
serde = { version = "1.0.101", features = ["derive"] }
serde_json = "1.0"
tokio = { version = "1.15.0", features = ["macros"] }
version_check = "0.9.2"
version-compare = "0.0.11"
mutation CreateReleaseMutation($branch: String!, $description: String!, $milestone: String!) {
releaseCreate(input: {
clientMutationId: "duniter-v2s-xtask"
description: $description
milestones: [$milestone]
name: $milestone
projectPath: "nodes/rust/duniter-v2s"
ref: $branch
tagName: $milestone
}) {
errors
}
}
query GetChangesQuery($milestone: String!) {
project(fullPath: "nodes/rust/duniter-v2s") {
mergeRequests(milestoneTitle: $milestone, state: merged) {
nodes {
iid
title
}
}
}
}
......@@ -5,12 +5,12 @@ The runtimes have been built using [{srtool_version}](https://github.com/parityt
## Ğ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}
🏋️ 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
......
schema {
query: Query
mutation: Mutation
}
type Query {
project(fullPath: ID!): Project
mergeRequest(id: MergeRequestID!): MergeRequest
}
type Mutation {
releaseCreate(input: ReleaseCreateInput!): ReleaseCreatePayload
}
type Project {
mergeRequests(
state: MergeRequestState
milestoneTitle: String
): MergeRequestConnection
}
scalar MergeRequestID
type MergeRequest {
conflicts: Boolean!
diffHeadSha: String
draft: Boolean!
headPipeline: Pipeline
id: ID!
iid: String!
mergeable: Boolean!
title: String!
}
type MergeRequestConnection {
count: Int!
nodes: [MergeRequest]
}
enum MergeRequestState {
opened
closed
locked
all
merged
}
type Pipeline {
active: Boolean!
cancelable: Boolean!
id: ID!
iid: String!
}
input ReleaseCreateInput {
projectPath: ID!
tagName: String!
name: String
description: String
milestones: [String!]
assets: ReleaseAssetsInput
clientMutationId: String
}
input ReleaseAssetsInput {
links: [ReleaseAssetLinkInput!]
}
input ReleaseAssetLinkInput {
name: String!
url: String!
directAssetPath: String
linkType: ReleaseAssetLinkType = OTHER
}
enum ReleaseAssetLinkType {
OTHER
RUNBOOK
PACKAGE
IMAGE
}
type ReleaseCreatePayload {
errors: [String!]!
}
......@@ -64,7 +64,7 @@ impl CallCategory {
("SmithsCert", "force_add_cert" | "del_cert" | "remove_all_certs_received_by") => {
Self::Root
}
("SmithsCollective", "set_members" | "disapprove_proposal") => Self::Root,
("TechnicalCommittee", "set_members" | "disapprove_proposal") => Self::Root,
("Utility", "dispatch_as") => Self::Root,
("Treasury", "approve_proposal" | "reject_proposal") => Self::OtherOrigin,
_ => Self::User,
......
......@@ -56,7 +56,8 @@ enum DuniterXTaskCommand {
Test,
}
fn main() -> Result<()> {
#[tokio::main(flavor = "current_thread")]
async fn main() -> Result<()> {
let args = DuniterXTask::parse();
if !version_check::is_min_version(MIN_RUST_VERSION).unwrap_or(false)
......@@ -78,7 +79,7 @@ fn main() -> Result<()> {
inject_runtime_code(&raw_spec, &runtime)
}
DuniterXTaskCommand::ReleaseRuntime { spec_version } => {
release_runtime::release_runtime(spec_version)
release_runtime::release_runtime(spec_version).await
}
DuniterXTaskCommand::Test => test(),
}
......
......@@ -14,39 +14,52 @@
// 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/>.
mod create_release;
mod get_changes;
use anyhow::{anyhow, Context, Result};
use serde::Deserialize;
use std::io::Read;
use std::process::Command;
#[derive(Deserialize)]
#[derive(Default, Deserialize)]
struct Srtool {
gen: String,
rustc: String,
runtimes: SrtoolRuntimes,
}
#[derive(Deserialize)]
#[derive(Default, Deserialize)]
struct SrtoolRuntimes {
compact: SrtoolRuntime,
compressed: SrtoolRuntime,
}
#[derive(Deserialize)]
#[derive(Default, Deserialize)]
struct SrtoolRuntime {
subwasm: SrtoolRuntimeSubWasm,
}
#[derive(Deserialize)]
#[derive(Default, Deserialize)]
struct SrtoolRuntimeSubWasm {
core_version: String,
core_version: CoreVersion,
metadata_version: u32,
size: u32,
blake2_256: String,
proposal_hash: String,
}
pub(super) fn release_runtime(_spec_version: u32) -> Result<()> {
#[derive(Default, Deserialize)]
#[serde(rename_all = "camelCase")]
struct CoreVersion {
//impl_name: String,
//impl_version: u32,
spec_name: String,
spec_version: u32,
//transaction_version: u32,
}
pub(super) async fn release_runtime(spec_version: u32) -> Result<()> {
// Get current dir
let pwd = std::env::current_dir()?
.into_os_string()
......@@ -57,6 +70,14 @@ pub(super) fn release_runtime(_spec_version: u32) -> Result<()> {
// TODO: create and push a git tag runtime-{spec_version}
// Create target folder for runtime build
Command::new("mkdir")
.args(["-p", "runtime/gdev/target"])
.status()?;
Command::new("chmod")
.args(["777", "runtime/gdev/target"])
.status()?;
// Build the new runtime
println!("Build gdev-runtime… (take a while)");
let output = Command::new("docker")
......@@ -70,7 +91,7 @@ pub(super) fn release_runtime(_spec_version: u32) -> Result<()> {
"RUNTIME_DIR=runtime/gdev",
"-v",
&format!("{}:/build", pwd),
"paritytech/srtool:1.60.0",
"paritytech/srtool:1.62.0",
"build",
"--app",
"--json",
......@@ -88,16 +109,20 @@ pub(super) fn release_runtime(_spec_version: u32) -> Result<()> {
.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")?;
let release_notes = gen_release_notes(spec_version, srtool)
.await
.with_context(|| "Fail to generate release notes")?;
// TODO: Call gitlab API to publish the release notes (and upload the wasm)
println!("{}", release_notes);
let gitlab_token =
std::env::var("GITLAB_TOKEN").with_context(|| "missing env var GITLAB_TOKEN")?;
create_release::create_release(gitlab_token, spec_version, release_notes).await?;
Ok(())
}
fn gen_release_notes(srtool: Srtool) -> Result<String> {
async fn gen_release_notes(spec_version: u32, 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)?;
......@@ -109,8 +134,8 @@ fn gen_release_notes(srtool: Srtool) -> Result<String> {
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();
// Get changes (list of MRs) from gitlab API
let changes = get_changes::get_changes(spec_version).await?;
// Fill template values
let mut values = std::collections::HashMap::new();
......@@ -121,7 +146,13 @@ fn gen_release_notes(srtool: Srtool) -> Result<String> {
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(
"core_version".to_owned(),
format!(
"{}-{}",
wasm.core_version.spec_name, wasm.core_version.spec_version
),
);
values.insert(
"compression_percent".to_owned(),
format!("{:.2}", compression_percent),
......
// 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, Result};
use graphql_client::{GraphQLQuery, Response};
#[derive(GraphQLQuery)]
#[graphql(
schema_path = "res/schema.gql",
query_path = "res/create_release.gql",
response_derives = "Debug"
)]
pub struct CreateReleaseMutation;
pub(super) async fn create_release(
gitlab_token: String,
spec_version: u32,
release_notes: String,
) -> Result<()> {
// this is the important line
let request_body = CreateReleaseMutation::build_query(create_release_mutation::Variables {
branch: format!("release/runtime-{}", spec_version - (spec_version % 100)),
description: release_notes,
milestone: format!("runtime-{}", spec_version),
});
let client = reqwest::Client::new();
let res = client
.post("https://git.duniter.org/api/graphql")
.header("PRIVATE-TOKEN", gitlab_token)
.json(&request_body)
.send()
.await?;
let response_body: Response<create_release_mutation::ResponseData> = res.json().await?;
if let Some(data) = response_body.data {
if let Some(release_create) = data.release_create {
if release_create.errors.is_empty() {
Ok(())
} else {
println!("{} errors:", release_create.errors.len());
for error in release_create.errors {
println!("{}", error);
}
Err(anyhow!("Logic errors"))
}
} else {
Err(anyhow!("Invalid response: no release_create"))
}
} else if let Some(errors) = response_body.errors {
println!("{} errors:", errors.len());
for error in errors {
println!("{}", error);
}
Err(anyhow!("GraphQL errors"))
} else {
Err(anyhow!("Invalid response: no data nor errors"))
}
}
// 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, Result};
use graphql_client::{GraphQLQuery, Response};
#[derive(GraphQLQuery)]
#[graphql(
schema_path = "res/schema.gql",
query_path = "res/get_changes.gql",
response_derives = "Debug"
)]
pub struct GetChangesQuery;
pub(super) async fn get_changes(spec_version: u32) -> Result<String> {
// this is the important line
let request_body = GetChangesQuery::build_query(get_changes_query::Variables {
milestone: format!("runtime-{}", spec_version),
});
let client = reqwest::Client::new();
let res = client
.post("https://git.duniter.org/api/graphql")
.json(&request_body)
.send()
.await?;
let response_body: Response<get_changes_query::ResponseData> = res.json().await?;
if let Some(data) = response_body.data {
if let Some(project) = data.project {
if let Some(merge_requests) = project.merge_requests {
if let Some(nodes) = merge_requests.nodes {
let mut changes = String::new();
for merge_request in nodes.into_iter().flatten() {
changes.push_str(&format!(
"* {mr_title} (!{mr_number})\n",
mr_title = merge_request.title,
mr_number = merge_request.iid
));
}
Ok(changes)
} else {
Err(anyhow!("No changes found"))
}
} else {
Err(anyhow!("No changes found"))
}
} else {
Err(anyhow!("Project not found"))
}
} else if let Some(errors) = response_body.errors {
println!("{} errors:", errors.len());
for error in errors {
println!("{}", error);
}
Err(anyhow!("GraphQL errors"))
} else {
Err(anyhow!("Invalid response: no data nor errors"))
}
}