Skip to content

Commit

Permalink
chore: Avoid using git submodule for new project template (#119)
Browse files Browse the repository at this point in the history
[`cargo publish` does not include the new project template as it has
`Cargo.toml`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-exclude-and-include-fields),
so we need to rename it to `Cargo.toml.template` or remove it, and
having an external repo without Cargo.toml defeats the purpose. Thus, I
merged the code into this repo and we will need to set up CI to test
that template.
  • Loading branch information
frol authored Nov 24, 2023
1 parent 6ca9ab9 commit 8cbb09f
Show file tree
Hide file tree
Showing 15 changed files with 321 additions and 12 deletions.
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +0,0 @@
[submodule "cargo-near/src/commands/new/new-project-template"]
path = cargo-near/src/commands/new/new-project-template
url = https://github.com/near/cargo-near-new-project-template
6 changes: 0 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,6 @@ Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
dual licensed as below, without any additional terms or conditions.

Note, fetching the git repository of cargo-near, don't forget to pull the submodules after cloning:

```console
git submodule update --init
```

## License

Licensed under either of
Expand Down
1 change: 0 additions & 1 deletion cargo-near/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ repository = "https://github.com/near/cargo-near"
license = "MIT OR Apache-2.0"
keywords = ["cargo", "near", "contract", "abi", "build"]
categories = ["development-tools", "development-tools::cargo-plugins", "development-tools::build-utils", "command-line-utilities"]
include = ["/src"]

[package.metadata.wix]
upgrade-guid = "FFBAE83D-C3FA-45DD-9F19-C8F312E905C5"
Expand Down
2 changes: 1 addition & 1 deletion cargo-near/src/commands/new/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ const NEW_PROJECT_FILES: &[NewProjectFile] = &[
},
NewProjectFile {
file_path: "Cargo.toml",
content: include_str!("new-project-template/Cargo.toml"),
content: include_str!("new-project-template/Cargo.toml.template"),
},
NewProjectFile {
file_path: "README.md",
Expand Down
1 change: 0 additions & 1 deletion cargo-near/src/commands/new/new-project-template
Submodule new-project-template deleted from 9d5349
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Deploy to production
on:
push:
branches: [main]

jobs:
test:
uses: ./.github/workflows/test.yml

deploy-staging:
name: Deploy to production
needs: [test]
runs-on: ubuntu-latest
steps:
- 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.4.1/cargo-near-installer.sh | sh
- name: Deploy to production
run: |
cargo near deploy "${{ vars.NEAR_CONTRACT_PRODUCTION_ACCOUNT_ID }}" \
without-init-call \
network-config "${{ vars.NEAR_CONTRACT_PRODUCTION_NETWORK }}" \
sign-with-plaintext-private-key \
--signer-public-key "${{ vars.NEAR_CONTRACT_PRODUCTION_ACCOUNT_PUBLIC_KEY }}" \
--signer-private-key "${{ secrets.NEAR_CONTRACT_PRODUCTION_ACCOUNT_PRIVATE_KEY }}" \
send
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Deploy to staging
on:
pull_request:

jobs:
test:
uses: ./.github/workflows/test.yml

deploy-staging:
name: Deploy to staging subaccount
permissions:
pull-requests: write
needs: [test]
runs-on: ubuntu-latest
env:
NEAR_CONTRACT_PR_STAGING_ACCOUNT_ID: gh-${{ github.event.number }}.${{ vars.NEAR_CONTRACT_STAGING_ACCOUNT_ID }}

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Install near CLI
run: curl --proto '=https' --tlsv1.2 -LsSf https://github.com/near/near-cli-rs/releases/download/v0.7.0/near-cli-rs-installer.sh | sh
- name: Create staging account
if: github.event.action == 'opened' || github.event.action == 'reopened'
run: |
near account create-account fund-myself "${{ env.NEAR_CONTRACT_PR_STAGING_ACCOUNT_ID }}" '10 NEAR' \
use-manually-provided-public-key "${{ vars.NEAR_CONTRACT_STAGING_ACCOUNT_PUBLIC_KEY }}" \
sign-as "${{ vars.NEAR_CONTRACT_STAGING_ACCOUNT_ID }}" \
network-config "${{ vars.NEAR_CONTRACT_STAGING_NETWORK }}" \
sign-with-plaintext-private-key \
--signer-public-key "${{ vars.NEAR_CONTRACT_STAGING_ACCOUNT_PUBLIC_KEY }}" \
--signer-private-key "${{ secrets.NEAR_CONTRACT_STAGING_ACCOUNT_PRIVATE_KEY }}" \
send
- name: Install cargo-near CLI
run: curl --proto '=https' --tlsv1.2 -LsSf https://github.com/near/cargo-near/releases/download/cargo-near-v0.4.1/cargo-near-installer.sh | sh
- name: Deploy to staging
run: |
cargo near deploy "${{ env.NEAR_CONTRACT_PR_STAGING_ACCOUNT_ID }}" \
without-init-call \
network-config "${{ vars.NEAR_CONTRACT_STAGING_NETWORK }}" \
sign-with-plaintext-private-key \
--signer-public-key "${{ vars.NEAR_CONTRACT_STAGING_ACCOUNT_PUBLIC_KEY }}" \
--signer-private-key "${{ secrets.NEAR_CONTRACT_STAGING_ACCOUNT_PRIVATE_KEY }}" \
send
- name: Comment on pull request
env:
GH_TOKEN: ${{ github.token }}
run: |
gh pr comment "${{ github.event.number }}" --body "Staging contract is deployed to ["'`'"${{ env.NEAR_CONTRACT_PR_STAGING_ACCOUNT_ID }}"'`'" account](https://explorer.${{ vars.NEAR_CONTRACT_STAGING_NETWORK }}.near.org/accounts/${{ env.NEAR_CONTRACT_PR_STAGING_ACCOUNT_ID }})"
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Test
on:
workflow_call:

jobs:
code-formatting:
name: Code Formatting
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- run: cargo fmt --check

code-linter:
name: Code Linter
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Run cargo clippy
run: |
rustup component add clippy
cargo clippy --all-features --workspace --tests -- --warn clippy::all --warn clippy::nursery
tests:
name: Tests
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Run cargo test
run: cargo test
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Undeploy staging
on:
pull_request:
types: [closed]

jobs:
cleanup-staging:
name: Cleanup staging account
runs-on: ubuntu-latest
env:
NEAR_CONTRACT_PR_STAGING_ACCOUNT_ID: gh-${{ github.event.number }}.${{ vars.NEAR_CONTRACT_STAGING_ACCOUNT_ID }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install near CLI
run: curl --proto '=https' --tlsv1.2 -LsSf https://github.com/near/near-cli-rs/releases/download/v0.7.0/near-cli-rs-installer.sh | sh
- name: Remove staging account
run: |
near account delete-account "${{ env.NEAR_CONTRACT_PR_STAGING_ACCOUNT_ID }}" \
beneficiary "${{ vars.NEAR_CONTRACT_STAGING_ACCOUNT_ID }}" \
network-config "${{ vars.NEAR_CONTRACT_STAGING_NETWORK }}" \
sign-with-plaintext-private-key \
--signer-public-key "${{ vars.NEAR_CONTRACT_STAGING_ACCOUNT_PUBLIC_KEY }}" \
--signer-private-key "${{ secrets.NEAR_CONTRACT_STAGING_ACCOUNT_PRIVATE_KEY }}" \
send
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/target
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[package]
name = "cargo-near-new-project-name"
description = "cargo-near-new-project-description"
version = "0.1.0"
edition = "2021"
# TODO: Fill out the repository field to help NEAR ecosystem tools to discover your project.
# NEP-0330 is automatically implemented for all contracts built with near-sdk-rs.
# Link to the repository will be available via `contract_source_metadata` view-function.
#repository = "https://github.com/xxx/xxx"

[lib]
crate-type = ["cdylib", "rlib"]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
near-sdk = "5.0.0-alpha.1"

[dev-dependencies]
near-workspaces = { version = "0.9.0", default-features = false, features = ["install", "unstable"] }
tokio = { version = "1.12.0", features = ["full"] }
serde_json = "1"

[profile.release]
codegen-units = 1
# Tell `rustc` to optimize for small code size.
opt-level = "z"
lto = true
debug = false
panic = "abort"
# Opt into extra safety checks on arithmetic operations https://stackoverflow.com/a/64136471/249801
overflow-checks = true
37 changes: 37 additions & 0 deletions cargo-near/src/commands/new/new-project-template/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# cargo-near-new-project-name

cargo-near-new-project-description

## How to Build Locally?

Install [`cargo-near`](https://github.com/near/cargo-near) and run:

```bash
cargo near build
```

## How to Test Locally?

```bash
cargo test
```

## How to Deploy?

Deployment is automated with GitHub Actions CI/CD pipeline.
To deploy manually, install [`cargo-near`](https://github.com/near/cargo-near) and run:

```bash
cargo near deploy <account-id>
```

## Useful Links

- [cargo-near](https://github.com/near/cargo-near) - NEAR smart contract development toolkit for Rust
- [near CLI](https://near.cli.rs) - Iteract with NEAR blockchain from command line
- [NEAR Rust SDK Documentation](https://docs.near.org/sdk/rust/introduction)
- [NEAR Documentation](https://docs.near.org)
- [NEAR StackOverflow](https://stackoverflow.com/questions/tagged/nearprotocol)
- [NEAR Discord](https://near.chat)
- [NEAR Telegram Developers Community Group](https://t.me/neardev)
- NEAR DevHub: [Telegram](https://t.me/neardevhub), [Twitter](https://twitter.com/neardevhub)
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[toolchain]
channel = "1.73.0"
components = ["rustfmt"]
targets = ["wasm32-unknown-unknown"]
78 changes: 78 additions & 0 deletions cargo-near/src/commands/new/new-project-template/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
use near_sdk::borsh::{BorshDeserialize, BorshSerialize};
use near_sdk::collections::LookupMap;
use near_sdk::{env, near_bindgen, AccountId, BorshStorageKey};

#[near_bindgen]
#[derive(BorshDeserialize, BorshSerialize)]
#[borsh(crate = "near_sdk::borsh")]
pub struct StatusMessage {
records: LookupMap<AccountId, String>,
}

#[derive(BorshSerialize, BorshStorageKey)]
#[borsh(crate = "near_sdk::borsh")]
enum StorageKey {
StatusMessageRecords,
}

impl Default for StatusMessage {
fn default() -> Self {
Self {
records: LookupMap::new(StorageKey::StatusMessageRecords),
}
}
}

#[near_bindgen]
impl StatusMessage {
pub fn set_status(&mut self, message: String) {
let account_id = env::predecessor_account_id();
self.records.insert(&account_id, &message);
}

pub fn get_status(&self, account_id: AccountId) -> Option<String> {
self.records.get(&account_id)
}
}

#[cfg(not(target_arch = "wasm32"))]
#[cfg(test)]
mod tests {
use near_sdk::test_utils::{accounts, VMContextBuilder};
use near_sdk::testing_env;

use super::*;

// Allows for modifying the environment of the mocked blockchain
fn get_context(predecessor_account_id: AccountId) -> VMContextBuilder {
let mut builder = VMContextBuilder::new();
builder
.current_account_id(accounts(0))
.signer_account_id(predecessor_account_id.clone())
.predecessor_account_id(predecessor_account_id);
builder
}

#[test]
fn set_get_message() {
let mut context = get_context(accounts(1));
// Initialize the mocked blockchain
testing_env!(context.build());

// Set the testing environment for the subsequent calls
testing_env!(context.predecessor_account_id(accounts(1)).build());

let mut contract = StatusMessage::default();
contract.set_status("hello".to_string());
assert_eq!(
"hello".to_string(),
contract.get_status(accounts(1)).unwrap()
);
}

#[test]
fn get_nonexistent_message() {
let contract = StatusMessage::default();
assert_eq!(None, contract.get_status("francis.near".parse().unwrap()));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use serde_json::json;

#[tokio::test]
async fn test_contract_is_operational() -> Result<(), Box<dyn std::error::Error>> {
let sandbox = near_workspaces::sandbox().await?;
let contract_wasm = near_workspaces::compile_project("./").await?;

let contract = sandbox.dev_deploy(&contract_wasm).await?;

let user1_account = sandbox.dev_create_account().await?;
let user2_account = sandbox.dev_create_account().await?;

let outcome = user1_account
.call(contract.id(), "set_status")
.args_json(json!({"message": "test status"}))
.transact()
.await?;
assert!(outcome.is_success());

let user1_message_outcome = contract
.view("get_status")
.args_json(json!({"account_id": user1_account.id()}))
.await?;
assert_eq!(user1_message_outcome.json::<String>()?, "test status");

let user2_message_outcome = contract
.view("get_status")
.args_json(json!({"account_id": user2_account.id()}))
.await?;
assert_eq!(user2_message_outcome.result, b"null");

Ok(())
}

0 comments on commit 8cbb09f

Please sign in to comment.