diff --git a/.ci/release_script.sh b/.ci/release_script.sh deleted file mode 100644 index 5f3b6d389b2ecf2af9392324f94f9d81d6d0fa8c..0000000000000000000000000000000000000000 --- a/.ci/release_script.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/bash - -# stop script if any command fails -set -e - -# Vérifiez si le token d'accès privé GitLab est défini -if [ -z "$GITLAB_PRIVATE_TOKEN" ]; then - echo "Token d'accès privé GitLab non défini. Arrêt du script." - exit 1 -fi - -if [ -z "$CI_COMMIT_TAG" ]; then - echo "This script should only be run on a tag." - exit 1 -fi - -# Variables -PROJECT_ID="604" -RELEASE_NAME="v$CI_COMMIT_TAG" -RELEASE_DESCRIPTION="Release v$CI_COMMIT_TAG is awesome !" -ARTIFACT_PATH="target/release/gcli" -GITLAB_API_URL="https://git.duniter.org/api/v4" - -# Création de la release -echo "Création de la release $RELEASE_NAME..." -curl --header "PRIVATE-TOKEN: $GITLAB_PRIVATE_TOKEN" \ - --data "name=$RELEASE_NAME&tag_name=$CI_COMMIT_TAG&description=$RELEASE_DESCRIPTION" \ - "$GITLAB_API_URL/projects/$PROJECT_ID/releases" - -# Construction de l'URL de l'artéfact -ARTIFACT_URL="$CI_PROJECT_URL/-/jobs/artifacts/$CI_COMMIT_TAG/raw/$ARTIFACT_PATH?job=build" - -# Ajout de l'artéfact à la release -echo "Ajout de l'artéfact à la release..." -curl --header "PRIVATE-TOKEN: $GITLAB_PRIVATE_TOKEN" \ - --data-urlencode "url=$ARTIFACT_URL" \ - --data-urlencode "name=$(basename $ARTIFACT_PATH)" \ - "$GITLAB_API_URL/projects/$PROJECT_ID/releases/$CI_COMMIT_TAG/assets/links" - -echo "Script terminé." diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 74553382c04235f0230ebe0231b0761488115d92..6bc60149ffd5d2bddaa4065a8635315c6476e98f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,5 +1,6 @@ # Official language image. Look for the different tagged releases at: # https://hub.docker.com/r/library/rust/tags/ + image: "rust:latest" stages: @@ -19,22 +20,39 @@ build: - target/release/gcli # use cache to avoid re-downloading and re-building all dependencies cache: - - key: - files: - - Cargo.lock - paths: - - target/release + key: + files: + - Cargo.lock + paths: + - target/release # only build gcli when adding a tag only: - tags release: stage: release - image: rust + image: registry.gitlab.com/gitlab-org/release-cli:latest script: - - chmod +x .ci/release_script.sh - - .ci/release_script.sh + - echo "Creating a release..." + - apk update && apk add git + - git fetch --tags + - LAST_VERSION=$(git tag --sort=-v:refname | sed -n '2p') + - git log --pretty="format:- %s ([%h]($CI_PROJECT_URL/-/commit/%h)) " HEAD...$LAST_VERSION --reverse > release_description.txt + # Define release parameters + release: + # Release name and description using the tag name + name: "v$CI_COMMIT_TAG" + description: "Latest changes:\n$(cat release_description.txt)" + # Set the tag for the release + tag_name: "$CI_COMMIT_TAG" + # Attach the artifact to the release + assets: + links: + - name: "gcli v$CI_COMMIT_TAG for Linux" + url: "$CI_PROJECT_URL/-/jobs/artifacts/$CI_COMMIT_TAG/raw/target/release/gcli?job=build" + # Trigger release creation only for tagged commits only: - tags + # Not necessary but clearly shows the dependency dependencies: - build diff --git a/Cargo.lock b/Cargo.lock index 5cf8c391a12905c87cb6203914d594db29dab0ef..000e9efcdb7c840b72ff1e70dcaf1208a844215a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1173,6 +1173,31 @@ version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +[[package]] +name = "crossterm" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e64e6c0fbe2c17357405f7c758c1ef960fce08bdfb2c03d88d2a18d7e09c4b67" +dependencies = [ + "bitflags 1.3.2", + "crossterm_winapi", + "libc", + "mio", + "parking_lot", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +dependencies = [ + "winapi", +] + [[package]] name = "crunchy" version = "0.2.2" @@ -1467,7 +1492,7 @@ dependencies = [ "regex", "syn 2.0.48", "termcolor", - "toml 0.8.8", + "toml 0.8.9", "walkdir", ] @@ -1875,7 +1900,7 @@ dependencies = [ [[package]] name = "gcli" -version = "0.2.1" +version = "0.2.2" dependencies = [ "anyhow", "bs58", @@ -1885,6 +1910,7 @@ dependencies = [ "futures", "graphql_client", "hex", + "inquire", "log", "nacl", "parity-scale-codec", @@ -2333,6 +2359,22 @@ dependencies = [ "generic-array 0.14.7", ] +[[package]] +name = "inquire" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c33e7c1ddeb15c9abcbfef6029d8e29f69b52b6d6c891031b88ed91b5065803b" +dependencies = [ + "bitflags 1.3.2", + "crossterm", + "dyn-clone", + "lazy_static", + "newline-converter", + "thiserror", + "unicode-segmentation", + "unicode-width", +] + [[package]] name = "instant" version = "0.1.12" @@ -2728,6 +2770,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" dependencies = [ "libc", + "log", "wasi", "windows-sys 0.48.0", ] @@ -2756,6 +2799,15 @@ dependencies = [ "tempfile", ] +[[package]] +name = "newline-converter" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f71d09d5c87634207f894c6b31b6a2b2c64ea3bdcf71bd5599fdbbe1600c00f" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "no-std-net" version = "0.6.0" @@ -3150,7 +3202,7 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" dependencies = [ - "toml_edit 0.21.0", + "toml_edit 0.21.1", ] [[package]] @@ -4024,6 +4076,27 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "signal-hook" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-mio" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" +dependencies = [ + "libc", + "mio", + "signal-hook", +] + [[package]] name = "signal-hook-registry" version = "1.4.1" @@ -5031,14 +5104,14 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" +checksum = "c6a4b9e8023eb94392d3dca65d717c53abc5dad49c07cb65bb8fcd87115fa325" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.21.0", + "toml_edit 0.21.1", ] [[package]] @@ -5074,9 +5147,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.21.0" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ "indexmap 2.2.1", "serde", @@ -5267,6 +5340,18 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + +[[package]] +name = "unicode-width" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" + [[package]] name = "unicode-xid" version = "0.2.4" diff --git a/Cargo.toml b/Cargo.toml index ae6e0208ea64032eecf58baa920bad8758b5cdc9..19e223c2441933748e3eeb09581393a7bbc8715b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,14 +1,22 @@ [package] -authors = ["librelois <c@elo.tf>", "tuxmain <tuxmain@zettascript.org>", "h30x <hugo@trentesaux.fr>"] +authors = [ + "librelois <c@elo.tf>", + "tuxmain <tuxmain@zettascript.org>", + "h30x <hugo@trentesaux.fr>", +] edition = "2021" -license = "AGPL-3.0" +license = "AGPL-3.0-only" name = "gcli" repository = "https://git.duniter.org/clients/rust/gcli-v2s" -version = "0.2.1" +version = "0.2.2" [dependencies] # subxt is main dependency -subxt = { git = 'https://github.com/duniter/subxt', branch = 'subxt-v0.34.0-duniter-substrate-v1.6.0', default-features = false, features = ["substrate-compat", "native", "jsonrpsee"] } +subxt = { git = 'https://github.com/duniter/subxt', branch = 'subxt-v0.34.0-duniter-substrate-v1.6.0', default-features = false, features = [ + "substrate-compat", + "native", + "jsonrpsee", +] } # substrate primitives dependencies sp-core = { git = "https://github.com/duniter/duniter-polkadot-sdk.git", branch = "duniter-substrate-v1.6.0" } sp-runtime = { git = "https://github.com/duniter/duniter-polkadot-sdk.git", branch = "duniter-substrate-v1.6.0" } @@ -27,9 +35,10 @@ serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0.113" tokio = { version = "^1.35.1", features = ["macros"] } confy = "^0.5.1" -scrypt = { version = "^0.11", default-features = false } # for old-style key generation -nacl = { version = "^0.5.3" } # for old-style key generation +scrypt = { version = "^0.11", default-features = false } # for old-style key generation +nacl = { version = "^0.5.3" } # for old-style key generation bs58 = "^0.5.0" +inquire = "0.6.2" # allows to build gcli for different runtimes and with different predefined networks [features] @@ -37,5 +46,3 @@ default = ["gdev"] # default runtime is "gdev", gdev network is available gdev = [] gtest = [] g1 = [] - - diff --git a/src/commands.rs b/src/commands.rs index 3ce40227796a407e7cd83fe8e806a3363632e896..277764b2f115d52555166b96be2221fcd64a23fe 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -8,6 +8,7 @@ pub mod expire; pub mod identity; pub mod net_test; pub mod oneshot; +pub mod publish; pub mod revocation; pub mod runtime; pub mod smith; diff --git a/src/commands/publish.rs b/src/commands/publish.rs new file mode 100644 index 0000000000000000000000000000000000000000..cdae6ef940b1a7884dd0bccdc4e51ea34ac1e891 --- /dev/null +++ b/src/commands/publish.rs @@ -0,0 +1,55 @@ +// commands/publish.rs +// This module handles the 'publish' command of the CLI. + +use crate::GcliError; +use anyhow::anyhow; +use inquire::Confirm; +use std::process::Command; + +/// Executes the 'publish' operation. +pub async fn handle_command() -> Result<(), GcliError> { + // Step 1: Get actual version of gcli + const VERSION: &str = env!("CARGO_PKG_VERSION"); + + // Step 2: Check if the git tag already exists + let tag_check_output = Command::new("git").args(["tag", "-l", VERSION]).output()?; + + if !tag_check_output.stdout.is_empty() { + return Err(GcliError::Logic(format!("Tag {VERSION} already exists"))); + } + + // Display a confirmation prompt with the version number. + match Confirm::new(&format!( + "Are you sure you want to publish version {VERSION} ?" + )) + .with_default(false) + .prompt() + { + Ok(true) => { + // User confirmed, proceed publishing + // Step 3: Create and push the git tag + Command::new("git") + .args(["tag", "-a", VERSION, "-m", &format!("Release v{VERSION}")]) + .status() + .map_err(|e| anyhow!(e))?; + + Command::new("git") + .args(["push", "origin", &format!("refs/tags/{VERSION}")]) + .status() + .map_err(|e| anyhow!(e))?; + println!("Publication of version {VERSION} completed successfully."); + Ok(()) + } + Ok(false) => { + // User did not confirm, cancel the operation + println!("Publication cancelled."); + Ok(()) + } + Err(_) => { + // There was an error with the prompt, return an error + Err(GcliError::Input( + "Failed to display confirmation prompt".to_string(), + )) + } + } +} diff --git a/src/main.rs b/src/main.rs index eb0241866ce02b46fa833eaba50548f2ca3788ee..3eaa6df94ad8f53dcf50884882f0d2399dd7e507 100644 --- a/src/main.rs +++ b/src/main.rs @@ -100,6 +100,9 @@ pub enum Subcommand { /// Cesium #[clap(subcommand, hide = true)] Cesium(commands::cesium::Subcommand), + /// Publish a new git tag with actual version + #[clap(hide = true)] + Publish, } /// main function @@ -135,6 +138,7 @@ async fn main() -> Result<(), GcliError> { Subcommand::Indexer(subcommand) => indexer::handle_command(data, subcommand).await, Subcommand::Config(subcommand) => conf::handle_command(data, subcommand), Subcommand::Cesium(subcommand) => commands::cesium::handle_command(data, subcommand).await, + Subcommand::Publish => commands::publish::handle_command().await, }; if let Err(ref e) = result { println!("{}", e) diff --git a/src/utils.rs b/src/utils.rs index c2b73022d8122adaaeed18175fedeed166375b70..91c0796334bba8cd4fc05a465f56bd8453f6326f 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -103,6 +103,8 @@ pub enum GcliError { Input(String), /// error coming from anyhow (to be removed) Anyhow(anyhow::Error), + /// error coming from io + IoError(std::io::Error), } impl std::fmt::Display for GcliError { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { @@ -132,3 +134,8 @@ impl From<confy::ConfyError> for GcliError { GcliError::Anyhow(e.into()) } } +impl From<std::io::Error> for GcliError { + fn from(error: std::io::Error) -> Self { + GcliError::IoError(error) + } +}