Skip to content
Snippets Groups Projects
Commit 02bd89b6 authored by Cédric Moreau's avatar Cédric Moreau
Browse files

feat(#195): `print-spec` and `release-network` commands

parent 3f32c4a8
Branches
No related tags found
No related merge requests found
mutation CreateReleaseMutation($branch: String!, $description: String!, $network: String! $links: [ReleaseAssetLinkInput!]!) {
releaseCreate(input: {
clientMutationId: "duniter-v2s-xtask"
description: $description
milestones: []
name: $network
projectPath: "nodes/rust/duniter-v2s"
ref: $branch
tagName: $network
assets: {
links: $links
}
}) {
errors
}
}
query GetReleaseOfProjectQuery($milestone: String!) {
query GetReleaseOfProjectQuery($tag: String!) {
project(fullPath: "nodes/rust/duniter-v2s") {
release(tagName: $milestone) {
release(tagName: $tag) {
id
tagName
assets {
......
......@@ -53,10 +53,12 @@ enum DuniterXTaskCommand {
/// Raw spec filepath
raw_spec: PathBuf,
},
/// Release a new network
ReleaseNetwork { network: String, branch: String },
/// Release a new runtime
ReleaseRuntime { milestone: String, branch: String },
/// Update raw specs locally with the files published on a Release
UpdateRawSpecs { milestone: String },
/// Print the chainSpec published on given Network Release
PrintSpec { network: String },
/// Create asset in a release
CreateAssetLink {
tag: String,
......@@ -81,8 +83,14 @@ async fn main() -> Result<()> {
);
std::process::exit(1);
}
match &args.command {
DuniterXTaskCommand::PrintSpec { .. } => { /* no print */ }
_ => {
Command::new("rustc").arg("--version").status()?;
Command::new("cargo").arg("--version").status()?;
}
}
match args.command {
DuniterXTaskCommand::Build { production } => build(production),
......@@ -90,12 +98,13 @@ async fn main() -> Result<()> {
DuniterXTaskCommand::InjectRuntimeCode { runtime, raw_spec } => {
inject_runtime_code(&raw_spec, &runtime)
}
DuniterXTaskCommand::ReleaseNetwork { network, branch } => {
release_runtime::release_network(network, branch).await
}
DuniterXTaskCommand::ReleaseRuntime { milestone, branch } => {
release_runtime::release_runtime(milestone, branch).await
}
DuniterXTaskCommand::UpdateRawSpecs { milestone } => {
release_runtime::update_raw_specs(milestone).await
}
DuniterXTaskCommand::PrintSpec { network } => release_runtime::print_spec(network).await,
DuniterXTaskCommand::CreateAssetLink {
tag,
asset_name,
......
......@@ -15,6 +15,7 @@
// along with Duniter-v2S. If not, see <https://www.gnu.org/licenses/>.
mod create_asset_link;
mod create_network_release;
mod create_release;
mod get_changes;
mod get_issues;
......@@ -61,6 +62,50 @@ struct CoreVersion {
//transaction_version: u32,
}
pub(super) async fn release_network(network: String, branch: String) -> Result<()> {
let mut release_notes = String::from(
"
# Runtime
",
);
// Generate release notes
let currency = network.clone();
let env_var = "SRTOOL_OUTPUT".to_string();
if let Ok(sr_tool_output_file) = std::env::var(env_var) {
let read = fs::read_to_string(sr_tool_output_file);
match read {
Ok(sr_tool_output) => {
release_notes.push_str(
gen_release_notes(currency.to_string(), sr_tool_output)
.with_context(|| {
format!("Fail to generate release notes for {}", currency)
})?
.as_str(),
);
}
Err(e) => {
eprintln!("srtool JSON output could not be read ({}). Skipped.", e)
}
}
}
println!("{}", release_notes);
let gitlab_token =
std::env::var("GITLAB_TOKEN").with_context(|| "missing env var GITLAB_TOKEN")?;
create_network_release::create_network_release(
gitlab_token,
branch,
network,
release_notes.to_string(),
)
.await?;
Ok(())
}
pub(super) async fn release_runtime(milestone: String, branch: String) -> Result<()> {
// TODO: check spec_version in the code and bump if necessary (with a commit)
// TODO: create and push a git tag runtime-{spec_version}
......@@ -134,20 +179,22 @@ pub(super) async fn release_runtime(milestone: String, branch: String) -> Result
Ok(())
}
pub(super) async fn update_raw_specs(milestone: String) -> Result<()> {
let specs = vec!["gdev-raw.json", "gtest-raw.json", "g1-raw.json"];
println!("Fetching release info…");
let assets = get_release::get_release(milestone).await?;
for spec in specs {
if let Some(gdev_raw_specs) = assets.iter().find(|asset| asset.ends_with(spec)) {
println!("Downloading {}…", spec);
let client = reqwest::Client::new();
let res = client.get(gdev_raw_specs).send().await?;
let write_to = format!("./node/specs/{}", spec);
fs::write(write_to, res.bytes().await?)?;
pub(super) async fn print_spec(network: String) -> Result<()> {
let spec_file = match network.clone() {
network if network.starts_with("g1") => "g1.json",
network if network.starts_with("gtest") => "gtest.json",
network if network.starts_with("gdev") => "gdev.json",
_ => {
return Err(anyhow!("Invalid network"));
}
};
let assets = get_release::get_release(network).await?;
if let Some(gdev_spec) = assets.iter().find(|asset| asset.ends_with(spec_file)) {
let client = reqwest::Client::new();
let res = client.get(gdev_spec).send().await?;
let spec = String::from_utf8(res.bytes().await?.to_vec())?;
println!("{}", spec);
}
println!("Done.");
Ok(())
}
......
// Copyright 2021 Axiom-Team
//
// This file is part of Duniter-v2S.
//
// Duniter-v2S 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.
//
// Duniter-v2S 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 Duniter-v2S. 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_network_release.gql",
response_derives = "Debug"
)]
pub struct CreateReleaseMutation;
pub(super) async fn create_network_release(
gitlab_token: String,
branch: String,
network: String,
release_notes: String,
) -> Result<()> {
// this is the important line
let request_body = CreateReleaseMutation::build_query(create_release_mutation::Variables {
branch,
description: release_notes,
network,
links: vec![],
});
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 if let Some(errors) = response_body.errors {
Err(anyhow!("Errors: {:?}", 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"))
}
}
......@@ -25,12 +25,10 @@ use graphql_client::{GraphQLQuery, Response};
)]
pub struct GetReleaseOfProjectQuery;
pub(super) async fn get_release(milestone: String) -> Result<Vec<String>> {
pub(super) async fn get_release(tag: String) -> Result<Vec<String>> {
// this is the important line
let request_body =
GetReleaseOfProjectQuery::build_query(get_release_of_project_query::Variables {
milestone,
});
GetReleaseOfProjectQuery::build_query(get_release_of_project_query::Variables { tag });
let client = reqwest::Client::new();
let res = client
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment