diff --git a/README.md b/README.md index 19aeb7bf..6ebc571d 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,8 @@ cargo near new Initializes a new project skeleton to create a contract from a template. +[Example](./docs/workflows.md) of github [workflows](./cargo-near/src/commands/new/new-project-template/.github/workflows) configuration, created by `cargo near new`. + --- ```console diff --git a/cargo-near-build/src/near/docker_build/git_checks/dirty.rs b/cargo-near-build/src/near/docker_build/git_checks/dirty.rs index 6aa38a8c..092b49ee 100644 --- a/cargo-near-build/src/near/docker_build/git_checks/dirty.rs +++ b/cargo-near-build/src/near/docker_build/git_checks/dirty.rs @@ -14,7 +14,7 @@ pub fn check_then_handle( ) -> eyre::Result<()> { let result = check(repo_root); match (result, context) { - (Err(err), BuildContext::Deploy) => { + (Err(err), BuildContext::Deploy { .. }) => { println!( "{}", "Either commit and push, or revert following changes to continue deployment:" diff --git a/cargo-near-build/src/near/docker_build/mod.rs b/cargo-near-build/src/near/docker_build/mod.rs index 8fcbadb3..1a029da6 100644 --- a/cargo-near-build/src/near/docker_build/mod.rs +++ b/cargo-near-build/src/near/docker_build/mod.rs @@ -38,17 +38,29 @@ pub fn run(docker_opts: DockerBuildOpts) -> eyre::Result { metadata::ReproducibleBuild::parse(cloned_repo.crate_metadata()) })?; - if let BuildContext::Deploy = docker_opts.context { - pretty_print::handle_step( - "Performing check that current HEAD has been pushed to remote...", - || { - git_checks::pushed_to_remote::check( - // this unwrap depends on `metadata::ReproducibleBuild::validate` logic - &docker_build_meta.repository.clone().unwrap(), - crate_in_repo.head, - ) - }, - )?; + if let BuildContext::Deploy { + skip_git_remote_check, + } = docker_opts.context + { + if !skip_git_remote_check { + pretty_print::handle_step( + "Performing check that current HEAD has been pushed to remote...", + || { + git_checks::pushed_to_remote::check( + // this unwrap depends on `metadata::ReproducibleBuild::validate` logic + &docker_build_meta.repository.clone().unwrap(), + crate_in_repo.head, + ) + }, + )?; + } else { + pretty_print::handle_step( + "Check that current HEAD has been pushed to remote was configured out by `--skip-git-remote-check` flag", + || { + Ok(()) + }, + )?; + } } if std::env::var(env_keys::nep330::nonspec::SERVER_DISABLE_INTERACTIVE).is_err() { pretty_print::handle_step("Performing `docker` sanity check...", || { diff --git a/cargo-near-build/src/types/near/build/input/mod.rs b/cargo-near-build/src/types/near/build/input/mod.rs index f549082f..023e6788 100644 --- a/cargo-near-build/src/types/near/build/input/mod.rs +++ b/cargo-near-build/src/types/near/build/input/mod.rs @@ -8,7 +8,7 @@ mod docker_context; #[derive(Debug, Clone, Copy)] pub enum BuildContext { Build, - Deploy, + Deploy { skip_git_remote_check: bool }, } /// argument of [build](crate::build) function diff --git a/cargo-near-build/src/types/near/docker_build/cloned_repo.rs b/cargo-near-build/src/types/near/docker_build/cloned_repo.rs index b672476f..cc83b187 100644 --- a/cargo-near-build/src/types/near/docker_build/cloned_repo.rs +++ b/cargo-near-build/src/types/near/docker_build/cloned_repo.rs @@ -37,7 +37,7 @@ impl ClonedRepo { println!("{}", WARN_BECOMES_ERR.red(),); std::thread::sleep(Duration::new(5, 0)); } - (true, BuildContext::Deploy) => { + (true, BuildContext::Deploy { .. }) => { println!( "{}", "Check in Cargo.lock for contract being built into source control.".yellow() diff --git a/cargo-near-build/src/types/source_id/mod.rs b/cargo-near-build/src/types/source_id/mod.rs index b5a96011..fde41e7b 100644 --- a/cargo-near-build/src/types/source_id/mod.rs +++ b/cargo-near-build/src/types/source_id/mod.rs @@ -80,8 +80,7 @@ impl std::fmt::Display for Precise { /// Information to find a specific commit in a Git repository. #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum GitReference { - /// From a specific revision. Can be a commit hash (either short or full), - /// or a named reference like `refs/pull/493/head`. + /// From a specific revision. Can be a commit hash (only full form) Rev(String), } diff --git a/cargo-near/src/commands/build_command/mod.rs b/cargo-near/src/commands/build_command/mod.rs index 1d70ead2..c6bfdc23 100644 --- a/cargo-near/src/commands/build_command/mod.rs +++ b/cargo-near/src/commands/build_command/mod.rs @@ -48,6 +48,14 @@ pub struct BuildCommand { impl BuildCommand { pub fn run(self, context: BuildContext) -> color_eyre::eyre::Result { if self.no_docker() { + if let BuildContext::Deploy { + skip_git_remote_check: true, + } = context + { + return Err(color_eyre::eyre::eyre!( + "`--skip-git-remote-check` flag is only applicable for docker builds" + )); + } cargo_near_build::build(self.into()) } else { cargo_near_build::docker::build(cargo_near_build::docker::DockerBuildOpts { diff --git a/cargo-near/src/commands/deploy/mod.rs b/cargo-near/src/commands/deploy/mod.rs index 6d6bc9a8..a3e81c15 100644 --- a/cargo-near/src/commands/deploy/mod.rs +++ b/cargo-near/src/commands/deploy/mod.rs @@ -10,6 +10,9 @@ pub struct Contract { #[interactive_clap(flatten)] /// Specify a build command args: build_command_args: build_command::BuildCommand, + /// whether to check that code has been pushed to repository during docker build + #[interactive_clap(long)] + skip_git_remote_check: bool, #[interactive_clap(skip_default_input_arg)] /// What is the contract account ID? contract_account_id: near_cli_rs::types::account_id::AccountId, @@ -28,7 +31,9 @@ impl ContractContext { let file_path = scope .build_command_args .clone() - .run(cargo_near_build::BuildContext::Deploy)? + .run(cargo_near_build::BuildContext::Deploy { + skip_git_remote_check: scope.skip_git_remote_check, + })? .path; Ok(Self( @@ -82,9 +87,12 @@ impl interactive_clap::FromCli for Contract { .clone() .expect("Unexpected error"); + let skip_git_remote_check = clap_variant.skip_git_remote_check; + let new_context_scope = InteractiveClapContextScopeForContract { build_command_args, contract_account_id, + skip_git_remote_check, }; let output_context = diff --git a/cargo-near/src/commands/new/mod.rs b/cargo-near/src/commands/new/mod.rs index 55939d5b..69c9f36b 100644 --- a/cargo-near/src/commands/new/mod.rs +++ b/cargo-near/src/commands/new/mod.rs @@ -44,7 +44,11 @@ impl NewContext { &new_file_path, new_project_file .content - .replace("cargo-near-new-project-name", project_name), + .replace("cargo-near-new-project-name", project_name) + .replace( + "cargo-near-new-ci-tool-version-self", + env!("CARGO_PKG_VERSION"), + ), ) .wrap_err_with(|| format!("Failed to write to file: {}", new_file_path.display()))?; } diff --git a/cargo-near/src/commands/new/new-project-template/.github/workflows/deploy-production.yml b/cargo-near/src/commands/new/new-project-template/.github/workflows/deploy-production.yml index f79ba718..f892d532 100644 --- a/cargo-near/src/commands/new/new-project-template/.github/workflows/deploy-production.yml +++ b/cargo-near/src/commands/new/new-project-template/.github/workflows/deploy-production.yml @@ -15,7 +15,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 - name: Install cargo-near CLI - run: curl --proto '=https' --tlsv1.2 -LsSf https://github.com/near/cargo-near/releases/download/cargo-near-v0.6.2/cargo-near-installer.sh | sh + run: curl --proto '=https' --tlsv1.2 -LsSf https://github.com/near/cargo-near/releases/download/cargo-near-vcargo-near-new-ci-tool-version-self/cargo-near-installer.sh | sh - name: Deploy to production run: | cargo near deploy "${{ vars.NEAR_CONTRACT_PRODUCTION_ACCOUNT_ID }}" \ diff --git a/cargo-near/src/commands/new/new-project-template/.github/workflows/deploy-staging.yml b/cargo-near/src/commands/new/new-project-template/.github/workflows/deploy-staging.yml index 5ddc7831..0f75164a 100644 --- a/cargo-near/src/commands/new/new-project-template/.github/workflows/deploy-staging.yml +++ b/cargo-near/src/commands/new/new-project-template/.github/workflows/deploy-staging.yml @@ -34,10 +34,14 @@ jobs: send - name: Install cargo-near CLI - run: curl --proto '=https' --tlsv1.2 -LsSf https://github.com/near/cargo-near/releases/download/cargo-near-v0.6.2/cargo-near-installer.sh | sh + run: curl --proto '=https' --tlsv1.2 -LsSf https://github.com/near/cargo-near/releases/download/cargo-near-vcargo-near-new-ci-tool-version-self/cargo-near-installer.sh | sh - name: Deploy to staging + # `--skip-git-remote-check` was used + # as pull request git refs `refs/pull/NUMBER/merge` are somewhat harder to access and live only as long as PRs do + # + # WASM reproducibility check akin to SourceScan won't be available for staging contracts, deployed from PRs run: | - cargo near deploy "${{ env.NEAR_CONTRACT_PR_STAGING_ACCOUNT_ID }}" \ + cargo near deploy --skip-git-remote-check "${{ env.NEAR_CONTRACT_PR_STAGING_ACCOUNT_ID }}" \ without-init-call \ network-config "${{ vars.NEAR_CONTRACT_STAGING_NETWORK }}" \ sign-with-plaintext-private-key \ diff --git a/cargo-near/src/commands/new/new-project-template/tests/test_basics.rs b/cargo-near/src/commands/new/new-project-template/tests/test_basics.rs index d6eabeed..e86b4bf0 100644 --- a/cargo-near/src/commands/new/new-project-template/tests/test_basics.rs +++ b/cargo-near/src/commands/new/new-project-template/tests/test_basics.rs @@ -16,10 +16,7 @@ async fn test_contract_is_operational() -> Result<(), Box .await?; assert!(outcome.is_success()); - let user_message_outcome = contract - .view("get_greeting") - .args_json(json!({})) - .await?; + let user_message_outcome = contract.view("get_greeting").args_json(json!({})).await?; assert_eq!(user_message_outcome.json::()?, "Hello World!"); Ok(()) diff --git a/docs/gh_settings_secrets_and_vars.png b/docs/gh_settings_secrets_and_vars.png new file mode 100644 index 00000000..391c9275 Binary files /dev/null and b/docs/gh_settings_secrets_and_vars.png differ diff --git a/docs/workflows.md b/docs/workflows.md new file mode 100644 index 00000000..08811b5a --- /dev/null +++ b/docs/workflows.md @@ -0,0 +1,25 @@ +![gh_settings_secrets_and_vars](./gh_settings_secrets_and_vars.png) + +Example production account values: + +```bash +# variables +NEAR_CONTRACT_PRODUCTION_ACCOUNT_ID=cargo_near_test_workflows.testnet +NEAR_CONTRACT_PRODUCTION_NETWORK=testnet +NEAR_CONTRACT_PRODUCTION_ACCOUNT_PUBLIC_KEY=ed25519:EvCRvguSjeaTGuzQPQmLg1GqWLqgihBKKcSHT4xtS8K +# secrets +NEAR_CONTRACT_PRODUCTION_ACCOUNT_PRIVATE_KEY=ed25519:4diBhcs9ECg3sDPE97gCFhHbB21BSRheWSzrqt1UVciEoMhpecnFjqapeSfrxxxxxxxxxxxxxxxxxxxxxxxxxxxx +``` + +Example staging account values: + +```bash +# variables +NEAR_CONTRACT_STAGING_ACCOUNT_PUBLIC_KEY=ed25519:EvCRvguSjeaTGuzQPQmLg1GqWLqgihBKKcSHT4xtS8K +NEAR_CONTRACT_STAGING_ACCOUNT_ID=cargo_near_test_workflows.testnet +NEAR_CONTRACT_STAGING_NETWORK=testnet +# secrets +NEAR_CONTRACT_STAGING_ACCOUNT_PRIVATE_KEY=ed25519:4diBhcs9ECg3sDPE97gCFhHbB21BSRheWSzrqt1UVciEoMhpecnFjqapeSfrxxxxxxxxxxxxxxxxxxxxxxxxxxxx +``` + +NOTE: last chars of both private keys examples are redacted/replaced with `'x'` char.